1bdf2d80f459d43f5a6df074431bacf41584f81b7shannon.woods@transgaming.com#include "precompiled.h"
295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com//
3e2e9798bbcf01eb94375432dacd7a54617532dc2shannon.woods@transgaming.com// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com// Use of this source code is governed by a BSD-style license that can be
595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com// found in the LICENSE file.
695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com//
795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com// Texture.cpp: Implements the gl::Texture class and its derived classes
995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com// Texture2D and TextureCubeMap. Implements GL texture objects and related
1095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com// functionality. [OpenGL ES 2.0.24] section 3.7 page 63.
1195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
1295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com#include "libGLESv2/Texture.h"
1395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
1495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com#include "libGLESv2/main.h"
15a2ecfcccf1d1a85e6054a7314ce1f9de0648ac7fshannonwoods@chromium.org#include "common/mathutil.h"
16a2ecfcccf1d1a85e6054a7314ce1f9de0648ac7fshannonwoods@chromium.org#include "common/utilities.h"
174ad58e083de84d1bc9bae56154886395192bee9cshannonwoods@chromium.org#include "libGLESv2/formatutils.h"
18486d9e9b6b4ed31f66d2624b8e822020fe40a1f7shannon.woods@transgaming.com#include "libGLESv2/Renderbuffer.h"
19486d9e9b6b4ed31f66d2624b8e822020fe40a1f7shannon.woods@transgaming.com#include "libGLESv2/renderer/Image.h"
20486d9e9b6b4ed31f66d2624b8e822020fe40a1f7shannon.woods@transgaming.com#include "libGLESv2/renderer/Renderer.h"
21486d9e9b6b4ed31f66d2624b8e822020fe40a1f7shannon.woods@transgaming.com#include "libGLESv2/renderer/TextureStorage.h"
22486d9e9b6b4ed31f66d2624b8e822020fe40a1f7shannon.woods@transgaming.com#include "libEGL/Surface.h"
231beb1db8015f38674fc78cd4e53316934b0e3839Jamie Madill#include "libGLESv2/Buffer.h"
241beb1db8015f38674fc78cd4e53316934b0e3839Jamie Madill#include "libGLESv2/renderer/BufferStorage.h"
250e0510fd08426f39f104c5dc937c9d7f4469db95Jamie Madill#include "libGLESv2/renderer/RenderTarget.h"
2695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
2795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.comnamespace gl
2895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
2995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
30f898990d682b639d7093dc837c6da3e70242d02bJamie Madillbool IsMipmapFiltered(const SamplerState &samplerState)
31f898990d682b639d7093dc837c6da3e70242d02bJamie Madill{
32f898990d682b639d7093dc837c6da3e70242d02bJamie Madill    switch (samplerState.minFilter)
33f898990d682b639d7093dc837c6da3e70242d02bJamie Madill    {
34f898990d682b639d7093dc837c6da3e70242d02bJamie Madill      case GL_NEAREST:
35f898990d682b639d7093dc837c6da3e70242d02bJamie Madill      case GL_LINEAR:
36f898990d682b639d7093dc837c6da3e70242d02bJamie Madill        return false;
37f898990d682b639d7093dc837c6da3e70242d02bJamie Madill      case GL_NEAREST_MIPMAP_NEAREST:
38f898990d682b639d7093dc837c6da3e70242d02bJamie Madill      case GL_LINEAR_MIPMAP_NEAREST:
39f898990d682b639d7093dc837c6da3e70242d02bJamie Madill      case GL_NEAREST_MIPMAP_LINEAR:
40f898990d682b639d7093dc837c6da3e70242d02bJamie Madill      case GL_LINEAR_MIPMAP_LINEAR:
41f898990d682b639d7093dc837c6da3e70242d02bJamie Madill        return true;
42f898990d682b639d7093dc837c6da3e70242d02bJamie Madill      default: UNREACHABLE();
43f898990d682b639d7093dc837c6da3e70242d02bJamie Madill        return false;
44f898990d682b639d7093dc837c6da3e70242d02bJamie Madill    }
45f898990d682b639d7093dc837c6da3e70242d02bJamie Madill}
46f898990d682b639d7093dc837c6da3e70242d02bJamie Madill
47d4589c97f7d7c3be8896f8addc6f2cbd50ef73c3Jamie Madillbool IsRenderTargetUsage(GLenum usage)
48d4589c97f7d7c3be8896f8addc6f2cbd50ef73c3Jamie Madill{
49d4589c97f7d7c3be8896f8addc6f2cbd50ef73c3Jamie Madill    return (usage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE);
50d4589c97f7d7c3be8896f8addc6f2cbd50ef73c3Jamie Madill}
51d4589c97f7d7c3be8896f8addc6f2cbd50ef73c3Jamie Madill
524907f2c4c071e1920b90f106383a7f026e03d746Geoff LangTexture::Texture(rx::Renderer *renderer, GLuint id, GLenum target) : RefCountObject(id)
5395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
54370482e77de4d88ed2954757bf519f2f8bcd364edaniel@transgaming.com    mRenderer = renderer;
55370482e77de4d88ed2954757bf519f2f8bcd364edaniel@transgaming.com
56ebf139fe6f43719ea599457776209f3064fabb95daniel@transgaming.com    mSamplerState.minFilter = GL_NEAREST_MIPMAP_LINEAR;
57ebf139fe6f43719ea599457776209f3064fabb95daniel@transgaming.com    mSamplerState.magFilter = GL_LINEAR;
58ebf139fe6f43719ea599457776209f3064fabb95daniel@transgaming.com    mSamplerState.wrapS = GL_REPEAT;
59ebf139fe6f43719ea599457776209f3064fabb95daniel@transgaming.com    mSamplerState.wrapT = GL_REPEAT;
600b3a8dfb1e698f7ba69708f9f1bbe73179dcd07eshannon.woods%transgaming.com@gtempaccount.com    mSamplerState.wrapR = GL_REPEAT;
61ebf139fe6f43719ea599457776209f3064fabb95daniel@transgaming.com    mSamplerState.maxAnisotropy = 1.0f;
628de682870a82cad54f3fffe5c6723e858656f7e2Nicolas Capens    mSamplerState.baseLevel = 0;
638de682870a82cad54f3fffe5c6723e858656f7e2Nicolas Capens    mSamplerState.maxLevel = 1000;
648de682870a82cad54f3fffe5c6723e858656f7e2Nicolas Capens    mSamplerState.minLod = -1000.0f;
658de682870a82cad54f3fffe5c6723e858656f7e2Nicolas Capens    mSamplerState.maxLod = 1000.0f;
66c82fc41362dae28c98b16c76dda04e2988a02de1Geoff Lang    mSamplerState.compareMode = GL_NONE;
67c82fc41362dae28c98b16c76dda04e2988a02de1Geoff Lang    mSamplerState.compareFunc = GL_LEQUAL;
68bc90a4804f58d2b24babe6f247db57b9a6cdc58fGeoff Lang    mSamplerState.swizzleRed = GL_RED;
69bc90a4804f58d2b24babe6f247db57b9a6cdc58fGeoff Lang    mSamplerState.swizzleGreen = GL_GREEN;
70bc90a4804f58d2b24babe6f247db57b9a6cdc58fGeoff Lang    mSamplerState.swizzleBlue = GL_BLUE;
71bc90a4804f58d2b24babe6f247db57b9a6cdc58fGeoff Lang    mSamplerState.swizzleAlpha = GL_ALPHA;
7295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    mUsage = GL_NONE;
73c82fc41362dae28c98b16c76dda04e2988a02de1Geoff Lang
7495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    mDirtyImages = true;
7595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
7695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    mImmutable = false;
774907f2c4c071e1920b90f106383a7f026e03d746Geoff Lang
784907f2c4c071e1920b90f106383a7f026e03d746Geoff Lang    mTarget = target;
7995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
8095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
8195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.comTexture::~Texture()
8295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
8395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
8495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
854907f2c4c071e1920b90f106383a7f026e03d746Geoff LangGLenum Texture::getTarget() const
864907f2c4c071e1920b90f106383a7f026e03d746Geoff Lang{
874907f2c4c071e1920b90f106383a7f026e03d746Geoff Lang    return mTarget;
884907f2c4c071e1920b90f106383a7f026e03d746Geoff Lang}
894907f2c4c071e1920b90f106383a7f026e03d746Geoff Lang
903c7fa226aeb81469b93142b54e339f13a46ab835Jamie Madillvoid Texture::addProxyRef(const FramebufferAttachment *proxy)
918040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang{
928040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang    mRenderbufferProxies.addRef(proxy);
938040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang}
948040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang
953c7fa226aeb81469b93142b54e339f13a46ab835Jamie Madillvoid Texture::releaseProxy(const FramebufferAttachment *proxy)
968040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang{
978040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang    mRenderbufferProxies.release(proxy);
988040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang}
998040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang
10063b5f1fd695007afca2329967f9db507c9d7f139Geoff Langvoid Texture::setMinFilter(GLenum filter)
10195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
10263b5f1fd695007afca2329967f9db507c9d7f139Geoff Lang    mSamplerState.minFilter = filter;
10395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
10495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
10563b5f1fd695007afca2329967f9db507c9d7f139Geoff Langvoid Texture::setMagFilter(GLenum filter)
10695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
10763b5f1fd695007afca2329967f9db507c9d7f139Geoff Lang    mSamplerState.magFilter = filter;
10895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
10995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
11063b5f1fd695007afca2329967f9db507c9d7f139Geoff Langvoid Texture::setWrapS(GLenum wrap)
11195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
11263b5f1fd695007afca2329967f9db507c9d7f139Geoff Lang    mSamplerState.wrapS = wrap;
11395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
11495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
11563b5f1fd695007afca2329967f9db507c9d7f139Geoff Langvoid Texture::setWrapT(GLenum wrap)
11695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
11763b5f1fd695007afca2329967f9db507c9d7f139Geoff Lang    mSamplerState.wrapT = wrap;
11895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
11995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
12063b5f1fd695007afca2329967f9db507c9d7f139Geoff Langvoid Texture::setWrapR(GLenum wrap)
1210b3a8dfb1e698f7ba69708f9f1bbe73179dcd07eshannon.woods%transgaming.com@gtempaccount.com{
12263b5f1fd695007afca2329967f9db507c9d7f139Geoff Lang    mSamplerState.wrapR = wrap;
1230b3a8dfb1e698f7ba69708f9f1bbe73179dcd07eshannon.woods%transgaming.com@gtempaccount.com}
1240b3a8dfb1e698f7ba69708f9f1bbe73179dcd07eshannon.woods%transgaming.com@gtempaccount.com
12563b5f1fd695007afca2329967f9db507c9d7f139Geoff Langvoid Texture::setMaxAnisotropy(float textureMaxAnisotropy, float contextMaxAnisotropy)
12607ab841a88e2779dec5d5a347a8403c7d84f28e8daniel@transgaming.com{
12763b5f1fd695007afca2329967f9db507c9d7f139Geoff Lang    mSamplerState.maxAnisotropy = std::min(textureMaxAnisotropy, contextMaxAnisotropy);
12807ab841a88e2779dec5d5a347a8403c7d84f28e8daniel@transgaming.com}
12907ab841a88e2779dec5d5a347a8403c7d84f28e8daniel@transgaming.com
13063b5f1fd695007afca2329967f9db507c9d7f139Geoff Langvoid Texture::setCompareMode(GLenum mode)
131c82fc41362dae28c98b16c76dda04e2988a02de1Geoff Lang{
13263b5f1fd695007afca2329967f9db507c9d7f139Geoff Lang    mSamplerState.compareMode = mode;
133c82fc41362dae28c98b16c76dda04e2988a02de1Geoff Lang}
134c82fc41362dae28c98b16c76dda04e2988a02de1Geoff Lang
13563b5f1fd695007afca2329967f9db507c9d7f139Geoff Langvoid Texture::setCompareFunc(GLenum func)
136c82fc41362dae28c98b16c76dda04e2988a02de1Geoff Lang{
13763b5f1fd695007afca2329967f9db507c9d7f139Geoff Lang    mSamplerState.compareFunc = func;
138c82fc41362dae28c98b16c76dda04e2988a02de1Geoff Lang}
139c82fc41362dae28c98b16c76dda04e2988a02de1Geoff Lang
140bc90a4804f58d2b24babe6f247db57b9a6cdc58fGeoff Langvoid Texture::setSwizzleRed(GLenum swizzle)
141bc90a4804f58d2b24babe6f247db57b9a6cdc58fGeoff Lang{
142bc90a4804f58d2b24babe6f247db57b9a6cdc58fGeoff Lang    mSamplerState.swizzleRed = swizzle;
143bc90a4804f58d2b24babe6f247db57b9a6cdc58fGeoff Lang}
144bc90a4804f58d2b24babe6f247db57b9a6cdc58fGeoff Lang
145bc90a4804f58d2b24babe6f247db57b9a6cdc58fGeoff Langvoid Texture::setSwizzleGreen(GLenum swizzle)
146bc90a4804f58d2b24babe6f247db57b9a6cdc58fGeoff Lang{
147bc90a4804f58d2b24babe6f247db57b9a6cdc58fGeoff Lang    mSamplerState.swizzleGreen = swizzle;
148bc90a4804f58d2b24babe6f247db57b9a6cdc58fGeoff Lang}
149bc90a4804f58d2b24babe6f247db57b9a6cdc58fGeoff Lang
150bc90a4804f58d2b24babe6f247db57b9a6cdc58fGeoff Langvoid Texture::setSwizzleBlue(GLenum swizzle)
151bc90a4804f58d2b24babe6f247db57b9a6cdc58fGeoff Lang{
152bc90a4804f58d2b24babe6f247db57b9a6cdc58fGeoff Lang    mSamplerState.swizzleBlue = swizzle;
153bc90a4804f58d2b24babe6f247db57b9a6cdc58fGeoff Lang}
154bc90a4804f58d2b24babe6f247db57b9a6cdc58fGeoff Lang
155bc90a4804f58d2b24babe6f247db57b9a6cdc58fGeoff Langvoid Texture::setSwizzleAlpha(GLenum swizzle)
156bc90a4804f58d2b24babe6f247db57b9a6cdc58fGeoff Lang{
157bc90a4804f58d2b24babe6f247db57b9a6cdc58fGeoff Lang    mSamplerState.swizzleAlpha = swizzle;
158bc90a4804f58d2b24babe6f247db57b9a6cdc58fGeoff Lang}
159bc90a4804f58d2b24babe6f247db57b9a6cdc58fGeoff Lang
1608de682870a82cad54f3fffe5c6723e858656f7e2Nicolas Capensvoid Texture::setBaseLevel(GLint baseLevel)
1618de682870a82cad54f3fffe5c6723e858656f7e2Nicolas Capens{
1628de682870a82cad54f3fffe5c6723e858656f7e2Nicolas Capens    mSamplerState.baseLevel = baseLevel;
1638de682870a82cad54f3fffe5c6723e858656f7e2Nicolas Capens}
1648de682870a82cad54f3fffe5c6723e858656f7e2Nicolas Capens
1658de682870a82cad54f3fffe5c6723e858656f7e2Nicolas Capensvoid Texture::setMaxLevel(GLint maxLevel)
1668de682870a82cad54f3fffe5c6723e858656f7e2Nicolas Capens{
1678de682870a82cad54f3fffe5c6723e858656f7e2Nicolas Capens    mSamplerState.maxLevel = maxLevel;
1688de682870a82cad54f3fffe5c6723e858656f7e2Nicolas Capens}
1698de682870a82cad54f3fffe5c6723e858656f7e2Nicolas Capens
1708de682870a82cad54f3fffe5c6723e858656f7e2Nicolas Capensvoid Texture::setMinLod(GLfloat minLod)
1718de682870a82cad54f3fffe5c6723e858656f7e2Nicolas Capens{
1728de682870a82cad54f3fffe5c6723e858656f7e2Nicolas Capens    mSamplerState.minLod = minLod;
1738de682870a82cad54f3fffe5c6723e858656f7e2Nicolas Capens}
1748de682870a82cad54f3fffe5c6723e858656f7e2Nicolas Capens
1758de682870a82cad54f3fffe5c6723e858656f7e2Nicolas Capensvoid Texture::setMaxLod(GLfloat maxLod)
1768de682870a82cad54f3fffe5c6723e858656f7e2Nicolas Capens{
1778de682870a82cad54f3fffe5c6723e858656f7e2Nicolas Capens    mSamplerState.maxLod = maxLod;
1788de682870a82cad54f3fffe5c6723e858656f7e2Nicolas Capens}
1798de682870a82cad54f3fffe5c6723e858656f7e2Nicolas Capens
18063b5f1fd695007afca2329967f9db507c9d7f139Geoff Langvoid Texture::setUsage(GLenum usage)
18195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
18263b5f1fd695007afca2329967f9db507c9d7f139Geoff Lang    mUsage = usage;
18395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
18495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
18595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.comGLenum Texture::getMinFilter() const
18695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
187ebf139fe6f43719ea599457776209f3064fabb95daniel@transgaming.com    return mSamplerState.minFilter;
18895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
18995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
19095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.comGLenum Texture::getMagFilter() const
19195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
192ebf139fe6f43719ea599457776209f3064fabb95daniel@transgaming.com    return mSamplerState.magFilter;
19395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
19495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
19595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.comGLenum Texture::getWrapS() const
19695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
197ebf139fe6f43719ea599457776209f3064fabb95daniel@transgaming.com    return mSamplerState.wrapS;
19895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
19995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
20095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.comGLenum Texture::getWrapT() const
20195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
202ebf139fe6f43719ea599457776209f3064fabb95daniel@transgaming.com    return mSamplerState.wrapT;
20395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
20495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
2050b3a8dfb1e698f7ba69708f9f1bbe73179dcd07eshannon.woods%transgaming.com@gtempaccount.comGLenum Texture::getWrapR() const
2060b3a8dfb1e698f7ba69708f9f1bbe73179dcd07eshannon.woods%transgaming.com@gtempaccount.com{
2070b3a8dfb1e698f7ba69708f9f1bbe73179dcd07eshannon.woods%transgaming.com@gtempaccount.com    return mSamplerState.wrapR;
2080b3a8dfb1e698f7ba69708f9f1bbe73179dcd07eshannon.woods%transgaming.com@gtempaccount.com}
2090b3a8dfb1e698f7ba69708f9f1bbe73179dcd07eshannon.woods%transgaming.com@gtempaccount.com
21007ab841a88e2779dec5d5a347a8403c7d84f28e8daniel@transgaming.comfloat Texture::getMaxAnisotropy() const
21107ab841a88e2779dec5d5a347a8403c7d84f28e8daniel@transgaming.com{
212ebf139fe6f43719ea599457776209f3064fabb95daniel@transgaming.com    return mSamplerState.maxAnisotropy;
213ebf139fe6f43719ea599457776209f3064fabb95daniel@transgaming.com}
214ebf139fe6f43719ea599457776209f3064fabb95daniel@transgaming.com
215bc90a4804f58d2b24babe6f247db57b9a6cdc58fGeoff LangGLenum Texture::getSwizzleRed() const
216bc90a4804f58d2b24babe6f247db57b9a6cdc58fGeoff Lang{
217bc90a4804f58d2b24babe6f247db57b9a6cdc58fGeoff Lang    return mSamplerState.swizzleRed;
218bc90a4804f58d2b24babe6f247db57b9a6cdc58fGeoff Lang}
219bc90a4804f58d2b24babe6f247db57b9a6cdc58fGeoff Lang
220bc90a4804f58d2b24babe6f247db57b9a6cdc58fGeoff LangGLenum Texture::getSwizzleGreen() const
221bc90a4804f58d2b24babe6f247db57b9a6cdc58fGeoff Lang{
222bc90a4804f58d2b24babe6f247db57b9a6cdc58fGeoff Lang    return mSamplerState.swizzleGreen;
223bc90a4804f58d2b24babe6f247db57b9a6cdc58fGeoff Lang}
224bc90a4804f58d2b24babe6f247db57b9a6cdc58fGeoff Lang
225bc90a4804f58d2b24babe6f247db57b9a6cdc58fGeoff LangGLenum Texture::getSwizzleBlue() const
226bc90a4804f58d2b24babe6f247db57b9a6cdc58fGeoff Lang{
227bc90a4804f58d2b24babe6f247db57b9a6cdc58fGeoff Lang    return mSamplerState.swizzleBlue;
228bc90a4804f58d2b24babe6f247db57b9a6cdc58fGeoff Lang}
229bc90a4804f58d2b24babe6f247db57b9a6cdc58fGeoff Lang
230bc90a4804f58d2b24babe6f247db57b9a6cdc58fGeoff LangGLenum Texture::getSwizzleAlpha() const
231bc90a4804f58d2b24babe6f247db57b9a6cdc58fGeoff Lang{
232bc90a4804f58d2b24babe6f247db57b9a6cdc58fGeoff Lang    return mSamplerState.swizzleAlpha;
233bc90a4804f58d2b24babe6f247db57b9a6cdc58fGeoff Lang}
234bc90a4804f58d2b24babe6f247db57b9a6cdc58fGeoff Lang
2358de682870a82cad54f3fffe5c6723e858656f7e2Nicolas CapensGLint Texture::getBaseLevel() const
2368de682870a82cad54f3fffe5c6723e858656f7e2Nicolas Capens{
2378de682870a82cad54f3fffe5c6723e858656f7e2Nicolas Capens    return mSamplerState.baseLevel;
2388de682870a82cad54f3fffe5c6723e858656f7e2Nicolas Capens}
2398de682870a82cad54f3fffe5c6723e858656f7e2Nicolas Capens
2408de682870a82cad54f3fffe5c6723e858656f7e2Nicolas CapensGLint Texture::getMaxLevel() const
2418de682870a82cad54f3fffe5c6723e858656f7e2Nicolas Capens{
2428de682870a82cad54f3fffe5c6723e858656f7e2Nicolas Capens    return mSamplerState.maxLevel;
2438de682870a82cad54f3fffe5c6723e858656f7e2Nicolas Capens}
2448de682870a82cad54f3fffe5c6723e858656f7e2Nicolas Capens
2458de682870a82cad54f3fffe5c6723e858656f7e2Nicolas CapensGLfloat Texture::getMinLod() const
2468de682870a82cad54f3fffe5c6723e858656f7e2Nicolas Capens{
2478de682870a82cad54f3fffe5c6723e858656f7e2Nicolas Capens    return mSamplerState.minLod;
2488de682870a82cad54f3fffe5c6723e858656f7e2Nicolas Capens}
2498de682870a82cad54f3fffe5c6723e858656f7e2Nicolas Capens
2508de682870a82cad54f3fffe5c6723e858656f7e2Nicolas CapensGLfloat Texture::getMaxLod() const
2518de682870a82cad54f3fffe5c6723e858656f7e2Nicolas Capens{
2528de682870a82cad54f3fffe5c6723e858656f7e2Nicolas Capens    return mSamplerState.maxLod;
2538de682870a82cad54f3fffe5c6723e858656f7e2Nicolas Capens}
2548de682870a82cad54f3fffe5c6723e858656f7e2Nicolas Capens
255bc90a4804f58d2b24babe6f247db57b9a6cdc58fGeoff Langbool Texture::isSwizzled() const
256bc90a4804f58d2b24babe6f247db57b9a6cdc58fGeoff Lang{
257bc90a4804f58d2b24babe6f247db57b9a6cdc58fGeoff Lang    return mSamplerState.swizzleRed   != GL_RED   ||
258bc90a4804f58d2b24babe6f247db57b9a6cdc58fGeoff Lang           mSamplerState.swizzleGreen != GL_GREEN ||
259bc90a4804f58d2b24babe6f247db57b9a6cdc58fGeoff Lang           mSamplerState.swizzleBlue  != GL_BLUE  ||
260bc90a4804f58d2b24babe6f247db57b9a6cdc58fGeoff Lang           mSamplerState.swizzleAlpha != GL_ALPHA;
261bc90a4804f58d2b24babe6f247db57b9a6cdc58fGeoff Lang}
262bc90a4804f58d2b24babe6f247db57b9a6cdc58fGeoff Lang
263ebf139fe6f43719ea599457776209f3064fabb95daniel@transgaming.comvoid Texture::getSamplerState(SamplerState *sampler)
264ebf139fe6f43719ea599457776209f3064fabb95daniel@transgaming.com{
265ebf139fe6f43719ea599457776209f3064fabb95daniel@transgaming.com    *sampler = mSamplerState;
2668de682870a82cad54f3fffe5c6723e858656f7e2Nicolas Capens
2678de682870a82cad54f3fffe5c6723e858656f7e2Nicolas Capens    // Offset the effective base level by the texture storage's top level
2688de682870a82cad54f3fffe5c6723e858656f7e2Nicolas Capens    rx::TextureStorageInterface *texture = getNativeTexture();
2698de682870a82cad54f3fffe5c6723e858656f7e2Nicolas Capens    int topLevel = texture ? texture->getTopLevel() : 0;
2708de682870a82cad54f3fffe5c6723e858656f7e2Nicolas Capens    sampler->baseLevel = topLevel + mSamplerState.baseLevel;
27107ab841a88e2779dec5d5a347a8403c7d84f28e8daniel@transgaming.com}
27207ab841a88e2779dec5d5a347a8403c7d84f28e8daniel@transgaming.com
27395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.comGLenum Texture::getUsage() const
27495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
27595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    return mUsage;
27695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
27795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
278d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie MadillGLint Texture::getBaseLevelWidth() const
279d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill{
280d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill    const rx::Image *baseImage = getBaseLevelImage();
281d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill    return (baseImage ? baseImage->getWidth() : 0);
282d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill}
283d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill
284d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie MadillGLint Texture::getBaseLevelHeight() const
285d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill{
286d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill    const rx::Image *baseImage = getBaseLevelImage();
287d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill    return (baseImage ? baseImage->getHeight() : 0);
288d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill}
289d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill
290d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie MadillGLint Texture::getBaseLevelDepth() const
291d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill{
292d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill    const rx::Image *baseImage = getBaseLevelImage();
293d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill    return (baseImage ? baseImage->getDepth() : 0);
294d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill}
295d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill
296b8f8b89b1305f5c56ea890e2d10fd2ec9cc1f2adJamie Madill// Note: "base level image" is loosely defined to be any image from the base level,
297b8f8b89b1305f5c56ea890e2d10fd2ec9cc1f2adJamie Madill// where in the base of 2D array textures and cube maps there are several. Don't use
298b8f8b89b1305f5c56ea890e2d10fd2ec9cc1f2adJamie Madill// the base level image for anything except querying texture format and size.
299d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie MadillGLenum Texture::getBaseLevelInternalFormat() const
300d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill{
301d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill    const rx::Image *baseImage = getBaseLevelImage();
302d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill    return (baseImage ? baseImage->getInternalFormat() : GL_NONE);
303d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill}
304d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill
30588f18f458dec5c2aff302db93c57e51d89fbffa2Jamie Madillvoid Texture::setImage(const PixelUnpackState &unpack, GLenum type, const void *pixels, rx::Image *image)
30695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
307c30003d6fe8f8860f201635fc37c3458eb70a41eJamie Madill    // No-op
308c30003d6fe8f8860f201635fc37c3458eb70a41eJamie Madill    if (image->getWidth() == 0 || image->getHeight() == 0 || image->getDepth() == 0)
309c30003d6fe8f8860f201635fc37c3458eb70a41eJamie Madill    {
310c30003d6fe8f8860f201635fc37c3458eb70a41eJamie Madill        return;
311c30003d6fe8f8860f201635fc37c3458eb70a41eJamie Madill    }
312c30003d6fe8f8860f201635fc37c3458eb70a41eJamie Madill
313abef6807251f99d504e849ccb8ac756fcb9c3a97Jamie Madill    // We no longer need the "GLenum format" parameter to TexImage to determine what data format "pixels" contains.
314abef6807251f99d504e849ccb8ac756fcb9c3a97Jamie Madill    // From our image internal format we know how many channels to expect, and "type" gives the format of pixel's components.
3151beb1db8015f38674fc78cd4e53316934b0e3839Jamie Madill    const void *pixelData = pixels;
3161beb1db8015f38674fc78cd4e53316934b0e3839Jamie Madill
3171beb1db8015f38674fc78cd4e53316934b0e3839Jamie Madill    if (unpack.pixelBuffer.id() != 0)
3181beb1db8015f38674fc78cd4e53316934b0e3839Jamie Madill    {
3191beb1db8015f38674fc78cd4e53316934b0e3839Jamie Madill        // Do a CPU readback here, if we have an unpack buffer bound and the fast GPU path is not supported
3201beb1db8015f38674fc78cd4e53316934b0e3839Jamie Madill        Buffer *pixelBuffer = unpack.pixelBuffer.get();
3211beb1db8015f38674fc78cd4e53316934b0e3839Jamie Madill        ptrdiff_t offset = reinterpret_cast<ptrdiff_t>(pixels);
3221beb1db8015f38674fc78cd4e53316934b0e3839Jamie Madill        const void *bufferData = pixelBuffer->getStorage()->getData();
3231beb1db8015f38674fc78cd4e53316934b0e3839Jamie Madill        pixelData = static_cast<const unsigned char *>(bufferData) + offset;
3241beb1db8015f38674fc78cd4e53316934b0e3839Jamie Madill    }
3251beb1db8015f38674fc78cd4e53316934b0e3839Jamie Madill
3261beb1db8015f38674fc78cd4e53316934b0e3839Jamie Madill    if (pixelData != NULL)
32795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    {
3281beb1db8015f38674fc78cd4e53316934b0e3839Jamie Madill        image->loadData(0, 0, 0, image->getWidth(), image->getHeight(), image->getDepth(), unpack.alignment, type, pixelData);
32995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        mDirtyImages = true;
33095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    }
33195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
33295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
333005df41f8900641ed1df60700c8e2eca659a33cbGeoff Langbool Texture::isFastUnpackable(const PixelUnpackState &unpack, GLenum sizedInternalFormat)
3348cc7d97539904d9e1058b43153bd6201f4e84d1dJamie Madill{
3358cc7d97539904d9e1058b43153bd6201f4e84d1dJamie Madill    return unpack.pixelBuffer.id() != 0 && mRenderer->supportsFastCopyBufferToTexture(sizedInternalFormat);
3368cc7d97539904d9e1058b43153bd6201f4e84d1dJamie Madill}
3378cc7d97539904d9e1058b43153bd6201f4e84d1dJamie Madill
3381beb1db8015f38674fc78cd4e53316934b0e3839Jamie Madillbool Texture::fastUnpackPixels(const PixelUnpackState &unpack, const void *pixels, const Box &destArea,
3398cc7d97539904d9e1058b43153bd6201f4e84d1dJamie Madill                               GLenum sizedInternalFormat, GLenum type, rx::RenderTarget *destRenderTarget)
3401beb1db8015f38674fc78cd4e53316934b0e3839Jamie Madill{
3411beb1db8015f38674fc78cd4e53316934b0e3839Jamie Madill    if (destArea.width <= 0 && destArea.height <= 0 && destArea.depth <= 0)
3421beb1db8015f38674fc78cd4e53316934b0e3839Jamie Madill    {
3431beb1db8015f38674fc78cd4e53316934b0e3839Jamie Madill        return true;
3441beb1db8015f38674fc78cd4e53316934b0e3839Jamie Madill    }
3451beb1db8015f38674fc78cd4e53316934b0e3839Jamie Madill
3461beb1db8015f38674fc78cd4e53316934b0e3839Jamie Madill    // In order to perform the fast copy through the shader, we must have the right format, and be able
3471beb1db8015f38674fc78cd4e53316934b0e3839Jamie Madill    // to create a render target.
3488cc7d97539904d9e1058b43153bd6201f4e84d1dJamie Madill    ASSERT(mRenderer->supportsFastCopyBufferToTexture(sizedInternalFormat));
3491beb1db8015f38674fc78cd4e53316934b0e3839Jamie Madill
3508cc7d97539904d9e1058b43153bd6201f4e84d1dJamie Madill    unsigned int offset = reinterpret_cast<unsigned int>(pixels);
3511beb1db8015f38674fc78cd4e53316934b0e3839Jamie Madill
3528cc7d97539904d9e1058b43153bd6201f4e84d1dJamie Madill    return mRenderer->fastCopyBufferToTexture(unpack, offset, destRenderTarget, sizedInternalFormat, type, destArea);
3531beb1db8015f38674fc78cd4e53316934b0e3839Jamie Madill}
3541beb1db8015f38674fc78cd4e53316934b0e3839Jamie Madill
35531b13e1ff922519d727c151e7ee3eb93d453e5eadaniel@transgaming.comvoid Texture::setCompressedImage(GLsizei imageSize, const void *pixels, rx::Image *image)
35695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
35795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    if (pixels != NULL)
35895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    {
3594760c563c3d41b97c1677454c9e700595c25a04bshannon.woods%transgaming.com@gtempaccount.com        image->loadCompressedData(0, 0, 0, image->getWidth(), image->getHeight(), image->getDepth(), pixels);
36095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        mDirtyImages = true;
36195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    }
36295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
36395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
3644760c563c3d41b97c1677454c9e700595c25a04bshannon.woods%transgaming.com@gtempaccount.combool Texture::subImage(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
36588f18f458dec5c2aff302db93c57e51d89fbffa2Jamie Madill                       GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels, rx::Image *image)
36695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
367065e1a32293a2a3149fd0899607842cac0864d7fJamie Madill    const void *pixelData = pixels;
368065e1a32293a2a3149fd0899607842cac0864d7fJamie Madill
369065e1a32293a2a3149fd0899607842cac0864d7fJamie Madill    // CPU readback & copy where direct GPU copy is not supported
370065e1a32293a2a3149fd0899607842cac0864d7fJamie Madill    if (unpack.pixelBuffer.id() != 0)
371065e1a32293a2a3149fd0899607842cac0864d7fJamie Madill    {
372065e1a32293a2a3149fd0899607842cac0864d7fJamie Madill        Buffer *pixelBuffer = unpack.pixelBuffer.get();
373065e1a32293a2a3149fd0899607842cac0864d7fJamie Madill        unsigned int offset = reinterpret_cast<unsigned int>(pixels);
374065e1a32293a2a3149fd0899607842cac0864d7fJamie Madill        const void *bufferData = pixelBuffer->getStorage()->getData();
375065e1a32293a2a3149fd0899607842cac0864d7fJamie Madill        pixelData = static_cast<const unsigned char *>(bufferData) + offset;
376065e1a32293a2a3149fd0899607842cac0864d7fJamie Madill    }
377065e1a32293a2a3149fd0899607842cac0864d7fJamie Madill
378065e1a32293a2a3149fd0899607842cac0864d7fJamie Madill    if (pixelData != NULL)
37995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    {
380065e1a32293a2a3149fd0899607842cac0864d7fJamie Madill        image->loadData(xoffset, yoffset, zoffset, width, height, depth, unpack.alignment, type, pixelData);
38195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        mDirtyImages = true;
38295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    }
38395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
38495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    return true;
38595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
38695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
3874760c563c3d41b97c1677454c9e700595c25a04bshannon.woods%transgaming.com@gtempaccount.combool Texture::subImageCompressed(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
3884760c563c3d41b97c1677454c9e700595c25a04bshannon.woods%transgaming.com@gtempaccount.com                                 GLenum format, GLsizei imageSize, const void *pixels, rx::Image *image)
38995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
39095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    if (pixels != NULL)
39195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    {
3924760c563c3d41b97c1677454c9e700595c25a04bshannon.woods%transgaming.com@gtempaccount.com        image->loadCompressedData(xoffset, yoffset, zoffset, width, height, depth, pixels);
39395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        mDirtyImages = true;
39495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    }
39595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
39695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    return true;
39795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
39895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
39987705f8292857d1446f0967c43b7fac66a70d9c2daniel@transgaming.comrx::TextureStorageInterface *Texture::getNativeTexture()
40095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
40195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    // ensure the underlying texture is created
4022ebab858840fb19d4284314caebee4b3cf0700c8Jamie Madill    initializeStorage(false);
4039d4346f0b65ace31bf3e0df8c1f6598e2f32a803daniel@transgaming.com
4042ebab858840fb19d4284314caebee4b3cf0700c8Jamie Madill    rx::TextureStorageInterface *storage = getBaseLevelStorage();
4059d4346f0b65ace31bf3e0df8c1f6598e2f32a803daniel@transgaming.com    if (storage)
40695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    {
407169d11186cb1fdef8920668169682cf84749606dJamie Madill        updateStorage();
40895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    }
40995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
4109d4346f0b65ace31bf3e0df8c1f6598e2f32a803daniel@transgaming.com    return storage;
41195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
41295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
41395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.combool Texture::hasDirtyImages() const
41495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
41595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    return mDirtyImages;
41695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
41795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
41895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.comvoid Texture::resetDirty()
41995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
42095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    mDirtyImages = false;
42195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
42295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
42395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.comunsigned int Texture::getTextureSerial()
42495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
4252ebab858840fb19d4284314caebee4b3cf0700c8Jamie Madill    rx::TextureStorageInterface *texture = getNativeTexture();
42695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    return texture ? texture->getTextureSerial() : 0;
42795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
42895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
42995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.combool Texture::isImmutable() const
43095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
43195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    return mImmutable;
43295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
43395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
43451a943707572a8ba132bae05095af4855c8939e9Jamie Madillint Texture::immutableLevelCount()
43551a943707572a8ba132bae05095af4855c8939e9Jamie Madill{
436bf712d0a32847868913a3521b44912a5c29f08b8Nicolas Capens    return (mImmutable ? getNativeTexture()->getStorageInstance()->getLevelCount() : 0);
43751a943707572a8ba132bae05095af4855c8939e9Jamie Madill}
43851a943707572a8ba132bae05095af4855c8939e9Jamie Madill
4399599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.comGLint Texture::creationLevels(GLsizei width, GLsizei height, GLsizei depth) const
4409599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com{
4416b7440ca15e3acd080d52b11f2e084195fa7f9c9Jamie Madill    if ((isPow2(width) && isPow2(height) && isPow2(depth)) || mRenderer->getNonPower2TextureSupport())
44295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    {
4436b7440ca15e3acd080d52b11f2e084195fa7f9c9Jamie Madill        // Maximum number of levels
44498705b7de3de71d3f5becc8ed3974e5b26c03fa3Geoff Lang        return log2(std::max(std::max(width, height), depth)) + 1;
44595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    }
44695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    else
44795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    {
44895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        // OpenGL ES 2.0 without GL_OES_texture_npot does not permit NPOT mipmaps.
44995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        return 1;
45095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    }
45195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
45295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
45322f843a1e1b9ede7ac1035923f99a7c5956a9badJamie Madillint Texture::mipLevels() const
45422f843a1e1b9ede7ac1035923f99a7c5956a9badJamie Madill{
45598705b7de3de71d3f5becc8ed3974e5b26c03fa3Geoff Lang    return log2(std::max(std::max(getBaseLevelWidth(), getBaseLevelHeight()), getBaseLevelDepth())) + 1;
45622f843a1e1b9ede7ac1035923f99a7c5956a9badJamie Madill}
45722f843a1e1b9ede7ac1035923f99a7c5956a9badJamie Madill
4584907f2c4c071e1920b90f106383a7f026e03d746Geoff LangTexture2D::Texture2D(rx::Renderer *renderer, GLuint id) : Texture(renderer, id, GL_TEXTURE_2D)
45995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
46095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    mTexStorage = NULL;
46195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    mSurface = NULL;
462d9ec902281ce1efe9a1905a43d86f2f4a3495ae5daniel@transgaming.com
463d9ec902281ce1efe9a1905a43d86f2f4a3495ae5daniel@transgaming.com    for (int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++i)
464d9ec902281ce1efe9a1905a43d86f2f4a3495ae5daniel@transgaming.com    {
465244e1838a3d475c26e6bc1830aab5e87f8bf8c48daniel@transgaming.com        mImageArray[i] = renderer->createImage();
466d9ec902281ce1efe9a1905a43d86f2f4a3495ae5daniel@transgaming.com    }
46795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
46895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
46995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.comTexture2D::~Texture2D()
47095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
47195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    delete mTexStorage;
47295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    mTexStorage = NULL;
47395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
47495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    if (mSurface)
47595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    {
47695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        mSurface->setBoundTexture(NULL);
47795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        mSurface = NULL;
47895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    }
479d9ec902281ce1efe9a1905a43d86f2f4a3495ae5daniel@transgaming.com
480d9ec902281ce1efe9a1905a43d86f2f4a3495ae5daniel@transgaming.com    for (int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++i)
481d9ec902281ce1efe9a1905a43d86f2f4a3495ae5daniel@transgaming.com    {
482d9ec902281ce1efe9a1905a43d86f2f4a3495ae5daniel@transgaming.com        delete mImageArray[i];
483d9ec902281ce1efe9a1905a43d86f2f4a3495ae5daniel@transgaming.com    }
48495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
48595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
48695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.comGLsizei Texture2D::getWidth(GLint level) const
48795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
48895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
489d9ec902281ce1efe9a1905a43d86f2f4a3495ae5daniel@transgaming.com        return mImageArray[level]->getWidth();
49095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    else
49195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        return 0;
49295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
49395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
49495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.comGLsizei Texture2D::getHeight(GLint level) const
49595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
49695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
497d9ec902281ce1efe9a1905a43d86f2f4a3495ae5daniel@transgaming.com        return mImageArray[level]->getHeight();
49895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    else
49995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        return 0;
50095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
50195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
50295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.comGLenum Texture2D::getInternalFormat(GLint level) const
50395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
50495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
505d9ec902281ce1efe9a1905a43d86f2f4a3495ae5daniel@transgaming.com        return mImageArray[level]->getInternalFormat();
50695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    else
50795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        return GL_NONE;
50895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
50995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
51020d36667199abc703cddff58ebdfd5eef726a51cdaniel@transgaming.comGLenum Texture2D::getActualFormat(GLint level) const
51195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
51295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
513d9ec902281ce1efe9a1905a43d86f2f4a3495ae5daniel@transgaming.com        return mImageArray[level]->getActualFormat();
51495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    else
515cbf727aeb4669eeaaff8cf7a2a1b1c2749d78620Geoff Lang        return GL_NONE;
51695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
51795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
518005df41f8900641ed1df60700c8e2eca659a33cbGeoff Langvoid Texture2D::redefineImage(GLint level, GLenum internalformat, GLsizei width, GLsizei height)
51995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
52095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    releaseTexImage();
5218a40668486c169387175c650bfcfdaef1e0a4ed2shannon.woods@transgaming.com
522e2e9798bbcf01eb94375432dacd7a54617532dc2shannon.woods@transgaming.com    // If there currently is a corresponding storage texture image, it has these parameters
523d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill    const int storageWidth = std::max(1, getBaseLevelWidth() >> level);
524d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill    const int storageHeight = std::max(1, getBaseLevelHeight() >> level);
525005df41f8900641ed1df60700c8e2eca659a33cbGeoff Lang    const GLenum storageFormat = getBaseLevelInternalFormat();
52695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
52756074f3318a3854b8bfad1498ef719c73212290fshannon.woods%transgaming.com@gtempaccount.com    mImageArray[level]->redefine(mRenderer, GL_TEXTURE_2D, internalformat, width, height, 1, false);
528e2e9798bbcf01eb94375432dacd7a54617532dc2shannon.woods@transgaming.com
529e2e9798bbcf01eb94375432dacd7a54617532dc2shannon.woods@transgaming.com    if (mTexStorage)
53095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    {
531bf712d0a32847868913a3521b44912a5c29f08b8Nicolas Capens        const int storageLevels = mTexStorage->getLevelCount();
532bf712d0a32847868913a3521b44912a5c29f08b8Nicolas Capens
533e2e9798bbcf01eb94375432dacd7a54617532dc2shannon.woods@transgaming.com        if ((level >= storageLevels && storageLevels != 0) ||
534e2e9798bbcf01eb94375432dacd7a54617532dc2shannon.woods@transgaming.com            width != storageWidth ||
535e2e9798bbcf01eb94375432dacd7a54617532dc2shannon.woods@transgaming.com            height != storageHeight ||
536e2e9798bbcf01eb94375432dacd7a54617532dc2shannon.woods@transgaming.com            internalformat != storageFormat)   // Discard mismatched storage
53795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        {
538e2e9798bbcf01eb94375432dacd7a54617532dc2shannon.woods@transgaming.com            for (int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
539e2e9798bbcf01eb94375432dacd7a54617532dc2shannon.woods@transgaming.com            {
540e2e9798bbcf01eb94375432dacd7a54617532dc2shannon.woods@transgaming.com                mImageArray[i]->markDirty();
541e2e9798bbcf01eb94375432dacd7a54617532dc2shannon.woods@transgaming.com            }
54295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
543e2e9798bbcf01eb94375432dacd7a54617532dc2shannon.woods@transgaming.com            delete mTexStorage;
544e2e9798bbcf01eb94375432dacd7a54617532dc2shannon.woods@transgaming.com            mTexStorage = NULL;
545e2e9798bbcf01eb94375432dacd7a54617532dc2shannon.woods@transgaming.com            mDirtyImages = true;
546e2e9798bbcf01eb94375432dacd7a54617532dc2shannon.woods@transgaming.com        }
54795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    }
54895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
54995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
550005df41f8900641ed1df60700c8e2eca659a33cbGeoff Langvoid Texture2D::setImage(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
55195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
5524ad58e083de84d1bc9bae56154886395192bee9cshannonwoods@chromium.org    GLuint clientVersion = mRenderer->getCurrentClientVersion();
553005df41f8900641ed1df60700c8e2eca659a33cbGeoff Lang    GLenum sizedInternalFormat = IsSizedInternalFormat(internalFormat, clientVersion) ? internalFormat
554005df41f8900641ed1df60700c8e2eca659a33cbGeoff Lang                                                                                      : GetSizedInternalFormat(format, type, clientVersion);
5554ad58e083de84d1bc9bae56154886395192bee9cshannonwoods@chromium.org    redefineImage(level, sizedInternalFormat, width, height);
55695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
5578cc7d97539904d9e1058b43153bd6201f4e84d1dJamie Madill    bool fastUnpacked = false;
5588cc7d97539904d9e1058b43153bd6201f4e84d1dJamie Madill
5591beb1db8015f38674fc78cd4e53316934b0e3839Jamie Madill    // Attempt a fast gpu copy of the pixel data to the surface
5608cc7d97539904d9e1058b43153bd6201f4e84d1dJamie Madill    if (isFastUnpackable(unpack, sizedInternalFormat) && isLevelComplete(level))
5611beb1db8015f38674fc78cd4e53316934b0e3839Jamie Madill    {
5628cc7d97539904d9e1058b43153bd6201f4e84d1dJamie Madill        // Will try to create RT storage if it does not exist
5638cc7d97539904d9e1058b43153bd6201f4e84d1dJamie Madill        rx::RenderTarget *destRenderTarget = getRenderTarget(level);
5648cc7d97539904d9e1058b43153bd6201f4e84d1dJamie Madill        Box destArea(0, 0, 0, getWidth(level), getHeight(level), 1);
5658cc7d97539904d9e1058b43153bd6201f4e84d1dJamie Madill
5668cc7d97539904d9e1058b43153bd6201f4e84d1dJamie Madill        if (destRenderTarget && fastUnpackPixels(unpack, pixels, destArea, sizedInternalFormat, type, destRenderTarget))
5678cc7d97539904d9e1058b43153bd6201f4e84d1dJamie Madill        {
5688cc7d97539904d9e1058b43153bd6201f4e84d1dJamie Madill            // Ensure we don't overwrite our newly initialized data
5698cc7d97539904d9e1058b43153bd6201f4e84d1dJamie Madill            mImageArray[level]->markClean();
5708cc7d97539904d9e1058b43153bd6201f4e84d1dJamie Madill
5718cc7d97539904d9e1058b43153bd6201f4e84d1dJamie Madill            fastUnpacked = true;
5728cc7d97539904d9e1058b43153bd6201f4e84d1dJamie Madill        }
5731beb1db8015f38674fc78cd4e53316934b0e3839Jamie Madill    }
5748cc7d97539904d9e1058b43153bd6201f4e84d1dJamie Madill
5758cc7d97539904d9e1058b43153bd6201f4e84d1dJamie Madill    if (!fastUnpacked)
5761beb1db8015f38674fc78cd4e53316934b0e3839Jamie Madill    {
5771beb1db8015f38674fc78cd4e53316934b0e3839Jamie Madill        Texture::setImage(unpack, type, pixels, mImageArray[level]);
5781beb1db8015f38674fc78cd4e53316934b0e3839Jamie Madill    }
57995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
58095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
58195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.comvoid Texture2D::bindTexImage(egl::Surface *surface)
58295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
58395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    releaseTexImage();
58495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
585005df41f8900641ed1df60700c8e2eca659a33cbGeoff Lang    GLenum internalformat = surface->getFormat();
58695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
58756074f3318a3854b8bfad1498ef719c73212290fshannon.woods%transgaming.com@gtempaccount.com    mImageArray[0]->redefine(mRenderer, GL_TEXTURE_2D, internalformat, surface->getWidth(), surface->getHeight(), 1, true);
58895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
58995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    delete mTexStorage;
590d8353dd8e5e4a12cb6efbd5ebe15e573a9b84913daniel@transgaming.com    mTexStorage = new rx::TextureStorageInterface2D(mRenderer, surface->getSwapChain());
59195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
59295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    mDirtyImages = true;
59395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    mSurface = surface;
59495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    mSurface->setBoundTexture(this);
59595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
59695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
59795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.comvoid Texture2D::releaseTexImage()
59895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
59995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    if (mSurface)
60095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    {
60195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        mSurface->setBoundTexture(NULL);
60295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        mSurface = NULL;
60395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
60495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        if (mTexStorage)
60595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        {
60695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com            delete mTexStorage;
60795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com            mTexStorage = NULL;
60895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        }
60995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
61095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        for (int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
61195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        {
61256074f3318a3854b8bfad1498ef719c73212290fshannon.woods%transgaming.com@gtempaccount.com            mImageArray[i]->redefine(mRenderer, GL_TEXTURE_2D, GL_NONE, 0, 0, 0, true);
61395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        }
61495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    }
61595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
61695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
61795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.comvoid Texture2D::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels)
61895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
6196452adf7c249d05fd447f8f74a2b114b85c79e2ddaniel@transgaming.com    // compressed formats don't have separate sized internal formats-- we can just use the compressed format directly
620e2e9798bbcf01eb94375432dacd7a54617532dc2shannon.woods@transgaming.com    redefineImage(level, format, width, height);
62195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
622d9ec902281ce1efe9a1905a43d86f2f4a3495ae5daniel@transgaming.com    Texture::setCompressedImage(imageSize, pixels, mImageArray[level]);
62395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
62495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
62595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.comvoid Texture2D::commitRect(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
62695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
62707bb8cf4f5d734c9ba15adadf5a765fa22cf25ceJamie Madill    if (isValidLevel(level))
62895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    {
629d9ec902281ce1efe9a1905a43d86f2f4a3495ae5daniel@transgaming.com        rx::Image *image = mImageArray[level];
630169d11186cb1fdef8920668169682cf84749606dJamie Madill        if (image->copyToStorage(mTexStorage, level, xoffset, yoffset, width, height))
63195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        {
63295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com            image->markClean();
63395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        }
63495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    }
63595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
63695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
63788f18f458dec5c2aff302db93c57e51d89fbffa2Jamie Madillvoid Texture2D::subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
63895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
639065e1a32293a2a3149fd0899607842cac0864d7fJamie Madill    bool fastUnpacked = false;
640065e1a32293a2a3149fd0899607842cac0864d7fJamie Madill
641065e1a32293a2a3149fd0899607842cac0864d7fJamie Madill    if (isFastUnpackable(unpack, getInternalFormat(level)) && isLevelComplete(level))
642065e1a32293a2a3149fd0899607842cac0864d7fJamie Madill    {
643065e1a32293a2a3149fd0899607842cac0864d7fJamie Madill        rx::RenderTarget *renderTarget = getRenderTarget(level);
644065e1a32293a2a3149fd0899607842cac0864d7fJamie Madill        Box destArea(xoffset, yoffset, 0, width, height, 1);
645065e1a32293a2a3149fd0899607842cac0864d7fJamie Madill
646065e1a32293a2a3149fd0899607842cac0864d7fJamie Madill        if (renderTarget && fastUnpackPixels(unpack, pixels, destArea, getInternalFormat(level), type, renderTarget))
647065e1a32293a2a3149fd0899607842cac0864d7fJamie Madill        {
648065e1a32293a2a3149fd0899607842cac0864d7fJamie Madill            // Ensure we don't overwrite our newly initialized data
649065e1a32293a2a3149fd0899607842cac0864d7fJamie Madill            mImageArray[level]->markClean();
650065e1a32293a2a3149fd0899607842cac0864d7fJamie Madill
651065e1a32293a2a3149fd0899607842cac0864d7fJamie Madill            fastUnpacked = true;
652065e1a32293a2a3149fd0899607842cac0864d7fJamie Madill        }
653065e1a32293a2a3149fd0899607842cac0864d7fJamie Madill    }
654065e1a32293a2a3149fd0899607842cac0864d7fJamie Madill
655065e1a32293a2a3149fd0899607842cac0864d7fJamie Madill    if (!fastUnpacked && Texture::subImage(xoffset, yoffset, 0, width, height, 1, format, type, unpack, pixels, mImageArray[level]))
65695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    {
65795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        commitRect(level, xoffset, yoffset, width, height);
65895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    }
65995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
66095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
66195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.comvoid Texture2D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels)
66295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
6634760c563c3d41b97c1677454c9e700595c25a04bshannon.woods%transgaming.com@gtempaccount.com    if (Texture::subImageCompressed(xoffset, yoffset, 0, width, height, 1, format, imageSize, pixels, mImageArray[level]))
66495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    {
66595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        commitRect(level, xoffset, yoffset, width, height);
66695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    }
66795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
66895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
66995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.comvoid Texture2D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
67095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
671557aab057cafe276182e798a50ce8c23b410f6f4shannonwoods@chromium.org    GLuint clientVersion = mRenderer->getCurrentClientVersion();
672005df41f8900641ed1df60700c8e2eca659a33cbGeoff Lang    GLenum sizedInternalFormat = IsSizedInternalFormat(format, clientVersion) ? format
673005df41f8900641ed1df60700c8e2eca659a33cbGeoff Lang                                                                              : GetSizedInternalFormat(format, GL_UNSIGNED_BYTE, clientVersion);
674557aab057cafe276182e798a50ce8c23b410f6f4shannonwoods@chromium.org    redefineImage(level, sizedInternalFormat, width, height);
6758a40668486c169387175c650bfcfdaef1e0a4ed2shannon.woods@transgaming.com
676d9ec902281ce1efe9a1905a43d86f2f4a3495ae5daniel@transgaming.com    if (!mImageArray[level]->isRenderableFormat())
67795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    {
678e5dcce75bb08208387723a4e0494ca19073e05a7shannon.woods%transgaming.com@gtempaccount.com        mImageArray[level]->copy(0, 0, 0, x, y, width, height, source);
67995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        mDirtyImages = true;
68095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    }
68195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    else
68295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    {
683e83d1a93c6996ceaad179b008a31fed91ff78914Jamie Madill        ensureRenderTarget();
684d9ec902281ce1efe9a1905a43d86f2f4a3495ae5daniel@transgaming.com        mImageArray[level]->markClean();
68595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
68607bb8cf4f5d734c9ba15adadf5a765fa22cf25ceJamie Madill        if (width != 0 && height != 0 && isValidLevel(level))
68795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        {
688664916b706c6adc2c09a003f08dc68d487dec147shannon.woods@transgaming.com            gl::Rectangle sourceRect;
689664916b706c6adc2c09a003f08dc68d487dec147shannon.woods@transgaming.com            sourceRect.x = x;
690664916b706c6adc2c09a003f08dc68d487dec147shannon.woods@transgaming.com            sourceRect.width = width;
691664916b706c6adc2c09a003f08dc68d487dec147shannon.woods@transgaming.com            sourceRect.y = y;
692664916b706c6adc2c09a003f08dc68d487dec147shannon.woods@transgaming.com            sourceRect.height = height;
69395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
694de8a7fff02ab478458e4f511719e15f141c90fe7daniel@transgaming.com            mRenderer->copyImage(source, sourceRect, format, 0, 0, mTexStorage, level);
69595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        }
69695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    }
69795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
69895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
6999599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.comvoid Texture2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
70095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
70107edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    // can only make our texture storage to a render target if level 0 is defined (with a width & height) and
70207edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    // the current level we're copying to is defined (with appropriate format, width & height)
70307edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    bool canCreateRenderTarget = isLevelComplete(level) && isLevelComplete(0);
70407edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill
70507edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    if (!mImageArray[level]->isRenderableFormat() || (!mTexStorage && !canCreateRenderTarget))
70695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    {
707e5dcce75bb08208387723a4e0494ca19073e05a7shannon.woods%transgaming.com@gtempaccount.com        mImageArray[level]->copy(xoffset, yoffset, 0, x, y, width, height, source);
70895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        mDirtyImages = true;
70995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    }
71095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    else
71195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    {
712e83d1a93c6996ceaad179b008a31fed91ff78914Jamie Madill        ensureRenderTarget();
71395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
71407bb8cf4f5d734c9ba15adadf5a765fa22cf25ceJamie Madill        if (isValidLevel(level))
71595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        {
716169d11186cb1fdef8920668169682cf84749606dJamie Madill            updateStorageLevel(level);
71707edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill
718557aab057cafe276182e798a50ce8c23b410f6f4shannonwoods@chromium.org            GLuint clientVersion = mRenderer->getCurrentClientVersion();
719557aab057cafe276182e798a50ce8c23b410f6f4shannonwoods@chromium.org
720664916b706c6adc2c09a003f08dc68d487dec147shannon.woods@transgaming.com            gl::Rectangle sourceRect;
721664916b706c6adc2c09a003f08dc68d487dec147shannon.woods@transgaming.com            sourceRect.x = x;
722664916b706c6adc2c09a003f08dc68d487dec147shannon.woods@transgaming.com            sourceRect.width = width;
723664916b706c6adc2c09a003f08dc68d487dec147shannon.woods@transgaming.com            sourceRect.y = y;
724664916b706c6adc2c09a003f08dc68d487dec147shannon.woods@transgaming.com            sourceRect.height = height;
72595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
726557aab057cafe276182e798a50ce8c23b410f6f4shannonwoods@chromium.org            mRenderer->copyImage(source, sourceRect,
727d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill                                 gl::GetFormat(getBaseLevelInternalFormat(), clientVersion),
728de8a7fff02ab478458e4f511719e15f141c90fe7daniel@transgaming.com                                 xoffset, yoffset, mTexStorage, level);
72995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        }
73095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    }
73195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
73295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
73395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.comvoid Texture2D::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
73495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
73595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    for (int level = 0; level < levels; level++)
73695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    {
73773b5d06e9c46bdbbaf83f09b5669b665f12d0208Jamie Madill        GLsizei levelWidth = std::max(1, width >> level);
73873b5d06e9c46bdbbaf83f09b5669b665f12d0208Jamie Madill        GLsizei levelHeight = std::max(1, height >> level);
73973b5d06e9c46bdbbaf83f09b5669b665f12d0208Jamie Madill        mImageArray[level]->redefine(mRenderer, GL_TEXTURE_2D, internalformat, levelWidth, levelHeight, 1, true);
74095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    }
74195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
74295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    for (int level = levels; level < IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
74395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    {
74456074f3318a3854b8bfad1498ef719c73212290fshannon.woods%transgaming.com@gtempaccount.com        mImageArray[level]->redefine(mRenderer, GL_TEXTURE_2D, GL_NONE, 0, 0, 0, true);
74595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    }
74695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
74773b5d06e9c46bdbbaf83f09b5669b665f12d0208Jamie Madill    mImmutable = true;
74895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
749bf712d0a32847868913a3521b44912a5c29f08b8Nicolas Capens    setCompleteTexStorage(new rx::TextureStorageInterface2D(mRenderer, internalformat, IsRenderTargetUsage(mUsage), width, height, levels));
75073b5d06e9c46bdbbaf83f09b5669b665f12d0208Jamie Madill}
75173b5d06e9c46bdbbaf83f09b5669b665f12d0208Jamie Madill
75273b5d06e9c46bdbbaf83f09b5669b665f12d0208Jamie Madillvoid Texture2D::setCompleteTexStorage(rx::TextureStorageInterface2D *newCompleteTexStorage)
75373b5d06e9c46bdbbaf83f09b5669b665f12d0208Jamie Madill{
75473b5d06e9c46bdbbaf83f09b5669b665f12d0208Jamie Madill    SafeDelete(mTexStorage);
75573b5d06e9c46bdbbaf83f09b5669b665f12d0208Jamie Madill    mTexStorage = newCompleteTexStorage;
75673b5d06e9c46bdbbaf83f09b5669b665f12d0208Jamie Madill
75773b5d06e9c46bdbbaf83f09b5669b665f12d0208Jamie Madill    if (mTexStorage && mTexStorage->isManaged())
75873b5d06e9c46bdbbaf83f09b5669b665f12d0208Jamie Madill    {
759bf712d0a32847868913a3521b44912a5c29f08b8Nicolas Capens        for (int level = 0; level < mTexStorage->getLevelCount(); level++)
76095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        {
761d9ec902281ce1efe9a1905a43d86f2f4a3495ae5daniel@transgaming.com            mImageArray[level]->setManagedSurface(mTexStorage, level);
76295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        }
76395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    }
76473b5d06e9c46bdbbaf83f09b5669b665f12d0208Jamie Madill
76573b5d06e9c46bdbbaf83f09b5669b665f12d0208Jamie Madill    mDirtyImages = true;
76695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
76795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
76895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com// Tests for 2D texture sampling completeness. [OpenGL ES 2.0.24] section 3.8.2 page 85.
769f898990d682b639d7093dc837c6da3e70242d02bJamie Madillbool Texture2D::isSamplerComplete(const SamplerState &samplerState) const
77095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
771d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill    GLsizei width = getBaseLevelWidth();
772d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill    GLsizei height = getBaseLevelHeight();
77395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
77495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    if (width <= 0 || height <= 0)
77595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    {
77695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        return false;
77795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    }
77895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
779f6fb959eeacff28579f996e122962ceda8b2845cshannonwoods@chromium.org    if (!IsTextureFilteringSupported(getInternalFormat(0), mRenderer))
78095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    {
781f898990d682b639d7093dc837c6da3e70242d02bJamie Madill        if (samplerState.magFilter != GL_NEAREST ||
782f898990d682b639d7093dc837c6da3e70242d02bJamie Madill            (samplerState.minFilter != GL_NEAREST && samplerState.minFilter != GL_NEAREST_MIPMAP_NEAREST))
78395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        {
78495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com            return false;
78595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        }
78695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    }
78795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
788ea32d48b64ab98a881c432409b27db9773e7cc7cdaniel@transgaming.com    bool npotSupport = mRenderer->getNonPower2TextureSupport();
78995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
79095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    if (!npotSupport)
79195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    {
792f898990d682b639d7093dc837c6da3e70242d02bJamie Madill        if ((samplerState.wrapS != GL_CLAMP_TO_EDGE && !isPow2(width)) ||
793f898990d682b639d7093dc837c6da3e70242d02bJamie Madill            (samplerState.wrapT != GL_CLAMP_TO_EDGE && !isPow2(height)))
79495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        {
79595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com            return false;
79695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        }
79795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    }
79895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
799f898990d682b639d7093dc837c6da3e70242d02bJamie Madill    if (IsMipmapFiltered(samplerState))
80095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    {
80195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        if (!npotSupport)
80295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        {
80395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com            if (!isPow2(width) || !isPow2(height))
80495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com            {
80595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com                return false;
80695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com            }
80795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        }
80895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
80995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        if (!isMipmapComplete())
81095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        {
81195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com            return false;
81295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        }
81395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    }
81495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
815c82fc41362dae28c98b16c76dda04e2988a02de1Geoff Lang    // OpenGLES 3.0.2 spec section 3.8.13 states that a texture is not mipmap complete if:
816c82fc41362dae28c98b16c76dda04e2988a02de1Geoff Lang    // The internalformat specified for the texture arrays is a sized internal depth or
817c82fc41362dae28c98b16c76dda04e2988a02de1Geoff Lang    // depth and stencil format (see table 3.13), the value of TEXTURE_COMPARE_-
818c82fc41362dae28c98b16c76dda04e2988a02de1Geoff Lang    // MODE is NONE, and either the magnification filter is not NEAREST or the mini-
819c82fc41362dae28c98b16c76dda04e2988a02de1Geoff Lang    // fication filter is neither NEAREST nor NEAREST_MIPMAP_NEAREST.
8202a20562ffcfb32ddba3105f3f9020f3a7a4da0a8Jamie Madill    if (gl::GetDepthBits(getInternalFormat(0), mRenderer->getCurrentClientVersion()) > 0 &&
8212a20562ffcfb32ddba3105f3f9020f3a7a4da0a8Jamie Madill        mRenderer->getCurrentClientVersion() > 2)
822c82fc41362dae28c98b16c76dda04e2988a02de1Geoff Lang    {
823c82fc41362dae28c98b16c76dda04e2988a02de1Geoff Lang        if (mSamplerState.compareMode == GL_NONE)
824c82fc41362dae28c98b16c76dda04e2988a02de1Geoff Lang        {
825c82fc41362dae28c98b16c76dda04e2988a02de1Geoff Lang            if ((mSamplerState.minFilter != GL_NEAREST && mSamplerState.minFilter != GL_NEAREST_MIPMAP_NEAREST) ||
826c82fc41362dae28c98b16c76dda04e2988a02de1Geoff Lang                mSamplerState.magFilter != GL_NEAREST)
827c82fc41362dae28c98b16c76dda04e2988a02de1Geoff Lang            {
828c82fc41362dae28c98b16c76dda04e2988a02de1Geoff Lang                return false;
829c82fc41362dae28c98b16c76dda04e2988a02de1Geoff Lang            }
830c82fc41362dae28c98b16c76dda04e2988a02de1Geoff Lang        }
831c82fc41362dae28c98b16c76dda04e2988a02de1Geoff Lang    }
832c82fc41362dae28c98b16c76dda04e2988a02de1Geoff Lang
83395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    return true;
83495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
83595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
83695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com// Tests for 2D texture (mipmap) completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.
83795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.combool Texture2D::isMipmapComplete() const
83895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
83998705b7de3de71d3f5becc8ed3974e5b26c03fa3Geoff Lang    int levelCount = mipLevels();
84007edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill
84198705b7de3de71d3f5becc8ed3974e5b26c03fa3Geoff Lang    for (int level = 0; level < levelCount; level++)
84207edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    {
84307edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill        if (!isLevelComplete(level))
84407edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill        {
84507edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill            return false;
84607edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill        }
84707edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    }
84807edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill
84907edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    return true;
85007edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill}
85107edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill
85207edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madillbool Texture2D::isLevelComplete(int level) const
85307edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill{
85495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    if (isImmutable())
85595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    {
85695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        return true;
85795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    }
85895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
859648c9683e04c668663b92bd2d2f1f93ae962c716Jamie Madill    const rx::Image *baseImage = getBaseLevelImage();
860648c9683e04c668663b92bd2d2f1f93ae962c716Jamie Madill
861648c9683e04c668663b92bd2d2f1f93ae962c716Jamie Madill    GLsizei width = baseImage->getWidth();
862648c9683e04c668663b92bd2d2f1f93ae962c716Jamie Madill    GLsizei height = baseImage->getHeight();
86395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
86495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    if (width <= 0 || height <= 0)
86595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    {
86695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        return false;
86795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    }
86895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
86907edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    // The base image level is complete if the width and height are positive
87007edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    if (level == 0)
87107edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    {
87207edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill        return true;
87307edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    }
87495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
87507edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    ASSERT(level >= 1 && level <= (int)ArraySize(mImageArray) && mImageArray[level] != NULL);
87607edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    rx::Image *image = mImageArray[level];
87707edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill
878648c9683e04c668663b92bd2d2f1f93ae962c716Jamie Madill    if (image->getInternalFormat() != baseImage->getInternalFormat())
87995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    {
88007edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill        return false;
88107edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    }
88295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
88307edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    if (image->getWidth() != std::max(1, width >> level))
88407edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    {
88507edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill        return false;
88607edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    }
88795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
88807edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    if (image->getHeight() != std::max(1, height >> level))
88907edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    {
89007edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill        return false;
89195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    }
89295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
89395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    return true;
89495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
89595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
89695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.combool Texture2D::isCompressed(GLint level) const
89795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
898f6fb959eeacff28579f996e122962ceda8b2845cshannonwoods@chromium.org    return IsFormatCompressed(getInternalFormat(level), mRenderer->getCurrentClientVersion());
89995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
90095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
90195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.combool Texture2D::isDepth(GLint level) const
90295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
903f6fb959eeacff28579f996e122962ceda8b2845cshannonwoods@chromium.org    return GetDepthBits(getInternalFormat(level), mRenderer->getCurrentClientVersion()) > 0;
90495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
90595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
906f032cb880084ee6c42297f9a046f607287c0cc7adaniel@transgaming.com// Constructs a native texture resource from the texture images
90773b5d06e9c46bdbbaf83f09b5669b665f12d0208Jamie Madillvoid Texture2D::initializeStorage(bool renderTarget)
90895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
90973b5d06e9c46bdbbaf83f09b5669b665f12d0208Jamie Madill    // Only initialize the first time this texture is used as a render target or shader resource
91073b5d06e9c46bdbbaf83f09b5669b665f12d0208Jamie Madill    if (mTexStorage)
91173b5d06e9c46bdbbaf83f09b5669b665f12d0208Jamie Madill    {
91273b5d06e9c46bdbbaf83f09b5669b665f12d0208Jamie Madill        return;
91373b5d06e9c46bdbbaf83f09b5669b665f12d0208Jamie Madill    }
914e6a0984658b9e97df38c7137257f9be974082cc2daniel@transgaming.com
91573b5d06e9c46bdbbaf83f09b5669b665f12d0208Jamie Madill    // do not attempt to create storage for nonexistant data
91673b5d06e9c46bdbbaf83f09b5669b665f12d0208Jamie Madill    if (!isLevelComplete(0))
91773b5d06e9c46bdbbaf83f09b5669b665f12d0208Jamie Madill    {
91873b5d06e9c46bdbbaf83f09b5669b665f12d0208Jamie Madill        return;
91973b5d06e9c46bdbbaf83f09b5669b665f12d0208Jamie Madill    }
920e6a0984658b9e97df38c7137257f9be974082cc2daniel@transgaming.com
92173b5d06e9c46bdbbaf83f09b5669b665f12d0208Jamie Madill    bool createRenderTarget = (renderTarget || IsRenderTargetUsage(mUsage));
92295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
92373b5d06e9c46bdbbaf83f09b5669b665f12d0208Jamie Madill    setCompleteTexStorage(createCompleteStorage(createRenderTarget));
92473b5d06e9c46bdbbaf83f09b5669b665f12d0208Jamie Madill    ASSERT(mTexStorage);
92595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
92673b5d06e9c46bdbbaf83f09b5669b665f12d0208Jamie Madill    // flush image data to the storage
92773b5d06e9c46bdbbaf83f09b5669b665f12d0208Jamie Madill    updateStorage();
92873b5d06e9c46bdbbaf83f09b5669b665f12d0208Jamie Madill}
92995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
93073b5d06e9c46bdbbaf83f09b5669b665f12d0208Jamie Madillrx::TextureStorageInterface2D *Texture2D::createCompleteStorage(bool renderTarget) const
93173b5d06e9c46bdbbaf83f09b5669b665f12d0208Jamie Madill{
93273b5d06e9c46bdbbaf83f09b5669b665f12d0208Jamie Madill    GLsizei width = getBaseLevelWidth();
93373b5d06e9c46bdbbaf83f09b5669b665f12d0208Jamie Madill    GLsizei height = getBaseLevelHeight();
93473b5d06e9c46bdbbaf83f09b5669b665f12d0208Jamie Madill
93573b5d06e9c46bdbbaf83f09b5669b665f12d0208Jamie Madill    ASSERT(width > 0 && height > 0);
93673b5d06e9c46bdbbaf83f09b5669b665f12d0208Jamie Madill
93773b5d06e9c46bdbbaf83f09b5669b665f12d0208Jamie Madill    // use existing storage level count, when previously specified by TexStorage*D
938bf712d0a32847868913a3521b44912a5c29f08b8Nicolas Capens    GLint levels = (mTexStorage ? mTexStorage->getLevelCount() : creationLevels(width, height, 1));
93973b5d06e9c46bdbbaf83f09b5669b665f12d0208Jamie Madill
940bf712d0a32847868913a3521b44912a5c29f08b8Nicolas Capens    return new rx::TextureStorageInterface2D(mRenderer, getBaseLevelInternalFormat(), renderTarget, width, height, levels);
94195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
94295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
943169d11186cb1fdef8920668169682cf84749606dJamie Madillvoid Texture2D::updateStorage()
94495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
945946b948d8e5faa2ce63af6a7850889be0eaba45fGeoff Lang    ASSERT(mTexStorage != NULL);
946946b948d8e5faa2ce63af6a7850889be0eaba45fGeoff Lang    GLint storageLevels = mTexStorage->getLevelCount();
947946b948d8e5faa2ce63af6a7850889be0eaba45fGeoff Lang    for (int level = 0; level < storageLevels; level++)
94895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    {
949648c9683e04c668663b92bd2d2f1f93ae962c716Jamie Madill        if (mImageArray[level]->isDirty() && isLevelComplete(level))
950d9b9a508c5059aa08a87d1a7c0f1a729dd3979aeJamie Madill        {
951169d11186cb1fdef8920668169682cf84749606dJamie Madill            updateStorageLevel(level);
952d9b9a508c5059aa08a87d1a7c0f1a729dd3979aeJamie Madill        }
95307edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    }
95407edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill}
95595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
956169d11186cb1fdef8920668169682cf84749606dJamie Madillvoid Texture2D::updateStorageLevel(int level)
95707edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill{
95807edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    ASSERT(level <= (int)ArraySize(mImageArray) && mImageArray[level] != NULL);
959aee7ad8846b5e2e2405af850fea6dc3f4b7fc8b5Jamie Madill    ASSERT(isLevelComplete(level));
96007edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill
961aee7ad8846b5e2e2405af850fea6dc3f4b7fc8b5Jamie Madill    if (mImageArray[level]->isDirty())
96207edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    {
963aee7ad8846b5e2e2405af850fea6dc3f4b7fc8b5Jamie Madill        commitRect(level, 0, 0, getWidth(level), getHeight(level));
96495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    }
96595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
96695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
967e83d1a93c6996ceaad179b008a31fed91ff78914Jamie Madillbool Texture2D::ensureRenderTarget()
96895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
96973b5d06e9c46bdbbaf83f09b5669b665f12d0208Jamie Madill    initializeStorage(true);
970e83d1a93c6996ceaad179b008a31fed91ff78914Jamie Madill
97173b5d06e9c46bdbbaf83f09b5669b665f12d0208Jamie Madill    if (getBaseLevelWidth() > 0 && getBaseLevelHeight() > 0)
97295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    {
97373b5d06e9c46bdbbaf83f09b5669b665f12d0208Jamie Madill        ASSERT(mTexStorage);
97473b5d06e9c46bdbbaf83f09b5669b665f12d0208Jamie Madill        if (!mTexStorage->isRenderTarget())
97595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        {
97673b5d06e9c46bdbbaf83f09b5669b665f12d0208Jamie Madill            rx::TextureStorageInterface2D *newRenderTargetStorage = createCompleteStorage(true);
97773b5d06e9c46bdbbaf83f09b5669b665f12d0208Jamie Madill
97873b5d06e9c46bdbbaf83f09b5669b665f12d0208Jamie Madill            if (!mRenderer->copyToRenderTarget(newRenderTargetStorage, mTexStorage))
97973b5d06e9c46bdbbaf83f09b5669b665f12d0208Jamie Madill            {
98073b5d06e9c46bdbbaf83f09b5669b665f12d0208Jamie Madill                delete newRenderTargetStorage;
981e83d1a93c6996ceaad179b008a31fed91ff78914Jamie Madill                return gl::error(GL_OUT_OF_MEMORY, false);
98295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com            }
98373b5d06e9c46bdbbaf83f09b5669b665f12d0208Jamie Madill
98473b5d06e9c46bdbbaf83f09b5669b665f12d0208Jamie Madill            setCompleteTexStorage(newRenderTargetStorage);
98595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        }
98695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    }
98795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
988e83d1a93c6996ceaad179b008a31fed91ff78914Jamie Madill    return (mTexStorage && mTexStorage->isRenderTarget());
98995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
99095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
99195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.comvoid Texture2D::generateMipmaps()
99295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
99395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    // Purge array levels 1 through q and reset them to represent the generated mipmap levels.
99498705b7de3de71d3f5becc8ed3974e5b26c03fa3Geoff Lang    int levelCount = mipLevels();
99598705b7de3de71d3f5becc8ed3974e5b26c03fa3Geoff Lang    for (int level = 1; level < levelCount; level++)
99695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    {
99722f843a1e1b9ede7ac1035923f99a7c5956a9badJamie Madill        redefineImage(level, getBaseLevelInternalFormat(),
99822f843a1e1b9ede7ac1035923f99a7c5956a9badJamie Madill                      std::max(getBaseLevelWidth() >> level, 1),
99922f843a1e1b9ede7ac1035923f99a7c5956a9badJamie Madill                      std::max(getBaseLevelHeight() >> level, 1));
100095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    }
100195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
100295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    if (mTexStorage && mTexStorage->isRenderTarget())
100395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    {
100498705b7de3de71d3f5becc8ed3974e5b26c03fa3Geoff Lang        for (int level = 1; level < levelCount; level++)
100595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        {
100622f843a1e1b9ede7ac1035923f99a7c5956a9badJamie Madill            mTexStorage->generateMipmap(level);
100795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
100822f843a1e1b9ede7ac1035923f99a7c5956a9badJamie Madill            mImageArray[level]->markClean();
100995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        }
101095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    }
101195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    else
101295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    {
101398705b7de3de71d3f5becc8ed3974e5b26c03fa3Geoff Lang        for (int level = 1; level < levelCount; level++)
101495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        {
101522f843a1e1b9ede7ac1035923f99a7c5956a9badJamie Madill            mRenderer->generateMipmap(mImageArray[level], mImageArray[level - 1]);
101695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        }
101795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    }
101895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
101995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
1020d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madillconst rx::Image *Texture2D::getBaseLevelImage() const
1021d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill{
1022d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill    return mImageArray[0];
1023d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill}
1024d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill
10252ebab858840fb19d4284314caebee4b3cf0700c8Jamie Madillrx::TextureStorageInterface *Texture2D::getBaseLevelStorage()
10262ebab858840fb19d4284314caebee4b3cf0700c8Jamie Madill{
10272ebab858840fb19d4284314caebee4b3cf0700c8Jamie Madill    return mTexStorage;
10282ebab858840fb19d4284314caebee4b3cf0700c8Jamie Madill}
10292ebab858840fb19d4284314caebee4b3cf0700c8Jamie Madill
10303c7fa226aeb81469b93142b54e339f13a46ab835Jamie MadillFramebufferAttachment *Texture2D::getAttachment(GLint level)
103195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
10323c7fa226aeb81469b93142b54e339f13a46ab835Jamie Madill    FramebufferAttachment *attachment = mRenderbufferProxies.get(level, 0);
10333c7fa226aeb81469b93142b54e339f13a46ab835Jamie Madill    if (!attachment)
103495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    {
10353c7fa226aeb81469b93142b54e339f13a46ab835Jamie Madill        attachment = new FramebufferAttachment(mRenderer, id(), new Texture2DAttachment(this, level));
10363c7fa226aeb81469b93142b54e339f13a46ab835Jamie Madill        mRenderbufferProxies.add(level, 0, attachment);
103795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    }
103895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
10393c7fa226aeb81469b93142b54e339f13a46ab835Jamie Madill    return attachment;
10408040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang}
10418040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang
10428040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Langunsigned int Texture2D::getRenderTargetSerial(GLint level)
10438040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang{
1044e83d1a93c6996ceaad179b008a31fed91ff78914Jamie Madill    return (ensureRenderTarget() ? mTexStorage->getRenderTargetSerial(level) : 0);
104595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
104695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
10478040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Langrx::RenderTarget *Texture2D::getRenderTarget(GLint level)
104895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
104995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    // ensure the underlying texture is created
10502ebab858840fb19d4284314caebee4b3cf0700c8Jamie Madill    if (!ensureRenderTarget())
105195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    {
105295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        return NULL;
105395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    }
105495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
1055169d11186cb1fdef8920668169682cf84749606dJamie Madill    updateStorageLevel(level);
10568040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang
105795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    // ensure this is NOT a depth texture
10588040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang    if (isDepth(level))
105995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    {
106095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        return NULL;
106195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    }
106234da397e13a101d6157619bfbd6c2f33efbd1a31daniel@transgaming.com
10638040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang    return mTexStorage->getRenderTarget(level);
106495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
106595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
10668040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Langrx::RenderTarget *Texture2D::getDepthSencil(GLint level)
106795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
106895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    // ensure the underlying texture is created
10692ebab858840fb19d4284314caebee4b3cf0700c8Jamie Madill    if (!ensureRenderTarget())
107095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    {
107195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        return NULL;
107295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    }
107395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
1074169d11186cb1fdef8920668169682cf84749606dJamie Madill    updateStorageLevel(level);
107595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
107695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    // ensure this is actually a depth texture
10778040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang    if (!isDepth(level))
107895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    {
107995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        return NULL;
108095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    }
10818040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang
10828040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang    return mTexStorage->getRenderTarget(level);
108395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
108495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
108507bb8cf4f5d734c9ba15adadf5a765fa22cf25ceJamie Madillbool Texture2D::isValidLevel(int level) const
1086690d8aeaf674d181c82b6067ddbad3ebe687cd10daniel@transgaming.com{
1087bf712d0a32847868913a3521b44912a5c29f08b8Nicolas Capens    return (mTexStorage ? (level >= 0 && level < mTexStorage->getLevelCount()) : false);
1088690d8aeaf674d181c82b6067ddbad3ebe687cd10daniel@transgaming.com}
1089690d8aeaf674d181c82b6067ddbad3ebe687cd10daniel@transgaming.com
10904907f2c4c071e1920b90f106383a7f026e03d746Geoff LangTextureCubeMap::TextureCubeMap(rx::Renderer *renderer, GLuint id) : Texture(renderer, id, GL_TEXTURE_CUBE_MAP)
109195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
109295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    mTexStorage = NULL;
109395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    for (int i = 0; i < 6; i++)
109495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    {
1095d9ec902281ce1efe9a1905a43d86f2f4a3495ae5daniel@transgaming.com        for (int j = 0; j < IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++j)
1096d9ec902281ce1efe9a1905a43d86f2f4a3495ae5daniel@transgaming.com        {
1097244e1838a3d475c26e6bc1830aab5e87f8bf8c48daniel@transgaming.com            mImageArray[i][j] = renderer->createImage();
1098d9ec902281ce1efe9a1905a43d86f2f4a3495ae5daniel@transgaming.com        }
109995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    }
110095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
110195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
110295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.comTextureCubeMap::~TextureCubeMap()
110395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
110495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    for (int i = 0; i < 6; i++)
110595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    {
1106d9ec902281ce1efe9a1905a43d86f2f4a3495ae5daniel@transgaming.com        for (int j = 0; j < IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++j)
1107d9ec902281ce1efe9a1905a43d86f2f4a3495ae5daniel@transgaming.com        {
1108d9ec902281ce1efe9a1905a43d86f2f4a3495ae5daniel@transgaming.com            delete mImageArray[i][j];
1109d9ec902281ce1efe9a1905a43d86f2f4a3495ae5daniel@transgaming.com        }
111095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    }
111195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
111295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    delete mTexStorage;
111395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    mTexStorage = NULL;
111495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
111595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
111695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.comGLsizei TextureCubeMap::getWidth(GLenum target, GLint level) const
111795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
111895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
11192db197cd72c8ef3b109af0e9e444fd734a3acca4Jamie Madill        return mImageArray[targetToIndex(target)][level]->getWidth();
112095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    else
112195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        return 0;
112295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
112395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
112495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.comGLsizei TextureCubeMap::getHeight(GLenum target, GLint level) const
112595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
112695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
11272db197cd72c8ef3b109af0e9e444fd734a3acca4Jamie Madill        return mImageArray[targetToIndex(target)][level]->getHeight();
112895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    else
112995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        return 0;
113095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
113195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
113295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.comGLenum TextureCubeMap::getInternalFormat(GLenum target, GLint level) const
113395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
113495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
11352db197cd72c8ef3b109af0e9e444fd734a3acca4Jamie Madill        return mImageArray[targetToIndex(target)][level]->getInternalFormat();
113695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    else
113795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        return GL_NONE;
113895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
113995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
114020d36667199abc703cddff58ebdfd5eef726a51cdaniel@transgaming.comGLenum TextureCubeMap::getActualFormat(GLenum target, GLint level) const
114195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
114295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
11432db197cd72c8ef3b109af0e9e444fd734a3acca4Jamie Madill        return mImageArray[targetToIndex(target)][level]->getActualFormat();
114495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    else
1145cbf727aeb4669eeaaff8cf7a2a1b1c2749d78620Geoff Lang        return GL_NONE;
114695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
114795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
1148005df41f8900641ed1df60700c8e2eca659a33cbGeoff Langvoid TextureCubeMap::setImagePosX(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
114995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
115088f18f458dec5c2aff302db93c57e51d89fbffa2Jamie Madill    setImage(0, level, width, height, internalFormat, format, type, unpack, pixels);
115195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
115295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
1153005df41f8900641ed1df60700c8e2eca659a33cbGeoff Langvoid TextureCubeMap::setImageNegX(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
115495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
115588f18f458dec5c2aff302db93c57e51d89fbffa2Jamie Madill    setImage(1, level, width, height, internalFormat, format, type, unpack, pixels);
115695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
115795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
1158005df41f8900641ed1df60700c8e2eca659a33cbGeoff Langvoid TextureCubeMap::setImagePosY(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
115995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
116088f18f458dec5c2aff302db93c57e51d89fbffa2Jamie Madill    setImage(2, level, width, height, internalFormat, format, type, unpack, pixels);
116195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
116295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
1163005df41f8900641ed1df60700c8e2eca659a33cbGeoff Langvoid TextureCubeMap::setImageNegY(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
116495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
116588f18f458dec5c2aff302db93c57e51d89fbffa2Jamie Madill    setImage(3, level, width, height, internalFormat, format, type, unpack, pixels);
116695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
116795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
1168005df41f8900641ed1df60700c8e2eca659a33cbGeoff Langvoid TextureCubeMap::setImagePosZ(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
116995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
117088f18f458dec5c2aff302db93c57e51d89fbffa2Jamie Madill    setImage(4, level, width, height, internalFormat, format, type, unpack, pixels);
117195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
117295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
1173005df41f8900641ed1df60700c8e2eca659a33cbGeoff Langvoid TextureCubeMap::setImageNegZ(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
117495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
117588f18f458dec5c2aff302db93c57e51d89fbffa2Jamie Madill    setImage(5, level, width, height, internalFormat, format, type, unpack, pixels);
117695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
117795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
11782db197cd72c8ef3b109af0e9e444fd734a3acca4Jamie Madillvoid TextureCubeMap::setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels)
117995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
11806452adf7c249d05fd447f8f74a2b114b85c79e2ddaniel@transgaming.com    // compressed formats don't have separate sized internal formats-- we can just use the compressed format directly
11812db197cd72c8ef3b109af0e9e444fd734a3acca4Jamie Madill    int faceIndex = targetToIndex(target);
11822db197cd72c8ef3b109af0e9e444fd734a3acca4Jamie Madill    redefineImage(faceIndex, level, format, width, height);
118395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
11842db197cd72c8ef3b109af0e9e444fd734a3acca4Jamie Madill    Texture::setCompressedImage(imageSize, pixels, mImageArray[faceIndex][level]);
118595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
118695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
11872db197cd72c8ef3b109af0e9e444fd734a3acca4Jamie Madillvoid TextureCubeMap::commitRect(int faceIndex, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
118895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
118907bb8cf4f5d734c9ba15adadf5a765fa22cf25ceJamie Madill    if (isValidFaceLevel(faceIndex, level))
119095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    {
11912db197cd72c8ef3b109af0e9e444fd734a3acca4Jamie Madill        rx::Image *image = mImageArray[faceIndex][level];
1192169d11186cb1fdef8920668169682cf84749606dJamie Madill        if (image->copyToStorage(mTexStorage, faceIndex, level, xoffset, yoffset, width, height))
119395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com            image->markClean();
119495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    }
119595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
119695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
119788f18f458dec5c2aff302db93c57e51d89fbffa2Jamie Madillvoid TextureCubeMap::subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
119895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
11992db197cd72c8ef3b109af0e9e444fd734a3acca4Jamie Madill    int faceIndex = targetToIndex(target);
12002db197cd72c8ef3b109af0e9e444fd734a3acca4Jamie Madill    if (Texture::subImage(xoffset, yoffset, 0, width, height, 1, format, type, unpack, pixels, mImageArray[faceIndex][level]))
120195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    {
12022db197cd72c8ef3b109af0e9e444fd734a3acca4Jamie Madill        commitRect(faceIndex, level, xoffset, yoffset, width, height);
120395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    }
120495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
120595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
120695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.comvoid TextureCubeMap::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels)
120795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
12082db197cd72c8ef3b109af0e9e444fd734a3acca4Jamie Madill    int faceIndex = targetToIndex(target);
12092db197cd72c8ef3b109af0e9e444fd734a3acca4Jamie Madill    if (Texture::subImageCompressed(xoffset, yoffset, 0, width, height, 1, format, imageSize, pixels, mImageArray[faceIndex][level]))
121095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    {
12112db197cd72c8ef3b109af0e9e444fd734a3acca4Jamie Madill        commitRect(faceIndex, level, xoffset, yoffset, width, height);
121295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    }
121395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
121495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
121595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com// Tests for cube map sampling completeness. [OpenGL ES 2.0.24] section 3.8.2 page 86.
1216f898990d682b639d7093dc837c6da3e70242d02bJamie Madillbool TextureCubeMap::isSamplerComplete(const SamplerState &samplerState) const
121795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
1218d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill    int size = getBaseLevelWidth();
121995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
1220f898990d682b639d7093dc837c6da3e70242d02bJamie Madill    bool mipmapping = IsMipmapFiltered(samplerState);
122195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
1222f6fb959eeacff28579f996e122962ceda8b2845cshannonwoods@chromium.org    if (!IsTextureFilteringSupported(getInternalFormat(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0), mRenderer))
122395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    {
1224f898990d682b639d7093dc837c6da3e70242d02bJamie Madill        if (samplerState.magFilter != GL_NEAREST ||
1225f898990d682b639d7093dc837c6da3e70242d02bJamie Madill            (samplerState.minFilter != GL_NEAREST && samplerState.minFilter != GL_NEAREST_MIPMAP_NEAREST))
122695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        {
122795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com            return false;
122895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        }
122995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    }
123095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
1231ea32d48b64ab98a881c432409b27db9773e7cc7cdaniel@transgaming.com    if (!isPow2(size) && !mRenderer->getNonPower2TextureSupport())
123295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    {
1233f898990d682b639d7093dc837c6da3e70242d02bJamie Madill        if (samplerState.wrapS != GL_CLAMP_TO_EDGE || samplerState.wrapT != GL_CLAMP_TO_EDGE || mipmapping)
123495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        {
123595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com            return false;
123695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        }
123795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    }
123895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
123995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    if (!mipmapping)
124095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    {
124195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        if (!isCubeComplete())
124295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        {
124395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com            return false;
124495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        }
124595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    }
124695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    else
124795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    {
124895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        if (!isMipmapCubeComplete())   // Also tests for isCubeComplete()
124995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        {
125095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com            return false;
125195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        }
125295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    }
125395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
125495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    return true;
125595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
125695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
125795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com// Tests for cube texture completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.
125895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.combool TextureCubeMap::isCubeComplete() const
125995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
1260c1f8b16bd24f7caa6abb2edd5f20079b7a63dfc0Jamie Madill    int    baseWidth  = getBaseLevelWidth();
1261c1f8b16bd24f7caa6abb2edd5f20079b7a63dfc0Jamie Madill    int    baseHeight = getBaseLevelHeight();
1262c1f8b16bd24f7caa6abb2edd5f20079b7a63dfc0Jamie Madill    GLenum baseFormat = getBaseLevelInternalFormat();
1263c1f8b16bd24f7caa6abb2edd5f20079b7a63dfc0Jamie Madill
1264c1f8b16bd24f7caa6abb2edd5f20079b7a63dfc0Jamie Madill    if (baseWidth <= 0 || baseWidth != baseHeight)
126595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    {
126695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        return false;
126795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    }
126895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
12692db197cd72c8ef3b109af0e9e444fd734a3acca4Jamie Madill    for (int faceIndex = 1; faceIndex < 6; faceIndex++)
127095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    {
12712db197cd72c8ef3b109af0e9e444fd734a3acca4Jamie Madill        const rx::Image &faceBaseImage = *mImageArray[faceIndex][0];
1272c1f8b16bd24f7caa6abb2edd5f20079b7a63dfc0Jamie Madill
1273c1f8b16bd24f7caa6abb2edd5f20079b7a63dfc0Jamie Madill        if (faceBaseImage.getWidth()          != baseWidth  ||
1274c1f8b16bd24f7caa6abb2edd5f20079b7a63dfc0Jamie Madill            faceBaseImage.getHeight()         != baseHeight ||
1275c1f8b16bd24f7caa6abb2edd5f20079b7a63dfc0Jamie Madill            faceBaseImage.getInternalFormat() != baseFormat )
127695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        {
127795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com            return false;
127895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        }
127995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    }
128095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
128195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    return true;
128295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
128395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
128495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.combool TextureCubeMap::isMipmapCubeComplete() const
128595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
128695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    if (isImmutable())
128795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    {
128895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        return true;
128995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    }
129095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
129195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    if (!isCubeComplete())
129295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    {
129395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        return false;
129495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    }
129595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
129698705b7de3de71d3f5becc8ed3974e5b26c03fa3Geoff Lang    int levelCount = mipLevels();
129795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
129895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    for (int face = 0; face < 6; face++)
129995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    {
130098705b7de3de71d3f5becc8ed3974e5b26c03fa3Geoff Lang        for (int level = 1; level < levelCount; level++)
130195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        {
130207edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill            if (!isFaceLevelComplete(face, level))
130395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com            {
130495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com                return false;
130595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com            }
130695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        }
130795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    }
130895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
130995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    return true;
131095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
131195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
13122db197cd72c8ef3b109af0e9e444fd734a3acca4Jamie Madillbool TextureCubeMap::isFaceLevelComplete(int faceIndex, int level) const
131307edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill{
13142db197cd72c8ef3b109af0e9e444fd734a3acca4Jamie Madill    ASSERT(level >= 0 && faceIndex < 6 && level < (int)ArraySize(mImageArray[faceIndex]) && mImageArray[faceIndex][level] != NULL);
131507edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill
131607edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    if (isImmutable())
131707edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    {
131807edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill        return true;
131907edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    }
132007edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill
1321d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill    int baseSize = getBaseLevelWidth();
132207edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill
1323d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill    if (baseSize <= 0)
132407edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    {
132507edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill        return false;
132607edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    }
132707edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill
1328d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill    // "isCubeComplete" checks for base level completeness and we must call that
1329d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill    // to determine if any face at level 0 is complete. We omit that check here
1330d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill    // to avoid re-checking cube-completeness for every face at level 0.
133107edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    if (level == 0)
133207edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    {
133307edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill        return true;
133407edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    }
133507edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill
1336d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill    // Check that non-zero levels are consistent with the base level.
13372db197cd72c8ef3b109af0e9e444fd734a3acca4Jamie Madill    const rx::Image *faceLevelImage = mImageArray[faceIndex][level];
133807edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill
1339d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill    if (faceLevelImage->getInternalFormat() != getBaseLevelInternalFormat())
134007edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    {
134107edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill        return false;
134207edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    }
134307edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill
1344d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill    if (faceLevelImage->getWidth() != std::max(1, baseSize >> level))
134507edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    {
134607edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill        return false;
134707edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    }
134807edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill
134907edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    return true;
135007edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill}
135107edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill
135295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.combool TextureCubeMap::isCompressed(GLenum target, GLint level) const
135395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
1354f6fb959eeacff28579f996e122962ceda8b2845cshannonwoods@chromium.org    return IsFormatCompressed(getInternalFormat(target, level), mRenderer->getCurrentClientVersion());
135595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
135695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
13578040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Langbool TextureCubeMap::isDepth(GLenum target, GLint level) const
13588040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang{
13598040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang    return GetDepthBits(getInternalFormat(target, level), mRenderer->getCurrentClientVersion()) > 0;
13608040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang}
13618040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang
136273b5d06e9c46bdbbaf83f09b5669b665f12d0208Jamie Madillvoid TextureCubeMap::initializeStorage(bool renderTarget)
136395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
13643c0989c6b5dc3711260adb3249f423fb32db681fJamie Madill    // Only initialize the first time this texture is used as a render target or shader resource
13653c0989c6b5dc3711260adb3249f423fb32db681fJamie Madill    if (mTexStorage)
13663c0989c6b5dc3711260adb3249f423fb32db681fJamie Madill    {
13673c0989c6b5dc3711260adb3249f423fb32db681fJamie Madill        return;
13683c0989c6b5dc3711260adb3249f423fb32db681fJamie Madill    }
13693c0989c6b5dc3711260adb3249f423fb32db681fJamie Madill
13703c0989c6b5dc3711260adb3249f423fb32db681fJamie Madill    // do not attempt to create storage for nonexistant data
13713c0989c6b5dc3711260adb3249f423fb32db681fJamie Madill    if (!isFaceLevelComplete(0, 0))
13723c0989c6b5dc3711260adb3249f423fb32db681fJamie Madill    {
13733c0989c6b5dc3711260adb3249f423fb32db681fJamie Madill        return;
13743c0989c6b5dc3711260adb3249f423fb32db681fJamie Madill    }
13753c0989c6b5dc3711260adb3249f423fb32db681fJamie Madill
13763c0989c6b5dc3711260adb3249f423fb32db681fJamie Madill    bool createRenderTarget = (renderTarget || IsRenderTargetUsage(mUsage));
13773c0989c6b5dc3711260adb3249f423fb32db681fJamie Madill
13783c0989c6b5dc3711260adb3249f423fb32db681fJamie Madill    setCompleteTexStorage(createCompleteStorage(createRenderTarget));
13793c0989c6b5dc3711260adb3249f423fb32db681fJamie Madill    ASSERT(mTexStorage);
13803c0989c6b5dc3711260adb3249f423fb32db681fJamie Madill
13813c0989c6b5dc3711260adb3249f423fb32db681fJamie Madill    // flush image data to the storage
13823c0989c6b5dc3711260adb3249f423fb32db681fJamie Madill    updateStorage();
13833c0989c6b5dc3711260adb3249f423fb32db681fJamie Madill}
13843c0989c6b5dc3711260adb3249f423fb32db681fJamie Madill
13853c0989c6b5dc3711260adb3249f423fb32db681fJamie Madillrx::TextureStorageInterfaceCube *TextureCubeMap::createCompleteStorage(bool renderTarget) const
13863c0989c6b5dc3711260adb3249f423fb32db681fJamie Madill{
1387d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill    GLsizei size = getBaseLevelWidth();
1388e6a0984658b9e97df38c7137257f9be974082cc2daniel@transgaming.com
13893c0989c6b5dc3711260adb3249f423fb32db681fJamie Madill    ASSERT(size > 0);
1390e6a0984658b9e97df38c7137257f9be974082cc2daniel@transgaming.com
13913c0989c6b5dc3711260adb3249f423fb32db681fJamie Madill    // use existing storage level count, when previously specified by TexStorage*D
1392bf712d0a32847868913a3521b44912a5c29f08b8Nicolas Capens    GLint levels = (mTexStorage ? mTexStorage->getLevelCount() : creationLevels(size, size, 1));
139395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
1394bf712d0a32847868913a3521b44912a5c29f08b8Nicolas Capens    return new rx::TextureStorageInterfaceCube(mRenderer, getBaseLevelInternalFormat(), renderTarget, size, levels);
13953c0989c6b5dc3711260adb3249f423fb32db681fJamie Madill}
139695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
13973c0989c6b5dc3711260adb3249f423fb32db681fJamie Madillvoid TextureCubeMap::setCompleteTexStorage(rx::TextureStorageInterfaceCube *newCompleteTexStorage)
13983c0989c6b5dc3711260adb3249f423fb32db681fJamie Madill{
13993c0989c6b5dc3711260adb3249f423fb32db681fJamie Madill    SafeDelete(mTexStorage);
14003c0989c6b5dc3711260adb3249f423fb32db681fJamie Madill    mTexStorage = newCompleteTexStorage;
140195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
14023c0989c6b5dc3711260adb3249f423fb32db681fJamie Madill    if (mTexStorage && mTexStorage->isManaged())
14033c0989c6b5dc3711260adb3249f423fb32db681fJamie Madill    {
14042db197cd72c8ef3b109af0e9e444fd734a3acca4Jamie Madill        for (int faceIndex = 0; faceIndex < 6; faceIndex++)
140595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        {
1406bf712d0a32847868913a3521b44912a5c29f08b8Nicolas Capens            for (int level = 0; level < mTexStorage->getLevelCount(); level++)
140795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com            {
14082db197cd72c8ef3b109af0e9e444fd734a3acca4Jamie Madill                mImageArray[faceIndex][level]->setManagedSurface(mTexStorage, faceIndex, level);
140995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com            }
141095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        }
141195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    }
141295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
141395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    mDirtyImages = true;
141495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
141595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
1416169d11186cb1fdef8920668169682cf84749606dJamie Madillvoid TextureCubeMap::updateStorage()
141795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
1418946b948d8e5faa2ce63af6a7850889be0eaba45fGeoff Lang    ASSERT(mTexStorage != NULL);
1419946b948d8e5faa2ce63af6a7850889be0eaba45fGeoff Lang    GLint storageLevels = mTexStorage->getLevelCount();
142095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    for (int face = 0; face < 6; face++)
142195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    {
1422946b948d8e5faa2ce63af6a7850889be0eaba45fGeoff Lang        for (int level = 0; level < storageLevels; level++)
142395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        {
1424946b948d8e5faa2ce63af6a7850889be0eaba45fGeoff Lang            if (mImageArray[face][level]->isDirty() && isFaceLevelComplete(face, level))
1425d9b9a508c5059aa08a87d1a7c0f1a729dd3979aeJamie Madill            {
1426169d11186cb1fdef8920668169682cf84749606dJamie Madill                updateStorageFaceLevel(face, level);
1427d9b9a508c5059aa08a87d1a7c0f1a729dd3979aeJamie Madill            }
142895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        }
142995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    }
143095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
143195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
1432169d11186cb1fdef8920668169682cf84749606dJamie Madillvoid TextureCubeMap::updateStorageFaceLevel(int faceIndex, int level)
143307edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill{
14342db197cd72c8ef3b109af0e9e444fd734a3acca4Jamie Madill    ASSERT(level >= 0 && faceIndex < 6 && level < (int)ArraySize(mImageArray[faceIndex]) && mImageArray[faceIndex][level] != NULL);
14352db197cd72c8ef3b109af0e9e444fd734a3acca4Jamie Madill    rx::Image *image = mImageArray[faceIndex][level];
143607edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill
143707edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    if (image->isDirty())
143807edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    {
14392db197cd72c8ef3b109af0e9e444fd734a3acca4Jamie Madill        commitRect(faceIndex, level, 0, 0, image->getWidth(), image->getHeight());
144007edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    }
144107edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill}
144207edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill
1443e83d1a93c6996ceaad179b008a31fed91ff78914Jamie Madillbool TextureCubeMap::ensureRenderTarget()
144495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
14453c0989c6b5dc3711260adb3249f423fb32db681fJamie Madill    initializeStorage(true);
144695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
14473c0989c6b5dc3711260adb3249f423fb32db681fJamie Madill    if (getBaseLevelWidth() > 0)
144895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    {
14493c0989c6b5dc3711260adb3249f423fb32db681fJamie Madill        ASSERT(mTexStorage);
14503c0989c6b5dc3711260adb3249f423fb32db681fJamie Madill        if (!mTexStorage->isRenderTarget())
145195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        {
14523c0989c6b5dc3711260adb3249f423fb32db681fJamie Madill            rx::TextureStorageInterfaceCube *newRenderTargetStorage = createCompleteStorage(true);
14533c0989c6b5dc3711260adb3249f423fb32db681fJamie Madill
14543c0989c6b5dc3711260adb3249f423fb32db681fJamie Madill            if (!mRenderer->copyToRenderTarget(newRenderTargetStorage, mTexStorage))
145595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com            {
14563c0989c6b5dc3711260adb3249f423fb32db681fJamie Madill                delete newRenderTargetStorage;
1457e83d1a93c6996ceaad179b008a31fed91ff78914Jamie Madill                return gl::error(GL_OUT_OF_MEMORY, false);
145895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com            }
14593c0989c6b5dc3711260adb3249f423fb32db681fJamie Madill
14603c0989c6b5dc3711260adb3249f423fb32db681fJamie Madill            setCompleteTexStorage(newRenderTargetStorage);
146195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        }
146295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    }
146395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
1464e83d1a93c6996ceaad179b008a31fed91ff78914Jamie Madill    return (mTexStorage && mTexStorage->isRenderTarget());
146595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
146695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
1467005df41f8900641ed1df60700c8e2eca659a33cbGeoff Langvoid TextureCubeMap::setImage(int faceIndex, GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
146895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
14694ad58e083de84d1bc9bae56154886395192bee9cshannonwoods@chromium.org    GLuint clientVersion = mRenderer->getCurrentClientVersion();
1470005df41f8900641ed1df60700c8e2eca659a33cbGeoff Lang    GLenum sizedInternalFormat = IsSizedInternalFormat(internalFormat, clientVersion) ? internalFormat
1471005df41f8900641ed1df60700c8e2eca659a33cbGeoff Lang                                                                                      : GetSizedInternalFormat(format, type, clientVersion);
14724ad58e083de84d1bc9bae56154886395192bee9cshannonwoods@chromium.org
14734ad58e083de84d1bc9bae56154886395192bee9cshannonwoods@chromium.org    redefineImage(faceIndex, level, sizedInternalFormat, width, height);
147495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
147588f18f458dec5c2aff302db93c57e51d89fbffa2Jamie Madill    Texture::setImage(unpack, type, pixels, mImageArray[faceIndex][level]);
147695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
147795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
14782db197cd72c8ef3b109af0e9e444fd734a3acca4Jamie Madillint TextureCubeMap::targetToIndex(GLenum target)
147995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
148095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    META_ASSERT(GL_TEXTURE_CUBE_MAP_NEGATIVE_X - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 1);
148195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    META_ASSERT(GL_TEXTURE_CUBE_MAP_POSITIVE_Y - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 2);
148295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    META_ASSERT(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 3);
148395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    META_ASSERT(GL_TEXTURE_CUBE_MAP_POSITIVE_Z - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 4);
148495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    META_ASSERT(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 5);
148595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
14862db197cd72c8ef3b109af0e9e444fd734a3acca4Jamie Madill    return target - GL_TEXTURE_CUBE_MAP_POSITIVE_X;
148795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
148895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
14892db197cd72c8ef3b109af0e9e444fd734a3acca4Jamie Madillvoid TextureCubeMap::redefineImage(int faceIndex, GLint level, GLenum internalformat, GLsizei width, GLsizei height)
149095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
1491e2e9798bbcf01eb94375432dacd7a54617532dc2shannon.woods@transgaming.com    // If there currently is a corresponding storage texture image, it has these parameters
1492d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill    const int storageWidth = std::max(1, getBaseLevelWidth() >> level);
1493d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill    const int storageHeight = std::max(1, getBaseLevelHeight() >> level);
1494005df41f8900641ed1df60700c8e2eca659a33cbGeoff Lang    const GLenum storageFormat = getBaseLevelInternalFormat();
149595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
14962db197cd72c8ef3b109af0e9e444fd734a3acca4Jamie Madill    mImageArray[faceIndex][level]->redefine(mRenderer, GL_TEXTURE_CUBE_MAP, internalformat, width, height, 1, false);
1497e2e9798bbcf01eb94375432dacd7a54617532dc2shannon.woods@transgaming.com
1498e2e9798bbcf01eb94375432dacd7a54617532dc2shannon.woods@transgaming.com    if (mTexStorage)
149995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    {
1500bf712d0a32847868913a3521b44912a5c29f08b8Nicolas Capens        const int storageLevels = mTexStorage->getLevelCount();
1501bf712d0a32847868913a3521b44912a5c29f08b8Nicolas Capens
1502e2e9798bbcf01eb94375432dacd7a54617532dc2shannon.woods@transgaming.com        if ((level >= storageLevels && storageLevels != 0) ||
1503e2e9798bbcf01eb94375432dacd7a54617532dc2shannon.woods@transgaming.com            width != storageWidth ||
1504e2e9798bbcf01eb94375432dacd7a54617532dc2shannon.woods@transgaming.com            height != storageHeight ||
1505e2e9798bbcf01eb94375432dacd7a54617532dc2shannon.woods@transgaming.com            internalformat != storageFormat)   // Discard mismatched storage
150695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        {
15072db197cd72c8ef3b109af0e9e444fd734a3acca4Jamie Madill            for (int level = 0; level < IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
150895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com            {
15092db197cd72c8ef3b109af0e9e444fd734a3acca4Jamie Madill                for (int faceIndex = 0; faceIndex < 6; faceIndex++)
1510e2e9798bbcf01eb94375432dacd7a54617532dc2shannon.woods@transgaming.com                {
15112db197cd72c8ef3b109af0e9e444fd734a3acca4Jamie Madill                    mImageArray[faceIndex][level]->markDirty();
1512e2e9798bbcf01eb94375432dacd7a54617532dc2shannon.woods@transgaming.com                }
151395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com            }
151495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
1515e2e9798bbcf01eb94375432dacd7a54617532dc2shannon.woods@transgaming.com            delete mTexStorage;
1516e2e9798bbcf01eb94375432dacd7a54617532dc2shannon.woods@transgaming.com            mTexStorage = NULL;
151795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
1518e2e9798bbcf01eb94375432dacd7a54617532dc2shannon.woods@transgaming.com            mDirtyImages = true;
1519e2e9798bbcf01eb94375432dacd7a54617532dc2shannon.woods@transgaming.com        }
152095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    }
152195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
152295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
152395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.comvoid TextureCubeMap::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
152495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
15252db197cd72c8ef3b109af0e9e444fd734a3acca4Jamie Madill    int faceIndex = targetToIndex(target);
1526557aab057cafe276182e798a50ce8c23b410f6f4shannonwoods@chromium.org    GLuint clientVersion = mRenderer->getCurrentClientVersion();
1527005df41f8900641ed1df60700c8e2eca659a33cbGeoff Lang    GLenum sizedInternalFormat = IsSizedInternalFormat(format, clientVersion) ? format
1528005df41f8900641ed1df60700c8e2eca659a33cbGeoff Lang                                                                              : GetSizedInternalFormat(format, GL_UNSIGNED_BYTE, clientVersion);
15292db197cd72c8ef3b109af0e9e444fd734a3acca4Jamie Madill    redefineImage(faceIndex, level, sizedInternalFormat, width, height);
153095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
15312db197cd72c8ef3b109af0e9e444fd734a3acca4Jamie Madill    if (!mImageArray[faceIndex][level]->isRenderableFormat())
153295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    {
15332db197cd72c8ef3b109af0e9e444fd734a3acca4Jamie Madill        mImageArray[faceIndex][level]->copy(0, 0, 0, x, y, width, height, source);
153495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        mDirtyImages = true;
153595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    }
153695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    else
153795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    {
1538e83d1a93c6996ceaad179b008a31fed91ff78914Jamie Madill        ensureRenderTarget();
15392db197cd72c8ef3b109af0e9e444fd734a3acca4Jamie Madill        mImageArray[faceIndex][level]->markClean();
154095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
154195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        ASSERT(width == height);
154295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
154307bb8cf4f5d734c9ba15adadf5a765fa22cf25ceJamie Madill        if (width > 0 && isValidFaceLevel(faceIndex, level))
154495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        {
1545664916b706c6adc2c09a003f08dc68d487dec147shannon.woods@transgaming.com            gl::Rectangle sourceRect;
1546664916b706c6adc2c09a003f08dc68d487dec147shannon.woods@transgaming.com            sourceRect.x = x;
1547664916b706c6adc2c09a003f08dc68d487dec147shannon.woods@transgaming.com            sourceRect.width = width;
1548664916b706c6adc2c09a003f08dc68d487dec147shannon.woods@transgaming.com            sourceRect.y = y;
1549664916b706c6adc2c09a003f08dc68d487dec147shannon.woods@transgaming.com            sourceRect.height = height;
155095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
1551de8a7fff02ab478458e4f511719e15f141c90fe7daniel@transgaming.com            mRenderer->copyImage(source, sourceRect, format, 0, 0, mTexStorage, target, level);
155295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        }
155395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    }
155495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
155595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
15569599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.comvoid TextureCubeMap::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
155795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
15582db197cd72c8ef3b109af0e9e444fd734a3acca4Jamie Madill    int faceIndex = targetToIndex(target);
15592db197cd72c8ef3b109af0e9e444fd734a3acca4Jamie Madill
1560d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill    // We can only make our texture storage to a render target if the level we're copying *to* is complete
1561d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill    // and the base level is cube-complete. The base level must be cube complete (common case) because we cannot
1562d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill    // rely on the "getBaseLevel*" methods reliably otherwise.
15632db197cd72c8ef3b109af0e9e444fd734a3acca4Jamie Madill    bool canCreateRenderTarget = isFaceLevelComplete(faceIndex, level) && isCubeComplete();
156495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
15652db197cd72c8ef3b109af0e9e444fd734a3acca4Jamie Madill    if (!mImageArray[faceIndex][level]->isRenderableFormat() || (!mTexStorage && !canCreateRenderTarget))
156695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    {
15672db197cd72c8ef3b109af0e9e444fd734a3acca4Jamie Madill        mImageArray[faceIndex][level]->copy(0, 0, 0, x, y, width, height, source);
156895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        mDirtyImages = true;
156995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    }
157095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    else
157195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    {
1572e83d1a93c6996ceaad179b008a31fed91ff78914Jamie Madill        ensureRenderTarget();
157395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
157407bb8cf4f5d734c9ba15adadf5a765fa22cf25ceJamie Madill        if (isValidFaceLevel(faceIndex, level))
157595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        {
1576169d11186cb1fdef8920668169682cf84749606dJamie Madill            updateStorageFaceLevel(faceIndex, level);
157707edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill
1578557aab057cafe276182e798a50ce8c23b410f6f4shannonwoods@chromium.org            GLuint clientVersion = mRenderer->getCurrentClientVersion();
1579557aab057cafe276182e798a50ce8c23b410f6f4shannonwoods@chromium.org
1580664916b706c6adc2c09a003f08dc68d487dec147shannon.woods@transgaming.com            gl::Rectangle sourceRect;
1581664916b706c6adc2c09a003f08dc68d487dec147shannon.woods@transgaming.com            sourceRect.x = x;
1582664916b706c6adc2c09a003f08dc68d487dec147shannon.woods@transgaming.com            sourceRect.width = width;
1583664916b706c6adc2c09a003f08dc68d487dec147shannon.woods@transgaming.com            sourceRect.y = y;
1584664916b706c6adc2c09a003f08dc68d487dec147shannon.woods@transgaming.com            sourceRect.height = height;
158595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
1586d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill            mRenderer->copyImage(source, sourceRect, gl::GetFormat(getBaseLevelInternalFormat(), clientVersion),
1587de8a7fff02ab478458e4f511719e15f141c90fe7daniel@transgaming.com                                 xoffset, yoffset, mTexStorage, target, level);
158895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        }
158995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    }
159095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
159195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
159295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.comvoid TextureCubeMap::storage(GLsizei levels, GLenum internalformat, GLsizei size)
159395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
159495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    for (int level = 0; level < levels; level++)
159595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    {
1596d311019e4dcb22ec707692acb2b3dcc0e0ecc24cGeoff Lang        GLsizei mipSize = std::max(1, size >> level);
15972db197cd72c8ef3b109af0e9e444fd734a3acca4Jamie Madill        for (int faceIndex = 0; faceIndex < 6; faceIndex++)
159895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        {
15992db197cd72c8ef3b109af0e9e444fd734a3acca4Jamie Madill            mImageArray[faceIndex][level]->redefine(mRenderer, GL_TEXTURE_CUBE_MAP, internalformat, mipSize, mipSize, 1, true);
160095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        }
160195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    }
160295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
160395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    for (int level = levels; level < IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
160495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    {
16052db197cd72c8ef3b109af0e9e444fd734a3acca4Jamie Madill        for (int faceIndex = 0; faceIndex < 6; faceIndex++)
160695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        {
16072db197cd72c8ef3b109af0e9e444fd734a3acca4Jamie Madill            mImageArray[faceIndex][level]->redefine(mRenderer, GL_TEXTURE_CUBE_MAP, GL_NONE, 0, 0, 0, true);
160895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        }
160995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    }
161095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
16113c0989c6b5dc3711260adb3249f423fb32db681fJamie Madill    mImmutable = true;
161295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
1613bf712d0a32847868913a3521b44912a5c29f08b8Nicolas Capens    setCompleteTexStorage(new rx::TextureStorageInterfaceCube(mRenderer, internalformat, IsRenderTargetUsage(mUsage), size, levels));
161495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
161595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
161695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.comvoid TextureCubeMap::generateMipmaps()
161795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
161895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    // Purge array levels 1 through q and reset them to represent the generated mipmap levels.
161998705b7de3de71d3f5becc8ed3974e5b26c03fa3Geoff Lang    int levelCount = mipLevels();
16202db197cd72c8ef3b109af0e9e444fd734a3acca4Jamie Madill    for (int faceIndex = 0; faceIndex < 6; faceIndex++)
162195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    {
162298705b7de3de71d3f5becc8ed3974e5b26c03fa3Geoff Lang        for (int level = 1; level < levelCount; level++)
162395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        {
162422f843a1e1b9ede7ac1035923f99a7c5956a9badJamie Madill            int faceLevelSize = (std::max(mImageArray[faceIndex][0]->getWidth() >> level, 1));
162522f843a1e1b9ede7ac1035923f99a7c5956a9badJamie Madill            redefineImage(faceIndex, level, mImageArray[faceIndex][0]->getInternalFormat(), faceLevelSize, faceLevelSize);
162695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        }
162795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    }
162895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
162995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    if (mTexStorage && mTexStorage->isRenderTarget())
163095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    {
16312db197cd72c8ef3b109af0e9e444fd734a3acca4Jamie Madill        for (int faceIndex = 0; faceIndex < 6; faceIndex++)
163295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        {
163398705b7de3de71d3f5becc8ed3974e5b26c03fa3Geoff Lang            for (int level = 1; level < levelCount; level++)
163495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com            {
16352db197cd72c8ef3b109af0e9e444fd734a3acca4Jamie Madill                mTexStorage->generateMipmap(faceIndex, level);
163695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
16372db197cd72c8ef3b109af0e9e444fd734a3acca4Jamie Madill                mImageArray[faceIndex][level]->markClean();
163895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com            }
163995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        }
164095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    }
164195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    else
164295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    {
16432db197cd72c8ef3b109af0e9e444fd734a3acca4Jamie Madill        for (int faceIndex = 0; faceIndex < 6; faceIndex++)
164495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        {
164598705b7de3de71d3f5becc8ed3974e5b26c03fa3Geoff Lang            for (int level = 1; level < levelCount; level++)
164695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com            {
16472db197cd72c8ef3b109af0e9e444fd734a3acca4Jamie Madill                mRenderer->generateMipmap(mImageArray[faceIndex][level], mImageArray[faceIndex][level - 1]);
164895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com            }
164995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        }
165095a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    }
165195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
165295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
1653d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madillconst rx::Image *TextureCubeMap::getBaseLevelImage() const
1654d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill{
1655d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill    // Note: if we are not cube-complete, there is no single base level image that can describe all
1656d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill    // cube faces, so this method is only well-defined for a cube-complete base level.
1657d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill    return mImageArray[0][0];
1658d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill}
1659d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill
16602ebab858840fb19d4284314caebee4b3cf0700c8Jamie Madillrx::TextureStorageInterface *TextureCubeMap::getBaseLevelStorage()
16612ebab858840fb19d4284314caebee4b3cf0700c8Jamie Madill{
16622ebab858840fb19d4284314caebee4b3cf0700c8Jamie Madill    return mTexStorage;
16632ebab858840fb19d4284314caebee4b3cf0700c8Jamie Madill}
16642ebab858840fb19d4284314caebee4b3cf0700c8Jamie Madill
16653c7fa226aeb81469b93142b54e339f13a46ab835Jamie MadillFramebufferAttachment *TextureCubeMap::getAttachment(GLenum target, GLint level)
166695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
1667560a8d889b6866d7d29da968971818437e9cde36Jamie Madill    ASSERT(!IsCubemapTextureTarget(target));
16682db197cd72c8ef3b109af0e9e444fd734a3acca4Jamie Madill    int faceIndex = targetToIndex(target);
166995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
16703c7fa226aeb81469b93142b54e339f13a46ab835Jamie Madill    FramebufferAttachment *attachment = mRenderbufferProxies.get(level, faceIndex);
16713c7fa226aeb81469b93142b54e339f13a46ab835Jamie Madill    if (!attachment)
167295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    {
16733c7fa226aeb81469b93142b54e339f13a46ab835Jamie Madill        attachment = new FramebufferAttachment(mRenderer, id(), new TextureCubeMapAttachment(this, target, level));
16743c7fa226aeb81469b93142b54e339f13a46ab835Jamie Madill        mRenderbufferProxies.add(level, faceIndex, attachment);
167595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    }
167695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
16773c7fa226aeb81469b93142b54e339f13a46ab835Jamie Madill    return attachment;
167895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
167995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
16802db197cd72c8ef3b109af0e9e444fd734a3acca4Jamie Madillunsigned int TextureCubeMap::getRenderTargetSerial(GLenum target, GLint level)
16818040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang{
16822db197cd72c8ef3b109af0e9e444fd734a3acca4Jamie Madill    return (ensureRenderTarget() ? mTexStorage->getRenderTargetSerial(target, level) : 0);
16838040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang}
16848040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang
16858040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Langrx::RenderTarget *TextureCubeMap::getRenderTarget(GLenum target, GLint level)
168695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com{
168795a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    ASSERT(IsCubemapTextureTarget(target));
168895a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
168995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    // ensure the underlying texture is created
16902ebab858840fb19d4284314caebee4b3cf0700c8Jamie Madill    if (!ensureRenderTarget())
169195a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    {
169295a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com        return NULL;
169395a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com    }
169495a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
1695169d11186cb1fdef8920668169682cf84749606dJamie Madill    updateStorageFaceLevel(targetToIndex(target), level);
16968040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang
16978040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang    // ensure this is NOT a depth texture
16988040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang    if (isDepth(target, level))
16998040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang    {
17008040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang        return NULL;
17018040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang    }
17028040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang
17038040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang    return mTexStorage->getRenderTarget(target, level);
17048040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang}
17058040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang
17068040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Langrx::RenderTarget *TextureCubeMap::getDepthStencil(GLenum target, GLint level)
17078040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang{
17088040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang    ASSERT(IsCubemapTextureTarget(target));
17098040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang
17108040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang    // ensure the underlying texture is created
17112ebab858840fb19d4284314caebee4b3cf0700c8Jamie Madill    if (!ensureRenderTarget())
17128040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang    {
17138040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang        return NULL;
17148040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang    }
17158040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang
1716169d11186cb1fdef8920668169682cf84749606dJamie Madill    updateStorageFaceLevel(targetToIndex(target), level);
17178040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang
17188040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang    // ensure this is a depth texture
17198040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang    if (!isDepth(target, level))
17208040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang    {
17218040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang        return NULL;
17228040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang    }
17238040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang
17248040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang    return mTexStorage->getRenderTarget(target, level);
172595a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
172695a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com
172707bb8cf4f5d734c9ba15adadf5a765fa22cf25ceJamie Madillbool TextureCubeMap::isValidFaceLevel(int faceIndex, int level) const
1728690d8aeaf674d181c82b6067ddbad3ebe687cd10daniel@transgaming.com{
1729bf712d0a32847868913a3521b44912a5c29f08b8Nicolas Capens    return (mTexStorage ? (level >= 0 && level < mTexStorage->getLevelCount()) : 0);
1730690d8aeaf674d181c82b6067ddbad3ebe687cd10daniel@transgaming.com}
1731690d8aeaf674d181c82b6067ddbad3ebe687cd10daniel@transgaming.com
17324907f2c4c071e1920b90f106383a7f026e03d746Geoff LangTexture3D::Texture3D(rx::Renderer *renderer, GLuint id) : Texture(renderer, id, GL_TEXTURE_3D)
17339599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com{
17349599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com    mTexStorage = NULL;
17359599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com
17369599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com    for (int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++i)
17379599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com    {
17389599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com        mImageArray[i] = renderer->createImage();
17399599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com    }
17409599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com}
17419599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com
17429599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.comTexture3D::~Texture3D()
17439599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com{
17449599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com    delete mTexStorage;
17459599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com    mTexStorage = NULL;
17469599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com
17479599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com    for (int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++i)
17489599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com    {
17499599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com        delete mImageArray[i];
17509599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com    }
17519599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com}
17529599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com
17539599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.comGLsizei Texture3D::getWidth(GLint level) const
17549599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com{
17559599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com    return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mImageArray[level]->getWidth() : 0;
17569599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com}
17579599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com
17589599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.comGLsizei Texture3D::getHeight(GLint level) const
17599599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com{
17609599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com    return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mImageArray[level]->getHeight() : 0;
17619599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com}
17629599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com
17639599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.comGLsizei Texture3D::getDepth(GLint level) const
17649599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com{
17659599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com    return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mImageArray[level]->getDepth() : 0;
17669599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com}
17679599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com
17689599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.comGLenum Texture3D::getInternalFormat(GLint level) const
17699599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com{
17709599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com    return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mImageArray[level]->getInternalFormat() : GL_NONE;
17719599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com}
17729599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com
17739599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.comGLenum Texture3D::getActualFormat(GLint level) const
17749599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com{
1775cbf727aeb4669eeaaff8cf7a2a1b1c2749d78620Geoff Lang    return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mImageArray[level]->getActualFormat() : GL_NONE;
17769599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com}
17779599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com
17789599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.combool Texture3D::isCompressed(GLint level) const
17799599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com{
1780f6fb959eeacff28579f996e122962ceda8b2845cshannonwoods@chromium.org    return IsFormatCompressed(getInternalFormat(level), mRenderer->getCurrentClientVersion());
17819599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com}
17829599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com
17839599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.combool Texture3D::isDepth(GLint level) const
17849599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com{
1785f6fb959eeacff28579f996e122962ceda8b2845cshannonwoods@chromium.org    return GetDepthBits(getInternalFormat(level), mRenderer->getCurrentClientVersion()) > 0;
17869599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com}
17879599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com
1788005df41f8900641ed1df60700c8e2eca659a33cbGeoff Langvoid Texture3D::setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
17899599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com{
17904ad58e083de84d1bc9bae56154886395192bee9cshannonwoods@chromium.org    GLuint clientVersion = mRenderer->getCurrentClientVersion();
1791005df41f8900641ed1df60700c8e2eca659a33cbGeoff Lang    GLenum sizedInternalFormat = IsSizedInternalFormat(internalFormat, clientVersion) ? internalFormat
1792005df41f8900641ed1df60700c8e2eca659a33cbGeoff Lang                                                                                      : GetSizedInternalFormat(format, type, clientVersion);
17934ad58e083de84d1bc9bae56154886395192bee9cshannonwoods@chromium.org    redefineImage(level, sizedInternalFormat, width, height, depth);
17949599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com
1795a2d4e55dc2e856c70deb22e67d3d368f4de556eeJamie Madill    bool fastUnpacked = false;
1796a2d4e55dc2e856c70deb22e67d3d368f4de556eeJamie Madill
1797a2d4e55dc2e856c70deb22e67d3d368f4de556eeJamie Madill    // Attempt a fast gpu copy of the pixel data to the surface if the app bound an unpack buffer
1798a2d4e55dc2e856c70deb22e67d3d368f4de556eeJamie Madill    if (isFastUnpackable(unpack, sizedInternalFormat))
1799a2d4e55dc2e856c70deb22e67d3d368f4de556eeJamie Madill    {
1800a2d4e55dc2e856c70deb22e67d3d368f4de556eeJamie Madill        // Will try to create RT storage if it does not exist
1801a2d4e55dc2e856c70deb22e67d3d368f4de556eeJamie Madill        rx::RenderTarget *destRenderTarget = getRenderTarget(level);
1802a2d4e55dc2e856c70deb22e67d3d368f4de556eeJamie Madill        Box destArea(0, 0, 0, getWidth(level), getHeight(level), getDepth(level));
1803a2d4e55dc2e856c70deb22e67d3d368f4de556eeJamie Madill
1804a2d4e55dc2e856c70deb22e67d3d368f4de556eeJamie Madill        if (destRenderTarget && fastUnpackPixels(unpack, pixels, destArea, sizedInternalFormat, type, destRenderTarget))
1805a2d4e55dc2e856c70deb22e67d3d368f4de556eeJamie Madill        {
1806a2d4e55dc2e856c70deb22e67d3d368f4de556eeJamie Madill            // Ensure we don't overwrite our newly initialized data
1807a2d4e55dc2e856c70deb22e67d3d368f4de556eeJamie Madill            mImageArray[level]->markClean();
1808a2d4e55dc2e856c70deb22e67d3d368f4de556eeJamie Madill
1809a2d4e55dc2e856c70deb22e67d3d368f4de556eeJamie Madill            fastUnpacked = true;
1810a2d4e55dc2e856c70deb22e67d3d368f4de556eeJamie Madill        }
1811a2d4e55dc2e856c70deb22e67d3d368f4de556eeJamie Madill    }
1812a2d4e55dc2e856c70deb22e67d3d368f4de556eeJamie Madill
1813a2d4e55dc2e856c70deb22e67d3d368f4de556eeJamie Madill    if (!fastUnpacked)
1814a2d4e55dc2e856c70deb22e67d3d368f4de556eeJamie Madill    {
1815a2d4e55dc2e856c70deb22e67d3d368f4de556eeJamie Madill        Texture::setImage(unpack, type, pixels, mImageArray[level]);
1816a2d4e55dc2e856c70deb22e67d3d368f4de556eeJamie Madill    }
18179599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com}
18189599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com
18199599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.comvoid Texture3D::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels)
18209599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com{
18219599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com    // compressed formats don't have separate sized internal formats-- we can just use the compressed format directly
18229599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com    redefineImage(level, format, width, height, depth);
18239599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com
18249599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com    Texture::setCompressedImage(imageSize, pixels, mImageArray[level]);
18259599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com}
18269599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com
182788f18f458dec5c2aff302db93c57e51d89fbffa2Jamie Madillvoid 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)
18289599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com{
1829ba4f10a37232a431dcd52c1fd7023a23d2963a65Jamie Madill    bool fastUnpacked = false;
1830ba4f10a37232a431dcd52c1fd7023a23d2963a65Jamie Madill
1831ba4f10a37232a431dcd52c1fd7023a23d2963a65Jamie Madill    // Attempt a fast gpu copy of the pixel data to the surface if the app bound an unpack buffer
1832ba4f10a37232a431dcd52c1fd7023a23d2963a65Jamie Madill    if (isFastUnpackable(unpack, getInternalFormat(level)))
1833ba4f10a37232a431dcd52c1fd7023a23d2963a65Jamie Madill    {
1834ba4f10a37232a431dcd52c1fd7023a23d2963a65Jamie Madill        rx::RenderTarget *destRenderTarget = getRenderTarget(level);
1835ba4f10a37232a431dcd52c1fd7023a23d2963a65Jamie Madill        Box destArea(xoffset, yoffset, zoffset, width, height, depth);
1836ba4f10a37232a431dcd52c1fd7023a23d2963a65Jamie Madill
1837ba4f10a37232a431dcd52c1fd7023a23d2963a65Jamie Madill        if (destRenderTarget && fastUnpackPixels(unpack, pixels, destArea, getInternalFormat(level), type, destRenderTarget))
1838ba4f10a37232a431dcd52c1fd7023a23d2963a65Jamie Madill        {
1839ba4f10a37232a431dcd52c1fd7023a23d2963a65Jamie Madill            // Ensure we don't overwrite our newly initialized data
1840ba4f10a37232a431dcd52c1fd7023a23d2963a65Jamie Madill            mImageArray[level]->markClean();
1841ba4f10a37232a431dcd52c1fd7023a23d2963a65Jamie Madill
1842ba4f10a37232a431dcd52c1fd7023a23d2963a65Jamie Madill            fastUnpacked = true;
1843ba4f10a37232a431dcd52c1fd7023a23d2963a65Jamie Madill        }
1844ba4f10a37232a431dcd52c1fd7023a23d2963a65Jamie Madill    }
1845ba4f10a37232a431dcd52c1fd7023a23d2963a65Jamie Madill
1846ba4f10a37232a431dcd52c1fd7023a23d2963a65Jamie Madill    if (!fastUnpacked && Texture::subImage(xoffset, yoffset, zoffset, width, height, depth, format, type, unpack, pixels, mImageArray[level]))
18479599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com    {
18489599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com        commitRect(level, xoffset, yoffset, zoffset, width, height, depth);
18499599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com    }
18509599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com}
18519599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com
18529599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.comvoid Texture3D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels)
18539599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com{
18549599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com    if (Texture::subImageCompressed(xoffset, yoffset, zoffset, width, height, depth, format, imageSize, pixels, mImageArray[level]))
18559599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com    {
18569599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com        commitRect(level, xoffset, yoffset, zoffset, width, height, depth);
18579599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com    }
18589599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com}
18599599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com
18609599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.comvoid Texture3D::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
18619599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com{
18629599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com    for (int level = 0; level < levels; level++)
18639599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com    {
1864e664e2064b93c244160c9b22cd96d33ee588a1ceJamie Madill        GLsizei levelWidth = std::max(1, width >> level);
1865e664e2064b93c244160c9b22cd96d33ee588a1ceJamie Madill        GLsizei levelHeight = std::max(1, height >> level);
1866e664e2064b93c244160c9b22cd96d33ee588a1ceJamie Madill        GLsizei levelDepth = std::max(1, depth >> level);
1867e664e2064b93c244160c9b22cd96d33ee588a1ceJamie Madill        mImageArray[level]->redefine(mRenderer, GL_TEXTURE_3D, internalformat, levelWidth, levelHeight, levelDepth, true);
18689599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com    }
18699599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com
18709599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com    for (int level = levels; level < IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
18719599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com    {
187256074f3318a3854b8bfad1498ef719c73212290fshannon.woods%transgaming.com@gtempaccount.com        mImageArray[level]->redefine(mRenderer, GL_TEXTURE_3D, GL_NONE, 0, 0, 0, true);
18739599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com    }
18749599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com
1875e664e2064b93c244160c9b22cd96d33ee588a1ceJamie Madill    mImmutable = true;
18769599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com
1877bf712d0a32847868913a3521b44912a5c29f08b8Nicolas Capens    setCompleteTexStorage(new rx::TextureStorageInterface3D(mRenderer, internalformat, IsRenderTargetUsage(mUsage), width, height, depth, levels));
18789599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com}
18799599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com
18809599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.comvoid Texture3D::generateMipmaps()
18819599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com{
188237b8a91a113a18525436e824658151818f88dde2shannonwoods@chromium.org    // Purge array levels 1 through q and reset them to represent the generated mipmap levels.
188398705b7de3de71d3f5becc8ed3974e5b26c03fa3Geoff Lang    int levelCount = mipLevels();
188498705b7de3de71d3f5becc8ed3974e5b26c03fa3Geoff Lang    for (int level = 1; level < levelCount; level++)
188537b8a91a113a18525436e824658151818f88dde2shannonwoods@chromium.org    {
188622f843a1e1b9ede7ac1035923f99a7c5956a9badJamie Madill        redefineImage(level, getBaseLevelInternalFormat(),
188722f843a1e1b9ede7ac1035923f99a7c5956a9badJamie Madill                      std::max(getBaseLevelWidth() >> level, 1),
188822f843a1e1b9ede7ac1035923f99a7c5956a9badJamie Madill                      std::max(getBaseLevelHeight() >> level, 1),
188922f843a1e1b9ede7ac1035923f99a7c5956a9badJamie Madill                      std::max(getBaseLevelDepth() >> level, 1));
189037b8a91a113a18525436e824658151818f88dde2shannonwoods@chromium.org    }
189137b8a91a113a18525436e824658151818f88dde2shannonwoods@chromium.org
189237b8a91a113a18525436e824658151818f88dde2shannonwoods@chromium.org    if (mTexStorage && mTexStorage->isRenderTarget())
189337b8a91a113a18525436e824658151818f88dde2shannonwoods@chromium.org    {
189498705b7de3de71d3f5becc8ed3974e5b26c03fa3Geoff Lang        for (int level = 1; level < levelCount; level++)
189537b8a91a113a18525436e824658151818f88dde2shannonwoods@chromium.org        {
189622f843a1e1b9ede7ac1035923f99a7c5956a9badJamie Madill            mTexStorage->generateMipmap(level);
189737b8a91a113a18525436e824658151818f88dde2shannonwoods@chromium.org
189822f843a1e1b9ede7ac1035923f99a7c5956a9badJamie Madill            mImageArray[level]->markClean();
189937b8a91a113a18525436e824658151818f88dde2shannonwoods@chromium.org        }
190037b8a91a113a18525436e824658151818f88dde2shannonwoods@chromium.org    }
190137b8a91a113a18525436e824658151818f88dde2shannonwoods@chromium.org    else
190237b8a91a113a18525436e824658151818f88dde2shannonwoods@chromium.org    {
190398705b7de3de71d3f5becc8ed3974e5b26c03fa3Geoff Lang        for (int level = 1; level < levelCount; level++)
190437b8a91a113a18525436e824658151818f88dde2shannonwoods@chromium.org        {
190522f843a1e1b9ede7ac1035923f99a7c5956a9badJamie Madill            mRenderer->generateMipmap(mImageArray[level], mImageArray[level - 1]);
190637b8a91a113a18525436e824658151818f88dde2shannonwoods@chromium.org        }
190737b8a91a113a18525436e824658151818f88dde2shannonwoods@chromium.org    }
19089599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com}
19099599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com
1910d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madillconst rx::Image *Texture3D::getBaseLevelImage() const
1911d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill{
1912d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill    return mImageArray[0];
1913d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill}
1914d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill
19152ebab858840fb19d4284314caebee4b3cf0700c8Jamie Madillrx::TextureStorageInterface *Texture3D::getBaseLevelStorage()
19162ebab858840fb19d4284314caebee4b3cf0700c8Jamie Madill{
19172ebab858840fb19d4284314caebee4b3cf0700c8Jamie Madill    return mTexStorage;
19182ebab858840fb19d4284314caebee4b3cf0700c8Jamie Madill}
19192ebab858840fb19d4284314caebee4b3cf0700c8Jamie Madill
19209599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.comvoid Texture3D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
19219599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com{
192207edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    // can only make our texture storage to a render target if level 0 is defined (with a width & height) and
192307edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    // the current level we're copying to is defined (with appropriate format, width & height)
192407edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    bool canCreateRenderTarget = isLevelComplete(level) && isLevelComplete(0);
192507edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill
192607edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    if (!mImageArray[level]->isRenderableFormat() || (!mTexStorage && !canCreateRenderTarget))
19279599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com    {
19289599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com        mImageArray[level]->copy(xoffset, yoffset, zoffset, x, y, width, height, source);
19299599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com        mDirtyImages = true;
19309599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com    }
19319599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com    else
19329599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com    {
1933e83d1a93c6996ceaad179b008a31fed91ff78914Jamie Madill        ensureRenderTarget();
19349599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com
193507bb8cf4f5d734c9ba15adadf5a765fa22cf25ceJamie Madill        if (isValidLevel(level))
19369599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com        {
1937169d11186cb1fdef8920668169682cf84749606dJamie Madill            updateStorageLevel(level);
193807edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill
19399599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com            gl::Rectangle sourceRect;
19409599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com            sourceRect.x = x;
19419599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com            sourceRect.width = width;
19429599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com            sourceRect.y = y;
19439599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com            sourceRect.height = height;
19449599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com
1945557aab057cafe276182e798a50ce8c23b410f6f4shannonwoods@chromium.org            GLuint clientVersion = mRenderer->getCurrentClientVersion();
1946557aab057cafe276182e798a50ce8c23b410f6f4shannonwoods@chromium.org
19479599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com            mRenderer->copyImage(source, sourceRect,
1948d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill                                 gl::GetFormat(getBaseLevelInternalFormat(), clientVersion),
19499599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com                                 xoffset, yoffset, zoffset, mTexStorage, level);
19509599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com        }
19519599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com    }
19529599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com}
19539599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com
1954f898990d682b639d7093dc837c6da3e70242d02bJamie Madillbool Texture3D::isSamplerComplete(const SamplerState &samplerState) const
19559599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com{
1956d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill    GLsizei width = getBaseLevelWidth();
1957d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill    GLsizei height = getBaseLevelHeight();
1958d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill    GLsizei depth = getBaseLevelDepth();
19599599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com
19609599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com    if (width <= 0 || height <= 0 || depth <= 0)
19619599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com    {
19629599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com        return false;
19639599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com    }
19649599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com
1965f6fb959eeacff28579f996e122962ceda8b2845cshannonwoods@chromium.org    if (!IsTextureFilteringSupported(getInternalFormat(0), mRenderer))
19669599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com    {
1967f898990d682b639d7093dc837c6da3e70242d02bJamie Madill        if (samplerState.magFilter != GL_NEAREST ||
1968f898990d682b639d7093dc837c6da3e70242d02bJamie Madill            (samplerState.minFilter != GL_NEAREST && samplerState.minFilter != GL_NEAREST_MIPMAP_NEAREST))
19699599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com        {
19709599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com            return false;
19719599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com        }
19729599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com    }
19739599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com
1974f898990d682b639d7093dc837c6da3e70242d02bJamie Madill    if (IsMipmapFiltered(samplerState) && !isMipmapComplete())
19759599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com    {
19769599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com        return false;
19779599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com    }
19789599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com
19799599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com    return true;
19809599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com}
19819599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com
19829599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.combool Texture3D::isMipmapComplete() const
19839599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com{
198498705b7de3de71d3f5becc8ed3974e5b26c03fa3Geoff Lang    int levelCount = mipLevels();
198507edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill
198698705b7de3de71d3f5becc8ed3974e5b26c03fa3Geoff Lang    for (int level = 0; level < levelCount; level++)
198707edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    {
198807edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill        if (!isLevelComplete(level))
198907edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill        {
199007edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill            return false;
199107edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill        }
199207edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    }
199307edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill
199407edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    return true;
199507edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill}
199607edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill
199707edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madillbool Texture3D::isLevelComplete(int level) const
199807edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill{
199907edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    ASSERT(level >= 0 && level < (int)ArraySize(mImageArray) && mImageArray[level] != NULL);
200007edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill
20019599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com    if (isImmutable())
20029599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com    {
20039599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com        return true;
20049599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com    }
20059599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com
2006d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill    GLsizei width = getBaseLevelWidth();
2007d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill    GLsizei height = getBaseLevelHeight();
2008d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill    GLsizei depth = getBaseLevelDepth();
20099599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com
20109599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com    if (width <= 0 || height <= 0 || depth <= 0)
20119599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com    {
20129599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com        return false;
20139599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com    }
20149599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com
201507edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    if (level == 0)
201607edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    {
201707edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill        return true;
201807edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    }
20199599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com
202007edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    rx::Image *levelImage = mImageArray[level];
202107edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill
2022d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill    if (levelImage->getInternalFormat() != getBaseLevelInternalFormat())
20239599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com    {
202407edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill        return false;
202507edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    }
20269599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com
202707edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    if (levelImage->getWidth() != std::max(1, width >> level))
202807edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    {
202907edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill        return false;
203007edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    }
20319599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com
203207edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    if (levelImage->getHeight() != std::max(1, height >> level))
203307edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    {
203407edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill        return false;
203507edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    }
20369599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com
203707edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    if (levelImage->getDepth() != std::max(1, depth >> level))
203807edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    {
203907edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill        return false;
20409599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com    }
20419599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com
20429599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com    return true;
20439599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com}
20449599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com
20453c7fa226aeb81469b93142b54e339f13a46ab835Jamie MadillFramebufferAttachment *Texture3D::getAttachment(GLint level, GLint layer)
20469599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com{
20473c7fa226aeb81469b93142b54e339f13a46ab835Jamie Madill    FramebufferAttachment *attachment = mRenderbufferProxies.get(level, layer);
20483c7fa226aeb81469b93142b54e339f13a46ab835Jamie Madill    if (!attachment)
20498040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang    {
20503c7fa226aeb81469b93142b54e339f13a46ab835Jamie Madill        attachment = new FramebufferAttachment(mRenderer, id(), new Texture3DAttachment(this, level, layer));
20513c7fa226aeb81469b93142b54e339f13a46ab835Jamie Madill        mRenderbufferProxies.add(level, 0, attachment);
20528040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang    }
20538040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang
20543c7fa226aeb81469b93142b54e339f13a46ab835Jamie Madill    return attachment;
20558040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang}
20568040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang
20578040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Langunsigned int Texture3D::getRenderTargetSerial(GLint level, GLint layer)
20588040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang{
2059e83d1a93c6996ceaad179b008a31fed91ff78914Jamie Madill    return (ensureRenderTarget() ? mTexStorage->getRenderTargetSerial(level, layer) : 0);
20609599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com}
20619599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com
206207bb8cf4f5d734c9ba15adadf5a765fa22cf25ceJamie Madillbool Texture3D::isValidLevel(int level) const
20639599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com{
2064bf712d0a32847868913a3521b44912a5c29f08b8Nicolas Capens    return (mTexStorage ? (level >= 0 && level < mTexStorage->getLevelCount()) : 0);
20659599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com}
20669599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com
206773b5d06e9c46bdbbaf83f09b5669b665f12d0208Jamie Madillvoid Texture3D::initializeStorage(bool renderTarget)
20689599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com{
2069e664e2064b93c244160c9b22cd96d33ee588a1ceJamie Madill    // Only initialize the first time this texture is used as a render target or shader resource
2070e664e2064b93c244160c9b22cd96d33ee588a1ceJamie Madill    if (mTexStorage)
2071e664e2064b93c244160c9b22cd96d33ee588a1ceJamie Madill    {
2072e664e2064b93c244160c9b22cd96d33ee588a1ceJamie Madill        return;
2073e664e2064b93c244160c9b22cd96d33ee588a1ceJamie Madill    }
2074e664e2064b93c244160c9b22cd96d33ee588a1ceJamie Madill
2075e664e2064b93c244160c9b22cd96d33ee588a1ceJamie Madill    // do not attempt to create storage for nonexistant data
2076e664e2064b93c244160c9b22cd96d33ee588a1ceJamie Madill    if (!isLevelComplete(0))
2077e664e2064b93c244160c9b22cd96d33ee588a1ceJamie Madill    {
2078e664e2064b93c244160c9b22cd96d33ee588a1ceJamie Madill        return;
2079e664e2064b93c244160c9b22cd96d33ee588a1ceJamie Madill    }
2080e664e2064b93c244160c9b22cd96d33ee588a1ceJamie Madill
2081e664e2064b93c244160c9b22cd96d33ee588a1ceJamie Madill    bool createRenderTarget = (renderTarget || mUsage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE);
2082e664e2064b93c244160c9b22cd96d33ee588a1ceJamie Madill
2083e664e2064b93c244160c9b22cd96d33ee588a1ceJamie Madill    setCompleteTexStorage(createCompleteStorage(createRenderTarget));
2084e664e2064b93c244160c9b22cd96d33ee588a1ceJamie Madill    ASSERT(mTexStorage);
2085e664e2064b93c244160c9b22cd96d33ee588a1ceJamie Madill
2086e664e2064b93c244160c9b22cd96d33ee588a1ceJamie Madill    // flush image data to the storage
2087e664e2064b93c244160c9b22cd96d33ee588a1ceJamie Madill    updateStorage();
2088e664e2064b93c244160c9b22cd96d33ee588a1ceJamie Madill}
2089e664e2064b93c244160c9b22cd96d33ee588a1ceJamie Madill
2090e664e2064b93c244160c9b22cd96d33ee588a1ceJamie Madillrx::TextureStorageInterface3D *Texture3D::createCompleteStorage(bool renderTarget) const
2091e664e2064b93c244160c9b22cd96d33ee588a1ceJamie Madill{
2092d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill    GLsizei width = getBaseLevelWidth();
2093d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill    GLsizei height = getBaseLevelHeight();
2094d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill    GLsizei depth = getBaseLevelDepth();
20959599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com
2096e664e2064b93c244160c9b22cd96d33ee588a1ceJamie Madill    ASSERT(width > 0 && height > 0 && depth > 0);
20979599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com
2098e664e2064b93c244160c9b22cd96d33ee588a1ceJamie Madill    // use existing storage level count, when previously specified by TexStorage*D
2099bf712d0a32847868913a3521b44912a5c29f08b8Nicolas Capens    GLint levels = (mTexStorage ? mTexStorage->getLevelCount() : creationLevels(width, height, depth));
21009599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com
2101bf712d0a32847868913a3521b44912a5c29f08b8Nicolas Capens    return new rx::TextureStorageInterface3D(mRenderer, getBaseLevelInternalFormat(), renderTarget, width, height, depth, levels);
2102e664e2064b93c244160c9b22cd96d33ee588a1ceJamie Madill}
21039599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com
2104e664e2064b93c244160c9b22cd96d33ee588a1ceJamie Madillvoid Texture3D::setCompleteTexStorage(rx::TextureStorageInterface3D *newCompleteTexStorage)
2105e664e2064b93c244160c9b22cd96d33ee588a1ceJamie Madill{
2106e664e2064b93c244160c9b22cd96d33ee588a1ceJamie Madill    SafeDelete(mTexStorage);
2107e664e2064b93c244160c9b22cd96d33ee588a1ceJamie Madill    mTexStorage = newCompleteTexStorage;
21089599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com    mDirtyImages = true;
2109e664e2064b93c244160c9b22cd96d33ee588a1ceJamie Madill
2110e664e2064b93c244160c9b22cd96d33ee588a1ceJamie Madill    // We do not support managed 3D storage, as that is D3D9/ES2-only
2111e664e2064b93c244160c9b22cd96d33ee588a1ceJamie Madill    ASSERT(!mTexStorage->isManaged());
21129599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com}
21139599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com
2114169d11186cb1fdef8920668169682cf84749606dJamie Madillvoid Texture3D::updateStorage()
21159599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com{
2116946b948d8e5faa2ce63af6a7850889be0eaba45fGeoff Lang    ASSERT(mTexStorage != NULL);
2117946b948d8e5faa2ce63af6a7850889be0eaba45fGeoff Lang    GLint storageLevels = mTexStorage->getLevelCount();
2118946b948d8e5faa2ce63af6a7850889be0eaba45fGeoff Lang    for (int level = 0; level < storageLevels; level++)
21199599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com    {
2120946b948d8e5faa2ce63af6a7850889be0eaba45fGeoff Lang        if (mImageArray[level]->isDirty() && isLevelComplete(level))
2121d9b9a508c5059aa08a87d1a7c0f1a729dd3979aeJamie Madill        {
2122169d11186cb1fdef8920668169682cf84749606dJamie Madill            updateStorageLevel(level);
2123d9b9a508c5059aa08a87d1a7c0f1a729dd3979aeJamie Madill        }
212407edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    }
212507edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill}
21269599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com
2127169d11186cb1fdef8920668169682cf84749606dJamie Madillvoid Texture3D::updateStorageLevel(int level)
212807edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill{
212907edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    ASSERT(level >= 0 && level < (int)ArraySize(mImageArray) && mImageArray[level] != NULL);
2130aee7ad8846b5e2e2405af850fea6dc3f4b7fc8b5Jamie Madill    ASSERT(isLevelComplete(level));
213107edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill
2132aee7ad8846b5e2e2405af850fea6dc3f4b7fc8b5Jamie Madill    if (mImageArray[level]->isDirty())
213307edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    {
2134aee7ad8846b5e2e2405af850fea6dc3f4b7fc8b5Jamie Madill        commitRect(level, 0, 0, 0, getWidth(level), getHeight(level), getDepth(level));
21359599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com    }
21369599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com}
21379599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com
2138e83d1a93c6996ceaad179b008a31fed91ff78914Jamie Madillbool Texture3D::ensureRenderTarget()
21399599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com{
2140e664e2064b93c244160c9b22cd96d33ee588a1ceJamie Madill    initializeStorage(true);
21419599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com
2142e664e2064b93c244160c9b22cd96d33ee588a1ceJamie Madill    if (getBaseLevelWidth() > 0 && getBaseLevelHeight() > 0 && getBaseLevelDepth() > 0)
21439599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com    {
2144e664e2064b93c244160c9b22cd96d33ee588a1ceJamie Madill        ASSERT(mTexStorage);
2145e664e2064b93c244160c9b22cd96d33ee588a1ceJamie Madill        if (!mTexStorage->isRenderTarget())
21469599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com        {
2147e664e2064b93c244160c9b22cd96d33ee588a1ceJamie Madill            rx::TextureStorageInterface3D *newRenderTargetStorage = createCompleteStorage(true);
2148e664e2064b93c244160c9b22cd96d33ee588a1ceJamie Madill
2149e664e2064b93c244160c9b22cd96d33ee588a1ceJamie Madill            if (!mRenderer->copyToRenderTarget(newRenderTargetStorage, mTexStorage))
21509599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com            {
2151e664e2064b93c244160c9b22cd96d33ee588a1ceJamie Madill                delete newRenderTargetStorage;
2152e83d1a93c6996ceaad179b008a31fed91ff78914Jamie Madill                return gl::error(GL_OUT_OF_MEMORY, false);
21539599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com            }
2154e664e2064b93c244160c9b22cd96d33ee588a1ceJamie Madill
2155e664e2064b93c244160c9b22cd96d33ee588a1ceJamie Madill            setCompleteTexStorage(newRenderTargetStorage);
21569599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com        }
21579599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com    }
21589599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com
2159e83d1a93c6996ceaad179b008a31fed91ff78914Jamie Madill    return (mTexStorage && mTexStorage->isRenderTarget());
21609599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com}
21619599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com
2162a2d4e55dc2e856c70deb22e67d3d368f4de556eeJamie Madillrx::RenderTarget *Texture3D::getRenderTarget(GLint level)
2163a2d4e55dc2e856c70deb22e67d3d368f4de556eeJamie Madill{
2164a2d4e55dc2e856c70deb22e67d3d368f4de556eeJamie Madill    // ensure the underlying texture is created
21652ebab858840fb19d4284314caebee4b3cf0700c8Jamie Madill    if (!ensureRenderTarget())
2166a2d4e55dc2e856c70deb22e67d3d368f4de556eeJamie Madill    {
2167a2d4e55dc2e856c70deb22e67d3d368f4de556eeJamie Madill        return NULL;
2168a2d4e55dc2e856c70deb22e67d3d368f4de556eeJamie Madill    }
2169a2d4e55dc2e856c70deb22e67d3d368f4de556eeJamie Madill
2170169d11186cb1fdef8920668169682cf84749606dJamie Madill    updateStorageLevel(level);
2171a2d4e55dc2e856c70deb22e67d3d368f4de556eeJamie Madill
2172a2d4e55dc2e856c70deb22e67d3d368f4de556eeJamie Madill    // ensure this is NOT a depth texture
2173a2d4e55dc2e856c70deb22e67d3d368f4de556eeJamie Madill    if (isDepth(level))
2174a2d4e55dc2e856c70deb22e67d3d368f4de556eeJamie Madill    {
2175a2d4e55dc2e856c70deb22e67d3d368f4de556eeJamie Madill        return NULL;
2176a2d4e55dc2e856c70deb22e67d3d368f4de556eeJamie Madill    }
2177a2d4e55dc2e856c70deb22e67d3d368f4de556eeJamie Madill
2178a2d4e55dc2e856c70deb22e67d3d368f4de556eeJamie Madill    return mTexStorage->getRenderTarget(level);
2179a2d4e55dc2e856c70deb22e67d3d368f4de556eeJamie Madill}
2180a2d4e55dc2e856c70deb22e67d3d368f4de556eeJamie Madill
21818040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Langrx::RenderTarget *Texture3D::getRenderTarget(GLint level, GLint layer)
21828040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang{
21838040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang    // ensure the underlying texture is created
21842ebab858840fb19d4284314caebee4b3cf0700c8Jamie Madill    if (!ensureRenderTarget())
21858040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang    {
21868040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang        return NULL;
21878040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang    }
21888040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang
2189169d11186cb1fdef8920668169682cf84749606dJamie Madill    updateStorage();
21908040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang
21918040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang    // ensure this is NOT a depth texture
21928040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang    if (isDepth(level))
21938040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang    {
21948040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang        return NULL;
21958040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang    }
21968040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang
21978040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang    return mTexStorage->getRenderTarget(level, layer);
21988040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang}
21998040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang
22008040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Langrx::RenderTarget *Texture3D::getDepthStencil(GLint level, GLint layer)
22019599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com{
22028040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang    // ensure the underlying texture is created
22032ebab858840fb19d4284314caebee4b3cf0700c8Jamie Madill    if (!ensureRenderTarget())
22048040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang    {
22058040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang        return NULL;
22068040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang    }
22078040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang
2208169d11186cb1fdef8920668169682cf84749606dJamie Madill    updateStorageLevel(level);
22098040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang
22108040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang    // ensure this is a depth texture
22118040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang    if (!isDepth(level))
22128040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang    {
22138040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang        return NULL;
22148040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang    }
22158040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang
22168040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang    return mTexStorage->getRenderTarget(level, layer);
22179599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com}
22189599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com
2219005df41f8900641ed1df60700c8e2eca659a33cbGeoff Langvoid Texture3D::redefineImage(GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
22209599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com{
22219599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com    // If there currently is a corresponding storage texture image, it has these parameters
2222d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill    const int storageWidth = std::max(1, getBaseLevelWidth() >> level);
2223d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill    const int storageHeight = std::max(1, getBaseLevelHeight() >> level);
2224d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill    const int storageDepth = std::max(1, getBaseLevelDepth() >> level);
2225005df41f8900641ed1df60700c8e2eca659a33cbGeoff Lang    const GLenum storageFormat = getBaseLevelInternalFormat();
22269599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com
222756074f3318a3854b8bfad1498ef719c73212290fshannon.woods%transgaming.com@gtempaccount.com    mImageArray[level]->redefine(mRenderer, GL_TEXTURE_3D, internalformat, width, height, depth, false);
22289599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com
22299599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com    if (mTexStorage)
22309599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com    {
2231bf712d0a32847868913a3521b44912a5c29f08b8Nicolas Capens        const int storageLevels = mTexStorage->getLevelCount();
22329599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com
22339599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com        if ((level >= storageLevels && storageLevels != 0) ||
22349599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com            width != storageWidth ||
22359599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com            height != storageHeight ||
22369599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com            depth != storageDepth ||
22379599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com            internalformat != storageFormat)   // Discard mismatched storage
22389599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com        {
22399599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com            for (int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
22409599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com            {
22419599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com                mImageArray[i]->markDirty();
22429599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com            }
22439599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com
22449599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com            delete mTexStorage;
22459599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com            mTexStorage = NULL;
22469599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com            mDirtyImages = true;
22479599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com        }
22489599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com    }
22499599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com}
22509599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com
22519599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.comvoid Texture3D::commitRect(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth)
22529599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com{
225307bb8cf4f5d734c9ba15adadf5a765fa22cf25ceJamie Madill    if (isValidLevel(level))
22549599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com    {
22559599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com        rx::Image *image = mImageArray[level];
2256169d11186cb1fdef8920668169682cf84749606dJamie Madill        if (image->copyToStorage(mTexStorage, level, xoffset, yoffset, zoffset, width, height, depth))
22579599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com        {
22589599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com            image->markClean();
22599599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com        }
22609599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com    }
22619599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com}
22629599656abe17aa402ac8d8f4f4f1e47dc0b7a696shannon.woods%transgaming.com@gtempaccount.com
22634907f2c4c071e1920b90f106383a7f026e03d746Geoff LangTexture2DArray::Texture2DArray(rx::Renderer *renderer, GLuint id) : Texture(renderer, id, GL_TEXTURE_2D_ARRAY)
22647625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com{
22657625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com    mTexStorage = NULL;
22667625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com
22677625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com    for (int level = 0; level < IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++level)
22687625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com    {
22697625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com        mLayerCounts[level] = 0;
2270644f766c7305f09f9662e7206e6e2163ce9248a1shannonwoods@chromium.org        mImageArray[level] = NULL;
22717625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com    }
22727625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com}
22737625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com
22747625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.comTexture2DArray::~Texture2DArray()
22757625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com{
22767625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com    delete mTexStorage;
22777625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com    mTexStorage = NULL;
2278884a4626ae1d56feeb9971e0b6f095b5c897eda1Jamie Madill
2279884a4626ae1d56feeb9971e0b6f095b5c897eda1Jamie Madill    deleteImages();
2280884a4626ae1d56feeb9971e0b6f095b5c897eda1Jamie Madill}
2281884a4626ae1d56feeb9971e0b6f095b5c897eda1Jamie Madill
2282884a4626ae1d56feeb9971e0b6f095b5c897eda1Jamie Madillvoid Texture2DArray::deleteImages()
2283884a4626ae1d56feeb9971e0b6f095b5c897eda1Jamie Madill{
22847625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com    for (int level = 0; level < IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++level)
22857625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com    {
2286644f766c7305f09f9662e7206e6e2163ce9248a1shannonwoods@chromium.org        for (int layer = 0; layer < mLayerCounts[level]; ++layer)
22877625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com        {
22887625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com            delete mImageArray[level][layer];
22897625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com        }
2290644f766c7305f09f9662e7206e6e2163ce9248a1shannonwoods@chromium.org        delete[] mImageArray[level];
2291884a4626ae1d56feeb9971e0b6f095b5c897eda1Jamie Madill        mImageArray[level] = NULL;
2292884a4626ae1d56feeb9971e0b6f095b5c897eda1Jamie Madill        mLayerCounts[level] = 0;
22937625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com    }
22947625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com}
22957625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com
22967625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.comGLsizei Texture2DArray::getWidth(GLint level) const
22977625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com{
2298644f766c7305f09f9662e7206e6e2163ce9248a1shannonwoods@chromium.org    return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && mLayerCounts[level] > 0) ? mImageArray[level][0]->getWidth() : 0;
22997625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com}
23007625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com
23017625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.comGLsizei Texture2DArray::getHeight(GLint level) const
23027625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com{
2303644f766c7305f09f9662e7206e6e2163ce9248a1shannonwoods@chromium.org    return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && mLayerCounts[level] > 0) ? mImageArray[level][0]->getHeight() : 0;
23047625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com}
23057625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com
2306b8f8b89b1305f5c56ea890e2d10fd2ec9cc1f2adJamie MadillGLsizei Texture2DArray::getLayers(GLint level) const
23077625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com{
2308644f766c7305f09f9662e7206e6e2163ce9248a1shannonwoods@chromium.org    return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && mLayerCounts[level] > 0) ? mLayerCounts[level] : 0;
23097625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com}
23107625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com
23117625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.comGLenum Texture2DArray::getInternalFormat(GLint level) const
23127625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com{
2313644f766c7305f09f9662e7206e6e2163ce9248a1shannonwoods@chromium.org    return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && mLayerCounts[level] > 0) ? mImageArray[level][0]->getInternalFormat() : GL_NONE;
23147625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com}
23157625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com
23167625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.comGLenum Texture2DArray::getActualFormat(GLint level) const
23177625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com{
2318cbf727aeb4669eeaaff8cf7a2a1b1c2749d78620Geoff Lang    return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && mLayerCounts[level] > 0) ? mImageArray[level][0]->getActualFormat() : GL_NONE;
23197625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com}
23207625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com
23217625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.combool Texture2DArray::isCompressed(GLint level) const
23227625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com{
2323f6fb959eeacff28579f996e122962ceda8b2845cshannonwoods@chromium.org    return IsFormatCompressed(getInternalFormat(level), mRenderer->getCurrentClientVersion());
23247625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com}
23257625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com
23267625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.combool Texture2DArray::isDepth(GLint level) const
23277625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com{
2328f6fb959eeacff28579f996e122962ceda8b2845cshannonwoods@chromium.org    return GetDepthBits(getInternalFormat(level), mRenderer->getCurrentClientVersion()) > 0;
23297625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com}
23307625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com
2331005df41f8900641ed1df60700c8e2eca659a33cbGeoff Langvoid Texture2DArray::setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels)
23327625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com{
23334ad58e083de84d1bc9bae56154886395192bee9cshannonwoods@chromium.org    GLuint clientVersion = mRenderer->getCurrentClientVersion();
2334005df41f8900641ed1df60700c8e2eca659a33cbGeoff Lang    GLenum sizedInternalFormat = IsSizedInternalFormat(internalFormat, clientVersion) ? internalFormat
2335005df41f8900641ed1df60700c8e2eca659a33cbGeoff Lang                                                                                      : GetSizedInternalFormat(format, type, clientVersion);
23364ad58e083de84d1bc9bae56154886395192bee9cshannonwoods@chromium.org    redefineImage(level, sizedInternalFormat, width, height, depth);
23377625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com
233888f18f458dec5c2aff302db93c57e51d89fbffa2Jamie Madill    GLsizei inputDepthPitch = gl::GetDepthPitch(sizedInternalFormat, type, clientVersion, width, height, unpack.alignment);
23397625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com
23407625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com    for (int i = 0; i < depth; i++)
23417625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com    {
23420bbd11c1e2b1d916d4ea0a71fac3075e3fec309aGeoff Lang        const void *layerPixels = pixels ? (reinterpret_cast<const unsigned char*>(pixels) + (inputDepthPitch * i)) : NULL;
234388f18f458dec5c2aff302db93c57e51d89fbffa2Jamie Madill        Texture::setImage(unpack, type, layerPixels, mImageArray[level][i]);
23447625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com    }
23457625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com}
23467625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com
23477625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.comvoid Texture2DArray::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels)
23487625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com{
23497625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com    // compressed formats don't have separate sized internal formats-- we can just use the compressed format directly
23507625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com    redefineImage(level, format, width, height, depth);
23517625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com
2352557aab057cafe276182e798a50ce8c23b410f6f4shannonwoods@chromium.org    GLuint clientVersion = mRenderer->getCurrentClientVersion();
2353557aab057cafe276182e798a50ce8c23b410f6f4shannonwoods@chromium.org    GLsizei inputDepthPitch = gl::GetDepthPitch(format, GL_UNSIGNED_BYTE, clientVersion, width, height, 1);
23547625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com
23557625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com    for (int i = 0; i < depth; i++)
23567625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com    {
23570bbd11c1e2b1d916d4ea0a71fac3075e3fec309aGeoff Lang        const void *layerPixels = pixels ? (reinterpret_cast<const unsigned char*>(pixels) + (inputDepthPitch * i)) : NULL;
23587625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com        Texture::setCompressedImage(imageSize, layerPixels, mImageArray[level][i]);
23597625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com    }
23607625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com}
23617625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com
236288f18f458dec5c2aff302db93c57e51d89fbffa2Jamie Madillvoid 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)
23637625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com{
2364005df41f8900641ed1df60700c8e2eca659a33cbGeoff Lang    GLenum internalformat = getInternalFormat(level);
2365557aab057cafe276182e798a50ce8c23b410f6f4shannonwoods@chromium.org    GLuint clientVersion =  mRenderer->getCurrentClientVersion();
236688f18f458dec5c2aff302db93c57e51d89fbffa2Jamie Madill    GLsizei inputDepthPitch = gl::GetDepthPitch(internalformat, type, clientVersion, width, height, unpack.alignment);
23677625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com
23687625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com    for (int i = 0; i < depth; i++)
23697625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com    {
23707625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com        int layer = zoffset + i;
23710bbd11c1e2b1d916d4ea0a71fac3075e3fec309aGeoff Lang        const void *layerPixels = pixels ? (reinterpret_cast<const unsigned char*>(pixels) + (inputDepthPitch * i)) : NULL;
23727625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com
237388f18f458dec5c2aff302db93c57e51d89fbffa2Jamie Madill        if (Texture::subImage(xoffset, yoffset, zoffset, width, height, 1, format, type, unpack, layerPixels, mImageArray[level][layer]))
23747625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com        {
23757625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com            commitRect(level, xoffset, yoffset, layer, width, height);
23767625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com        }
23777625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com    }
23787625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com}
23797625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com
23807625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.comvoid Texture2DArray::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels)
23817625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com{
2382557aab057cafe276182e798a50ce8c23b410f6f4shannonwoods@chromium.org    GLuint clientVersion = mRenderer->getCurrentClientVersion();
2383557aab057cafe276182e798a50ce8c23b410f6f4shannonwoods@chromium.org    GLsizei inputDepthPitch = gl::GetDepthPitch(format, GL_UNSIGNED_BYTE, clientVersion, width, height, 1);
23847625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com
23857625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com    for (int i = 0; i < depth; i++)
23867625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com    {
23877625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com        int layer = zoffset + i;
23880bbd11c1e2b1d916d4ea0a71fac3075e3fec309aGeoff Lang        const void *layerPixels = pixels ? (reinterpret_cast<const unsigned char*>(pixels) + (inputDepthPitch * i)) : NULL;
23897625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com
23907625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com        if (Texture::subImageCompressed(xoffset, yoffset, zoffset, width, height, 1, format, imageSize, layerPixels, mImageArray[level][layer]))
23917625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com        {
23927625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com            commitRect(level, xoffset, yoffset, layer, width, height);
23937625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com        }
23947625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com    }
23957625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com}
23967625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com
23977625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.comvoid Texture2DArray::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
23987625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com{
2399884a4626ae1d56feeb9971e0b6f095b5c897eda1Jamie Madill    deleteImages();
24007625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com
24017625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com    for (int level = 0; level < IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
24027625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com    {
2403884a4626ae1d56feeb9971e0b6f095b5c897eda1Jamie Madill        GLsizei levelWidth = std::max(1, width >> level);
2404884a4626ae1d56feeb9971e0b6f095b5c897eda1Jamie Madill        GLsizei levelHeight = std::max(1, height >> level);
2405644f766c7305f09f9662e7206e6e2163ce9248a1shannonwoods@chromium.org
2406884a4626ae1d56feeb9971e0b6f095b5c897eda1Jamie Madill        mLayerCounts[level] = (level < levels ? depth : 0);
2407644f766c7305f09f9662e7206e6e2163ce9248a1shannonwoods@chromium.org
2408884a4626ae1d56feeb9971e0b6f095b5c897eda1Jamie Madill        if (mLayerCounts[level] > 0)
2409644f766c7305f09f9662e7206e6e2163ce9248a1shannonwoods@chromium.org        {
2410644f766c7305f09f9662e7206e6e2163ce9248a1shannonwoods@chromium.org            // Create new images for this level
2411884a4626ae1d56feeb9971e0b6f095b5c897eda1Jamie Madill            mImageArray[level] = new rx::Image*[mLayerCounts[level]];
2412644f766c7305f09f9662e7206e6e2163ce9248a1shannonwoods@chromium.org
2413644f766c7305f09f9662e7206e6e2163ce9248a1shannonwoods@chromium.org            for (int layer = 0; layer < mLayerCounts[level]; layer++)
24147625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com            {
2415644f766c7305f09f9662e7206e6e2163ce9248a1shannonwoods@chromium.org                mImageArray[level][layer] = mRenderer->createImage();
2416644f766c7305f09f9662e7206e6e2163ce9248a1shannonwoods@chromium.org                mImageArray[level][layer]->redefine(mRenderer, GL_TEXTURE_2D_ARRAY, internalformat, levelWidth,
2417644f766c7305f09f9662e7206e6e2163ce9248a1shannonwoods@chromium.org                                                    levelHeight, 1, true);
24187625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com            }
24197625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com        }
24207625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com    }
24217625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com
2422884a4626ae1d56feeb9971e0b6f095b5c897eda1Jamie Madill    mImmutable = true;
2423bf712d0a32847868913a3521b44912a5c29f08b8Nicolas Capens    setCompleteTexStorage(new rx::TextureStorageInterface2DArray(mRenderer, internalformat, IsRenderTargetUsage(mUsage), width, height, depth, levels));
24247625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com}
24257625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com
24267625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.comvoid Texture2DArray::generateMipmaps()
24277625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com{
2428d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill    int baseWidth = getBaseLevelWidth();
2429d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill    int baseHeight = getBaseLevelHeight();
2430d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill    int baseDepth = getBaseLevelDepth();
2431d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill    GLenum baseFormat = getBaseLevelInternalFormat();
2432d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill
243330aa1a9f438374a771cc789eddb4d2fd21860305shannonwoods@chromium.org    // Purge array levels 1 through q and reset them to represent the generated mipmap levels.
243498705b7de3de71d3f5becc8ed3974e5b26c03fa3Geoff Lang    int levelCount = mipLevels();
243598705b7de3de71d3f5becc8ed3974e5b26c03fa3Geoff Lang    for (int level = 1; level < levelCount; level++)
243630aa1a9f438374a771cc789eddb4d2fd21860305shannonwoods@chromium.org    {
243722f843a1e1b9ede7ac1035923f99a7c5956a9badJamie Madill        redefineImage(level, baseFormat, std::max(baseWidth >> level, 1), std::max(baseHeight >> level, 1), baseDepth);
243830aa1a9f438374a771cc789eddb4d2fd21860305shannonwoods@chromium.org    }
243930aa1a9f438374a771cc789eddb4d2fd21860305shannonwoods@chromium.org
244030aa1a9f438374a771cc789eddb4d2fd21860305shannonwoods@chromium.org    if (mTexStorage && mTexStorage->isRenderTarget())
244130aa1a9f438374a771cc789eddb4d2fd21860305shannonwoods@chromium.org    {
244298705b7de3de71d3f5becc8ed3974e5b26c03fa3Geoff Lang        for (int level = 1; level < levelCount; level++)
244330aa1a9f438374a771cc789eddb4d2fd21860305shannonwoods@chromium.org        {
244430aa1a9f438374a771cc789eddb4d2fd21860305shannonwoods@chromium.org            mTexStorage->generateMipmap(level);
244530aa1a9f438374a771cc789eddb4d2fd21860305shannonwoods@chromium.org
244630aa1a9f438374a771cc789eddb4d2fd21860305shannonwoods@chromium.org            for (int layer = 0; layer < mLayerCounts[level]; layer++)
244730aa1a9f438374a771cc789eddb4d2fd21860305shannonwoods@chromium.org            {
244830aa1a9f438374a771cc789eddb4d2fd21860305shannonwoods@chromium.org                mImageArray[level][layer]->markClean();
244930aa1a9f438374a771cc789eddb4d2fd21860305shannonwoods@chromium.org            }
245030aa1a9f438374a771cc789eddb4d2fd21860305shannonwoods@chromium.org        }
245130aa1a9f438374a771cc789eddb4d2fd21860305shannonwoods@chromium.org    }
245230aa1a9f438374a771cc789eddb4d2fd21860305shannonwoods@chromium.org    else
245330aa1a9f438374a771cc789eddb4d2fd21860305shannonwoods@chromium.org    {
245498705b7de3de71d3f5becc8ed3974e5b26c03fa3Geoff Lang        for (int level = 1; level < levelCount; level++)
245530aa1a9f438374a771cc789eddb4d2fd21860305shannonwoods@chromium.org        {
245630aa1a9f438374a771cc789eddb4d2fd21860305shannonwoods@chromium.org            for (int layer = 0; layer < mLayerCounts[level]; layer++)
245730aa1a9f438374a771cc789eddb4d2fd21860305shannonwoods@chromium.org            {
245830aa1a9f438374a771cc789eddb4d2fd21860305shannonwoods@chromium.org                mRenderer->generateMipmap(mImageArray[level][layer], mImageArray[level - 1][layer]);
245930aa1a9f438374a771cc789eddb4d2fd21860305shannonwoods@chromium.org            }
246030aa1a9f438374a771cc789eddb4d2fd21860305shannonwoods@chromium.org        }
246130aa1a9f438374a771cc789eddb4d2fd21860305shannonwoods@chromium.org    }
24627625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com}
24637625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com
2464d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madillconst rx::Image *Texture2DArray::getBaseLevelImage() const
2465d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill{
2466152ed093ed6ea7018ef5a50165e2ad126ed45b2dJamie Madill    return (mLayerCounts[0] > 0 ? mImageArray[0][0] : NULL);
2467d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill}
2468d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill
24692ebab858840fb19d4284314caebee4b3cf0700c8Jamie Madillrx::TextureStorageInterface *Texture2DArray::getBaseLevelStorage()
24702ebab858840fb19d4284314caebee4b3cf0700c8Jamie Madill{
24712ebab858840fb19d4284314caebee4b3cf0700c8Jamie Madill    return mTexStorage;
24722ebab858840fb19d4284314caebee4b3cf0700c8Jamie Madill}
24732ebab858840fb19d4284314caebee4b3cf0700c8Jamie Madill
24747625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.comvoid Texture2DArray::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
24757625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com{
247607edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    // can only make our texture storage to a render target if level 0 is defined (with a width & height) and
247707edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    // the current level we're copying to is defined (with appropriate format, width & height)
247807edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    bool canCreateRenderTarget = isLevelComplete(level) && isLevelComplete(0);
247907edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill
248007edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    if (!mImageArray[level][0]->isRenderableFormat() || (!mTexStorage && !canCreateRenderTarget))
24817625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com    {
24827625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com        mImageArray[level][zoffset]->copy(xoffset, yoffset, 0, x, y, width, height, source);
24837625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com        mDirtyImages = true;
24847625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com    }
24857625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com    else
24867625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com    {
2487e83d1a93c6996ceaad179b008a31fed91ff78914Jamie Madill        ensureRenderTarget();
24887625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com
248907bb8cf4f5d734c9ba15adadf5a765fa22cf25ceJamie Madill        if (isValidLevel(level))
24907625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com        {
2491169d11186cb1fdef8920668169682cf84749606dJamie Madill            updateStorageLevel(level);
249207edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill
2493557aab057cafe276182e798a50ce8c23b410f6f4shannonwoods@chromium.org            GLuint clientVersion = mRenderer->getCurrentClientVersion();
2494557aab057cafe276182e798a50ce8c23b410f6f4shannonwoods@chromium.org
24957625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com            gl::Rectangle sourceRect;
24967625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com            sourceRect.x = x;
24977625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com            sourceRect.width = width;
24987625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com            sourceRect.y = y;
24997625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com            sourceRect.height = height;
25007625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com
2501557aab057cafe276182e798a50ce8c23b410f6f4shannonwoods@chromium.org            mRenderer->copyImage(source, sourceRect, gl::GetFormat(getInternalFormat(0), clientVersion),
25027625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com                                 xoffset, yoffset, zoffset, mTexStorage, level);
25037625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com        }
25047625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com    }
25057625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com}
25067625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com
2507f898990d682b639d7093dc837c6da3e70242d02bJamie Madillbool Texture2DArray::isSamplerComplete(const SamplerState &samplerState) const
25087625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com{
2509d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill    GLsizei width = getBaseLevelWidth();
2510d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill    GLsizei height = getBaseLevelHeight();
2511b8f8b89b1305f5c56ea890e2d10fd2ec9cc1f2adJamie Madill    GLsizei depth = getLayers(0);
25127625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com
25137625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com    if (width <= 0 || height <= 0 || depth <= 0)
25147625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com    {
25157625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com        return false;
25167625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com    }
25177625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com
2518d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill    if (!IsTextureFilteringSupported(getBaseLevelInternalFormat(), mRenderer))
25197625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com    {
2520f898990d682b639d7093dc837c6da3e70242d02bJamie Madill        if (samplerState.magFilter != GL_NEAREST ||
2521f898990d682b639d7093dc837c6da3e70242d02bJamie Madill            (samplerState.minFilter != GL_NEAREST && samplerState.minFilter != GL_NEAREST_MIPMAP_NEAREST))
25227625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com        {
25237625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com            return false;
25247625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com        }
25257625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com    }
25267625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com
2527f898990d682b639d7093dc837c6da3e70242d02bJamie Madill    if (IsMipmapFiltered(samplerState) && !isMipmapComplete())
25287625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com    {
25297625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com        return false;
25307625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com    }
25317625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com
25327625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com    return true;
25337625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com}
25347625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com
25357625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.combool Texture2DArray::isMipmapComplete() const
25367625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com{
253798705b7de3de71d3f5becc8ed3974e5b26c03fa3Geoff Lang    int levelCount = mipLevels();
253807edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill
253998705b7de3de71d3f5becc8ed3974e5b26c03fa3Geoff Lang    for (int level = 1; level < levelCount; level++)
254007edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    {
254107edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill        if (!isLevelComplete(level))
254207edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill        {
254307edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill            return false;
254407edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill        }
254507edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    }
254607edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill
254707edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    return true;
254807edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill}
254907edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill
255007edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madillbool Texture2DArray::isLevelComplete(int level) const
255107edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill{
2552b8f8b89b1305f5c56ea890e2d10fd2ec9cc1f2adJamie Madill    ASSERT(level >= 0 && level < (int)ArraySize(mImageArray));
255307edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill
25547625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com    if (isImmutable())
25557625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com    {
25567625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com        return true;
25577625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com    }
25587625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com
2559d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill    GLsizei width = getBaseLevelWidth();
2560d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill    GLsizei height = getBaseLevelHeight();
2561b8f8b89b1305f5c56ea890e2d10fd2ec9cc1f2adJamie Madill    GLsizei layers = getLayers(0);
25627625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com
2563b8f8b89b1305f5c56ea890e2d10fd2ec9cc1f2adJamie Madill    if (width <= 0 || height <= 0 || layers <= 0)
25647625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com    {
25657625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com        return false;
25667625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com    }
25677625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com
256807edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    if (level == 0)
256907edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    {
257007edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill        return true;
257107edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    }
25727625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com
257307edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    if (getInternalFormat(level) != getInternalFormat(0))
25747625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com    {
257507edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill        return false;
257607edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    }
25777625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com
257807edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    if (getWidth(level) != std::max(1, width >> level))
257907edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    {
258007edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill        return false;
258107edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    }
25827625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com
258307edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    if (getHeight(level) != std::max(1, height >> level))
258407edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    {
258507edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill        return false;
258607edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    }
25877625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com
2588b8f8b89b1305f5c56ea890e2d10fd2ec9cc1f2adJamie Madill    if (getLayers(level) != layers)
258907edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    {
259007edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill        return false;
25917625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com    }
25927625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com
25937625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com    return true;
25947625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com}
25957625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com
25963c7fa226aeb81469b93142b54e339f13a46ab835Jamie MadillFramebufferAttachment *Texture2DArray::getAttachment(GLint level, GLint layer)
25977625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com{
25983c7fa226aeb81469b93142b54e339f13a46ab835Jamie Madill    FramebufferAttachment *attachment = mRenderbufferProxies.get(level, layer);
25993c7fa226aeb81469b93142b54e339f13a46ab835Jamie Madill    if (!attachment)
26008040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang    {
26013c7fa226aeb81469b93142b54e339f13a46ab835Jamie Madill        attachment = new FramebufferAttachment(mRenderer, id(), new Texture2DArrayAttachment(this, level, layer));
26023c7fa226aeb81469b93142b54e339f13a46ab835Jamie Madill        mRenderbufferProxies.add(level, 0, attachment);
26038040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang    }
26048040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang
26053c7fa226aeb81469b93142b54e339f13a46ab835Jamie Madill    return attachment;
26068040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang}
26078040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang
2608e83d1a93c6996ceaad179b008a31fed91ff78914Jamie Madillunsigned int Texture2DArray::getRenderTargetSerial(GLint level, GLint layer)
26098040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang{
2610e83d1a93c6996ceaad179b008a31fed91ff78914Jamie Madill    return (ensureRenderTarget() ? mTexStorage->getRenderTargetSerial(level, layer) : 0);
26117625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com}
26127625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com
261307bb8cf4f5d734c9ba15adadf5a765fa22cf25ceJamie Madillbool Texture2DArray::isValidLevel(int level) const
26147625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com{
2615bf712d0a32847868913a3521b44912a5c29f08b8Nicolas Capens    return (mTexStorage ? (level >= 0 && level < mTexStorage->getLevelCount()) : 0);
26167625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com}
26177625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com
261873b5d06e9c46bdbbaf83f09b5669b665f12d0208Jamie Madillvoid Texture2DArray::initializeStorage(bool renderTarget)
26197625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com{
2620884a4626ae1d56feeb9971e0b6f095b5c897eda1Jamie Madill    // Only initialize the first time this texture is used as a render target or shader resource
2621884a4626ae1d56feeb9971e0b6f095b5c897eda1Jamie Madill    if (mTexStorage)
2622884a4626ae1d56feeb9971e0b6f095b5c897eda1Jamie Madill    {
2623884a4626ae1d56feeb9971e0b6f095b5c897eda1Jamie Madill        return;
2624884a4626ae1d56feeb9971e0b6f095b5c897eda1Jamie Madill    }
26257625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com
2626884a4626ae1d56feeb9971e0b6f095b5c897eda1Jamie Madill    // do not attempt to create storage for nonexistant data
2627884a4626ae1d56feeb9971e0b6f095b5c897eda1Jamie Madill    if (!isLevelComplete(0))
26287625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com    {
2629884a4626ae1d56feeb9971e0b6f095b5c897eda1Jamie Madill        return;
26307625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com    }
26317625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com
2632884a4626ae1d56feeb9971e0b6f095b5c897eda1Jamie Madill    bool createRenderTarget = (renderTarget || mUsage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE);
26337625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com
2634884a4626ae1d56feeb9971e0b6f095b5c897eda1Jamie Madill    setCompleteTexStorage(createCompleteStorage(createRenderTarget));
2635884a4626ae1d56feeb9971e0b6f095b5c897eda1Jamie Madill    ASSERT(mTexStorage);
26367625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com
2637884a4626ae1d56feeb9971e0b6f095b5c897eda1Jamie Madill    // flush image data to the storage
2638884a4626ae1d56feeb9971e0b6f095b5c897eda1Jamie Madill    updateStorage();
2639884a4626ae1d56feeb9971e0b6f095b5c897eda1Jamie Madill}
2640884a4626ae1d56feeb9971e0b6f095b5c897eda1Jamie Madill
2641884a4626ae1d56feeb9971e0b6f095b5c897eda1Jamie Madillrx::TextureStorageInterface2DArray *Texture2DArray::createCompleteStorage(bool renderTarget) const
2642884a4626ae1d56feeb9971e0b6f095b5c897eda1Jamie Madill{
2643884a4626ae1d56feeb9971e0b6f095b5c897eda1Jamie Madill    GLsizei width = getBaseLevelWidth();
2644884a4626ae1d56feeb9971e0b6f095b5c897eda1Jamie Madill    GLsizei height = getBaseLevelHeight();
2645b8f8b89b1305f5c56ea890e2d10fd2ec9cc1f2adJamie Madill    GLsizei depth = getLayers(0);
2646884a4626ae1d56feeb9971e0b6f095b5c897eda1Jamie Madill
2647884a4626ae1d56feeb9971e0b6f095b5c897eda1Jamie Madill    ASSERT(width > 0 && height > 0 && depth > 0);
26487625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com
2649884a4626ae1d56feeb9971e0b6f095b5c897eda1Jamie Madill    // use existing storage level count, when previously specified by TexStorage*D
2650bf712d0a32847868913a3521b44912a5c29f08b8Nicolas Capens    GLint levels = (mTexStorage ? mTexStorage->getLevelCount() : creationLevels(width, height, 1));
2651884a4626ae1d56feeb9971e0b6f095b5c897eda1Jamie Madill
2652bf712d0a32847868913a3521b44912a5c29f08b8Nicolas Capens    return new rx::TextureStorageInterface2DArray(mRenderer, getBaseLevelInternalFormat(), renderTarget, width, height, depth, levels);
2653884a4626ae1d56feeb9971e0b6f095b5c897eda1Jamie Madill}
2654884a4626ae1d56feeb9971e0b6f095b5c897eda1Jamie Madill
2655884a4626ae1d56feeb9971e0b6f095b5c897eda1Jamie Madillvoid Texture2DArray::setCompleteTexStorage(rx::TextureStorageInterface2DArray *newCompleteTexStorage)
2656884a4626ae1d56feeb9971e0b6f095b5c897eda1Jamie Madill{
2657884a4626ae1d56feeb9971e0b6f095b5c897eda1Jamie Madill    SafeDelete(mTexStorage);
2658884a4626ae1d56feeb9971e0b6f095b5c897eda1Jamie Madill    mTexStorage = newCompleteTexStorage;
26597625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com    mDirtyImages = true;
2660884a4626ae1d56feeb9971e0b6f095b5c897eda1Jamie Madill
2661884a4626ae1d56feeb9971e0b6f095b5c897eda1Jamie Madill    // We do not support managed 2D array storage, as managed storage is ES2/D3D9 only
2662884a4626ae1d56feeb9971e0b6f095b5c897eda1Jamie Madill    ASSERT(!mTexStorage->isManaged());
26637625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com}
26647625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com
2665169d11186cb1fdef8920668169682cf84749606dJamie Madillvoid Texture2DArray::updateStorage()
26667625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com{
2667946b948d8e5faa2ce63af6a7850889be0eaba45fGeoff Lang    ASSERT(mTexStorage != NULL);
2668946b948d8e5faa2ce63af6a7850889be0eaba45fGeoff Lang    GLint storageLevels = mTexStorage->getLevelCount();
2669946b948d8e5faa2ce63af6a7850889be0eaba45fGeoff Lang    for (int level = 0; level < storageLevels; level++)
26707625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com    {
2671d9b9a508c5059aa08a87d1a7c0f1a729dd3979aeJamie Madill        if (isLevelComplete(level))
2672d9b9a508c5059aa08a87d1a7c0f1a729dd3979aeJamie Madill        {
2673169d11186cb1fdef8920668169682cf84749606dJamie Madill            updateStorageLevel(level);
2674d9b9a508c5059aa08a87d1a7c0f1a729dd3979aeJamie Madill        }
267507edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    }
267607edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill}
26777625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com
2678169d11186cb1fdef8920668169682cf84749606dJamie Madillvoid Texture2DArray::updateStorageLevel(int level)
267907edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill{
2680aee7ad8846b5e2e2405af850fea6dc3f4b7fc8b5Jamie Madill    ASSERT(level >= 0 && level < (int)ArraySize(mLayerCounts));
2681aee7ad8846b5e2e2405af850fea6dc3f4b7fc8b5Jamie Madill    ASSERT(isLevelComplete(level));
2682aee7ad8846b5e2e2405af850fea6dc3f4b7fc8b5Jamie Madill
268307edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    for (int layer = 0; layer < mLayerCounts[level]; layer++)
268407edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill    {
2685aee7ad8846b5e2e2405af850fea6dc3f4b7fc8b5Jamie Madill        ASSERT(mImageArray[level] != NULL && mImageArray[level][layer] != NULL);
2686aee7ad8846b5e2e2405af850fea6dc3f4b7fc8b5Jamie Madill        if (mImageArray[level][layer]->isDirty())
268707edd4486cd890393fe5cd4b4644f23e2fd2da7dJamie Madill        {
2688aee7ad8846b5e2e2405af850fea6dc3f4b7fc8b5Jamie Madill            commitRect(level, 0, 0, layer, getWidth(level), getHeight(level));
26897625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com        }
26907625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com    }
26917625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com}
26927625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com
2693e83d1a93c6996ceaad179b008a31fed91ff78914Jamie Madillbool Texture2DArray::ensureRenderTarget()
26947625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com{
2695884a4626ae1d56feeb9971e0b6f095b5c897eda1Jamie Madill    initializeStorage(true);
2696644f766c7305f09f9662e7206e6e2163ce9248a1shannonwoods@chromium.org
2697b8f8b89b1305f5c56ea890e2d10fd2ec9cc1f2adJamie Madill    if (getBaseLevelWidth() > 0 && getBaseLevelHeight() > 0 && getLayers(0) > 0)
26987625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com    {
2699884a4626ae1d56feeb9971e0b6f095b5c897eda1Jamie Madill        ASSERT(mTexStorage);
2700884a4626ae1d56feeb9971e0b6f095b5c897eda1Jamie Madill        if (!mTexStorage->isRenderTarget())
27017625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com        {
2702884a4626ae1d56feeb9971e0b6f095b5c897eda1Jamie Madill            rx::TextureStorageInterface2DArray *newRenderTargetStorage = createCompleteStorage(true);
2703884a4626ae1d56feeb9971e0b6f095b5c897eda1Jamie Madill
2704884a4626ae1d56feeb9971e0b6f095b5c897eda1Jamie Madill            if (!mRenderer->copyToRenderTarget(newRenderTargetStorage, mTexStorage))
27057625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com            {
2706884a4626ae1d56feeb9971e0b6f095b5c897eda1Jamie Madill                delete newRenderTargetStorage;
2707e83d1a93c6996ceaad179b008a31fed91ff78914Jamie Madill                return gl::error(GL_OUT_OF_MEMORY, false);
27087625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com            }
2709884a4626ae1d56feeb9971e0b6f095b5c897eda1Jamie Madill
2710884a4626ae1d56feeb9971e0b6f095b5c897eda1Jamie Madill            setCompleteTexStorage(newRenderTargetStorage);
27117625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com        }
27127625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com    }
27137625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com
2714e83d1a93c6996ceaad179b008a31fed91ff78914Jamie Madill    return (mTexStorage && mTexStorage->isRenderTarget());
27157625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com}
27167625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com
27178040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Langrx::RenderTarget *Texture2DArray::getRenderTarget(GLint level, GLint layer)
27187625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com{
27198040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang    // ensure the underlying texture is created
27202ebab858840fb19d4284314caebee4b3cf0700c8Jamie Madill    if (!ensureRenderTarget())
27218040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang    {
27228040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang        return NULL;
27238040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang    }
27248040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang
2725169d11186cb1fdef8920668169682cf84749606dJamie Madill    updateStorageLevel(level);
27268040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang
27278040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang    // ensure this is NOT a depth texture
27288040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang    if (isDepth(level))
27298040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang    {
27308040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang        return NULL;
27318040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang    }
27328040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang
27338040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang    return mTexStorage->getRenderTarget(level, layer);
27348040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang}
27358040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang
27368040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Langrx::RenderTarget *Texture2DArray::getDepthStencil(GLint level, GLint layer)
27378040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang{
27388040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang    // ensure the underlying texture is created
27392ebab858840fb19d4284314caebee4b3cf0700c8Jamie Madill    if (!ensureRenderTarget())
27408040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang    {
27418040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang        return NULL;
27428040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang    }
27438040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang
2744169d11186cb1fdef8920668169682cf84749606dJamie Madill    updateStorageLevel(level);
27458040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang
27468040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang    // ensure this is a depth texture
27478040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang    if (!isDepth(level))
27488040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang    {
27498040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang        return NULL;
27508040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang    }
27518040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang
27528040f57dd7011872581cc769ff4df2b7ad6ca069Geoff Lang    return mTexStorage->getRenderTarget(level, layer);
27537625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com}
27547625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com
2755005df41f8900641ed1df60700c8e2eca659a33cbGeoff Langvoid Texture2DArray::redefineImage(GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
27567625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com{
27577625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com    // If there currently is a corresponding storage texture image, it has these parameters
2758d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill    const int storageWidth = std::max(1, getBaseLevelWidth() >> level);
2759d3d2a34260af59003f285549c1d95ac5fd8d49eaJamie Madill    const int storageHeight = std::max(1, getBaseLevelHeight() >> level);
2760b8f8b89b1305f5c56ea890e2d10fd2ec9cc1f2adJamie Madill    const int storageDepth = getLayers(0);
2761005df41f8900641ed1df60700c8e2eca659a33cbGeoff Lang    const GLenum storageFormat = getBaseLevelInternalFormat();
27627625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com
2763644f766c7305f09f9662e7206e6e2163ce9248a1shannonwoods@chromium.org    for (int layer = 0; layer < mLayerCounts[level]; layer++)
27647625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com    {
2765644f766c7305f09f9662e7206e6e2163ce9248a1shannonwoods@chromium.org        delete mImageArray[level][layer];
27667625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com    }
2767644f766c7305f09f9662e7206e6e2163ce9248a1shannonwoods@chromium.org    delete[] mImageArray[level];
2768152ed093ed6ea7018ef5a50165e2ad126ed45b2dJamie Madill    mImageArray[level] = NULL;
27697625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com    mLayerCounts[level] = depth;
27707625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com
2771152ed093ed6ea7018ef5a50165e2ad126ed45b2dJamie Madill    if (depth > 0)
2772644f766c7305f09f9662e7206e6e2163ce9248a1shannonwoods@chromium.org    {
2773152ed093ed6ea7018ef5a50165e2ad126ed45b2dJamie Madill        mImageArray[level] = new rx::Image*[depth]();
2774152ed093ed6ea7018ef5a50165e2ad126ed45b2dJamie Madill
2775152ed093ed6ea7018ef5a50165e2ad126ed45b2dJamie Madill        for (int layer = 0; layer < mLayerCounts[level]; layer++)
2776152ed093ed6ea7018ef5a50165e2ad126ed45b2dJamie Madill        {
2777152ed093ed6ea7018ef5a50165e2ad126ed45b2dJamie Madill            mImageArray[level][layer] = mRenderer->createImage();
2778152ed093ed6ea7018ef5a50165e2ad126ed45b2dJamie Madill            mImageArray[level][layer]->redefine(mRenderer, GL_TEXTURE_2D_ARRAY, internalformat, width, height, 1, false);
2779152ed093ed6ea7018ef5a50165e2ad126ed45b2dJamie Madill        }
2780644f766c7305f09f9662e7206e6e2163ce9248a1shannonwoods@chromium.org    }
2781644f766c7305f09f9662e7206e6e2163ce9248a1shannonwoods@chromium.org
27827625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com    if (mTexStorage)
27837625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com    {
2784bf712d0a32847868913a3521b44912a5c29f08b8Nicolas Capens        const int storageLevels = mTexStorage->getLevelCount();
27857625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com
27867625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com        if ((level >= storageLevels && storageLevels != 0) ||
27877625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com            width != storageWidth ||
27887625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com            height != storageHeight ||
27897625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com            depth != storageDepth ||
27907625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com            internalformat != storageFormat)   // Discard mismatched storage
27917625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com        {
2792644f766c7305f09f9662e7206e6e2163ce9248a1shannonwoods@chromium.org            for (int level = 0; level < IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
27937625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com            {
2794644f766c7305f09f9662e7206e6e2163ce9248a1shannonwoods@chromium.org                for (int layer = 0; layer < mLayerCounts[level]; layer++)
27957625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com                {
27967625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com                    mImageArray[level][layer]->markDirty();
27977625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com                }
27987625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com            }
27997625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com
28007625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com            delete mTexStorage;
28017625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com            mTexStorage = NULL;
28027625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com            mDirtyImages = true;
28037625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com        }
28047625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com    }
28057625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com}
28067625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com
28077625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.comvoid Texture2DArray::commitRect(GLint level, GLint xoffset, GLint yoffset, GLint layerTarget, GLsizei width, GLsizei height)
28087625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com{
2809b8f8b89b1305f5c56ea890e2d10fd2ec9cc1f2adJamie Madill    if (isValidLevel(level) && layerTarget < getLayers(level))
28107625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com    {
28117625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com        rx::Image *image = mImageArray[level][layerTarget];
2812169d11186cb1fdef8920668169682cf84749606dJamie Madill        if (image->copyToStorage(mTexStorage, level, xoffset, yoffset, layerTarget, width, height))
28137625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com        {
28147625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com            image->markClean();
28157625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com        }
28167625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com    }
28177625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com}
28187625f798255604cb7d9b05d91086ae37029899d1shannon.woods%transgaming.com@gtempaccount.com
281995a758f3aaecea686132ea2a602e1612057c32abdaniel@transgaming.com}
2820