14834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com//
2cec3590a151059813b91b33cd5e000c94f5bccaaGeoff Lang// Copyright (c) 2012-2014 The ANGLE Project Authors. All rights reserved.
34834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com// Use of this source code is governed by a BSD-style license that can be
44834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com// found in the LICENSE file.
54834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com//
64834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com
74834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com// TextureStorage11.cpp: Implements the abstract rx::TextureStorage11 class and its concrete derived
84834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com// classes TextureStorage11_2D and TextureStorage11_Cube, which act as the interface to the D3D11 texture.
94834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com
10c7a4104957aa1f6fa36e4e9cf65d36b699eb05bdBrandon Jones#include "libGLESv2/renderer/d3d/d3d11/TextureStorage11.h"
11c7a4104957aa1f6fa36e4e9cf65d36b699eb05bdBrandon Jones#include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
12c7a4104957aa1f6fa36e4e9cf65d36b699eb05bdBrandon Jones#include "libGLESv2/renderer/d3d/d3d11/RenderTarget11.h"
13c7a4104957aa1f6fa36e4e9cf65d36b699eb05bdBrandon Jones#include "libGLESv2/renderer/d3d/d3d11/SwapChain11.h"
14c7a4104957aa1f6fa36e4e9cf65d36b699eb05bdBrandon Jones#include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h"
15c7a4104957aa1f6fa36e4e9cf65d36b699eb05bdBrandon Jones#include "libGLESv2/renderer/d3d/d3d11/Blit11.h"
16c7a4104957aa1f6fa36e4e9cf65d36b699eb05bdBrandon Jones#include "libGLESv2/renderer/d3d/d3d11/formatutils11.h"
176982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross#include "libGLESv2/renderer/d3d/d3d11/Image11.h"
180b7eef7c469bf717f7e1b57c6273f00d88e8b1d9Geoff Lang#include "libGLESv2/renderer/d3d/TextureD3D.h"
190b7eef7c469bf717f7e1b57c6273f00d88e8b1d9Geoff Lang#include "libGLESv2/main.h"
20ac7579c2bd0cc9afdf5892a766e6967bf3a341f0Jamie Madill#include "libGLESv2/ImageIndex.h"
214834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com
22a2ecfcccf1d1a85e6054a7314ce1f9de0648ac7fshannonwoods@chromium.org#include "common/utilities.h"
234834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com
244834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.comnamespace rx
254834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com{
264834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com
27644bbf2448bc2e29eadd811c303117cacb39189dGeoff LangTextureStorage11::SwizzleCacheValue::SwizzleCacheValue()
28644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang    : swizzleRed(GL_NONE), swizzleGreen(GL_NONE), swizzleBlue(GL_NONE), swizzleAlpha(GL_NONE)
29644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang{
30644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang}
31644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang
32644bbf2448bc2e29eadd811c303117cacb39189dGeoff LangTextureStorage11::SwizzleCacheValue::SwizzleCacheValue(GLenum red, GLenum green, GLenum blue, GLenum alpha)
33644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang    : swizzleRed(red), swizzleGreen(green), swizzleBlue(blue), swizzleAlpha(alpha)
34644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang{
35644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang}
36644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang
37644bbf2448bc2e29eadd811c303117cacb39189dGeoff Langbool TextureStorage11::SwizzleCacheValue::operator==(const SwizzleCacheValue &other) const
38644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang{
39644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang    return swizzleRed == other.swizzleRed &&
40644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang           swizzleGreen == other.swizzleGreen &&
41644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang           swizzleBlue == other.swizzleBlue &&
42644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang           swizzleAlpha == other.swizzleAlpha;
43644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang}
44644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang
45644bbf2448bc2e29eadd811c303117cacb39189dGeoff Langbool TextureStorage11::SwizzleCacheValue::operator!=(const SwizzleCacheValue &other) const
46644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang{
47644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang    return !(*this == other);
48644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang}
49644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang
50a9f85c63bd7cbe1ce85664c32d1bf5f7d020a82cNicolas CapensTextureStorage11::SRVKey::SRVKey(int baseLevel, int mipLevels, bool swizzle)
51a9f85c63bd7cbe1ce85664c32d1bf5f7d020a82cNicolas Capens    : baseLevel(baseLevel), mipLevels(mipLevels), swizzle(swizzle)
52a9f85c63bd7cbe1ce85664c32d1bf5f7d020a82cNicolas Capens{
53a9f85c63bd7cbe1ce85664c32d1bf5f7d020a82cNicolas Capens}
54a9f85c63bd7cbe1ce85664c32d1bf5f7d020a82cNicolas Capens
55a9f85c63bd7cbe1ce85664c32d1bf5f7d020a82cNicolas Capensbool TextureStorage11::SRVKey::operator==(const SRVKey &rhs) const
56a9f85c63bd7cbe1ce85664c32d1bf5f7d020a82cNicolas Capens{
57a9f85c63bd7cbe1ce85664c32d1bf5f7d020a82cNicolas Capens    return baseLevel == rhs.baseLevel &&
58a9f85c63bd7cbe1ce85664c32d1bf5f7d020a82cNicolas Capens           mipLevels == rhs.mipLevels &&
59a9f85c63bd7cbe1ce85664c32d1bf5f7d020a82cNicolas Capens           swizzle == rhs.swizzle;
60a9f85c63bd7cbe1ce85664c32d1bf5f7d020a82cNicolas Capens}
61a9f85c63bd7cbe1ce85664c32d1bf5f7d020a82cNicolas Capens
62a9f85c63bd7cbe1ce85664c32d1bf5f7d020a82cNicolas CapensTextureStorage11::SRVCache::~SRVCache()
63a9f85c63bd7cbe1ce85664c32d1bf5f7d020a82cNicolas Capens{
64a9f85c63bd7cbe1ce85664c32d1bf5f7d020a82cNicolas Capens    for (size_t i = 0; i < cache.size(); i++)
65a9f85c63bd7cbe1ce85664c32d1bf5f7d020a82cNicolas Capens    {
66a9f85c63bd7cbe1ce85664c32d1bf5f7d020a82cNicolas Capens        SafeRelease(cache[i].srv);
67a9f85c63bd7cbe1ce85664c32d1bf5f7d020a82cNicolas Capens    }
68a9f85c63bd7cbe1ce85664c32d1bf5f7d020a82cNicolas Capens}
69a9f85c63bd7cbe1ce85664c32d1bf5f7d020a82cNicolas Capens
70a9f85c63bd7cbe1ce85664c32d1bf5f7d020a82cNicolas CapensID3D11ShaderResourceView *TextureStorage11::SRVCache::find(const SRVKey &key) const
71a9f85c63bd7cbe1ce85664c32d1bf5f7d020a82cNicolas Capens{
72a9f85c63bd7cbe1ce85664c32d1bf5f7d020a82cNicolas Capens    for (size_t i = 0; i < cache.size(); i++)
73a9f85c63bd7cbe1ce85664c32d1bf5f7d020a82cNicolas Capens    {
74a9f85c63bd7cbe1ce85664c32d1bf5f7d020a82cNicolas Capens        if (cache[i].key == key)
75a9f85c63bd7cbe1ce85664c32d1bf5f7d020a82cNicolas Capens        {
76a9f85c63bd7cbe1ce85664c32d1bf5f7d020a82cNicolas Capens            return cache[i].srv;
77a9f85c63bd7cbe1ce85664c32d1bf5f7d020a82cNicolas Capens        }
78a9f85c63bd7cbe1ce85664c32d1bf5f7d020a82cNicolas Capens    }
79a9f85c63bd7cbe1ce85664c32d1bf5f7d020a82cNicolas Capens
80a9f85c63bd7cbe1ce85664c32d1bf5f7d020a82cNicolas Capens    return NULL;
81a9f85c63bd7cbe1ce85664c32d1bf5f7d020a82cNicolas Capens}
82a9f85c63bd7cbe1ce85664c32d1bf5f7d020a82cNicolas Capens
83a9f85c63bd7cbe1ce85664c32d1bf5f7d020a82cNicolas CapensID3D11ShaderResourceView *TextureStorage11::SRVCache::add(const SRVKey &key, ID3D11ShaderResourceView *srv)
84a9f85c63bd7cbe1ce85664c32d1bf5f7d020a82cNicolas Capens{
85a9f85c63bd7cbe1ce85664c32d1bf5f7d020a82cNicolas Capens    SRVPair pair = {key, srv};
86a9f85c63bd7cbe1ce85664c32d1bf5f7d020a82cNicolas Capens    cache.push_back(pair);
87a9f85c63bd7cbe1ce85664c32d1bf5f7d020a82cNicolas Capens
88a9f85c63bd7cbe1ce85664c32d1bf5f7d020a82cNicolas Capens    return srv;
89a9f85c63bd7cbe1ce85664c32d1bf5f7d020a82cNicolas Capens}
90a9f85c63bd7cbe1ce85664c32d1bf5f7d020a82cNicolas Capens
91fa7b76d08d5c2dddb7979471884834103c761747Nicolas CapensTextureStorage11::TextureStorage11(Renderer *renderer, UINT bindFlags)
924834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com    : mBindFlags(bindFlags),
93f61738a578693170902045f8a3fa2f383fd5c367Nicolas Capens      mTopLevel(0),
9453b0ecb848cd17a0e72a0b2813c196386e8cf3b1shannon.woods@transgaming.com      mMipLevels(0),
9553b0ecb848cd17a0e72a0b2813c196386e8cf3b1shannon.woods@transgaming.com      mTextureFormat(DXGI_FORMAT_UNKNOWN),
9653b0ecb848cd17a0e72a0b2813c196386e8cf3b1shannon.woods@transgaming.com      mShaderResourceFormat(DXGI_FORMAT_UNKNOWN),
9753b0ecb848cd17a0e72a0b2813c196386e8cf3b1shannon.woods@transgaming.com      mRenderTargetFormat(DXGI_FORMAT_UNKNOWN),
9853b0ecb848cd17a0e72a0b2813c196386e8cf3b1shannon.woods@transgaming.com      mDepthStencilFormat(DXGI_FORMAT_UNKNOWN),
9953b0ecb848cd17a0e72a0b2813c196386e8cf3b1shannon.woods@transgaming.com      mTextureWidth(0),
1002058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com      mTextureHeight(0),
1012058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com      mTextureDepth(0)
1024834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com{
1034834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com    mRenderer = Renderer11::makeRenderer11(renderer);
10441d9f7e97a6066b8300e3fab3ad3b83c083b3479Nicolas Capens
10541d9f7e97a6066b8300e3fab3ad3b83c083b3479Nicolas Capens    for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
10641d9f7e97a6066b8300e3fab3ad3b83c083b3479Nicolas Capens    {
10741d9f7e97a6066b8300e3fab3ad3b83c083b3479Nicolas Capens        mLevelSRVs[i] = NULL;
10841d9f7e97a6066b8300e3fab3ad3b83c083b3479Nicolas Capens    }
1094834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com}
1104834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com
1114834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.comTextureStorage11::~TextureStorage11()
1124834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com{
11341d9f7e97a6066b8300e3fab3ad3b83c083b3479Nicolas Capens    for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
11441d9f7e97a6066b8300e3fab3ad3b83c083b3479Nicolas Capens    {
11541d9f7e97a6066b8300e3fab3ad3b83c083b3479Nicolas Capens        SafeRelease(mLevelSRVs[level]);
11641d9f7e97a6066b8300e3fab3ad3b83c083b3479Nicolas Capens    }
1171e1b5e91c101bdb565f61c5341c69b2bb7702690daniel@transgaming.com}
1184834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com
1194834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.comTextureStorage11 *TextureStorage11::makeTextureStorage11(TextureStorage *storage)
1204834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com{
1218b400b1e8d84c5b93dd151807504a3e4b90d1b21apatrick@chromium.org    ASSERT(HAS_DYNAMIC_TYPE(TextureStorage11*, storage));
1224834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com    return static_cast<TextureStorage11*>(storage);
1234834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com}
1244834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com
125e4a492be45f39dffaea53c3523064844ee56e41bGeoff LangDWORD TextureStorage11::GetTextureBindFlags(GLenum internalFormat, bool renderTarget)
1264834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com{
127adc56358754883926714508e5b918a787dd20b20shannonwoods@chromium.org    UINT bindFlags = 0;
128adc56358754883926714508e5b918a787dd20b20shannonwoods@chromium.org
1299aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang    const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalFormat);
1309aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang    if (formatInfo.srvFormat != DXGI_FORMAT_UNKNOWN)
131adc56358754883926714508e5b918a787dd20b20shannonwoods@chromium.org    {
132adc56358754883926714508e5b918a787dd20b20shannonwoods@chromium.org        bindFlags |= D3D11_BIND_SHADER_RESOURCE;
133adc56358754883926714508e5b918a787dd20b20shannonwoods@chromium.org    }
1349aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang    if (formatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN)
1354834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com    {
1364834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com        bindFlags |= D3D11_BIND_DEPTH_STENCIL;
1374834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com    }
1389aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang    if (formatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN && renderTarget)
1394834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com    {
1404834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com        bindFlags |= D3D11_BIND_RENDER_TARGET;
1414834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com    }
1424834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com
143adc56358754883926714508e5b918a787dd20b20shannonwoods@chromium.org    return bindFlags;
1444834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com}
1454834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com
1464834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.comUINT TextureStorage11::getBindFlags() const
1474834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com{
1484834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com    return mBindFlags;
1494834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com}
150f61738a578693170902045f8a3fa2f383fd5c367Nicolas Capens
151f61738a578693170902045f8a3fa2f383fd5c367Nicolas Capensint TextureStorage11::getTopLevel() const
1524834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com{
153f61738a578693170902045f8a3fa2f383fd5c367Nicolas Capens    return mTopLevel;
1544834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com}
1554834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com
1564834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.combool TextureStorage11::isRenderTarget() const
1574834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com{
1584834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com    return (mBindFlags & (D3D11_BIND_RENDER_TARGET | D3D11_BIND_DEPTH_STENCIL)) != 0;
1594834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com}
1602058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com
1614834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.combool TextureStorage11::isManaged() const
1624834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com{
1634834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com    return false;
1644834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com}
1654834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com
166bf712d0a32847868913a3521b44912a5c29f08b8Nicolas Capensint TextureStorage11::getLevelCount() const
1674834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com{
168fa7b76d08d5c2dddb7979471884834103c761747Nicolas Capens    return mMipLevels - mTopLevel;
1694834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com}
1704834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com
171b16b8ed79d73c718cfe9247e9c8d2714d5eb4dc5Jamie Madillint TextureStorage11::getLevelWidth(int mipLevel) const
172b16b8ed79d73c718cfe9247e9c8d2714d5eb4dc5Jamie Madill{
173fa7b76d08d5c2dddb7979471884834103c761747Nicolas Capens    return std::max(static_cast<int>(mTextureWidth) >> mipLevel, 1);
174b16b8ed79d73c718cfe9247e9c8d2714d5eb4dc5Jamie Madill}
175b16b8ed79d73c718cfe9247e9c8d2714d5eb4dc5Jamie Madill
176b16b8ed79d73c718cfe9247e9c8d2714d5eb4dc5Jamie Madillint TextureStorage11::getLevelHeight(int mipLevel) const
177b16b8ed79d73c718cfe9247e9c8d2714d5eb4dc5Jamie Madill{
178fa7b76d08d5c2dddb7979471884834103c761747Nicolas Capens    return std::max(static_cast<int>(mTextureHeight) >> mipLevel, 1);
179b16b8ed79d73c718cfe9247e9c8d2714d5eb4dc5Jamie Madill}
180b16b8ed79d73c718cfe9247e9c8d2714d5eb4dc5Jamie Madill
181b16b8ed79d73c718cfe9247e9c8d2714d5eb4dc5Jamie Madillint TextureStorage11::getLevelDepth(int mipLevel) const
182b16b8ed79d73c718cfe9247e9c8d2714d5eb4dc5Jamie Madill{
183fa7b76d08d5c2dddb7979471884834103c761747Nicolas Capens    return std::max(static_cast<int>(mTextureDepth) >> mipLevel, 1);
184b16b8ed79d73c718cfe9247e9c8d2714d5eb4dc5Jamie Madill}
185b16b8ed79d73c718cfe9247e9c8d2714d5eb4dc5Jamie Madill
1864cfff5f3c8eb849efeb6dcc0893d145806cf8bb4Jamie MadillUINT TextureStorage11::getSubresourceIndex(int mipLevel, int layerTarget) const
1879a2f54dbdda14e3a72d1de41ddfdd6e817a29325daniel@transgaming.com{
1889a2f54dbdda14e3a72d1de41ddfdd6e817a29325daniel@transgaming.com    UINT index = 0;
18976b258f88ebb47cf1022ae6b4392f220a56383d4Nicolas Capens    if (getResource())
1909a2f54dbdda14e3a72d1de41ddfdd6e817a29325daniel@transgaming.com    {
1916c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com        index = D3D11CalcSubresource(mipLevel, layerTarget, mMipLevels);
1929a2f54dbdda14e3a72d1de41ddfdd6e817a29325daniel@transgaming.com    }
1939a2f54dbdda14e3a72d1de41ddfdd6e817a29325daniel@transgaming.com    return index;
1949a2f54dbdda14e3a72d1de41ddfdd6e817a29325daniel@transgaming.com}
1959a2f54dbdda14e3a72d1de41ddfdd6e817a29325daniel@transgaming.com
19641d9f7e97a6066b8300e3fab3ad3b83c083b3479Nicolas CapensID3D11ShaderResourceView *TextureStorage11::getSRV(const gl::SamplerState &samplerState)
19741d9f7e97a6066b8300e3fab3ad3b83c083b3479Nicolas Capens{
19841d9f7e97a6066b8300e3fab3ad3b83c083b3479Nicolas Capens    bool swizzleRequired = samplerState.swizzleRequired();
1996053a52e8d529c1bc7d35a8f92430bf8d93938b2Brandon Jones    bool mipmapping = gl::IsMipmapFiltered(samplerState);
20035adc099c7fb3497a665c47df5e43563d10579b2Nicolas Capens    unsigned int mipLevels = mipmapping ? (samplerState.maxLevel - samplerState.baseLevel) : 1;
20135adc099c7fb3497a665c47df5e43563d10579b2Nicolas Capens
20235adc099c7fb3497a665c47df5e43563d10579b2Nicolas Capens    // Make sure there's 'mipLevels' mipmap levels below the base level (offset by the top level,  which corresponds to GL level 0)
20335adc099c7fb3497a665c47df5e43563d10579b2Nicolas Capens    mipLevels = std::min(mipLevels, mMipLevels - mTopLevel - samplerState.baseLevel);
20441d9f7e97a6066b8300e3fab3ad3b83c083b3479Nicolas Capens
20541d9f7e97a6066b8300e3fab3ad3b83c083b3479Nicolas Capens    if (swizzleRequired)
20641d9f7e97a6066b8300e3fab3ad3b83c083b3479Nicolas Capens    {
20741d9f7e97a6066b8300e3fab3ad3b83c083b3479Nicolas Capens        verifySwizzleExists(samplerState.swizzleRed, samplerState.swizzleGreen, samplerState.swizzleBlue, samplerState.swizzleAlpha);
20841d9f7e97a6066b8300e3fab3ad3b83c083b3479Nicolas Capens    }
20941d9f7e97a6066b8300e3fab3ad3b83c083b3479Nicolas Capens
21035adc099c7fb3497a665c47df5e43563d10579b2Nicolas Capens    SRVKey key(samplerState.baseLevel, mipLevels, swizzleRequired);
21141d9f7e97a6066b8300e3fab3ad3b83c083b3479Nicolas Capens    ID3D11ShaderResourceView *srv = srvCache.find(key);
21241d9f7e97a6066b8300e3fab3ad3b83c083b3479Nicolas Capens
21341d9f7e97a6066b8300e3fab3ad3b83c083b3479Nicolas Capens    if(srv)
21441d9f7e97a6066b8300e3fab3ad3b83c083b3479Nicolas Capens    {
21541d9f7e97a6066b8300e3fab3ad3b83c083b3479Nicolas Capens        return srv;
21641d9f7e97a6066b8300e3fab3ad3b83c083b3479Nicolas Capens    }
21741d9f7e97a6066b8300e3fab3ad3b83c083b3479Nicolas Capens
21841d9f7e97a6066b8300e3fab3ad3b83c083b3479Nicolas Capens    DXGI_FORMAT format = (swizzleRequired ? mSwizzleShaderResourceFormat : mShaderResourceFormat);
21941d9f7e97a6066b8300e3fab3ad3b83c083b3479Nicolas Capens    ID3D11Resource *texture = swizzleRequired ? getSwizzleTexture() : getResource();
22041d9f7e97a6066b8300e3fab3ad3b83c083b3479Nicolas Capens
22135adc099c7fb3497a665c47df5e43563d10579b2Nicolas Capens    srv = createSRV(samplerState.baseLevel, mipLevels, format, texture);
22241d9f7e97a6066b8300e3fab3ad3b83c083b3479Nicolas Capens
22341d9f7e97a6066b8300e3fab3ad3b83c083b3479Nicolas Capens    return srvCache.add(key, srv);
22441d9f7e97a6066b8300e3fab3ad3b83c083b3479Nicolas Capens}
22541d9f7e97a6066b8300e3fab3ad3b83c083b3479Nicolas Capens
22641d9f7e97a6066b8300e3fab3ad3b83c083b3479Nicolas CapensID3D11ShaderResourceView *TextureStorage11::getSRVLevel(int mipLevel)
22741d9f7e97a6066b8300e3fab3ad3b83c083b3479Nicolas Capens{
22841d9f7e97a6066b8300e3fab3ad3b83c083b3479Nicolas Capens    if (mipLevel >= 0 && mipLevel < getLevelCount())
22941d9f7e97a6066b8300e3fab3ad3b83c083b3479Nicolas Capens    {
23041d9f7e97a6066b8300e3fab3ad3b83c083b3479Nicolas Capens        if (!mLevelSRVs[mipLevel])
23141d9f7e97a6066b8300e3fab3ad3b83c083b3479Nicolas Capens        {
23241d9f7e97a6066b8300e3fab3ad3b83c083b3479Nicolas Capens            mLevelSRVs[mipLevel] = createSRV(mipLevel, 1, mShaderResourceFormat, getResource());
23341d9f7e97a6066b8300e3fab3ad3b83c083b3479Nicolas Capens        }
23441d9f7e97a6066b8300e3fab3ad3b83c083b3479Nicolas Capens
23541d9f7e97a6066b8300e3fab3ad3b83c083b3479Nicolas Capens        return mLevelSRVs[mipLevel];
23641d9f7e97a6066b8300e3fab3ad3b83c083b3479Nicolas Capens    }
23741d9f7e97a6066b8300e3fab3ad3b83c083b3479Nicolas Capens    else
23841d9f7e97a6066b8300e3fab3ad3b83c083b3479Nicolas Capens    {
23941d9f7e97a6066b8300e3fab3ad3b83c083b3479Nicolas Capens        return NULL;
24041d9f7e97a6066b8300e3fab3ad3b83c083b3479Nicolas Capens    }
24141d9f7e97a6066b8300e3fab3ad3b83c083b3479Nicolas Capens}
24241d9f7e97a6066b8300e3fab3ad3b83c083b3479Nicolas Capens
243644bbf2448bc2e29eadd811c303117cacb39189dGeoff Langvoid TextureStorage11::generateSwizzles(GLenum swizzleRed, GLenum swizzleGreen, GLenum swizzleBlue, GLenum swizzleAlpha)
244644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang{
245644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang    SwizzleCacheValue swizzleTarget(swizzleRed, swizzleGreen, swizzleBlue, swizzleAlpha);
246bf712d0a32847868913a3521b44912a5c29f08b8Nicolas Capens    for (int level = 0; level < getLevelCount(); level++)
247644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang    {
248644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        // Check if the swizzle for this level is out of date
249644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        if (mSwizzleCache[level] != swizzleTarget)
250644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        {
251644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang            // Need to re-render the swizzle for this level
252644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang            ID3D11ShaderResourceView *sourceSRV = getSRVLevel(level);
253644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang            ID3D11RenderTargetView *destRTV = getSwizzleRenderTarget(level);
254644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang
255644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang            gl::Extents size(getLevelWidth(level), getLevelHeight(level), getLevelDepth(level));
256644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang
257644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang            Blit11 *blitter = mRenderer->getBlitter();
258644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang
259644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang            if (blitter->swizzleTexture(sourceSRV, destRTV, size, swizzleRed, swizzleGreen, swizzleBlue, swizzleAlpha))
260644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang            {
261644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang                mSwizzleCache[level] = swizzleTarget;
262644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang            }
263644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang            else
264644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang            {
265644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang                ERR("Failed to swizzle texture.");
266644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang            }
267644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        }
268644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang    }
269644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang}
270644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang
271644bbf2448bc2e29eadd811c303117cacb39189dGeoff Langvoid TextureStorage11::invalidateSwizzleCacheLevel(int mipLevel)
272644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang{
273644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang    if (mipLevel >= 0 && static_cast<unsigned int>(mipLevel) < ArraySize(mSwizzleCache))
274644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang    {
275644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        // The default constructor of SwizzleCacheValue has GL_NONE for all channels which is not a
276644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        // valid swizzle combination
277644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        mSwizzleCache[mipLevel] = SwizzleCacheValue();
278644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang    }
279644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang}
280644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang
281644bbf2448bc2e29eadd811c303117cacb39189dGeoff Langvoid TextureStorage11::invalidateSwizzleCache()
282644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang{
283644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang    for (unsigned int mipLevel = 0; mipLevel < ArraySize(mSwizzleCache); mipLevel++)
284644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang    {
285644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        invalidateSwizzleCacheLevel(mipLevel);
286644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang    }
287644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang}
288644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang
2892058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.combool TextureStorage11::updateSubresourceLevel(ID3D11Resource *srcTexture, unsigned int sourceSubresource,
2906c86bd5f6358dfe721133bae6e599c4c5fdaf04cshannon.woods%transgaming.com@gtempaccount.com                                              int level, int layerTarget, GLint xoffset, GLint yoffset, GLint zoffset,
2912058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com                                              GLsizei width, GLsizei height, GLsizei depth)
2929a2f54dbdda14e3a72d1de41ddfdd6e817a29325daniel@transgaming.com{
2939a2f54dbdda14e3a72d1de41ddfdd6e817a29325daniel@transgaming.com    if (srcTexture)
2949a2f54dbdda14e3a72d1de41ddfdd6e817a29325daniel@transgaming.com    {
295644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        invalidateSwizzleCacheLevel(level);
296644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang
297b16b8ed79d73c718cfe9247e9c8d2714d5eb4dc5Jamie Madill        gl::Extents texSize(getLevelWidth(level), getLevelHeight(level), getLevelDepth(level));
29879031cb5ad26829c32f95112cfec4bd69ff2a56eGeoff Lang        gl::Box copyArea(xoffset, yoffset, zoffset, width, height, depth);
29979031cb5ad26829c32f95112cfec4bd69ff2a56eGeoff Lang
30079031cb5ad26829c32f95112cfec4bd69ff2a56eGeoff Lang        bool fullCopy = copyArea.x == 0 &&
30179031cb5ad26829c32f95112cfec4bd69ff2a56eGeoff Lang                        copyArea.y == 0 &&
30279031cb5ad26829c32f95112cfec4bd69ff2a56eGeoff Lang                        copyArea.z == 0 &&
30379031cb5ad26829c32f95112cfec4bd69ff2a56eGeoff Lang                        copyArea.width  == texSize.width &&
30479031cb5ad26829c32f95112cfec4bd69ff2a56eGeoff Lang                        copyArea.height == texSize.height &&
30579031cb5ad26829c32f95112cfec4bd69ff2a56eGeoff Lang                        copyArea.depth  == texSize.depth;
30679031cb5ad26829c32f95112cfec4bd69ff2a56eGeoff Lang
30776b258f88ebb47cf1022ae6b4392f220a56383d4Nicolas Capens        ID3D11Resource *dstTexture = getResource();
308f61738a578693170902045f8a3fa2f383fd5c367Nicolas Capens        unsigned int dstSubresource = getSubresourceIndex(level + mTopLevel, layerTarget);
30979031cb5ad26829c32f95112cfec4bd69ff2a56eGeoff Lang
31079031cb5ad26829c32f95112cfec4bd69ff2a56eGeoff Lang        ASSERT(dstTexture);
31179031cb5ad26829c32f95112cfec4bd69ff2a56eGeoff Lang
3129aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang        const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mTextureFormat);
3139aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang        if (!fullCopy && (dxgiFormatInfo.depthBits > 0 || dxgiFormatInfo.stencilBits > 0))
31479031cb5ad26829c32f95112cfec4bd69ff2a56eGeoff Lang        {
31579031cb5ad26829c32f95112cfec4bd69ff2a56eGeoff Lang            // CopySubresourceRegion cannot copy partial depth stencils, use the blitter instead
31679031cb5ad26829c32f95112cfec4bd69ff2a56eGeoff Lang            Blit11 *blitter = mRenderer->getBlitter();
31779031cb5ad26829c32f95112cfec4bd69ff2a56eGeoff Lang
31879031cb5ad26829c32f95112cfec4bd69ff2a56eGeoff Lang            return blitter->copyDepthStencil(srcTexture, sourceSubresource, copyArea, texSize,
319125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang                                             dstTexture, dstSubresource, copyArea, texSize,
320125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang                                             NULL);
32179031cb5ad26829c32f95112cfec4bd69ff2a56eGeoff Lang        }
32279031cb5ad26829c32f95112cfec4bd69ff2a56eGeoff Lang        else
32379031cb5ad26829c32f95112cfec4bd69ff2a56eGeoff Lang        {
3249aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang            const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mTextureFormat);
3259aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang
32679031cb5ad26829c32f95112cfec4bd69ff2a56eGeoff Lang            D3D11_BOX srcBox;
32779031cb5ad26829c32f95112cfec4bd69ff2a56eGeoff Lang            srcBox.left = copyArea.x;
32879031cb5ad26829c32f95112cfec4bd69ff2a56eGeoff Lang            srcBox.top = copyArea.y;
3299aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang            srcBox.right = copyArea.x + roundUp((unsigned int)width, dxgiFormatInfo.blockWidth);
3309aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang            srcBox.bottom = copyArea.y + roundUp((unsigned int)height, dxgiFormatInfo.blockHeight);
33179031cb5ad26829c32f95112cfec4bd69ff2a56eGeoff Lang            srcBox.front = copyArea.z;
33279031cb5ad26829c32f95112cfec4bd69ff2a56eGeoff Lang            srcBox.back = copyArea.z + copyArea.depth;
33379031cb5ad26829c32f95112cfec4bd69ff2a56eGeoff Lang
33479031cb5ad26829c32f95112cfec4bd69ff2a56eGeoff Lang            ID3D11DeviceContext *context = mRenderer->getDeviceContext();
33579031cb5ad26829c32f95112cfec4bd69ff2a56eGeoff Lang
33679031cb5ad26829c32f95112cfec4bd69ff2a56eGeoff Lang            context->CopySubresourceRegion(dstTexture, dstSubresource, copyArea.x, copyArea.y, copyArea.z,
33779031cb5ad26829c32f95112cfec4bd69ff2a56eGeoff Lang                                           srcTexture, sourceSubresource, fullCopy ? NULL : &srcBox);
33879031cb5ad26829c32f95112cfec4bd69ff2a56eGeoff Lang            return true;
33979031cb5ad26829c32f95112cfec4bd69ff2a56eGeoff Lang        }
3409a2f54dbdda14e3a72d1de41ddfdd6e817a29325daniel@transgaming.com    }
3419a2f54dbdda14e3a72d1de41ddfdd6e817a29325daniel@transgaming.com
3429a2f54dbdda14e3a72d1de41ddfdd6e817a29325daniel@transgaming.com    return false;
3439a2f54dbdda14e3a72d1de41ddfdd6e817a29325daniel@transgaming.com}
3449a2f54dbdda14e3a72d1de41ddfdd6e817a29325daniel@transgaming.com
3456982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinrossbool TextureStorage11::copySubresourceLevel(ID3D11Resource* dstTexture, unsigned int dstSubresource,
3466982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross                                            int level, int layerTarget, GLint xoffset, GLint yoffset, GLint zoffset,
3476982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross                                            GLsizei width, GLsizei height, GLsizei depth)
3486982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross{
3496982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    if (dstTexture)
3506982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    {
3516982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        ID3D11Resource *srcTexture = getResource();
3526982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        unsigned int srcSubresource = getSubresourceIndex(level + mTopLevel, layerTarget);
3536982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
3546982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        ASSERT(srcTexture);
3556982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
3566982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        ID3D11DeviceContext *context = mRenderer->getDeviceContext();
3576982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
3586982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        context->CopySubresourceRegion(dstTexture, dstSubresource, xoffset, yoffset, zoffset,
3596982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross                                       srcTexture, srcSubresource, NULL);
3606982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        return true;
3616982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    }
3626982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
3636982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    return false;
3646982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross}
3656982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
36685bdfce9f7a1774c7e1a984a6f26c7f15b1fac78shannon.woods@transgaming.comvoid TextureStorage11::generateMipmapLayer(RenderTarget11 *source, RenderTarget11 *dest)
36785bdfce9f7a1774c7e1a984a6f26c7f15b1fac78shannon.woods@transgaming.com{
36885bdfce9f7a1774c7e1a984a6f26c7f15b1fac78shannon.woods@transgaming.com    if (source && dest)
36985bdfce9f7a1774c7e1a984a6f26c7f15b1fac78shannon.woods@transgaming.com    {
37085bdfce9f7a1774c7e1a984a6f26c7f15b1fac78shannon.woods@transgaming.com        ID3D11ShaderResourceView *sourceSRV = source->getShaderResourceView();
37185bdfce9f7a1774c7e1a984a6f26c7f15b1fac78shannon.woods@transgaming.com        ID3D11RenderTargetView *destRTV = dest->getRenderTargetView();
37285bdfce9f7a1774c7e1a984a6f26c7f15b1fac78shannon.woods@transgaming.com
37385bdfce9f7a1774c7e1a984a6f26c7f15b1fac78shannon.woods@transgaming.com        if (sourceSRV && destRTV)
37485bdfce9f7a1774c7e1a984a6f26c7f15b1fac78shannon.woods@transgaming.com        {
375b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang            gl::Box sourceArea(0, 0, 0, source->getWidth(), source->getHeight(), source->getDepth());
376b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang            gl::Extents sourceSize(source->getWidth(), source->getHeight(), source->getDepth());
377b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang
378b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang            gl::Box destArea(0, 0, 0, dest->getWidth(), dest->getHeight(), dest->getDepth());
379b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang            gl::Extents destSize(dest->getWidth(), dest->getHeight(), dest->getDepth());
380b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang
381b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang            Blit11 *blitter = mRenderer->getBlitter();
382b86b979da879358ec8a96e3dfc90672567a0c3c1Geoff Lang
383125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang            blitter->copyTexture(sourceSRV, sourceArea, sourceSize, destRTV, destArea, destSize, NULL,
3845d601382b51c29d1670b58c01360416bd929842dGeoff Lang                                 gl::GetInternalFormatInfo(source->getInternalFormat()).format, GL_LINEAR);
38585bdfce9f7a1774c7e1a984a6f26c7f15b1fac78shannon.woods@transgaming.com        }
38685bdfce9f7a1774c7e1a984a6f26c7f15b1fac78shannon.woods@transgaming.com    }
38785bdfce9f7a1774c7e1a984a6f26c7f15b1fac78shannon.woods@transgaming.com}
38885bdfce9f7a1774c7e1a984a6f26c7f15b1fac78shannon.woods@transgaming.com
389644bbf2448bc2e29eadd811c303117cacb39189dGeoff Langvoid TextureStorage11::verifySwizzleExists(GLenum swizzleRed, GLenum swizzleGreen, GLenum swizzleBlue, GLenum swizzleAlpha)
390644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang{
391644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang    SwizzleCacheValue swizzleTarget(swizzleRed, swizzleGreen, swizzleBlue, swizzleAlpha);
392644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang    for (unsigned int level = 0; level < mMipLevels; level++)
393644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang    {
394644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        ASSERT(mSwizzleCache[level] == swizzleTarget);
395644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang    }
396644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang}
397644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang
3984834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.comTextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, SwapChain11 *swapchain)
3992f06dbfb3f4bd815a3fe5b52638b091c1e356a04Jamie Madill    : TextureStorage11(renderer, D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE),
4002f06dbfb3f4bd815a3fe5b52638b091c1e356a04Jamie Madill      mTexture(swapchain->getOffscreenTexture()),
4012f06dbfb3f4bd815a3fe5b52638b091c1e356a04Jamie Madill      mSwizzleTexture(NULL)
4024834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com{
4032916b30eb47496327257254d355677a6ebb0388aGeoff Lang    mTexture->AddRef();
404e47e7363cf651100b85e042930f31cf5f8291fc1Nicolas Capens
405858d32fa8bc0298a7d78954f5340d5019d718d11shannon.woods@transgaming.com    for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
406858d32fa8bc0298a7d78954f5340d5019d718d11shannon.woods@transgaming.com    {
4076982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        mAssociatedImages[i] = NULL;
408858d32fa8bc0298a7d78954f5340d5019d718d11shannon.woods@transgaming.com        mRenderTarget[i] = NULL;
409644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        mSwizzleRenderTargets[i] = NULL;
410858d32fa8bc0298a7d78954f5340d5019d718d11shannon.woods@transgaming.com    }
4114834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com
4125b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com    D3D11_TEXTURE2D_DESC texDesc;
4135b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com    mTexture->GetDesc(&texDesc);
4145b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com    mMipLevels = texDesc.MipLevels;
4155b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com    mTextureFormat = texDesc.Format;
4165b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com    mTextureWidth = texDesc.Width;
4175b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com    mTextureHeight = texDesc.Height;
4182058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com    mTextureDepth = 1;
4195b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com
420e47e7363cf651100b85e042930f31cf5f8291fc1Nicolas Capens    ID3D11ShaderResourceView *srv = swapchain->getRenderTargetShaderResource();
4215b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com    D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
422e47e7363cf651100b85e042930f31cf5f8291fc1Nicolas Capens    srv->GetDesc(&srvDesc);
4235b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com    mShaderResourceFormat = srvDesc.Format;
4245b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com
4255b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com    ID3D11RenderTargetView* offscreenRTV = swapchain->getRenderTarget();
4265b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com    D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
4275b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com    offscreenRTV->GetDesc(&rtvDesc);
4285b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com    mRenderTargetFormat = rtvDesc.Format;
4294834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com
4309aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang    const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mTextureFormat);
4319aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang    const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(dxgiFormatInfo.internalFormat);
4329aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang    mSwizzleTextureFormat = formatInfo.swizzleTexFormat;
4339aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang    mSwizzleShaderResourceFormat = formatInfo.swizzleSRVFormat;
4349aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang    mSwizzleRenderTargetFormat = formatInfo.swizzleRTVFormat;
435644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang
4365b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com    mDepthStencilFormat = DXGI_FORMAT_UNKNOWN;
4372f06dbfb3f4bd815a3fe5b52638b091c1e356a04Jamie Madill
4382f06dbfb3f4bd815a3fe5b52638b091c1e356a04Jamie Madill    initializeSerials(1, 1);
4394834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com}
4404834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com
441bf712d0a32847868913a3521b44912a5c29f08b8Nicolas CapensTextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels)
4422f06dbfb3f4bd815a3fe5b52638b091c1e356a04Jamie Madill    : TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderTarget)),
4432f06dbfb3f4bd815a3fe5b52638b091c1e356a04Jamie Madill      mTexture(NULL),
4442f06dbfb3f4bd815a3fe5b52638b091c1e356a04Jamie Madill      mSwizzleTexture(NULL)
4454834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com{
446858d32fa8bc0298a7d78954f5340d5019d718d11shannon.woods@transgaming.com    for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
447858d32fa8bc0298a7d78954f5340d5019d718d11shannon.woods@transgaming.com    {
4486982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        mAssociatedImages[i] = NULL;
449858d32fa8bc0298a7d78954f5340d5019d718d11shannon.woods@transgaming.com        mRenderTarget[i] = NULL;
450644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        mSwizzleRenderTargets[i] = NULL;
451858d32fa8bc0298a7d78954f5340d5019d718d11shannon.woods@transgaming.com    }
452858d32fa8bc0298a7d78954f5340d5019d718d11shannon.woods@transgaming.com
4539aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang    const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat);
4549aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang    mTextureFormat = formatInfo.texFormat;
4559aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang    mShaderResourceFormat = formatInfo.srvFormat;
4569aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang    mDepthStencilFormat = formatInfo.dsvFormat;
4579aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang    mRenderTargetFormat = formatInfo.rtvFormat;
4589aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang    mSwizzleTextureFormat = formatInfo.swizzleTexFormat;
4599aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang    mSwizzleShaderResourceFormat = formatInfo.swizzleSRVFormat;
4609aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang    mSwizzleRenderTargetFormat = formatInfo.swizzleRTVFormat;
4615b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com
4624834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com    // if the width or height is not positive this should be treated as an incomplete texture
4634834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com    // we handle that here by skipping the d3d texture creation
4644834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com    if (width > 0 && height > 0)
4654834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com    {
4664834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com        // adjust size if needed for compressed textures
467f61738a578693170902045f8a3fa2f383fd5c367Nicolas Capens        d3d11::MakeValidSize(false, mTextureFormat, &width, &height, &mTopLevel);
4684834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com
4694834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com        ID3D11Device *device = mRenderer->getDevice();
4704834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com
4714834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com        D3D11_TEXTURE2D_DESC desc;
4724834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com        desc.Width = width;      // Compressed texture size constraints?
4734834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com        desc.Height = height;
474bf712d0a32847868913a3521b44912a5c29f08b8Nicolas Capens        desc.MipLevels = ((levels > 0) ? (mTopLevel + levels) : 0);
4754834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com        desc.ArraySize = 1;
4765b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com        desc.Format = mTextureFormat;
4774834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com        desc.SampleDesc.Count = 1;
4784834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com        desc.SampleDesc.Quality = 0;
4794834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com        desc.Usage = D3D11_USAGE_DEFAULT;
4804834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com        desc.BindFlags = getBindFlags();
4814834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com        desc.CPUAccessFlags = 0;
4824834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com        desc.MiscFlags = 0;
4834834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com
4844834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com        HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture);
4854834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com
486ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com        // this can happen from windows TDR
487ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com        if (d3d11::isDeviceLostError(result))
488ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com        {
489ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com            mRenderer->notifyDeviceLost();
490ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com            gl::error(GL_OUT_OF_MEMORY);
491ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com        }
492ddd6c80eaf97858d74d2e2effca558051fac5481shannon.woods@transgaming.com        else if (FAILED(result))
4934834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com        {
4944834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com            ASSERT(result == E_OUTOFMEMORY);
4954834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com            ERR("Creating image failed.");
496779aa2618c1333c034768f3a4ca7826a14753b60shannon.woods@transgaming.com            gl::error(GL_OUT_OF_MEMORY);
4974834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com        }
498b115455104f6d20ad1bad11ceddf68e7ce6c8052daniel@transgaming.com        else
499b115455104f6d20ad1bad11ceddf68e7ce6c8052daniel@transgaming.com        {
500b115455104f6d20ad1bad11ceddf68e7ce6c8052daniel@transgaming.com            mTexture->GetDesc(&desc);
501b115455104f6d20ad1bad11ceddf68e7ce6c8052daniel@transgaming.com            mMipLevels = desc.MipLevels;
502858d32fa8bc0298a7d78954f5340d5019d718d11shannon.woods@transgaming.com            mTextureWidth = desc.Width;
503858d32fa8bc0298a7d78954f5340d5019d718d11shannon.woods@transgaming.com            mTextureHeight = desc.Height;
5042058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com            mTextureDepth = 1;
505b115455104f6d20ad1bad11ceddf68e7ce6c8052daniel@transgaming.com        }
5064834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com    }
5072f06dbfb3f4bd815a3fe5b52638b091c1e356a04Jamie Madill
5082f06dbfb3f4bd815a3fe5b52638b091c1e356a04Jamie Madill    initializeSerials(getLevelCount(), 1);
5094834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com}
5104834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com
5114834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.comTextureStorage11_2D::~TextureStorage11_2D()
5124834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com{
5136982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    for (unsigned i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
5146982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    {
5156982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        if (mAssociatedImages[i] != NULL)
5166982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        {
5176982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross            bool imageAssociationCorrect = mAssociatedImages[i]->isAssociatedStorageValid(this);
5186982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross            ASSERT(imageAssociationCorrect);
5196982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
5206982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross            if (imageAssociationCorrect)
5216982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross            {
5226982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross                // We must let the Images recover their data before we delete it from the TextureStorage.
5236982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross                mAssociatedImages[i]->recoverFromAssociatedStorage();
5246982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross            }
5256982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        }
5266982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    }
5276982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
528ea2286352f5eba47dfaa3e9ab418bbacfd1ba8a1Geoff Lang    SafeRelease(mTexture);
529644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang    SafeRelease(mSwizzleTexture);
530e47e7363cf651100b85e042930f31cf5f8291fc1Nicolas Capens
531858d32fa8bc0298a7d78954f5340d5019d718d11shannon.woods@transgaming.com    for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
5324b47235339ceba9ea5182a24ea5d806d9c5521bbshannon.woods@transgaming.com    {
533ea2286352f5eba47dfaa3e9ab418bbacfd1ba8a1Geoff Lang        SafeDelete(mRenderTarget[i]);
534644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        SafeRelease(mSwizzleRenderTargets[i]);
5354b47235339ceba9ea5182a24ea5d806d9c5521bbshannon.woods@transgaming.com    }
5364834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com}
5374834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com
5384834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.comTextureStorage11_2D *TextureStorage11_2D::makeTextureStorage11_2D(TextureStorage *storage)
5394834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com{
5408b400b1e8d84c5b93dd151807504a3e4b90d1b21apatrick@chromium.org    ASSERT(HAS_DYNAMIC_TYPE(TextureStorage11_2D*, storage));
5414834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com    return static_cast<TextureStorage11_2D*>(storage);
5424834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com}
5434834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com
5446982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinrossvoid TextureStorage11_2D::associateImage(Image11* image, int level, int layerTarget)
5456982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross{
5466982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
5476982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
5486982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
5496982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    {
5506982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        mAssociatedImages[level] = image;
5516982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    }
5526982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross}
5536982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
5546982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinrossbool TextureStorage11_2D::isAssociatedImageValid(int level, int layerTarget, Image11* expectedImage)
5556982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross{
5566982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
5576982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    {
5586982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        // This validation check should never return false. It means the Image/TextureStorage association is broken.
5596982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        bool retValue = (mAssociatedImages[level] == expectedImage);
5606982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        ASSERT(retValue);
5616982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        return retValue;
5626982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    }
5636982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
5646982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    return false;
5656982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross}
5666982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
5676982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross// disassociateImage allows an Image to end its association with a Storage.
5686982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinrossvoid TextureStorage11_2D::disassociateImage(int level, int layerTarget, Image11* expectedImage)
5696982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross{
5706982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
5716982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
5726982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
5736982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    {
5746982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        ASSERT(mAssociatedImages[level] == expectedImage);
5756982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
5766982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        if (mAssociatedImages[level] == expectedImage)
5776982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        {
5786982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross            mAssociatedImages[level] = NULL;
5796982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        }
5806982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    }
5816982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross}
5826982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
5836982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross// releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image recover its data before ending the association.
5846982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinrossvoid TextureStorage11_2D::releaseAssociatedImage(int level, int layerTarget, Image11* incomingImage)
5856982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross{
5866982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
5876982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
5886982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
5896982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    {
5906982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        // No need to let the old Image recover its data, if it is also the incoming Image.
5916982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        if (mAssociatedImages[level] != NULL && mAssociatedImages[level] != incomingImage)
5926982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        {
5936982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross            // Ensure that the Image is still associated with this TextureStorage. This should be true.
5946982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross            bool imageAssociationCorrect = mAssociatedImages[level]->isAssociatedStorageValid(this);
5956982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross            ASSERT(imageAssociationCorrect);
5966982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
5976982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross            if (imageAssociationCorrect)
5986982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross            {
5996982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross                // Force the image to recover from storage before its data is overwritten.
6006982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross                // This will reset mAssociatedImages[level] to NULL too.
6016982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross                mAssociatedImages[level]->recoverFromAssociatedStorage();
6026982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross            }
6036982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        }
6046982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    }
6056982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross}
6066982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
60776b258f88ebb47cf1022ae6b4392f220a56383d4Nicolas CapensID3D11Resource *TextureStorage11_2D::getResource() const
6082058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com{
6092058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com    return mTexture;
6102058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com}
6112058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com
612ac7579c2bd0cc9afdf5892a766e6967bf3a341f0Jamie MadillRenderTarget *TextureStorage11_2D::getRenderTarget(const gl::ImageIndex &index)
6134834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com{
614ac7579c2bd0cc9afdf5892a766e6967bf3a341f0Jamie Madill    ASSERT(!index.hasLayer());
615ac7579c2bd0cc9afdf5892a766e6967bf3a341f0Jamie Madill
616ac7579c2bd0cc9afdf5892a766e6967bf3a341f0Jamie Madill    int level = index.mipIndex;
617ac7579c2bd0cc9afdf5892a766e6967bf3a341f0Jamie Madill
618bf712d0a32847868913a3521b44912a5c29f08b8Nicolas Capens    if (level >= 0 && level < getLevelCount())
6194b47235339ceba9ea5182a24ea5d806d9c5521bbshannon.woods@transgaming.com    {
620858d32fa8bc0298a7d78954f5340d5019d718d11shannon.woods@transgaming.com        if (!mRenderTarget[level])
621858d32fa8bc0298a7d78954f5340d5019d718d11shannon.woods@transgaming.com        {
622644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang            ID3D11ShaderResourceView *srv = getSRVLevel(level);
623644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang            if (!srv)
624183408d0c4fdaa702329c5a386e09129aa8b2bb2shannon.woods@transgaming.com            {
625644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang                return NULL;
626183408d0c4fdaa702329c5a386e09129aa8b2bb2shannon.woods@transgaming.com            }
627183408d0c4fdaa702329c5a386e09129aa8b2bb2shannon.woods@transgaming.com
6285b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com            if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN)
6295b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com            {
630644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang                ID3D11Device *device = mRenderer->getDevice();
631644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang
6325b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com                D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
6335b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com                rtvDesc.Format = mRenderTargetFormat;
6345b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com                rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
635fa7b76d08d5c2dddb7979471884834103c761747Nicolas Capens                rtvDesc.Texture2D.MipSlice = mTopLevel + level;
6365b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com
6375b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com                ID3D11RenderTargetView *rtv;
638644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang                HRESULT result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv);
6395b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com
6405b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com                if (result == E_OUTOFMEMORY)
6415b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com                {
6425b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com                    return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
6435b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com                }
6445b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com                ASSERT(SUCCEEDED(result));
6455b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com
646b16b8ed79d73c718cfe9247e9c8d2714d5eb4dc5Jamie Madill                mRenderTarget[level] = new RenderTarget11(mRenderer, rtv, mTexture, srv, getLevelWidth(level), getLevelHeight(level), 1);
6472916b30eb47496327257254d355677a6ebb0388aGeoff Lang
6482916b30eb47496327257254d355677a6ebb0388aGeoff Lang                // RenderTarget will take ownership of these resources
6492916b30eb47496327257254d355677a6ebb0388aGeoff Lang                SafeRelease(rtv);
6505b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com            }
6515b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com            else if (mDepthStencilFormat != DXGI_FORMAT_UNKNOWN)
6525b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com            {
653644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang                ID3D11Device *device = mRenderer->getDevice();
654644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang
6555b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com                D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
6565b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com                dsvDesc.Format = mDepthStencilFormat;
6575b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com                dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
658fa7b76d08d5c2dddb7979471884834103c761747Nicolas Capens                dsvDesc.Texture2D.MipSlice = mTopLevel + level;
6595b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com                dsvDesc.Flags = 0;
6605b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com
6615b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com                ID3D11DepthStencilView *dsv;
662644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang                HRESULT result = device->CreateDepthStencilView(mTexture, &dsvDesc, &dsv);
6635b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com
6645b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com                if (result == E_OUTOFMEMORY)
6655b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com                {
666ea2286352f5eba47dfaa3e9ab418bbacfd1ba8a1Geoff Lang                    SafeRelease(srv);
6675b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com                    return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
6685b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com                }
6695b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com                ASSERT(SUCCEEDED(result));
6705b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com
671b16b8ed79d73c718cfe9247e9c8d2714d5eb4dc5Jamie Madill                mRenderTarget[level] = new RenderTarget11(mRenderer, dsv, mTexture, srv, getLevelWidth(level), getLevelHeight(level), 1);
6722916b30eb47496327257254d355677a6ebb0388aGeoff Lang
6732916b30eb47496327257254d355677a6ebb0388aGeoff Lang                // RenderTarget will take ownership of these resources
6742916b30eb47496327257254d355677a6ebb0388aGeoff Lang                SafeRelease(dsv);
6755b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com            }
6765b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com            else
6775b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com            {
6785b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com                UNREACHABLE();
6795b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com            }
680858d32fa8bc0298a7d78954f5340d5019d718d11shannon.woods@transgaming.com        }
681858d32fa8bc0298a7d78954f5340d5019d718d11shannon.woods@transgaming.com
682858d32fa8bc0298a7d78954f5340d5019d718d11shannon.woods@transgaming.com        return mRenderTarget[level];
6834b47235339ceba9ea5182a24ea5d806d9c5521bbshannon.woods@transgaming.com    }
6844b47235339ceba9ea5182a24ea5d806d9c5521bbshannon.woods@transgaming.com    else
6854b47235339ceba9ea5182a24ea5d806d9c5521bbshannon.woods@transgaming.com    {
686858d32fa8bc0298a7d78954f5340d5019d718d11shannon.woods@transgaming.com        return NULL;
6874b47235339ceba9ea5182a24ea5d806d9c5521bbshannon.woods@transgaming.com    }
6884834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com}
6894834ee2ccfe4b0a89083daeb42607dc6e21da2e6daniel@transgaming.com
6901d31aca98b997c225fe87172659d3bf51340f285Nicolas CapensID3D11ShaderResourceView *TextureStorage11_2D::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture)
6911d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens{
6921d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens    D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
6931d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens    srvDesc.Format = format;
6941d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens    srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
6951d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens    srvDesc.Texture2D.MostDetailedMip = mTopLevel + baseLevel;
6961d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens    srvDesc.Texture2D.MipLevels = mipLevels;
6971d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens
6981d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens    ID3D11ShaderResourceView *SRV = NULL;
6991d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens
7001d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens    ID3D11Device *device = mRenderer->getDevice();
7011d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens    HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, &SRV);
702858d32fa8bc0298a7d78954f5340d5019d718d11shannon.woods@transgaming.com
7031d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens    if (result == E_OUTOFMEMORY)
7041d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens    {
7051d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens        gl::error(GL_OUT_OF_MEMORY);
7061d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens    }
7071d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens    ASSERT(SUCCEEDED(result));
7081d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens
7091d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens    return SRV;
710858d32fa8bc0298a7d78954f5340d5019d718d11shannon.woods@transgaming.com}
711858d32fa8bc0298a7d78954f5340d5019d718d11shannon.woods@transgaming.com
7125e48c034daedc48a998fa5eca094d0a0ed247725Jamie Madillvoid TextureStorage11_2D::generateMipmaps()
713858d32fa8bc0298a7d78954f5340d5019d718d11shannon.woods@transgaming.com{
7145e48c034daedc48a998fa5eca094d0a0ed247725Jamie Madill    // Base level must already be defined
715644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang
7165e48c034daedc48a998fa5eca094d0a0ed247725Jamie Madill    for (int level = 1; level < getLevelCount(); level++)
7175e48c034daedc48a998fa5eca094d0a0ed247725Jamie Madill    {
7185e48c034daedc48a998fa5eca094d0a0ed247725Jamie Madill        invalidateSwizzleCacheLevel(level);
7195e48c034daedc48a998fa5eca094d0a0ed247725Jamie Madill
7205e48c034daedc48a998fa5eca094d0a0ed247725Jamie Madill        gl::ImageIndex srcIndex = gl::ImageIndex::Make2D(level - 1);
7215e48c034daedc48a998fa5eca094d0a0ed247725Jamie Madill        gl::ImageIndex destIndex = gl::ImageIndex::Make2D(level);
722ac7579c2bd0cc9afdf5892a766e6967bf3a341f0Jamie Madill
7235e48c034daedc48a998fa5eca094d0a0ed247725Jamie Madill        RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTarget(srcIndex));
7245e48c034daedc48a998fa5eca094d0a0ed247725Jamie Madill        RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTarget(destIndex));
72585bdfce9f7a1774c7e1a984a6f26c7f15b1fac78shannon.woods@transgaming.com
7265e48c034daedc48a998fa5eca094d0a0ed247725Jamie Madill        generateMipmapLayer(source, dest);
7275e48c034daedc48a998fa5eca094d0a0ed247725Jamie Madill    }
728b50d5302513839a6b88a9f465b5a0a2ce252d2f3daniel@transgaming.com}
729b50d5302513839a6b88a9f465b5a0a2ce252d2f3daniel@transgaming.com
73041d9f7e97a6066b8300e3fab3ad3b83c083b3479Nicolas CapensID3D11Resource *TextureStorage11_2D::getSwizzleTexture()
731644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang{
732644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang    if (!mSwizzleTexture)
733644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang    {
734644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        ID3D11Device *device = mRenderer->getDevice();
735644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang
736644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        D3D11_TEXTURE2D_DESC desc;
737644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        desc.Width = mTextureWidth;
738644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        desc.Height = mTextureHeight;
739bf712d0a32847868913a3521b44912a5c29f08b8Nicolas Capens        desc.MipLevels = mMipLevels;
740644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        desc.ArraySize = 1;
741644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        desc.Format = mSwizzleTextureFormat;
742644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        desc.SampleDesc.Count = 1;
743644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        desc.SampleDesc.Quality = 0;
744644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        desc.Usage = D3D11_USAGE_DEFAULT;
745644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
746644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        desc.CPUAccessFlags = 0;
747644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        desc.MiscFlags = 0;
748644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang
749644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        HRESULT result = device->CreateTexture2D(&desc, NULL, &mSwizzleTexture);
750644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang
751644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        if (result == E_OUTOFMEMORY)
752644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        {
753644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang            return gl::error(GL_OUT_OF_MEMORY, static_cast<ID3D11Texture2D*>(NULL));
754644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        }
755644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        ASSERT(SUCCEEDED(result));
756644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang    }
757644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang
758644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang    return mSwizzleTexture;
759644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang}
760644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang
761644bbf2448bc2e29eadd811c303117cacb39189dGeoff LangID3D11RenderTargetView *TextureStorage11_2D::getSwizzleRenderTarget(int mipLevel)
762644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang{
763bf712d0a32847868913a3521b44912a5c29f08b8Nicolas Capens    if (mipLevel >= 0 && mipLevel < getLevelCount())
764644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang    {
765644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        if (!mSwizzleRenderTargets[mipLevel])
766644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        {
76741d9f7e97a6066b8300e3fab3ad3b83c083b3479Nicolas Capens            ID3D11Resource *swizzleTexture = getSwizzleTexture();
768644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang            if (!swizzleTexture)
769644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang            {
770644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang                return NULL;
771644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang            }
772644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang
773644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang            ID3D11Device *device = mRenderer->getDevice();
774644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang
775644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang            D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
776644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang            rtvDesc.Format = mSwizzleRenderTargetFormat;
777644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang            rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
778fa7b76d08d5c2dddb7979471884834103c761747Nicolas Capens            rtvDesc.Texture2D.MipSlice = mTopLevel + mipLevel;
779644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang
780644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang            HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]);
781cebb5aa092f92e1f727fe5e4300dbd83abd49afbGeoff Lang            if (result == E_OUTOFMEMORY)
782cebb5aa092f92e1f727fe5e4300dbd83abd49afbGeoff Lang            {
783cebb5aa092f92e1f727fe5e4300dbd83abd49afbGeoff Lang                return gl::error(GL_OUT_OF_MEMORY, static_cast<ID3D11RenderTargetView*>(NULL));
784cebb5aa092f92e1f727fe5e4300dbd83abd49afbGeoff Lang            }
785cebb5aa092f92e1f727fe5e4300dbd83abd49afbGeoff Lang            ASSERT(SUCCEEDED(result));
786644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        }
787644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang
788644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        return mSwizzleRenderTargets[mipLevel];
789644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang    }
790644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang    else
791644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang    {
792644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        return NULL;
793644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang    }
794644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang}
795644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang
796bf712d0a32847868913a3521b44912a5c29f08b8Nicolas CapensTextureStorage11_Cube::TextureStorage11_Cube(Renderer *renderer, GLenum internalformat, bool renderTarget, int size, int levels)
797e4a492be45f39dffaea53c3523064844ee56e41bGeoff Lang    : TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderTarget))
798b2151e5597bd5ed69cb8e0a55c8ad727efee1e04daniel@transgaming.com{
7992058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com    mTexture = NULL;
800644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang    mSwizzleTexture = NULL;
801e47e7363cf651100b85e042930f31cf5f8291fc1Nicolas Capens
802644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang    for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
8035cdd0586d171e2f81c1c47ca21736c0f3e912b11daniel@transgaming.com    {
804644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        mSwizzleRenderTargets[level] = NULL;
805644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        for (unsigned int face = 0; face < 6; face++)
806858d32fa8bc0298a7d78954f5340d5019d718d11shannon.woods@transgaming.com        {
8076982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross            mAssociatedImages[face][level] = NULL;
808644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang            mRenderTarget[face][level] = NULL;
809858d32fa8bc0298a7d78954f5340d5019d718d11shannon.woods@transgaming.com        }
8105cdd0586d171e2f81c1c47ca21736c0f3e912b11daniel@transgaming.com    }
8115cdd0586d171e2f81c1c47ca21736c0f3e912b11daniel@transgaming.com
8129aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang    const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat);
8139aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang    mTextureFormat = formatInfo.texFormat;
8149aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang    mShaderResourceFormat = formatInfo.srvFormat;
8159aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang    mDepthStencilFormat = formatInfo.dsvFormat;
8169aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang    mRenderTargetFormat = formatInfo.rtvFormat;
8179aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang    mSwizzleTextureFormat = formatInfo.swizzleTexFormat;
8189aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang    mSwizzleShaderResourceFormat = formatInfo.swizzleSRVFormat;
8199aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang    mSwizzleRenderTargetFormat = formatInfo.swizzleRTVFormat;
8205b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com
821b2151e5597bd5ed69cb8e0a55c8ad727efee1e04daniel@transgaming.com    // if the size is not positive this should be treated as an incomplete texture
822b2151e5597bd5ed69cb8e0a55c8ad727efee1e04daniel@transgaming.com    // we handle that here by skipping the d3d texture creation
823b2151e5597bd5ed69cb8e0a55c8ad727efee1e04daniel@transgaming.com    if (size > 0)
824b2151e5597bd5ed69cb8e0a55c8ad727efee1e04daniel@transgaming.com    {
825b2151e5597bd5ed69cb8e0a55c8ad727efee1e04daniel@transgaming.com        // adjust size if needed for compressed textures
826b2151e5597bd5ed69cb8e0a55c8ad727efee1e04daniel@transgaming.com        int height = size;
827f61738a578693170902045f8a3fa2f383fd5c367Nicolas Capens        d3d11::MakeValidSize(false, mTextureFormat, &size, &height, &mTopLevel);
828b2151e5597bd5ed69cb8e0a55c8ad727efee1e04daniel@transgaming.com
829b2151e5597bd5ed69cb8e0a55c8ad727efee1e04daniel@transgaming.com        ID3D11Device *device = mRenderer->getDevice();
830b2151e5597bd5ed69cb8e0a55c8ad727efee1e04daniel@transgaming.com
831b2151e5597bd5ed69cb8e0a55c8ad727efee1e04daniel@transgaming.com        D3D11_TEXTURE2D_DESC desc;
832b2151e5597bd5ed69cb8e0a55c8ad727efee1e04daniel@transgaming.com        desc.Width = size;
833b2151e5597bd5ed69cb8e0a55c8ad727efee1e04daniel@transgaming.com        desc.Height = size;
834bf712d0a32847868913a3521b44912a5c29f08b8Nicolas Capens        desc.MipLevels = ((levels > 0) ? (mTopLevel + levels) : 0);
835b2151e5597bd5ed69cb8e0a55c8ad727efee1e04daniel@transgaming.com        desc.ArraySize = 6;
8365b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com        desc.Format = mTextureFormat;
837b2151e5597bd5ed69cb8e0a55c8ad727efee1e04daniel@transgaming.com        desc.SampleDesc.Count = 1;
838b2151e5597bd5ed69cb8e0a55c8ad727efee1e04daniel@transgaming.com        desc.SampleDesc.Quality = 0;
839b2151e5597bd5ed69cb8e0a55c8ad727efee1e04daniel@transgaming.com        desc.Usage = D3D11_USAGE_DEFAULT;
840b2151e5597bd5ed69cb8e0a55c8ad727efee1e04daniel@transgaming.com        desc.BindFlags = getBindFlags();
841b2151e5597bd5ed69cb8e0a55c8ad727efee1e04daniel@transgaming.com        desc.CPUAccessFlags = 0;
842b2151e5597bd5ed69cb8e0a55c8ad727efee1e04daniel@transgaming.com        desc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
843b2151e5597bd5ed69cb8e0a55c8ad727efee1e04daniel@transgaming.com
844b2151e5597bd5ed69cb8e0a55c8ad727efee1e04daniel@transgaming.com        HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture);
845b2151e5597bd5ed69cb8e0a55c8ad727efee1e04daniel@transgaming.com
846b2151e5597bd5ed69cb8e0a55c8ad727efee1e04daniel@transgaming.com        if (FAILED(result))
847b2151e5597bd5ed69cb8e0a55c8ad727efee1e04daniel@transgaming.com        {
848b2151e5597bd5ed69cb8e0a55c8ad727efee1e04daniel@transgaming.com            ASSERT(result == E_OUTOFMEMORY);
849b2151e5597bd5ed69cb8e0a55c8ad727efee1e04daniel@transgaming.com            ERR("Creating image failed.");
850779aa2618c1333c034768f3a4ca7826a14753b60shannon.woods@transgaming.com            gl::error(GL_OUT_OF_MEMORY);
851b2151e5597bd5ed69cb8e0a55c8ad727efee1e04daniel@transgaming.com        }
852b115455104f6d20ad1bad11ceddf68e7ce6c8052daniel@transgaming.com        else
853b115455104f6d20ad1bad11ceddf68e7ce6c8052daniel@transgaming.com        {
854b115455104f6d20ad1bad11ceddf68e7ce6c8052daniel@transgaming.com            mTexture->GetDesc(&desc);
855b115455104f6d20ad1bad11ceddf68e7ce6c8052daniel@transgaming.com            mMipLevels = desc.MipLevels;
856858d32fa8bc0298a7d78954f5340d5019d718d11shannon.woods@transgaming.com            mTextureWidth = desc.Width;
857858d32fa8bc0298a7d78954f5340d5019d718d11shannon.woods@transgaming.com            mTextureHeight = desc.Height;
8582058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com            mTextureDepth = 1;
859b115455104f6d20ad1bad11ceddf68e7ce6c8052daniel@transgaming.com        }
860b2151e5597bd5ed69cb8e0a55c8ad727efee1e04daniel@transgaming.com    }
8612f06dbfb3f4bd815a3fe5b52638b091c1e356a04Jamie Madill
8622f06dbfb3f4bd815a3fe5b52638b091c1e356a04Jamie Madill    initializeSerials(getLevelCount() * 6, 6);
863b2151e5597bd5ed69cb8e0a55c8ad727efee1e04daniel@transgaming.com}
864b2151e5597bd5ed69cb8e0a55c8ad727efee1e04daniel@transgaming.com
8652f06dbfb3f4bd815a3fe5b52638b091c1e356a04Jamie Madill
866b2151e5597bd5ed69cb8e0a55c8ad727efee1e04daniel@transgaming.comTextureStorage11_Cube::~TextureStorage11_Cube()
867b2151e5597bd5ed69cb8e0a55c8ad727efee1e04daniel@transgaming.com{
8686982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
8696982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    {
8706982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        for (unsigned int face = 0; face < 6; face++)
8716982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        {
8726982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross            if (mAssociatedImages[face][level] != NULL)
8736982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross            {
8746982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross                bool imageAssociationCorrect = mAssociatedImages[face][level]->isAssociatedStorageValid(this);
8756982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross                ASSERT(imageAssociationCorrect);
8766982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
8776982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross                if (imageAssociationCorrect)
8786982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross                {
8796982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross                    // We must let the Images recover their data before we delete it from the TextureStorage.
8806982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross                    mAssociatedImages[face][level]->recoverFromAssociatedStorage();
8816982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross                }
8826982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross            }
8836982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        }
8846982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    }
8856982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
886ea2286352f5eba47dfaa3e9ab418bbacfd1ba8a1Geoff Lang    SafeRelease(mTexture);
887644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang    SafeRelease(mSwizzleTexture);
888e47e7363cf651100b85e042930f31cf5f8291fc1Nicolas Capens
889644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang    for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
8904b47235339ceba9ea5182a24ea5d806d9c5521bbshannon.woods@transgaming.com    {
891644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        SafeRelease(mSwizzleRenderTargets[level]);
892644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        for (unsigned int face = 0; face < 6; face++)
8934b47235339ceba9ea5182a24ea5d806d9c5521bbshannon.woods@transgaming.com        {
894644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang            SafeDelete(mRenderTarget[face][level]);
8954b47235339ceba9ea5182a24ea5d806d9c5521bbshannon.woods@transgaming.com        }
8964b47235339ceba9ea5182a24ea5d806d9c5521bbshannon.woods@transgaming.com    }
897b2151e5597bd5ed69cb8e0a55c8ad727efee1e04daniel@transgaming.com}
898b2151e5597bd5ed69cb8e0a55c8ad727efee1e04daniel@transgaming.com
899b2151e5597bd5ed69cb8e0a55c8ad727efee1e04daniel@transgaming.comTextureStorage11_Cube *TextureStorage11_Cube::makeTextureStorage11_Cube(TextureStorage *storage)
900b2151e5597bd5ed69cb8e0a55c8ad727efee1e04daniel@transgaming.com{
9018b400b1e8d84c5b93dd151807504a3e4b90d1b21apatrick@chromium.org    ASSERT(HAS_DYNAMIC_TYPE(TextureStorage11_Cube*, storage));
902b2151e5597bd5ed69cb8e0a55c8ad727efee1e04daniel@transgaming.com    return static_cast<TextureStorage11_Cube*>(storage);
903b2151e5597bd5ed69cb8e0a55c8ad727efee1e04daniel@transgaming.com}
904b2151e5597bd5ed69cb8e0a55c8ad727efee1e04daniel@transgaming.com
9056982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinrossvoid TextureStorage11_Cube::associateImage(Image11* image, int level, int layerTarget)
9066982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross{
9076982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
9086982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    ASSERT(0 <= layerTarget && layerTarget < 6);
9096982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
9106982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
9116982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    {
9126982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        if (0 <= layerTarget && layerTarget < 6)
9136982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        {
9146982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross            mAssociatedImages[layerTarget][level] = image;
9156982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        }
9166982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    }
9176982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross}
9186982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
9196982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinrossbool TextureStorage11_Cube::isAssociatedImageValid(int level, int layerTarget, Image11* expectedImage)
9206982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross{
9216982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
9226982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    {
9236982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        if (0 <= layerTarget && layerTarget < 6)
9246982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        {
9256982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross            // This validation check should never return false. It means the Image/TextureStorage association is broken.
9266982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross            bool retValue = (mAssociatedImages[layerTarget][level] == expectedImage);
9276982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross            ASSERT(retValue);
9286982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross            return retValue;
9296982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        }
9306982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    }
9316982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
9326982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    return false;
9336982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross}
9346982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
9356982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross// disassociateImage allows an Image to end its association with a Storage.
9366982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinrossvoid TextureStorage11_Cube::disassociateImage(int level, int layerTarget, Image11* expectedImage)
9376982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross{
9386982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
9396982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    ASSERT(0 <= layerTarget && layerTarget < 6);
9406982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
9416982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
9426982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    {
9436982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        if (0 <= layerTarget && layerTarget < 6)
9446982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        {
9456982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross            ASSERT(mAssociatedImages[layerTarget][level] == expectedImage);
9466982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
9476982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross            if (mAssociatedImages[layerTarget][level] == expectedImage)
9486982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross            {
9496982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross                mAssociatedImages[layerTarget][level] = NULL;
9506982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross            }
9516982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        }
9526982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    }
9536982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross}
9546982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
9556982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross// releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image recover its data before ending the association.
9566982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinrossvoid TextureStorage11_Cube::releaseAssociatedImage(int level, int layerTarget, Image11* incomingImage)
9576982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross{
9586982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
9596982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    ASSERT(0 <= layerTarget && layerTarget < 6);
9606982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
9616982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    if ((0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
9626982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    {
9636982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        if (0 <= layerTarget && layerTarget < 6)
9646982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        {
9656982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross            // No need to let the old Image recover its data, if it is also the incoming Image.
9666982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross            if (mAssociatedImages[layerTarget][level] != NULL && mAssociatedImages[layerTarget][level] != incomingImage)
9676982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross            {
9686982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross                // Ensure that the Image is still associated with this TextureStorage. This should be true.
9696982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross                bool imageAssociationCorrect = mAssociatedImages[layerTarget][level]->isAssociatedStorageValid(this);
9706982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross                ASSERT(imageAssociationCorrect);
9716982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
9726982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross                if (imageAssociationCorrect)
9736982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross                {
9746982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross                    // Force the image to recover from storage before its data is overwritten.
9756982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross                    // This will reset mAssociatedImages[level] to NULL too.
9766982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross                    mAssociatedImages[layerTarget][level]->recoverFromAssociatedStorage();
9776982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross                }
9786982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross            }
9796982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        }
9806982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    }
9816982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross}
9826982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
98376b258f88ebb47cf1022ae6b4392f220a56383d4Nicolas CapensID3D11Resource *TextureStorage11_Cube::getResource() const
9842058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com{
9852058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com    return mTexture;
9862058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com}
9872058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com
988ac7579c2bd0cc9afdf5892a766e6967bf3a341f0Jamie MadillRenderTarget *TextureStorage11_Cube::getRenderTarget(const gl::ImageIndex &index)
989b2151e5597bd5ed69cb8e0a55c8ad727efee1e04daniel@transgaming.com{
990ac7579c2bd0cc9afdf5892a766e6967bf3a341f0Jamie Madill    int faceIndex = index.layerIndex;
991ac7579c2bd0cc9afdf5892a766e6967bf3a341f0Jamie Madill    int level = index.mipIndex;
992ac7579c2bd0cc9afdf5892a766e6967bf3a341f0Jamie Madill
993bf712d0a32847868913a3521b44912a5c29f08b8Nicolas Capens    if (level >= 0 && level < getLevelCount())
9944b47235339ceba9ea5182a24ea5d806d9c5521bbshannon.woods@transgaming.com    {
9952db197cd72c8ef3b109af0e9e444fd734a3acca4Jamie Madill        if (!mRenderTarget[faceIndex][level])
996b2151e5597bd5ed69cb8e0a55c8ad727efee1e04daniel@transgaming.com        {
997858d32fa8bc0298a7d78954f5340d5019d718d11shannon.woods@transgaming.com            ID3D11Device *device = mRenderer->getDevice();
998858d32fa8bc0298a7d78954f5340d5019d718d11shannon.woods@transgaming.com            HRESULT result;
999b2151e5597bd5ed69cb8e0a55c8ad727efee1e04daniel@transgaming.com
10005b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com            D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
10015b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com            srvDesc.Format = mShaderResourceFormat;
1002bfc93bbaae3adb6db128796846bbd8f8c20ec831Shannon Woods            srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; // Will be used with Texture2D sampler, not TextureCube
1003fa7b76d08d5c2dddb7979471884834103c761747Nicolas Capens            srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + level;
10045b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com            srvDesc.Texture2DArray.MipLevels = 1;
10052db197cd72c8ef3b109af0e9e444fd734a3acca4Jamie Madill            srvDesc.Texture2DArray.FirstArraySlice = faceIndex;
10065b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com            srvDesc.Texture2DArray.ArraySize = 1;
10075b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com
10085b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com            ID3D11ShaderResourceView *srv;
10095b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com            result = device->CreateShaderResourceView(mTexture, &srvDesc, &srv);
10105b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com
10115b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com            if (result == E_OUTOFMEMORY)
10125b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com            {
10135b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com                return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
10145b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com            }
10155b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com            ASSERT(SUCCEEDED(result));
10165b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com
10175b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com            if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN)
1018b2151e5597bd5ed69cb8e0a55c8ad727efee1e04daniel@transgaming.com            {
1019858d32fa8bc0298a7d78954f5340d5019d718d11shannon.woods@transgaming.com                D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
10205b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com                rtvDesc.Format = mRenderTargetFormat;
1021858d32fa8bc0298a7d78954f5340d5019d718d11shannon.woods@transgaming.com                rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
1022fa7b76d08d5c2dddb7979471884834103c761747Nicolas Capens                rtvDesc.Texture2DArray.MipSlice = mTopLevel + level;
10232db197cd72c8ef3b109af0e9e444fd734a3acca4Jamie Madill                rtvDesc.Texture2DArray.FirstArraySlice = faceIndex;
1024858d32fa8bc0298a7d78954f5340d5019d718d11shannon.woods@transgaming.com                rtvDesc.Texture2DArray.ArraySize = 1;
10254b47235339ceba9ea5182a24ea5d806d9c5521bbshannon.woods@transgaming.com
1026858d32fa8bc0298a7d78954f5340d5019d718d11shannon.woods@transgaming.com                ID3D11RenderTargetView *rtv;
1027858d32fa8bc0298a7d78954f5340d5019d718d11shannon.woods@transgaming.com                result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv);
1028b2151e5597bd5ed69cb8e0a55c8ad727efee1e04daniel@transgaming.com
1029858d32fa8bc0298a7d78954f5340d5019d718d11shannon.woods@transgaming.com                if (result == E_OUTOFMEMORY)
1030858d32fa8bc0298a7d78954f5340d5019d718d11shannon.woods@transgaming.com                {
1031ea2286352f5eba47dfaa3e9ab418bbacfd1ba8a1Geoff Lang                    SafeRelease(srv);
1032779aa2618c1333c034768f3a4ca7826a14753b60shannon.woods@transgaming.com                    return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
10334b47235339ceba9ea5182a24ea5d806d9c5521bbshannon.woods@transgaming.com                }
1034858d32fa8bc0298a7d78954f5340d5019d718d11shannon.woods@transgaming.com                ASSERT(SUCCEEDED(result));
1035858d32fa8bc0298a7d78954f5340d5019d718d11shannon.woods@transgaming.com
1036b16b8ed79d73c718cfe9247e9c8d2714d5eb4dc5Jamie Madill                mRenderTarget[faceIndex][level] = new RenderTarget11(mRenderer, rtv, mTexture, srv, getLevelWidth(level), getLevelHeight(level), 1);
10372916b30eb47496327257254d355677a6ebb0388aGeoff Lang
10382916b30eb47496327257254d355677a6ebb0388aGeoff Lang                // RenderTarget will take ownership of these resources
10392916b30eb47496327257254d355677a6ebb0388aGeoff Lang                SafeRelease(rtv);
10402916b30eb47496327257254d355677a6ebb0388aGeoff Lang                SafeRelease(srv);
10415b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com            }
10425b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com            else if (mDepthStencilFormat != DXGI_FORMAT_UNKNOWN)
10435b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com            {
10445b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com                D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
10451294924fa0156929b1df4d0fb3d95a3985154f7aGeoff Lang                dsvDesc.Format = mDepthStencilFormat;
10465b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com                dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY;
10471294924fa0156929b1df4d0fb3d95a3985154f7aGeoff Lang                dsvDesc.Flags = 0;
1048fa7b76d08d5c2dddb7979471884834103c761747Nicolas Capens                dsvDesc.Texture2DArray.MipSlice = mTopLevel + level;
10492db197cd72c8ef3b109af0e9e444fd734a3acca4Jamie Madill                dsvDesc.Texture2DArray.FirstArraySlice = faceIndex;
10505b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com                dsvDesc.Texture2DArray.ArraySize = 1;
10515b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com
10525b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com                ID3D11DepthStencilView *dsv;
10535b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com                result = device->CreateDepthStencilView(mTexture, &dsvDesc, &dsv);
1054183408d0c4fdaa702329c5a386e09129aa8b2bb2shannon.woods@transgaming.com
1055183408d0c4fdaa702329c5a386e09129aa8b2bb2shannon.woods@transgaming.com                if (result == E_OUTOFMEMORY)
1056183408d0c4fdaa702329c5a386e09129aa8b2bb2shannon.woods@transgaming.com                {
1057ea2286352f5eba47dfaa3e9ab418bbacfd1ba8a1Geoff Lang                    SafeRelease(srv);
1058779aa2618c1333c034768f3a4ca7826a14753b60shannon.woods@transgaming.com                    return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
1059183408d0c4fdaa702329c5a386e09129aa8b2bb2shannon.woods@transgaming.com                }
1060183408d0c4fdaa702329c5a386e09129aa8b2bb2shannon.woods@transgaming.com                ASSERT(SUCCEEDED(result));
1061183408d0c4fdaa702329c5a386e09129aa8b2bb2shannon.woods@transgaming.com
1062b16b8ed79d73c718cfe9247e9c8d2714d5eb4dc5Jamie Madill                mRenderTarget[faceIndex][level] = new RenderTarget11(mRenderer, dsv, mTexture, srv, getLevelWidth(level), getLevelHeight(level), 1);
10632916b30eb47496327257254d355677a6ebb0388aGeoff Lang
10642916b30eb47496327257254d355677a6ebb0388aGeoff Lang                // RenderTarget will take ownership of these resources
10652916b30eb47496327257254d355677a6ebb0388aGeoff Lang                SafeRelease(dsv);
10662916b30eb47496327257254d355677a6ebb0388aGeoff Lang                SafeRelease(srv);
1067b2151e5597bd5ed69cb8e0a55c8ad727efee1e04daniel@transgaming.com            }
10685b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com            else
1069858d32fa8bc0298a7d78954f5340d5019d718d11shannon.woods@transgaming.com            {
10705b2d855fbe69f74db2ed98892e2f4f019dd78fceshannon.woods@transgaming.com                UNREACHABLE();
1071858d32fa8bc0298a7d78954f5340d5019d718d11shannon.woods@transgaming.com            }
1072b2151e5597bd5ed69cb8e0a55c8ad727efee1e04daniel@transgaming.com        }
1073858d32fa8bc0298a7d78954f5340d5019d718d11shannon.woods@transgaming.com
10742db197cd72c8ef3b109af0e9e444fd734a3acca4Jamie Madill        return mRenderTarget[faceIndex][level];
1075858d32fa8bc0298a7d78954f5340d5019d718d11shannon.woods@transgaming.com    }
1076858d32fa8bc0298a7d78954f5340d5019d718d11shannon.woods@transgaming.com    else
1077858d32fa8bc0298a7d78954f5340d5019d718d11shannon.woods@transgaming.com    {
1078858d32fa8bc0298a7d78954f5340d5019d718d11shannon.woods@transgaming.com        return NULL;
1079b2151e5597bd5ed69cb8e0a55c8ad727efee1e04daniel@transgaming.com    }
1080b2151e5597bd5ed69cb8e0a55c8ad727efee1e04daniel@transgaming.com}
1081b2151e5597bd5ed69cb8e0a55c8ad727efee1e04daniel@transgaming.com
1082e83fb0026bbaed48988966e3ed159836effc7091Nicolas CapensID3D11ShaderResourceView *TextureStorage11_Cube::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture)
10831d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens{
10841d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens    D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
10851d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens    srvDesc.Format = format;
1086b50d5302513839a6b88a9f465b5a0a2ce252d2f3daniel@transgaming.com
1087e83fb0026bbaed48988966e3ed159836effc7091Nicolas Capens    // Unnormalized integer cube maps are not supported by DX11; we emulate them as an array of six 2D textures
10889aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang    const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(format);
10899aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang    if (dxgiFormatInfo.componentType == GL_INT || dxgiFormatInfo.componentType == GL_UNSIGNED_INT)
10901d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens    {
10911d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens        srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
10921d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens        srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + baseLevel;
10931d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens        srvDesc.Texture2DArray.MipLevels = 1;
10941d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens        srvDesc.Texture2DArray.FirstArraySlice = 0;
10951d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens        srvDesc.Texture2DArray.ArraySize = 6;
10961d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens    }
10971d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens    else
10981d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens    {
10991d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens        srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
11001d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens        srvDesc.TextureCube.MipLevels = mipLevels;
11011d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens        srvDesc.TextureCube.MostDetailedMip = mTopLevel + baseLevel;
1102b50d5302513839a6b88a9f465b5a0a2ce252d2f3daniel@transgaming.com    }
1103858d32fa8bc0298a7d78954f5340d5019d718d11shannon.woods@transgaming.com
11041d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens    ID3D11ShaderResourceView *SRV = NULL;
11051d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens
11061d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens    ID3D11Device *device = mRenderer->getDevice();
11071d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens    HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, &SRV);
11081d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens
11091d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens    if (result == E_OUTOFMEMORY)
11101d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens    {
11111d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens        gl::error(GL_OUT_OF_MEMORY);
11121d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens    }
11131d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens    ASSERT(SUCCEEDED(result));
11141d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens
11151d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens    return SRV;
1116858d32fa8bc0298a7d78954f5340d5019d718d11shannon.woods@transgaming.com}
1117858d32fa8bc0298a7d78954f5340d5019d718d11shannon.woods@transgaming.com
11185e48c034daedc48a998fa5eca094d0a0ed247725Jamie Madillvoid TextureStorage11_Cube::generateMipmaps()
1119858d32fa8bc0298a7d78954f5340d5019d718d11shannon.woods@transgaming.com{
11205e48c034daedc48a998fa5eca094d0a0ed247725Jamie Madill    // Base level must already be defined
1121644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang
11225e48c034daedc48a998fa5eca094d0a0ed247725Jamie Madill    for (int faceIndex = 0; faceIndex < 6; faceIndex++)
11235e48c034daedc48a998fa5eca094d0a0ed247725Jamie Madill    {
11245e48c034daedc48a998fa5eca094d0a0ed247725Jamie Madill        for (int level = 1; level < getLevelCount(); level++)
11255e48c034daedc48a998fa5eca094d0a0ed247725Jamie Madill        {
11265e48c034daedc48a998fa5eca094d0a0ed247725Jamie Madill            invalidateSwizzleCacheLevel(level);
11275e48c034daedc48a998fa5eca094d0a0ed247725Jamie Madill
11285e48c034daedc48a998fa5eca094d0a0ed247725Jamie Madill            gl::ImageIndex srcIndex = gl::ImageIndex::MakeCube(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, level - 1);
11295e48c034daedc48a998fa5eca094d0a0ed247725Jamie Madill            gl::ImageIndex destIndex = gl::ImageIndex::MakeCube(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, level);
1130ac7579c2bd0cc9afdf5892a766e6967bf3a341f0Jamie Madill
11315e48c034daedc48a998fa5eca094d0a0ed247725Jamie Madill            RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTarget(srcIndex));
11325e48c034daedc48a998fa5eca094d0a0ed247725Jamie Madill            RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTarget(destIndex));
113385bdfce9f7a1774c7e1a984a6f26c7f15b1fac78shannon.woods@transgaming.com
11345e48c034daedc48a998fa5eca094d0a0ed247725Jamie Madill            generateMipmapLayer(source, dest);
11355e48c034daedc48a998fa5eca094d0a0ed247725Jamie Madill        }
11365e48c034daedc48a998fa5eca094d0a0ed247725Jamie Madill    }
1137b50d5302513839a6b88a9f465b5a0a2ce252d2f3daniel@transgaming.com}
1138b50d5302513839a6b88a9f465b5a0a2ce252d2f3daniel@transgaming.com
113941d9f7e97a6066b8300e3fab3ad3b83c083b3479Nicolas CapensID3D11Resource *TextureStorage11_Cube::getSwizzleTexture()
1140644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang{
1141644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang    if (!mSwizzleTexture)
1142644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang    {
1143644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        ID3D11Device *device = mRenderer->getDevice();
1144644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang
1145644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        D3D11_TEXTURE2D_DESC desc;
1146644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        desc.Width = mTextureWidth;
1147644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        desc.Height = mTextureHeight;
1148bf712d0a32847868913a3521b44912a5c29f08b8Nicolas Capens        desc.MipLevels = mMipLevels;
1149644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        desc.ArraySize = 6;
1150644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        desc.Format = mSwizzleTextureFormat;
1151644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        desc.SampleDesc.Count = 1;
1152644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        desc.SampleDesc.Quality = 0;
1153644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        desc.Usage = D3D11_USAGE_DEFAULT;
1154644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
1155644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        desc.CPUAccessFlags = 0;
1156644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        desc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
1157644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang
1158644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        HRESULT result = device->CreateTexture2D(&desc, NULL, &mSwizzleTexture);
1159644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang
1160644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        if (result == E_OUTOFMEMORY)
1161644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        {
1162644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang            return gl::error(GL_OUT_OF_MEMORY, static_cast<ID3D11Texture2D*>(NULL));
1163644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        }
1164644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        ASSERT(SUCCEEDED(result));
1165644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang    }
1166644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang
1167644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang    return mSwizzleTexture;
1168644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang}
1169644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang
1170644bbf2448bc2e29eadd811c303117cacb39189dGeoff LangID3D11RenderTargetView *TextureStorage11_Cube::getSwizzleRenderTarget(int mipLevel)
1171644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang{
1172bf712d0a32847868913a3521b44912a5c29f08b8Nicolas Capens    if (mipLevel >= 0 && mipLevel < getLevelCount())
1173644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang    {
1174644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        if (!mSwizzleRenderTargets[mipLevel])
1175644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        {
117641d9f7e97a6066b8300e3fab3ad3b83c083b3479Nicolas Capens            ID3D11Resource *swizzleTexture = getSwizzleTexture();
1177644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang            if (!swizzleTexture)
1178644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang            {
1179644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang                return NULL;
1180644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang            }
1181644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang
1182644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang            ID3D11Device *device = mRenderer->getDevice();
1183644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang
1184644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang            D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
1185644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang            rtvDesc.Format = mSwizzleRenderTargetFormat;
1186644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang            rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
1187fa7b76d08d5c2dddb7979471884834103c761747Nicolas Capens            rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel;
1188644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang            rtvDesc.Texture2DArray.FirstArraySlice = 0;
1189644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang            rtvDesc.Texture2DArray.ArraySize = 6;
1190644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang
1191644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang            HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]);
1192cebb5aa092f92e1f727fe5e4300dbd83abd49afbGeoff Lang
1193cebb5aa092f92e1f727fe5e4300dbd83abd49afbGeoff Lang            if (result == E_OUTOFMEMORY)
1194cebb5aa092f92e1f727fe5e4300dbd83abd49afbGeoff Lang            {
1195cebb5aa092f92e1f727fe5e4300dbd83abd49afbGeoff Lang                return gl::error(GL_OUT_OF_MEMORY, static_cast<ID3D11RenderTargetView*>(NULL));
1196cebb5aa092f92e1f727fe5e4300dbd83abd49afbGeoff Lang            }
1197cebb5aa092f92e1f727fe5e4300dbd83abd49afbGeoff Lang            ASSERT(SUCCEEDED(result));
1198644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        }
1199644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang
1200644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        return mSwizzleRenderTargets[mipLevel];
1201644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang    }
1202644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang    else
1203644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang    {
1204644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        return NULL;
1205644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang    }
1206644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang}
1207644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang
1208bf712d0a32847868913a3521b44912a5c29f08b8Nicolas CapensTextureStorage11_3D::TextureStorage11_3D(Renderer *renderer, GLenum internalformat, bool renderTarget,
1209bf712d0a32847868913a3521b44912a5c29f08b8Nicolas Capens                                         GLsizei width, GLsizei height, GLsizei depth, int levels)
1210e4a492be45f39dffaea53c3523064844ee56e41bGeoff Lang    : TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderTarget))
12112058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com{
12122058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com    mTexture = NULL;
1213644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang    mSwizzleTexture = NULL;
1214e47e7363cf651100b85e042930f31cf5f8291fc1Nicolas Capens
121515a8b1f683dbc9861cf05ded808f00796ecb0344shannonwoods@chromium.org    for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
121615a8b1f683dbc9861cf05ded808f00796ecb0344shannonwoods@chromium.org    {
12176982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        mAssociatedImages[i] = NULL;
121815a8b1f683dbc9861cf05ded808f00796ecb0344shannonwoods@chromium.org        mLevelRenderTargets[i] = NULL;
1219644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        mSwizzleRenderTargets[i] = NULL;
122015a8b1f683dbc9861cf05ded808f00796ecb0344shannonwoods@chromium.org    }
122115a8b1f683dbc9861cf05ded808f00796ecb0344shannonwoods@chromium.org
12229aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang    const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat);
12239aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang    mTextureFormat = formatInfo.texFormat;
12249aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang    mShaderResourceFormat = formatInfo.srvFormat;
12259aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang    mDepthStencilFormat = formatInfo.dsvFormat;
12269aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang    mRenderTargetFormat = formatInfo.rtvFormat;
12279aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang    mSwizzleTextureFormat = formatInfo.swizzleTexFormat;
12289aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang    mSwizzleShaderResourceFormat = formatInfo.swizzleSRVFormat;
12299aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang    mSwizzleRenderTargetFormat = formatInfo.swizzleRTVFormat;
12302058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com
12312058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com    // If the width, height or depth are not positive this should be treated as an incomplete texture
12322058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com    // we handle that here by skipping the d3d texture creation
12332058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com    if (width > 0 && height > 0 && depth > 0)
12342058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com    {
12352058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com        // adjust size if needed for compressed textures
1236f61738a578693170902045f8a3fa2f383fd5c367Nicolas Capens        d3d11::MakeValidSize(false, mTextureFormat, &width, &height, &mTopLevel);
12372058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com
12382058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com        ID3D11Device *device = mRenderer->getDevice();
12392058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com
12402058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com        D3D11_TEXTURE3D_DESC desc;
12412058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com        desc.Width = width;
12422058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com        desc.Height = height;
12432058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com        desc.Depth = depth;
1244bf712d0a32847868913a3521b44912a5c29f08b8Nicolas Capens        desc.MipLevels = ((levels > 0) ? (mTopLevel + levels) : 0);
12452058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com        desc.Format = mTextureFormat;
12462058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com        desc.Usage = D3D11_USAGE_DEFAULT;
12472058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com        desc.BindFlags = getBindFlags();
12482058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com        desc.CPUAccessFlags = 0;
12492058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com        desc.MiscFlags = 0;
12502058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com
12512058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com        HRESULT result = device->CreateTexture3D(&desc, NULL, &mTexture);
12522058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com
12532058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com        // this can happen from windows TDR
12542058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com        if (d3d11::isDeviceLostError(result))
12552058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com        {
12562058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com            mRenderer->notifyDeviceLost();
12572058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com            gl::error(GL_OUT_OF_MEMORY);
12582058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com        }
12592058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com        else if (FAILED(result))
12602058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com        {
12612058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com            ASSERT(result == E_OUTOFMEMORY);
12622058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com            ERR("Creating image failed.");
12632058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com            gl::error(GL_OUT_OF_MEMORY);
12642058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com        }
12652058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com        else
12662058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com        {
12672058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com            mTexture->GetDesc(&desc);
12682058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com            mMipLevels = desc.MipLevels;
12692058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com            mTextureWidth = desc.Width;
12702058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com            mTextureHeight = desc.Height;
12712058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com            mTextureDepth = desc.Depth;
12722058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com        }
12732058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com    }
12742f06dbfb3f4bd815a3fe5b52638b091c1e356a04Jamie Madill
12752f06dbfb3f4bd815a3fe5b52638b091c1e356a04Jamie Madill    initializeSerials(getLevelCount() * depth, depth);
12762058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com}
12772058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com
12782058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.comTextureStorage11_3D::~TextureStorage11_3D()
12792058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com{
12806982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    for (unsigned i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
12816982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    {
12826982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        if (mAssociatedImages[i] != NULL)
12836982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        {
12846982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross            bool imageAssociationCorrect = mAssociatedImages[i]->isAssociatedStorageValid(this);
12856982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross            ASSERT(imageAssociationCorrect);
12866982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
12876982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross            if (imageAssociationCorrect)
12886982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross            {
12896982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross                // We must let the Images recover their data before we delete it from the TextureStorage.
12906982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross                mAssociatedImages[i]->recoverFromAssociatedStorage();
12916982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross            }
12926982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        }
12936982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    }
12946982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
1295ea2286352f5eba47dfaa3e9ab418bbacfd1ba8a1Geoff Lang    SafeRelease(mTexture);
1296644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang    SafeRelease(mSwizzleTexture);
1297e47e7363cf651100b85e042930f31cf5f8291fc1Nicolas Capens
1298ea2286352f5eba47dfaa3e9ab418bbacfd1ba8a1Geoff Lang    for (RenderTargetMap::iterator i = mLevelLayerRenderTargets.begin(); i != mLevelLayerRenderTargets.end(); i++)
129963b3b8f9ed6a7b9da1bd52f940cfcd29d4907ffdshannon.woods%transgaming.com@gtempaccount.com    {
1300ea2286352f5eba47dfaa3e9ab418bbacfd1ba8a1Geoff Lang        SafeDelete(i->second);
130163b3b8f9ed6a7b9da1bd52f940cfcd29d4907ffdshannon.woods%transgaming.com@gtempaccount.com    }
130215a8b1f683dbc9861cf05ded808f00796ecb0344shannonwoods@chromium.org    mLevelLayerRenderTargets.clear();
130315a8b1f683dbc9861cf05ded808f00796ecb0344shannonwoods@chromium.org
130415a8b1f683dbc9861cf05ded808f00796ecb0344shannonwoods@chromium.org    for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
130515a8b1f683dbc9861cf05ded808f00796ecb0344shannonwoods@chromium.org    {
1306ea2286352f5eba47dfaa3e9ab418bbacfd1ba8a1Geoff Lang        SafeDelete(mLevelRenderTargets[i]);
1307644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        SafeRelease(mSwizzleRenderTargets[i]);
130815a8b1f683dbc9861cf05ded808f00796ecb0344shannonwoods@chromium.org    }
13092058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com}
13102058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com
13112058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.comTextureStorage11_3D *TextureStorage11_3D::makeTextureStorage11_3D(TextureStorage *storage)
13122058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com{
13132058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com    ASSERT(HAS_DYNAMIC_TYPE(TextureStorage11_3D*, storage));
13142058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com    return static_cast<TextureStorage11_3D*>(storage);
13152058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com}
13162058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com
13176982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinrossvoid TextureStorage11_3D::associateImage(Image11* image, int level, int layerTarget)
13186982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross{
13196982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
13206982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
13216982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
13226982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    {
13236982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        mAssociatedImages[level] = image;
13246982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    }
13256982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross}
13266982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
13276982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinrossbool TextureStorage11_3D::isAssociatedImageValid(int level, int layerTarget, Image11* expectedImage)
13286982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross{
13296982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
13306982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    {
13316982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        // This validation check should never return false. It means the Image/TextureStorage association is broken.
13326982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        bool retValue = (mAssociatedImages[level] == expectedImage);
13336982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        ASSERT(retValue);
13346982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        return retValue;
13356982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    }
13366982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
13376982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    return false;
13386982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross}
13396982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
13406982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross// disassociateImage allows an Image to end its association with a Storage.
13416982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinrossvoid TextureStorage11_3D::disassociateImage(int level, int layerTarget, Image11* expectedImage)
13426982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross{
13436982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
13446982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
13456982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
13466982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    {
13476982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        ASSERT(mAssociatedImages[level] == expectedImage);
13486982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
13496982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        if (mAssociatedImages[level] == expectedImage)
13506982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        {
13516982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross            mAssociatedImages[level] = NULL;
13526982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        }
13536982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    }
13546982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross}
13556982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
13566982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross// releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image recover its data before ending the association.
13576982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinrossvoid TextureStorage11_3D::releaseAssociatedImage(int level, int layerTarget, Image11* incomingImage)
13586982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross{
13596982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    ASSERT((0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS));
13606982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
13616982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
13626982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    {
13636982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        // No need to let the old Image recover its data, if it is also the incoming Image.
13646982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        if (mAssociatedImages[level] != NULL && mAssociatedImages[level] != incomingImage)
13656982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        {
13666982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross            // Ensure that the Image is still associated with this TextureStorage. This should be true.
13676982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross            bool imageAssociationCorrect = mAssociatedImages[level]->isAssociatedStorageValid(this);
13686982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross            ASSERT(imageAssociationCorrect);
13696982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
13706982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross            if (imageAssociationCorrect)
13716982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross            {
13726982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross                // Force the image to recover from storage before its data is overwritten.
13736982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross                // This will reset mAssociatedImages[level] to NULL too.
13746982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross                mAssociatedImages[level]->recoverFromAssociatedStorage();
13756982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross            }
13766982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        }
13776982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    }
13786982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross}
13796982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
138076b258f88ebb47cf1022ae6b4392f220a56383d4Nicolas CapensID3D11Resource *TextureStorage11_3D::getResource() const
13812058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com{
13822058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com    return mTexture;
13832058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com}
13842058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com
13851d31aca98b997c225fe87172659d3bf51340f285Nicolas CapensID3D11ShaderResourceView *TextureStorage11_3D::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture)
13861d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens{
13871d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens    D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
13881d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens    srvDesc.Format = format;
13891d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens    srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D;
13901d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens    srvDesc.Texture3D.MostDetailedMip = baseLevel;
13911d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens    srvDesc.Texture3D.MipLevels = mipLevels;
13922058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com
13931d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens    ID3D11ShaderResourceView *SRV = NULL;
13941d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens
13951d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens    ID3D11Device *device = mRenderer->getDevice();
13961d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens    HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, &SRV);
13971d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens
13981d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens    if (result == E_OUTOFMEMORY)
13991d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens    {
14001d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens        gl::error(GL_OUT_OF_MEMORY);
14011d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens    }
14021d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens    ASSERT(SUCCEEDED(result));
14031d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens
14041d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens    return SRV;
14052058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com}
14062058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com
1407ac7579c2bd0cc9afdf5892a766e6967bf3a341f0Jamie MadillRenderTarget *TextureStorage11_3D::getRenderTarget(const gl::ImageIndex &index)
140815a8b1f683dbc9861cf05ded808f00796ecb0344shannonwoods@chromium.org{
1409ac7579c2bd0cc9afdf5892a766e6967bf3a341f0Jamie Madill    int mipLevel = index.mipIndex;
1410ac7579c2bd0cc9afdf5892a766e6967bf3a341f0Jamie Madill
1411bf712d0a32847868913a3521b44912a5c29f08b8Nicolas Capens    if (mipLevel >= 0 && mipLevel < getLevelCount())
141215a8b1f683dbc9861cf05ded808f00796ecb0344shannonwoods@chromium.org    {
1413ac7579c2bd0cc9afdf5892a766e6967bf3a341f0Jamie Madill        ASSERT(mRenderTargetFormat != DXGI_FORMAT_UNKNOWN);
1414ac7579c2bd0cc9afdf5892a766e6967bf3a341f0Jamie Madill
1415ac7579c2bd0cc9afdf5892a766e6967bf3a341f0Jamie Madill        if (!index.hasLayer())
141615a8b1f683dbc9861cf05ded808f00796ecb0344shannonwoods@chromium.org        {
1417ac7579c2bd0cc9afdf5892a766e6967bf3a341f0Jamie Madill            if (!mLevelRenderTargets[mipLevel])
141815a8b1f683dbc9861cf05ded808f00796ecb0344shannonwoods@chromium.org            {
1419ac7579c2bd0cc9afdf5892a766e6967bf3a341f0Jamie Madill                ID3D11ShaderResourceView *srv = getSRVLevel(mipLevel);
1420ac7579c2bd0cc9afdf5892a766e6967bf3a341f0Jamie Madill                if (!srv)
1421ac7579c2bd0cc9afdf5892a766e6967bf3a341f0Jamie Madill                {
1422ac7579c2bd0cc9afdf5892a766e6967bf3a341f0Jamie Madill                    return NULL;
1423ac7579c2bd0cc9afdf5892a766e6967bf3a341f0Jamie Madill                }
142415a8b1f683dbc9861cf05ded808f00796ecb0344shannonwoods@chromium.org
1425644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang                ID3D11Device *device = mRenderer->getDevice();
1426644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang
142715a8b1f683dbc9861cf05ded808f00796ecb0344shannonwoods@chromium.org                D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
142815a8b1f683dbc9861cf05ded808f00796ecb0344shannonwoods@chromium.org                rtvDesc.Format = mRenderTargetFormat;
142915a8b1f683dbc9861cf05ded808f00796ecb0344shannonwoods@chromium.org                rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D;
1430fa7b76d08d5c2dddb7979471884834103c761747Nicolas Capens                rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel;
143115a8b1f683dbc9861cf05ded808f00796ecb0344shannonwoods@chromium.org                rtvDesc.Texture3D.FirstWSlice = 0;
143215a8b1f683dbc9861cf05ded808f00796ecb0344shannonwoods@chromium.org                rtvDesc.Texture3D.WSize = -1;
143315a8b1f683dbc9861cf05ded808f00796ecb0344shannonwoods@chromium.org
143415a8b1f683dbc9861cf05ded808f00796ecb0344shannonwoods@chromium.org                ID3D11RenderTargetView *rtv;
1435644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang                HRESULT result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv);
143615a8b1f683dbc9861cf05ded808f00796ecb0344shannonwoods@chromium.org
143715a8b1f683dbc9861cf05ded808f00796ecb0344shannonwoods@chromium.org                if (result == E_OUTOFMEMORY)
143815a8b1f683dbc9861cf05ded808f00796ecb0344shannonwoods@chromium.org                {
1439ea2286352f5eba47dfaa3e9ab418bbacfd1ba8a1Geoff Lang                    SafeRelease(srv);
144015a8b1f683dbc9861cf05ded808f00796ecb0344shannonwoods@chromium.org                    return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
144115a8b1f683dbc9861cf05ded808f00796ecb0344shannonwoods@chromium.org                }
144215a8b1f683dbc9861cf05ded808f00796ecb0344shannonwoods@chromium.org                ASSERT(SUCCEEDED(result));
144315a8b1f683dbc9861cf05ded808f00796ecb0344shannonwoods@chromium.org
1444b16b8ed79d73c718cfe9247e9c8d2714d5eb4dc5Jamie Madill                mLevelRenderTargets[mipLevel] = new RenderTarget11(mRenderer, rtv, mTexture, srv, getLevelWidth(mipLevel), getLevelHeight(mipLevel), getLevelDepth(mipLevel));
14452916b30eb47496327257254d355677a6ebb0388aGeoff Lang
14462916b30eb47496327257254d355677a6ebb0388aGeoff Lang                // RenderTarget will take ownership of these resources
14472916b30eb47496327257254d355677a6ebb0388aGeoff Lang                SafeRelease(rtv);
144815a8b1f683dbc9861cf05ded808f00796ecb0344shannonwoods@chromium.org            }
144915a8b1f683dbc9861cf05ded808f00796ecb0344shannonwoods@chromium.org
1450ac7579c2bd0cc9afdf5892a766e6967bf3a341f0Jamie Madill            return mLevelRenderTargets[mipLevel];
1451ac7579c2bd0cc9afdf5892a766e6967bf3a341f0Jamie Madill        }
1452ac7579c2bd0cc9afdf5892a766e6967bf3a341f0Jamie Madill        else
145363b3b8f9ed6a7b9da1bd52f940cfcd29d4907ffdshannon.woods%transgaming.com@gtempaccount.com        {
1454ac7579c2bd0cc9afdf5892a766e6967bf3a341f0Jamie Madill            int layer = index.layerIndex;
145563b3b8f9ed6a7b9da1bd52f940cfcd29d4907ffdshannon.woods%transgaming.com@gtempaccount.com
1456ac7579c2bd0cc9afdf5892a766e6967bf3a341f0Jamie Madill            LevelLayerKey key(mipLevel, layer);
1457ac7579c2bd0cc9afdf5892a766e6967bf3a341f0Jamie Madill            if (mLevelLayerRenderTargets.find(key) == mLevelLayerRenderTargets.end())
145863b3b8f9ed6a7b9da1bd52f940cfcd29d4907ffdshannon.woods%transgaming.com@gtempaccount.com            {
1459ac7579c2bd0cc9afdf5892a766e6967bf3a341f0Jamie Madill                ID3D11Device *device = mRenderer->getDevice();
1460ac7579c2bd0cc9afdf5892a766e6967bf3a341f0Jamie Madill                HRESULT result;
1461ac7579c2bd0cc9afdf5892a766e6967bf3a341f0Jamie Madill
1462ac7579c2bd0cc9afdf5892a766e6967bf3a341f0Jamie Madill                // TODO, what kind of SRV is expected here?
1463ac7579c2bd0cc9afdf5892a766e6967bf3a341f0Jamie Madill                ID3D11ShaderResourceView *srv = NULL;
1464ac7579c2bd0cc9afdf5892a766e6967bf3a341f0Jamie Madill
146563b3b8f9ed6a7b9da1bd52f940cfcd29d4907ffdshannon.woods%transgaming.com@gtempaccount.com                D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
146663b3b8f9ed6a7b9da1bd52f940cfcd29d4907ffdshannon.woods%transgaming.com@gtempaccount.com                rtvDesc.Format = mRenderTargetFormat;
146763b3b8f9ed6a7b9da1bd52f940cfcd29d4907ffdshannon.woods%transgaming.com@gtempaccount.com                rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D;
1468fa7b76d08d5c2dddb7979471884834103c761747Nicolas Capens                rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel;
146963b3b8f9ed6a7b9da1bd52f940cfcd29d4907ffdshannon.woods%transgaming.com@gtempaccount.com                rtvDesc.Texture3D.FirstWSlice = layer;
147063b3b8f9ed6a7b9da1bd52f940cfcd29d4907ffdshannon.woods%transgaming.com@gtempaccount.com                rtvDesc.Texture3D.WSize = 1;
147163b3b8f9ed6a7b9da1bd52f940cfcd29d4907ffdshannon.woods%transgaming.com@gtempaccount.com
147263b3b8f9ed6a7b9da1bd52f940cfcd29d4907ffdshannon.woods%transgaming.com@gtempaccount.com                ID3D11RenderTargetView *rtv;
147363b3b8f9ed6a7b9da1bd52f940cfcd29d4907ffdshannon.woods%transgaming.com@gtempaccount.com                result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv);
147463b3b8f9ed6a7b9da1bd52f940cfcd29d4907ffdshannon.woods%transgaming.com@gtempaccount.com
147563b3b8f9ed6a7b9da1bd52f940cfcd29d4907ffdshannon.woods%transgaming.com@gtempaccount.com                if (result == E_OUTOFMEMORY)
147663b3b8f9ed6a7b9da1bd52f940cfcd29d4907ffdshannon.woods%transgaming.com@gtempaccount.com                {
1477ea2286352f5eba47dfaa3e9ab418bbacfd1ba8a1Geoff Lang                    SafeRelease(srv);
147863b3b8f9ed6a7b9da1bd52f940cfcd29d4907ffdshannon.woods%transgaming.com@gtempaccount.com                    return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
147963b3b8f9ed6a7b9da1bd52f940cfcd29d4907ffdshannon.woods%transgaming.com@gtempaccount.com                }
148063b3b8f9ed6a7b9da1bd52f940cfcd29d4907ffdshannon.woods%transgaming.com@gtempaccount.com                ASSERT(SUCCEEDED(result));
148163b3b8f9ed6a7b9da1bd52f940cfcd29d4907ffdshannon.woods%transgaming.com@gtempaccount.com
1482b16b8ed79d73c718cfe9247e9c8d2714d5eb4dc5Jamie Madill                mLevelLayerRenderTargets[key] = new RenderTarget11(mRenderer, rtv, mTexture, srv, getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1);
14832916b30eb47496327257254d355677a6ebb0388aGeoff Lang
14842916b30eb47496327257254d355677a6ebb0388aGeoff Lang                // RenderTarget will take ownership of these resources
14852916b30eb47496327257254d355677a6ebb0388aGeoff Lang                SafeRelease(rtv);
14862916b30eb47496327257254d355677a6ebb0388aGeoff Lang                SafeRelease(srv);
148763b3b8f9ed6a7b9da1bd52f940cfcd29d4907ffdshannon.woods%transgaming.com@gtempaccount.com            }
148863b3b8f9ed6a7b9da1bd52f940cfcd29d4907ffdshannon.woods%transgaming.com@gtempaccount.com
1489ac7579c2bd0cc9afdf5892a766e6967bf3a341f0Jamie Madill            return mLevelLayerRenderTargets[key];
1490ac7579c2bd0cc9afdf5892a766e6967bf3a341f0Jamie Madill        }
149163b3b8f9ed6a7b9da1bd52f940cfcd29d4907ffdshannon.woods%transgaming.com@gtempaccount.com    }
1492ac7579c2bd0cc9afdf5892a766e6967bf3a341f0Jamie Madill
1493ac7579c2bd0cc9afdf5892a766e6967bf3a341f0Jamie Madill    return NULL;
149463b3b8f9ed6a7b9da1bd52f940cfcd29d4907ffdshannon.woods%transgaming.com@gtempaccount.com}
149563b3b8f9ed6a7b9da1bd52f940cfcd29d4907ffdshannon.woods%transgaming.com@gtempaccount.com
14965e48c034daedc48a998fa5eca094d0a0ed247725Jamie Madillvoid TextureStorage11_3D::generateMipmaps()
14972058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com{
14985e48c034daedc48a998fa5eca094d0a0ed247725Jamie Madill    // Base level must already be defined
14995e48c034daedc48a998fa5eca094d0a0ed247725Jamie Madill
15005e48c034daedc48a998fa5eca094d0a0ed247725Jamie Madill    for (int level = 1; level < getLevelCount(); level++)
15015e48c034daedc48a998fa5eca094d0a0ed247725Jamie Madill    {
15025e48c034daedc48a998fa5eca094d0a0ed247725Jamie Madill        invalidateSwizzleCacheLevel(level);
1503644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang
15045e48c034daedc48a998fa5eca094d0a0ed247725Jamie Madill        gl::ImageIndex srcIndex = gl::ImageIndex::Make3D(level - 1);
15055e48c034daedc48a998fa5eca094d0a0ed247725Jamie Madill        gl::ImageIndex destIndex = gl::ImageIndex::Make3D(level);
1506ac7579c2bd0cc9afdf5892a766e6967bf3a341f0Jamie Madill
15075e48c034daedc48a998fa5eca094d0a0ed247725Jamie Madill        RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTarget(srcIndex));
15085e48c034daedc48a998fa5eca094d0a0ed247725Jamie Madill        RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTarget(destIndex));
150937b8a91a113a18525436e824658151818f88dde2shannonwoods@chromium.org
15105e48c034daedc48a998fa5eca094d0a0ed247725Jamie Madill        generateMipmapLayer(source, dest);
15115e48c034daedc48a998fa5eca094d0a0ed247725Jamie Madill    }
15122058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com}
15132058d64a7c8c3cf5f79c3ab3fad055cd984c8497shannon.woods%transgaming.com@gtempaccount.com
151441d9f7e97a6066b8300e3fab3ad3b83c083b3479Nicolas CapensID3D11Resource *TextureStorage11_3D::getSwizzleTexture()
1515644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang{
1516644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang    if (!mSwizzleTexture)
1517644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang    {
1518644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        ID3D11Device *device = mRenderer->getDevice();
1519644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang
1520644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        D3D11_TEXTURE3D_DESC desc;
1521644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        desc.Width = mTextureWidth;
1522644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        desc.Height = mTextureHeight;
1523644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        desc.Depth = mTextureDepth;
1524bf712d0a32847868913a3521b44912a5c29f08b8Nicolas Capens        desc.MipLevels = mMipLevels;
1525644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        desc.Format = mSwizzleTextureFormat;
1526644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        desc.Usage = D3D11_USAGE_DEFAULT;
1527644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
1528644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        desc.CPUAccessFlags = 0;
1529644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        desc.MiscFlags = 0;
1530644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang
1531644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        HRESULT result = device->CreateTexture3D(&desc, NULL, &mSwizzleTexture);
1532644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang
1533644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        if (result == E_OUTOFMEMORY)
1534644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        {
1535644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang            return gl::error(GL_OUT_OF_MEMORY, static_cast<ID3D11Texture3D*>(NULL));
1536644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        }
1537644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        ASSERT(SUCCEEDED(result));
1538644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang    }
1539644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang
1540644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang    return mSwizzleTexture;
1541644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang}
1542644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang
1543644bbf2448bc2e29eadd811c303117cacb39189dGeoff LangID3D11RenderTargetView *TextureStorage11_3D::getSwizzleRenderTarget(int mipLevel)
1544644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang{
1545bf712d0a32847868913a3521b44912a5c29f08b8Nicolas Capens    if (mipLevel >= 0 && mipLevel < getLevelCount())
1546644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang    {
1547644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        if (!mSwizzleRenderTargets[mipLevel])
1548644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        {
154941d9f7e97a6066b8300e3fab3ad3b83c083b3479Nicolas Capens            ID3D11Resource *swizzleTexture = getSwizzleTexture();
1550644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang            if (!swizzleTexture)
1551644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang            {
1552644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang                return NULL;
1553644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang            }
1554644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang
1555644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang            ID3D11Device *device = mRenderer->getDevice();
1556644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang
1557644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang            D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
1558644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang            rtvDesc.Format = mSwizzleRenderTargetFormat;
1559644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang            rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D;
1560fa7b76d08d5c2dddb7979471884834103c761747Nicolas Capens            rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel;
1561644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang            rtvDesc.Texture3D.FirstWSlice = 0;
1562644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang            rtvDesc.Texture3D.WSize = -1;
1563644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang
1564644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang            HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]);
1565cebb5aa092f92e1f727fe5e4300dbd83abd49afbGeoff Lang
1566cebb5aa092f92e1f727fe5e4300dbd83abd49afbGeoff Lang            if (result == E_OUTOFMEMORY)
1567cebb5aa092f92e1f727fe5e4300dbd83abd49afbGeoff Lang            {
1568cebb5aa092f92e1f727fe5e4300dbd83abd49afbGeoff Lang                return gl::error(GL_OUT_OF_MEMORY, static_cast<ID3D11RenderTargetView*>(NULL));
1569cebb5aa092f92e1f727fe5e4300dbd83abd49afbGeoff Lang            }
1570cebb5aa092f92e1f727fe5e4300dbd83abd49afbGeoff Lang            ASSERT(SUCCEEDED(result));
1571644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        }
1572644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang
1573644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        return mSwizzleRenderTargets[mipLevel];
1574644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang    }
1575644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang    else
1576644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang    {
1577644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        return NULL;
1578644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang    }
1579644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang}
1580644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang
1581bf712d0a32847868913a3521b44912a5c29f08b8Nicolas CapensTextureStorage11_2DArray::TextureStorage11_2DArray(Renderer *renderer, GLenum internalformat, bool renderTarget,
1582bf712d0a32847868913a3521b44912a5c29f08b8Nicolas Capens                                                   GLsizei width, GLsizei height, GLsizei depth, int levels)
1583e4a492be45f39dffaea53c3523064844ee56e41bGeoff Lang    : TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderTarget))
1584969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com{
1585969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com    mTexture = NULL;
1586644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang    mSwizzleTexture = NULL;
1587e47e7363cf651100b85e042930f31cf5f8291fc1Nicolas Capens
1588644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang    for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
1589644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang    {
1590644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        mSwizzleRenderTargets[level] = NULL;
1591644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang    }
1592969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com
15939aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang    const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat);
15949aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang    mTextureFormat = formatInfo.texFormat;
15959aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang    mShaderResourceFormat = formatInfo.srvFormat;
15969aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang    mDepthStencilFormat = formatInfo.dsvFormat;
15979aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang    mRenderTargetFormat = formatInfo.rtvFormat;
15989aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang    mSwizzleTextureFormat = formatInfo.swizzleTexFormat;
15999aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang    mSwizzleShaderResourceFormat = formatInfo.swizzleSRVFormat;
16009aa00bbc5303cf7817d02d04860b044b3d29804dGeoff Lang    mSwizzleRenderTargetFormat = formatInfo.swizzleRTVFormat;
1601969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com
1602d38d66e49a77f0b84006c7e69964d93473892087shannonwoods@chromium.org    // if the width, height or depth is not positive this should be treated as an incomplete texture
1603969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com    // we handle that here by skipping the d3d texture creation
1604969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com    if (width > 0 && height > 0 && depth > 0)
1605969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com    {
1606969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com        // adjust size if needed for compressed textures
1607f61738a578693170902045f8a3fa2f383fd5c367Nicolas Capens        d3d11::MakeValidSize(false, mTextureFormat, &width, &height, &mTopLevel);
1608969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com
1609969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com        ID3D11Device *device = mRenderer->getDevice();
1610969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com
1611969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com        D3D11_TEXTURE2D_DESC desc;
1612969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com        desc.Width = width;
1613969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com        desc.Height = height;
1614bf712d0a32847868913a3521b44912a5c29f08b8Nicolas Capens        desc.MipLevels = ((levels > 0) ? (mTopLevel + levels) : 0);
1615969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com        desc.ArraySize = depth;
1616969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com        desc.Format = mTextureFormat;
1617969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com        desc.SampleDesc.Count = 1;
1618969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com        desc.SampleDesc.Quality = 0;
1619969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com        desc.Usage = D3D11_USAGE_DEFAULT;
1620969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com        desc.BindFlags = getBindFlags();
1621969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com        desc.CPUAccessFlags = 0;
1622969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com        desc.MiscFlags = 0;
1623969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com
1624969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com        HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture);
1625969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com
1626969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com        // this can happen from windows TDR
1627969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com        if (d3d11::isDeviceLostError(result))
1628969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com        {
1629969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com            mRenderer->notifyDeviceLost();
1630969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com            gl::error(GL_OUT_OF_MEMORY);
1631969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com        }
1632969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com        else if (FAILED(result))
1633969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com        {
1634969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com            ASSERT(result == E_OUTOFMEMORY);
1635969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com            ERR("Creating image failed.");
1636969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com            gl::error(GL_OUT_OF_MEMORY);
1637969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com        }
1638969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com        else
1639969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com        {
1640969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com            mTexture->GetDesc(&desc);
1641969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com            mMipLevels = desc.MipLevels;
1642969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com            mTextureWidth = desc.Width;
1643969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com            mTextureHeight = desc.Height;
1644969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com            mTextureDepth = desc.ArraySize;
1645969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com        }
1646969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com    }
16472f06dbfb3f4bd815a3fe5b52638b091c1e356a04Jamie Madill
16482f06dbfb3f4bd815a3fe5b52638b091c1e356a04Jamie Madill    initializeSerials(getLevelCount() * depth, depth);
1649969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com}
1650969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com
1651969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.comTextureStorage11_2DArray::~TextureStorage11_2DArray()
1652969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com{
16536982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    for (ImageMap::iterator i = mAssociatedImages.begin(); i != mAssociatedImages.end(); i++)
16546982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    {
16556982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        bool imageAssociationCorrect = i->second->isAssociatedStorageValid(this);
16566982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        ASSERT(imageAssociationCorrect);
16576982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
16586982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        if (imageAssociationCorrect)
16596982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        {
16606982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross            // We must let the Images recover their data before we delete it from the TextureStorage.
16616982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross            i->second->recoverFromAssociatedStorage();
16626982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        }
16636982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    }
16646982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    mAssociatedImages.clear();
16656982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
1666ea2286352f5eba47dfaa3e9ab418bbacfd1ba8a1Geoff Lang    SafeRelease(mTexture);
1667644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang    SafeRelease(mSwizzleTexture);
1668e47e7363cf651100b85e042930f31cf5f8291fc1Nicolas Capens
1669644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang    for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
1670644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang    {
1671644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        SafeRelease(mSwizzleRenderTargets[level]);
1672644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang    }
1673969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com
1674ea2286352f5eba47dfaa3e9ab418bbacfd1ba8a1Geoff Lang    for (RenderTargetMap::iterator i = mRenderTargets.begin(); i != mRenderTargets.end(); i++)
1675969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com    {
1676ea2286352f5eba47dfaa3e9ab418bbacfd1ba8a1Geoff Lang        SafeDelete(i->second);
1677969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com    }
1678969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com    mRenderTargets.clear();
1679969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com}
1680969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com
1681969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.comTextureStorage11_2DArray *TextureStorage11_2DArray::makeTextureStorage11_2DArray(TextureStorage *storage)
1682969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com{
1683969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com    ASSERT(HAS_DYNAMIC_TYPE(TextureStorage11_2DArray*, storage));
1684969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com    return static_cast<TextureStorage11_2DArray*>(storage);
1685969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com}
1686969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com
16876982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinrossvoid TextureStorage11_2DArray::associateImage(Image11* image, int level, int layerTarget)
16886982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross{
16896982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    ASSERT(0 <= level && level < getLevelCount());
16906982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
16916982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    if (0 <= level && level < getLevelCount())
16926982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    {
16936982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        LevelLayerKey key(level, layerTarget);
16946982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        mAssociatedImages[key] = image;
16956982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    }
16966982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross}
16976982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
16986982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinrossbool TextureStorage11_2DArray::isAssociatedImageValid(int level, int layerTarget, Image11* expectedImage)
16996982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross{
17006982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    LevelLayerKey key(level, layerTarget);
17016982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
17026982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    // This validation check should never return false. It means the Image/TextureStorage association is broken.
17036982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    bool retValue = (mAssociatedImages.find(key) != mAssociatedImages.end() && (mAssociatedImages[key] == expectedImage));
17046982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    ASSERT(retValue);
17056982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    return retValue;
17066982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross}
17076982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
17086982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross// disassociateImage allows an Image to end its association with a Storage.
17096982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinrossvoid TextureStorage11_2DArray::disassociateImage(int level, int layerTarget, Image11* expectedImage)
17106982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross{
17116982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    LevelLayerKey key(level, layerTarget);
17126982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
17136982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    bool imageAssociationCorrect = (mAssociatedImages.find(key) != mAssociatedImages.end() && (mAssociatedImages[key] == expectedImage));
17146982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    ASSERT(imageAssociationCorrect);
17156982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
17166982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    if (imageAssociationCorrect)
17176982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    {
17186982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        mAssociatedImages[key] = NULL;
17196982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    }
17206982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross}
17216982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
17226982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross// releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image recover its data before ending the association.
17236982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinrossvoid TextureStorage11_2DArray::releaseAssociatedImage(int level, int layerTarget, Image11* incomingImage)
17246982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross{
17256982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    LevelLayerKey key(level, layerTarget);
17266982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
17276982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    ASSERT(mAssociatedImages.find(key) != mAssociatedImages.end());
17286982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
17296982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    if (mAssociatedImages.find(key) != mAssociatedImages.end())
17306982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    {
17316982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        if (mAssociatedImages[key] != NULL && mAssociatedImages[key] != incomingImage)
17326982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        {
17336982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross            // Ensure that the Image is still associated with this TextureStorage. This should be true.
17346982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross            bool imageAssociationCorrect = mAssociatedImages[key]->isAssociatedStorageValid(this);
17356982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross            ASSERT(imageAssociationCorrect);
17366982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
17376982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross            if (imageAssociationCorrect)
17386982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross            {
17396982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross                // Force the image to recover from storage before its data is overwritten.
17406982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross                // This will reset mAssociatedImages[level] to NULL too.
17416982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross                mAssociatedImages[key]->recoverFromAssociatedStorage();
17426982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross            }
17436982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross        }
17446982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross    }
17456982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross}
17466982260b26e4d1c54b5fcea1679ecea4fee80321Austin Kinross
174776b258f88ebb47cf1022ae6b4392f220a56383d4Nicolas CapensID3D11Resource *TextureStorage11_2DArray::getResource() const
1748969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com{
1749969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com    return mTexture;
1750969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com}
1751969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com
17521d31aca98b997c225fe87172659d3bf51340f285Nicolas CapensID3D11ShaderResourceView *TextureStorage11_2DArray::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture)
17531d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens{
17541d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens    D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
17551d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens    srvDesc.Format = format;
17561d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens    srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
17571d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens    srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + baseLevel;
17581d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens    srvDesc.Texture2DArray.MipLevels = mipLevels;
17591d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens    srvDesc.Texture2DArray.FirstArraySlice = 0;
17601d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens    srvDesc.Texture2DArray.ArraySize = mTextureDepth;
17611d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens
17621d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens    ID3D11ShaderResourceView *SRV = NULL;
1763969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com
17641d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens    ID3D11Device *device = mRenderer->getDevice();
17651d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens    HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, &SRV);
17661d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens
17671d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens    if (result == E_OUTOFMEMORY)
17681d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens    {
17691d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens        gl::error(GL_OUT_OF_MEMORY);
17701d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens    }
17711d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens    ASSERT(SUCCEEDED(result));
17721d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens
17731d31aca98b997c225fe87172659d3bf51340f285Nicolas Capens    return SRV;
1774969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com}
1775969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com
1776ac7579c2bd0cc9afdf5892a766e6967bf3a341f0Jamie MadillRenderTarget *TextureStorage11_2DArray::getRenderTarget(const gl::ImageIndex &index)
1777969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com{
1778ac7579c2bd0cc9afdf5892a766e6967bf3a341f0Jamie Madill    ASSERT(index.hasLayer());
1779ac7579c2bd0cc9afdf5892a766e6967bf3a341f0Jamie Madill
1780ac7579c2bd0cc9afdf5892a766e6967bf3a341f0Jamie Madill    int mipLevel = index.mipIndex;
1781ac7579c2bd0cc9afdf5892a766e6967bf3a341f0Jamie Madill    int layer = index.layerIndex;
1782ac7579c2bd0cc9afdf5892a766e6967bf3a341f0Jamie Madill
1783bf712d0a32847868913a3521b44912a5c29f08b8Nicolas Capens    if (mipLevel >= 0 && mipLevel < getLevelCount())
1784969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com    {
1785969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com        LevelLayerKey key(mipLevel, layer);
1786969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com        if (mRenderTargets.find(key) == mRenderTargets.end())
1787969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com        {
1788969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com            ID3D11Device *device = mRenderer->getDevice();
1789969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com            HRESULT result;
1790969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com
179130aa1a9f438374a771cc789eddb4d2fd21860305shannonwoods@chromium.org            D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
179230aa1a9f438374a771cc789eddb4d2fd21860305shannonwoods@chromium.org            srvDesc.Format = mShaderResourceFormat;
179330aa1a9f438374a771cc789eddb4d2fd21860305shannonwoods@chromium.org            srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
1794fa7b76d08d5c2dddb7979471884834103c761747Nicolas Capens            srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + mipLevel;
179530aa1a9f438374a771cc789eddb4d2fd21860305shannonwoods@chromium.org            srvDesc.Texture2DArray.MipLevels = 1;
179630aa1a9f438374a771cc789eddb4d2fd21860305shannonwoods@chromium.org            srvDesc.Texture2DArray.FirstArraySlice = layer;
179730aa1a9f438374a771cc789eddb4d2fd21860305shannonwoods@chromium.org            srvDesc.Texture2DArray.ArraySize = 1;
179830aa1a9f438374a771cc789eddb4d2fd21860305shannonwoods@chromium.org
179930aa1a9f438374a771cc789eddb4d2fd21860305shannonwoods@chromium.org            ID3D11ShaderResourceView *srv;
180030aa1a9f438374a771cc789eddb4d2fd21860305shannonwoods@chromium.org            result = device->CreateShaderResourceView(mTexture, &srvDesc, &srv);
180130aa1a9f438374a771cc789eddb4d2fd21860305shannonwoods@chromium.org
180230aa1a9f438374a771cc789eddb4d2fd21860305shannonwoods@chromium.org            if (result == E_OUTOFMEMORY)
180330aa1a9f438374a771cc789eddb4d2fd21860305shannonwoods@chromium.org            {
180430aa1a9f438374a771cc789eddb4d2fd21860305shannonwoods@chromium.org                return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
180530aa1a9f438374a771cc789eddb4d2fd21860305shannonwoods@chromium.org            }
180630aa1a9f438374a771cc789eddb4d2fd21860305shannonwoods@chromium.org            ASSERT(SUCCEEDED(result));
1807969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com
1808969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com            if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN)
1809969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com            {
1810969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com                D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
1811969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com                rtvDesc.Format = mRenderTargetFormat;
1812969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com                rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
1813fa7b76d08d5c2dddb7979471884834103c761747Nicolas Capens                rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel;
1814969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com                rtvDesc.Texture2DArray.FirstArraySlice = layer;
1815969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com                rtvDesc.Texture2DArray.ArraySize = 1;
1816969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com
1817969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com                ID3D11RenderTargetView *rtv;
1818969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com                result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv);
1819969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com
1820969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com                if (result == E_OUTOFMEMORY)
1821969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com                {
1822969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com                    SafeRelease(srv);
1823969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com                    return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
1824969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com                }
1825969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com                ASSERT(SUCCEEDED(result));
1826969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com
1827b16b8ed79d73c718cfe9247e9c8d2714d5eb4dc5Jamie Madill                mRenderTargets[key] = new RenderTarget11(mRenderer, rtv, mTexture, srv, getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1);
18282916b30eb47496327257254d355677a6ebb0388aGeoff Lang
18292916b30eb47496327257254d355677a6ebb0388aGeoff Lang                // RenderTarget will take ownership of these resources
18302916b30eb47496327257254d355677a6ebb0388aGeoff Lang                SafeRelease(rtv);
18312916b30eb47496327257254d355677a6ebb0388aGeoff Lang                SafeRelease(srv);
1832969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com            }
1833969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com            else
1834969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com            {
1835969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com                UNREACHABLE();
1836969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com            }
1837969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com        }
1838969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com
1839969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com        return mRenderTargets[key];
1840969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com    }
1841969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com    else
1842969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com    {
1843969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com        return NULL;
1844969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com    }
1845969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com}
1846969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com
18475e48c034daedc48a998fa5eca094d0a0ed247725Jamie Madillvoid TextureStorage11_2DArray::generateMipmaps()
1848969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com{
18495e48c034daedc48a998fa5eca094d0a0ed247725Jamie Madill    // Base level must already be defined
18505e48c034daedc48a998fa5eca094d0a0ed247725Jamie Madill
18515e48c034daedc48a998fa5eca094d0a0ed247725Jamie Madill    for (int level = 0; level < getLevelCount(); level++)
185230aa1a9f438374a771cc789eddb4d2fd21860305shannonwoods@chromium.org    {
18535e48c034daedc48a998fa5eca094d0a0ed247725Jamie Madill        invalidateSwizzleCacheLevel(level);
18545e48c034daedc48a998fa5eca094d0a0ed247725Jamie Madill        for (unsigned int layer = 0; layer < mTextureDepth; layer++)
18555e48c034daedc48a998fa5eca094d0a0ed247725Jamie Madill        {
18565e48c034daedc48a998fa5eca094d0a0ed247725Jamie Madill            gl::ImageIndex sourceIndex = gl::ImageIndex::Make2DArray(level - 1, layer);
18575e48c034daedc48a998fa5eca094d0a0ed247725Jamie Madill            gl::ImageIndex destIndex = gl::ImageIndex::Make2DArray(level, layer);
1858ac7579c2bd0cc9afdf5892a766e6967bf3a341f0Jamie Madill
18595e48c034daedc48a998fa5eca094d0a0ed247725Jamie Madill            RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTarget(sourceIndex));
18605e48c034daedc48a998fa5eca094d0a0ed247725Jamie Madill            RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTarget(destIndex));
186130aa1a9f438374a771cc789eddb4d2fd21860305shannonwoods@chromium.org
18625e48c034daedc48a998fa5eca094d0a0ed247725Jamie Madill            generateMipmapLayer(source, dest);
18635e48c034daedc48a998fa5eca094d0a0ed247725Jamie Madill        }
186430aa1a9f438374a771cc789eddb4d2fd21860305shannonwoods@chromium.org    }
1865969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com}
1866969733786b68213ac06642ee81d6513bab8f3ef8shannon.woods%transgaming.com@gtempaccount.com
186741d9f7e97a6066b8300e3fab3ad3b83c083b3479Nicolas CapensID3D11Resource *TextureStorage11_2DArray::getSwizzleTexture()
1868644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang{
1869644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang    if (!mSwizzleTexture)
1870644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang    {
1871644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        ID3D11Device *device = mRenderer->getDevice();
1872644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang
1873644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        D3D11_TEXTURE2D_DESC desc;
1874644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        desc.Width = mTextureWidth;
1875644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        desc.Height = mTextureHeight;
1876bf712d0a32847868913a3521b44912a5c29f08b8Nicolas Capens        desc.MipLevels = mMipLevels;
1877644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        desc.ArraySize = mTextureDepth;
1878644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        desc.Format = mSwizzleTextureFormat;
1879644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        desc.SampleDesc.Count = 1;
1880644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        desc.SampleDesc.Quality = 0;
1881644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        desc.Usage = D3D11_USAGE_DEFAULT;
1882644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
1883644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        desc.CPUAccessFlags = 0;
1884644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        desc.MiscFlags = 0;
1885644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang
1886644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        HRESULT result = device->CreateTexture2D(&desc, NULL, &mSwizzleTexture);
1887644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang
1888644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        if (result == E_OUTOFMEMORY)
1889644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        {
1890644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang            return gl::error(GL_OUT_OF_MEMORY, static_cast<ID3D11Texture2D*>(NULL));
1891644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        }
1892644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        ASSERT(SUCCEEDED(result));
1893644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang    }
1894644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang
1895644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang    return mSwizzleTexture;
1896644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang}
1897644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang
1898644bbf2448bc2e29eadd811c303117cacb39189dGeoff LangID3D11RenderTargetView *TextureStorage11_2DArray::getSwizzleRenderTarget(int mipLevel)
1899644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang{
1900bf712d0a32847868913a3521b44912a5c29f08b8Nicolas Capens    if (mipLevel >= 0 && mipLevel < getLevelCount())
1901644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang    {
1902644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        if (!mSwizzleRenderTargets[mipLevel])
1903644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        {
190441d9f7e97a6066b8300e3fab3ad3b83c083b3479Nicolas Capens            ID3D11Resource *swizzleTexture = getSwizzleTexture();
1905644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang            if (!swizzleTexture)
1906644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang            {
1907644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang                return NULL;
1908644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang            }
1909644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang
1910644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang            ID3D11Device *device = mRenderer->getDevice();
1911644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang
1912644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang            D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
1913644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang            rtvDesc.Format = mSwizzleRenderTargetFormat;
1914644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang            rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
1915fa7b76d08d5c2dddb7979471884834103c761747Nicolas Capens            rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel;
1916644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang            rtvDesc.Texture2DArray.FirstArraySlice = 0;
1917644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang            rtvDesc.Texture2DArray.ArraySize = mTextureDepth;
1918644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang
1919644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang            HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]);
1920cebb5aa092f92e1f727fe5e4300dbd83abd49afbGeoff Lang
1921cebb5aa092f92e1f727fe5e4300dbd83abd49afbGeoff Lang            if (result == E_OUTOFMEMORY)
1922cebb5aa092f92e1f727fe5e4300dbd83abd49afbGeoff Lang            {
1923cebb5aa092f92e1f727fe5e4300dbd83abd49afbGeoff Lang                return gl::error(GL_OUT_OF_MEMORY, static_cast<ID3D11RenderTargetView*>(NULL));
1924cebb5aa092f92e1f727fe5e4300dbd83abd49afbGeoff Lang            }
1925cebb5aa092f92e1f727fe5e4300dbd83abd49afbGeoff Lang            ASSERT(SUCCEEDED(result));
1926644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        }
1927644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang
1928644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        return mSwizzleRenderTargets[mipLevel];
1929644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang    }
1930644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang    else
1931644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang    {
1932644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang        return NULL;
1933644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang    }
1934644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang}
1935644bbf2448bc2e29eadd811c303117cacb39189dGeoff Lang
1936858d32fa8bc0298a7d78954f5340d5019d718d11shannon.woods@transgaming.com}
1937