blob: 21d5b978c27975fa20b7f49a5f23c5249c7c2dba [file] [log] [blame]
shannon.woods@transgaming.combdf2d802013-02-28 23:16:20 +00001#include "precompiled.h"
daniel@transgaming.com4834ee22013-01-11 04:06:16 +00002//
Geoff Langcec35902014-04-16 10:52:36 -04003// Copyright (c) 2012-2014 The ANGLE Project Authors. All rights reserved.
daniel@transgaming.com4834ee22013-01-11 04:06:16 +00004// Use of this source code is governed by a BSD-style license that can be
5// found in the LICENSE file.
6//
7
8// TextureStorage11.cpp: Implements the abstract rx::TextureStorage11 class and its concrete derived
9// classes TextureStorage11_2D and TextureStorage11_Cube, which act as the interface to the D3D11 texture.
10
Brandon Jonesc7a41042014-06-23 12:03:25 -070011#include "libGLESv2/renderer/d3d/d3d11/TextureStorage11.h"
daniel@transgaming.com4834ee22013-01-11 04:06:16 +000012
Brandon Jones0511e802014-07-14 16:27:26 -070013#include "libGLESv2/renderer/d3d/TextureD3D.h"
Brandon Jonesc7a41042014-06-23 12:03:25 -070014#include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
15#include "libGLESv2/renderer/d3d/d3d11/RenderTarget11.h"
16#include "libGLESv2/renderer/d3d/d3d11/SwapChain11.h"
17#include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h"
18#include "libGLESv2/renderer/d3d/d3d11/Blit11.h"
19#include "libGLESv2/renderer/d3d/d3d11/formatutils11.h"
daniel@transgaming.com4834ee22013-01-11 04:06:16 +000020
shannonwoods@chromium.orga2ecfcc2013-05-30 00:11:59 +000021#include "common/utilities.h"
daniel@transgaming.com4834ee22013-01-11 04:06:16 +000022#include "libGLESv2/main.h"
23
24namespace rx
25{
26
Geoff Lang644bbf22013-09-17 17:02:43 -040027TextureStorage11::SwizzleCacheValue::SwizzleCacheValue()
28 : swizzleRed(GL_NONE), swizzleGreen(GL_NONE), swizzleBlue(GL_NONE), swizzleAlpha(GL_NONE)
29{
30}
31
32TextureStorage11::SwizzleCacheValue::SwizzleCacheValue(GLenum red, GLenum green, GLenum blue, GLenum alpha)
33 : swizzleRed(red), swizzleGreen(green), swizzleBlue(blue), swizzleAlpha(alpha)
34{
35}
36
37bool TextureStorage11::SwizzleCacheValue::operator==(const SwizzleCacheValue &other) const
38{
39 return swizzleRed == other.swizzleRed &&
40 swizzleGreen == other.swizzleGreen &&
41 swizzleBlue == other.swizzleBlue &&
42 swizzleAlpha == other.swizzleAlpha;
43}
44
45bool TextureStorage11::SwizzleCacheValue::operator!=(const SwizzleCacheValue &other) const
46{
47 return !(*this == other);
48}
49
Nicolas Capensa9f85c62014-04-11 17:23:29 -040050TextureStorage11::SRVKey::SRVKey(int baseLevel, int mipLevels, bool swizzle)
51 : baseLevel(baseLevel), mipLevels(mipLevels), swizzle(swizzle)
52{
53}
54
55bool TextureStorage11::SRVKey::operator==(const SRVKey &rhs) const
56{
57 return baseLevel == rhs.baseLevel &&
58 mipLevels == rhs.mipLevels &&
59 swizzle == rhs.swizzle;
60}
61
62TextureStorage11::SRVCache::~SRVCache()
63{
64 for (size_t i = 0; i < cache.size(); i++)
65 {
66 SafeRelease(cache[i].srv);
67 }
68}
69
70ID3D11ShaderResourceView *TextureStorage11::SRVCache::find(const SRVKey &key) const
71{
72 for (size_t i = 0; i < cache.size(); i++)
73 {
74 if (cache[i].key == key)
75 {
76 return cache[i].srv;
77 }
78 }
79
80 return NULL;
81}
82
83ID3D11ShaderResourceView *TextureStorage11::SRVCache::add(const SRVKey &key, ID3D11ShaderResourceView *srv)
84{
85 SRVPair pair = {key, srv};
86 cache.push_back(pair);
87
88 return srv;
89}
90
Nicolas Capensfa7b76d2014-03-31 14:51:45 -040091TextureStorage11::TextureStorage11(Renderer *renderer, UINT bindFlags)
daniel@transgaming.com4834ee22013-01-11 04:06:16 +000092 : mBindFlags(bindFlags),
Nicolas Capensf61738a2014-03-31 14:50:18 -040093 mTopLevel(0),
shannon.woods@transgaming.com53b0ecb2013-02-28 23:13:21 +000094 mMipLevels(0),
shannon.woods@transgaming.com53b0ecb2013-02-28 23:13:21 +000095 mTextureFormat(DXGI_FORMAT_UNKNOWN),
96 mShaderResourceFormat(DXGI_FORMAT_UNKNOWN),
97 mRenderTargetFormat(DXGI_FORMAT_UNKNOWN),
98 mDepthStencilFormat(DXGI_FORMAT_UNKNOWN),
99 mTextureWidth(0),
shannon.woods%transgaming.com@gtempaccount.com2058d642013-04-13 03:42:50 +0000100 mTextureHeight(0),
101 mTextureDepth(0)
daniel@transgaming.com4834ee22013-01-11 04:06:16 +0000102{
103 mRenderer = Renderer11::makeRenderer11(renderer);
Nicolas Capens41d9f7e2014-04-11 17:32:55 -0400104
105 for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
106 {
107 mLevelSRVs[i] = NULL;
108 }
daniel@transgaming.com4834ee22013-01-11 04:06:16 +0000109}
110
111TextureStorage11::~TextureStorage11()
112{
Nicolas Capens41d9f7e2014-04-11 17:32:55 -0400113 for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
114 {
115 SafeRelease(mLevelSRVs[level]);
116 }
daniel@transgaming.com1e1b5e92013-01-11 04:11:27 +0000117}
daniel@transgaming.com4834ee22013-01-11 04:06:16 +0000118
119TextureStorage11 *TextureStorage11::makeTextureStorage11(TextureStorage *storage)
120{
apatrick@chromium.org8b400b12013-01-30 21:53:40 +0000121 ASSERT(HAS_DYNAMIC_TYPE(TextureStorage11*, storage));
daniel@transgaming.com4834ee22013-01-11 04:06:16 +0000122 return static_cast<TextureStorage11*>(storage);
123}
124
Geoff Lange4a492b2014-06-19 14:14:41 -0400125DWORD TextureStorage11::GetTextureBindFlags(GLenum internalFormat, bool renderTarget)
daniel@transgaming.com4834ee22013-01-11 04:06:16 +0000126{
shannonwoods@chromium.orgadc56352013-05-30 00:09:08 +0000127 UINT bindFlags = 0;
128
Geoff Lange4a492b2014-06-19 14:14:41 -0400129 if (gl_d3d11::GetSRVFormat(internalFormat) != DXGI_FORMAT_UNKNOWN)
shannonwoods@chromium.orgadc56352013-05-30 00:09:08 +0000130 {
131 bindFlags |= D3D11_BIND_SHADER_RESOURCE;
132 }
Geoff Lange4a492b2014-06-19 14:14:41 -0400133 if (gl_d3d11::GetDSVFormat(internalFormat) != DXGI_FORMAT_UNKNOWN)
daniel@transgaming.com4834ee22013-01-11 04:06:16 +0000134 {
135 bindFlags |= D3D11_BIND_DEPTH_STENCIL;
136 }
Geoff Lange4a492b2014-06-19 14:14:41 -0400137 if (gl_d3d11::GetRTVFormat(internalFormat) != DXGI_FORMAT_UNKNOWN && renderTarget)
daniel@transgaming.com4834ee22013-01-11 04:06:16 +0000138 {
139 bindFlags |= D3D11_BIND_RENDER_TARGET;
140 }
daniel@transgaming.com4834ee22013-01-11 04:06:16 +0000141
shannonwoods@chromium.orgadc56352013-05-30 00:09:08 +0000142 return bindFlags;
daniel@transgaming.com4834ee22013-01-11 04:06:16 +0000143}
144
145UINT TextureStorage11::getBindFlags() const
146{
147 return mBindFlags;
148}
Nicolas Capensf61738a2014-03-31 14:50:18 -0400149
150int TextureStorage11::getTopLevel() const
daniel@transgaming.com4834ee22013-01-11 04:06:16 +0000151{
Nicolas Capensf61738a2014-03-31 14:50:18 -0400152 return mTopLevel;
daniel@transgaming.com4834ee22013-01-11 04:06:16 +0000153}
154
155bool TextureStorage11::isRenderTarget() const
156{
157 return (mBindFlags & (D3D11_BIND_RENDER_TARGET | D3D11_BIND_DEPTH_STENCIL)) != 0;
158}
shannon.woods%transgaming.com@gtempaccount.com2058d642013-04-13 03:42:50 +0000159
daniel@transgaming.com4834ee22013-01-11 04:06:16 +0000160bool TextureStorage11::isManaged() const
161{
162 return false;
163}
164
Nicolas Capensbf712d02014-03-31 14:23:35 -0400165int TextureStorage11::getLevelCount() const
daniel@transgaming.com4834ee22013-01-11 04:06:16 +0000166{
Nicolas Capensfa7b76d2014-03-31 14:51:45 -0400167 return mMipLevels - mTopLevel;
daniel@transgaming.com4834ee22013-01-11 04:06:16 +0000168}
169
Jamie Madillb16b8ed2013-10-24 17:49:45 -0400170int TextureStorage11::getLevelWidth(int mipLevel) const
171{
Nicolas Capensfa7b76d2014-03-31 14:51:45 -0400172 return std::max(static_cast<int>(mTextureWidth) >> mipLevel, 1);
Jamie Madillb16b8ed2013-10-24 17:49:45 -0400173}
174
175int TextureStorage11::getLevelHeight(int mipLevel) const
176{
Nicolas Capensfa7b76d2014-03-31 14:51:45 -0400177 return std::max(static_cast<int>(mTextureHeight) >> mipLevel, 1);
Jamie Madillb16b8ed2013-10-24 17:49:45 -0400178}
179
180int TextureStorage11::getLevelDepth(int mipLevel) const
181{
Nicolas Capensfa7b76d2014-03-31 14:51:45 -0400182 return std::max(static_cast<int>(mTextureDepth) >> mipLevel, 1);
Jamie Madillb16b8ed2013-10-24 17:49:45 -0400183}
184
Jamie Madill4cfff5f2013-10-24 17:49:46 -0400185UINT TextureStorage11::getSubresourceIndex(int mipLevel, int layerTarget) const
daniel@transgaming.com9a2f54d2013-01-11 04:06:36 +0000186{
187 UINT index = 0;
Nicolas Capens76b258f2014-04-03 10:59:42 -0400188 if (getResource())
daniel@transgaming.com9a2f54d2013-01-11 04:06:36 +0000189 {
shannon.woods%transgaming.com@gtempaccount.com6c86bd52013-04-13 03:45:45 +0000190 index = D3D11CalcSubresource(mipLevel, layerTarget, mMipLevels);
daniel@transgaming.com9a2f54d2013-01-11 04:06:36 +0000191 }
192 return index;
193}
194
Nicolas Capens41d9f7e2014-04-11 17:32:55 -0400195ID3D11ShaderResourceView *TextureStorage11::getSRV(const gl::SamplerState &samplerState)
196{
197 bool swizzleRequired = samplerState.swizzleRequired();
Brandon Jones142ec422014-07-16 10:31:30 -0700198 bool mipmapping = IsMipmapFiltered(samplerState);
Nicolas Capens35adc092014-04-11 17:49:31 -0400199 unsigned int mipLevels = mipmapping ? (samplerState.maxLevel - samplerState.baseLevel) : 1;
200
201 // Make sure there's 'mipLevels' mipmap levels below the base level (offset by the top level, which corresponds to GL level 0)
202 mipLevels = std::min(mipLevels, mMipLevels - mTopLevel - samplerState.baseLevel);
Nicolas Capens41d9f7e2014-04-11 17:32:55 -0400203
204 if (swizzleRequired)
205 {
206 verifySwizzleExists(samplerState.swizzleRed, samplerState.swizzleGreen, samplerState.swizzleBlue, samplerState.swizzleAlpha);
207 }
208
Nicolas Capens35adc092014-04-11 17:49:31 -0400209 SRVKey key(samplerState.baseLevel, mipLevels, swizzleRequired);
Nicolas Capens41d9f7e2014-04-11 17:32:55 -0400210 ID3D11ShaderResourceView *srv = srvCache.find(key);
211
212 if(srv)
213 {
214 return srv;
215 }
216
217 DXGI_FORMAT format = (swizzleRequired ? mSwizzleShaderResourceFormat : mShaderResourceFormat);
218 ID3D11Resource *texture = swizzleRequired ? getSwizzleTexture() : getResource();
219
Nicolas Capens35adc092014-04-11 17:49:31 -0400220 srv = createSRV(samplerState.baseLevel, mipLevels, format, texture);
Nicolas Capens41d9f7e2014-04-11 17:32:55 -0400221
222 return srvCache.add(key, srv);
223}
224
225ID3D11ShaderResourceView *TextureStorage11::getSRVLevel(int mipLevel)
226{
227 if (mipLevel >= 0 && mipLevel < getLevelCount())
228 {
229 if (!mLevelSRVs[mipLevel])
230 {
231 mLevelSRVs[mipLevel] = createSRV(mipLevel, 1, mShaderResourceFormat, getResource());
232 }
233
234 return mLevelSRVs[mipLevel];
235 }
236 else
237 {
238 return NULL;
239 }
240}
241
Geoff Lang644bbf22013-09-17 17:02:43 -0400242void TextureStorage11::generateSwizzles(GLenum swizzleRed, GLenum swizzleGreen, GLenum swizzleBlue, GLenum swizzleAlpha)
243{
244 SwizzleCacheValue swizzleTarget(swizzleRed, swizzleGreen, swizzleBlue, swizzleAlpha);
Nicolas Capensbf712d02014-03-31 14:23:35 -0400245 for (int level = 0; level < getLevelCount(); level++)
Geoff Lang644bbf22013-09-17 17:02:43 -0400246 {
247 // Check if the swizzle for this level is out of date
248 if (mSwizzleCache[level] != swizzleTarget)
249 {
250 // Need to re-render the swizzle for this level
251 ID3D11ShaderResourceView *sourceSRV = getSRVLevel(level);
252 ID3D11RenderTargetView *destRTV = getSwizzleRenderTarget(level);
253
254 gl::Extents size(getLevelWidth(level), getLevelHeight(level), getLevelDepth(level));
255
256 Blit11 *blitter = mRenderer->getBlitter();
257
258 if (blitter->swizzleTexture(sourceSRV, destRTV, size, swizzleRed, swizzleGreen, swizzleBlue, swizzleAlpha))
259 {
260 mSwizzleCache[level] = swizzleTarget;
261 }
262 else
263 {
264 ERR("Failed to swizzle texture.");
265 }
266 }
267 }
268}
269
270void TextureStorage11::invalidateSwizzleCacheLevel(int mipLevel)
271{
272 if (mipLevel >= 0 && static_cast<unsigned int>(mipLevel) < ArraySize(mSwizzleCache))
273 {
274 // The default constructor of SwizzleCacheValue has GL_NONE for all channels which is not a
275 // valid swizzle combination
276 mSwizzleCache[mipLevel] = SwizzleCacheValue();
277 }
278}
279
280void TextureStorage11::invalidateSwizzleCache()
281{
282 for (unsigned int mipLevel = 0; mipLevel < ArraySize(mSwizzleCache); mipLevel++)
283 {
284 invalidateSwizzleCacheLevel(mipLevel);
285 }
286}
287
shannon.woods%transgaming.com@gtempaccount.com2058d642013-04-13 03:42:50 +0000288bool TextureStorage11::updateSubresourceLevel(ID3D11Resource *srcTexture, unsigned int sourceSubresource,
shannon.woods%transgaming.com@gtempaccount.com6c86bd52013-04-13 03:45:45 +0000289 int level, int layerTarget, GLint xoffset, GLint yoffset, GLint zoffset,
shannon.woods%transgaming.com@gtempaccount.com2058d642013-04-13 03:42:50 +0000290 GLsizei width, GLsizei height, GLsizei depth)
daniel@transgaming.com9a2f54d2013-01-11 04:06:36 +0000291{
292 if (srcTexture)
293 {
Geoff Lang644bbf22013-09-17 17:02:43 -0400294 invalidateSwizzleCacheLevel(level);
295
Jamie Madillb16b8ed2013-10-24 17:49:45 -0400296 gl::Extents texSize(getLevelWidth(level), getLevelHeight(level), getLevelDepth(level));
Geoff Lang79031cb2013-08-12 12:55:17 -0400297 gl::Box copyArea(xoffset, yoffset, zoffset, width, height, depth);
daniel@transgaming.com9a2f54d2013-01-11 04:06:36 +0000298
Geoff Lang79031cb2013-08-12 12:55:17 -0400299 bool fullCopy = copyArea.x == 0 &&
300 copyArea.y == 0 &&
301 copyArea.z == 0 &&
302 copyArea.width == texSize.width &&
303 copyArea.height == texSize.height &&
304 copyArea.depth == texSize.depth;
shannon.woods%transgaming.com@gtempaccount.com2058d642013-04-13 03:42:50 +0000305
Nicolas Capens76b258f2014-04-03 10:59:42 -0400306 ID3D11Resource *dstTexture = getResource();
Nicolas Capensf61738a2014-03-31 14:50:18 -0400307 unsigned int dstSubresource = getSubresourceIndex(level + mTopLevel, layerTarget);
Geoff Lang79031cb2013-08-12 12:55:17 -0400308
309 ASSERT(dstTexture);
310
311 if (!fullCopy && (d3d11::GetDepthBits(mTextureFormat) > 0 || d3d11::GetStencilBits(mTextureFormat) > 0))
312 {
313 // CopySubresourceRegion cannot copy partial depth stencils, use the blitter instead
314 Blit11 *blitter = mRenderer->getBlitter();
315
316 return blitter->copyDepthStencil(srcTexture, sourceSubresource, copyArea, texSize,
Geoff Lang125deab2013-08-09 13:34:16 -0400317 dstTexture, dstSubresource, copyArea, texSize,
318 NULL);
Geoff Lang79031cb2013-08-12 12:55:17 -0400319 }
320 else
321 {
322 D3D11_BOX srcBox;
323 srcBox.left = copyArea.x;
324 srcBox.top = copyArea.y;
Jamie Madill9eeecfc2014-01-29 09:26:48 -0500325 srcBox.right = copyArea.x + roundUp((unsigned int)width, d3d11::GetBlockWidth(mTextureFormat));
326 srcBox.bottom = copyArea.y + roundUp((unsigned int)height, d3d11::GetBlockHeight(mTextureFormat));
Geoff Lang79031cb2013-08-12 12:55:17 -0400327 srcBox.front = copyArea.z;
328 srcBox.back = copyArea.z + copyArea.depth;
329
330 ID3D11DeviceContext *context = mRenderer->getDeviceContext();
331
332 context->CopySubresourceRegion(dstTexture, dstSubresource, copyArea.x, copyArea.y, copyArea.z,
333 srcTexture, sourceSubresource, fullCopy ? NULL : &srcBox);
334 return true;
335 }
daniel@transgaming.com9a2f54d2013-01-11 04:06:36 +0000336 }
337
338 return false;
339}
340
shannon.woods@transgaming.com85bdfce2013-01-25 21:51:07 +0000341void TextureStorage11::generateMipmapLayer(RenderTarget11 *source, RenderTarget11 *dest)
342{
343 if (source && dest)
344 {
345 ID3D11ShaderResourceView *sourceSRV = source->getShaderResourceView();
346 ID3D11RenderTargetView *destRTV = dest->getRenderTargetView();
347
348 if (sourceSRV && destRTV)
349 {
Geoff Langb86b9792013-06-04 16:32:05 -0400350 gl::Box sourceArea(0, 0, 0, source->getWidth(), source->getHeight(), source->getDepth());
351 gl::Extents sourceSize(source->getWidth(), source->getHeight(), source->getDepth());
shannon.woods@transgaming.com85bdfce2013-01-25 21:51:07 +0000352
Geoff Langb86b9792013-06-04 16:32:05 -0400353 gl::Box destArea(0, 0, 0, dest->getWidth(), dest->getHeight(), dest->getDepth());
354 gl::Extents destSize(dest->getWidth(), dest->getHeight(), dest->getDepth());
shannon.woods@transgaming.com85bdfce2013-01-25 21:51:07 +0000355
Geoff Langb86b9792013-06-04 16:32:05 -0400356 Blit11 *blitter = mRenderer->getBlitter();
357
Geoff Lang125deab2013-08-09 13:34:16 -0400358 blitter->copyTexture(sourceSRV, sourceArea, sourceSize, destRTV, destArea, destSize, NULL,
Geoff Lang5d601382014-07-22 15:14:06 -0400359 gl::GetInternalFormatInfo(source->getInternalFormat()).format, GL_LINEAR);
shannon.woods@transgaming.com85bdfce2013-01-25 21:51:07 +0000360 }
shannon.woods@transgaming.com85bdfce2013-01-25 21:51:07 +0000361 }
362}
363
Geoff Lang644bbf22013-09-17 17:02:43 -0400364void TextureStorage11::verifySwizzleExists(GLenum swizzleRed, GLenum swizzleGreen, GLenum swizzleBlue, GLenum swizzleAlpha)
365{
366 SwizzleCacheValue swizzleTarget(swizzleRed, swizzleGreen, swizzleBlue, swizzleAlpha);
367 for (unsigned int level = 0; level < mMipLevels; level++)
368 {
369 ASSERT(mSwizzleCache[level] == swizzleTarget);
370 }
371}
372
daniel@transgaming.com4834ee22013-01-11 04:06:16 +0000373TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, SwapChain11 *swapchain)
Nicolas Capensfa7b76d2014-03-31 14:51:45 -0400374 : TextureStorage11(renderer, D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE)
daniel@transgaming.com4834ee22013-01-11 04:06:16 +0000375{
shannon.woods@transgaming.com5b2d8552013-02-28 23:12:32 +0000376 mTexture = swapchain->getOffscreenTexture();
Geoff Lang2916b302013-11-28 13:41:10 -0500377 mTexture->AddRef();
Geoff Lang644bbf22013-09-17 17:02:43 -0400378 mSwizzleTexture = NULL;
Nicolas Capense47e7362014-03-27 13:34:56 -0400379
shannon.woods@transgaming.com858d32f2013-01-25 21:49:59 +0000380 for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
381 {
382 mRenderTarget[i] = NULL;
Geoff Lang644bbf22013-09-17 17:02:43 -0400383 mSwizzleRenderTargets[i] = NULL;
shannon.woods@transgaming.com858d32f2013-01-25 21:49:59 +0000384 }
daniel@transgaming.com4834ee22013-01-11 04:06:16 +0000385
shannon.woods@transgaming.com5b2d8552013-02-28 23:12:32 +0000386 D3D11_TEXTURE2D_DESC texDesc;
387 mTexture->GetDesc(&texDesc);
388 mMipLevels = texDesc.MipLevels;
389 mTextureFormat = texDesc.Format;
390 mTextureWidth = texDesc.Width;
391 mTextureHeight = texDesc.Height;
shannon.woods%transgaming.com@gtempaccount.com2058d642013-04-13 03:42:50 +0000392 mTextureDepth = 1;
daniel@transgaming.com4834ee22013-01-11 04:06:16 +0000393
Nicolas Capense47e7362014-03-27 13:34:56 -0400394 ID3D11ShaderResourceView *srv = swapchain->getRenderTargetShaderResource();
shannon.woods@transgaming.com5b2d8552013-02-28 23:12:32 +0000395 D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
Nicolas Capense47e7362014-03-27 13:34:56 -0400396 srv->GetDesc(&srvDesc);
shannon.woods@transgaming.com5b2d8552013-02-28 23:12:32 +0000397 mShaderResourceFormat = srvDesc.Format;
398
399 ID3D11RenderTargetView* offscreenRTV = swapchain->getRenderTarget();
400 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
401 offscreenRTV->GetDesc(&rtvDesc);
402 mRenderTargetFormat = rtvDesc.Format;
shannon.woods@transgaming.com5b2d8552013-02-28 23:12:32 +0000403
Geoff Lange4a492b2014-06-19 14:14:41 -0400404 GLenum internalFormat = d3d11_gl::GetInternalFormat(mTextureFormat);
405 mSwizzleTextureFormat = gl_d3d11::GetSwizzleTexFormat(internalFormat);
406 mSwizzleShaderResourceFormat = gl_d3d11::GetSwizzleSRVFormat(internalFormat);
407 mSwizzleRenderTargetFormat = gl_d3d11::GetSwizzleRTVFormat(internalFormat);
Geoff Lang644bbf22013-09-17 17:02:43 -0400408
shannon.woods@transgaming.com5b2d8552013-02-28 23:12:32 +0000409 mDepthStencilFormat = DXGI_FORMAT_UNKNOWN;
daniel@transgaming.com4834ee22013-01-11 04:06:16 +0000410}
411
Nicolas Capensbf712d02014-03-31 14:23:35 -0400412TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels)
Geoff Lange4a492b2014-06-19 14:14:41 -0400413 : TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderTarget))
daniel@transgaming.com4834ee22013-01-11 04:06:16 +0000414{
shannon.woods%transgaming.com@gtempaccount.com2058d642013-04-13 03:42:50 +0000415 mTexture = NULL;
Geoff Lang644bbf22013-09-17 17:02:43 -0400416 mSwizzleTexture = NULL;
Nicolas Capense47e7362014-03-27 13:34:56 -0400417
shannon.woods@transgaming.com858d32f2013-01-25 21:49:59 +0000418 for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
419 {
420 mRenderTarget[i] = NULL;
Geoff Lang644bbf22013-09-17 17:02:43 -0400421 mSwizzleRenderTargets[i] = NULL;
shannon.woods@transgaming.com858d32f2013-01-25 21:49:59 +0000422 }
423
Geoff Lange4a492b2014-06-19 14:14:41 -0400424 mTextureFormat = gl_d3d11::GetTexFormat(internalformat);
425 mShaderResourceFormat = gl_d3d11::GetSRVFormat(internalformat);
426 mDepthStencilFormat = gl_d3d11::GetDSVFormat(internalformat);
427 mRenderTargetFormat = gl_d3d11::GetRTVFormat(internalformat);
428 mSwizzleTextureFormat = gl_d3d11::GetSwizzleTexFormat(internalformat);
429 mSwizzleShaderResourceFormat = gl_d3d11::GetSwizzleSRVFormat(internalformat);
430 mSwizzleRenderTargetFormat = gl_d3d11::GetSwizzleRTVFormat(internalformat);
shannon.woods@transgaming.com5b2d8552013-02-28 23:12:32 +0000431
daniel@transgaming.com4834ee22013-01-11 04:06:16 +0000432 // if the width or height is not positive this should be treated as an incomplete texture
433 // we handle that here by skipping the d3d texture creation
434 if (width > 0 && height > 0)
435 {
436 // adjust size if needed for compressed textures
Nicolas Capensf61738a2014-03-31 14:50:18 -0400437 d3d11::MakeValidSize(false, mTextureFormat, &width, &height, &mTopLevel);
daniel@transgaming.com4834ee22013-01-11 04:06:16 +0000438
439 ID3D11Device *device = mRenderer->getDevice();
440
441 D3D11_TEXTURE2D_DESC desc;
442 desc.Width = width; // Compressed texture size constraints?
443 desc.Height = height;
Nicolas Capensbf712d02014-03-31 14:23:35 -0400444 desc.MipLevels = ((levels > 0) ? (mTopLevel + levels) : 0);
daniel@transgaming.com4834ee22013-01-11 04:06:16 +0000445 desc.ArraySize = 1;
shannon.woods@transgaming.com5b2d8552013-02-28 23:12:32 +0000446 desc.Format = mTextureFormat;
daniel@transgaming.com4834ee22013-01-11 04:06:16 +0000447 desc.SampleDesc.Count = 1;
448 desc.SampleDesc.Quality = 0;
449 desc.Usage = D3D11_USAGE_DEFAULT;
450 desc.BindFlags = getBindFlags();
451 desc.CPUAccessFlags = 0;
452 desc.MiscFlags = 0;
453
454 HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture);
455
shannon.woods@transgaming.comddd6c802013-02-28 23:05:14 +0000456 // this can happen from windows TDR
457 if (d3d11::isDeviceLostError(result))
458 {
459 mRenderer->notifyDeviceLost();
460 gl::error(GL_OUT_OF_MEMORY);
461 }
462 else if (FAILED(result))
daniel@transgaming.com4834ee22013-01-11 04:06:16 +0000463 {
464 ASSERT(result == E_OUTOFMEMORY);
465 ERR("Creating image failed.");
shannon.woods@transgaming.com779aa262013-02-28 23:04:58 +0000466 gl::error(GL_OUT_OF_MEMORY);
daniel@transgaming.com4834ee22013-01-11 04:06:16 +0000467 }
daniel@transgaming.comb1154552013-01-11 04:11:02 +0000468 else
469 {
470 mTexture->GetDesc(&desc);
471 mMipLevels = desc.MipLevels;
shannon.woods@transgaming.com858d32f2013-01-25 21:49:59 +0000472 mTextureWidth = desc.Width;
473 mTextureHeight = desc.Height;
shannon.woods%transgaming.com@gtempaccount.com2058d642013-04-13 03:42:50 +0000474 mTextureDepth = 1;
daniel@transgaming.comb1154552013-01-11 04:11:02 +0000475 }
daniel@transgaming.com4834ee22013-01-11 04:06:16 +0000476 }
daniel@transgaming.com4834ee22013-01-11 04:06:16 +0000477}
478
479TextureStorage11_2D::~TextureStorage11_2D()
480{
Geoff Langea228632013-07-30 15:17:12 -0400481 SafeRelease(mTexture);
Geoff Lang644bbf22013-09-17 17:02:43 -0400482 SafeRelease(mSwizzleTexture);
Nicolas Capense47e7362014-03-27 13:34:56 -0400483
shannon.woods@transgaming.com858d32f2013-01-25 21:49:59 +0000484 for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
shannon.woods@transgaming.com4b472352013-01-25 21:14:56 +0000485 {
Geoff Langea228632013-07-30 15:17:12 -0400486 SafeDelete(mRenderTarget[i]);
Geoff Lang644bbf22013-09-17 17:02:43 -0400487 SafeRelease(mSwizzleRenderTargets[i]);
shannon.woods@transgaming.com4b472352013-01-25 21:14:56 +0000488 }
daniel@transgaming.com4834ee22013-01-11 04:06:16 +0000489}
490
491TextureStorage11_2D *TextureStorage11_2D::makeTextureStorage11_2D(TextureStorage *storage)
492{
apatrick@chromium.org8b400b12013-01-30 21:53:40 +0000493 ASSERT(HAS_DYNAMIC_TYPE(TextureStorage11_2D*, storage));
daniel@transgaming.com4834ee22013-01-11 04:06:16 +0000494 return static_cast<TextureStorage11_2D*>(storage);
495}
496
Nicolas Capens76b258f2014-04-03 10:59:42 -0400497ID3D11Resource *TextureStorage11_2D::getResource() const
shannon.woods%transgaming.com@gtempaccount.com2058d642013-04-13 03:42:50 +0000498{
499 return mTexture;
500}
501
shannon.woods@transgaming.com858d32f2013-01-25 21:49:59 +0000502RenderTarget *TextureStorage11_2D::getRenderTarget(int level)
daniel@transgaming.com4834ee22013-01-11 04:06:16 +0000503{
Nicolas Capensbf712d02014-03-31 14:23:35 -0400504 if (level >= 0 && level < getLevelCount())
shannon.woods@transgaming.com4b472352013-01-25 21:14:56 +0000505 {
shannon.woods@transgaming.com858d32f2013-01-25 21:49:59 +0000506 if (!mRenderTarget[level])
507 {
Geoff Lang644bbf22013-09-17 17:02:43 -0400508 ID3D11ShaderResourceView *srv = getSRVLevel(level);
509 if (!srv)
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000510 {
Geoff Lang644bbf22013-09-17 17:02:43 -0400511 return NULL;
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000512 }
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000513
shannon.woods@transgaming.com5b2d8552013-02-28 23:12:32 +0000514 if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN)
515 {
Geoff Lang644bbf22013-09-17 17:02:43 -0400516 ID3D11Device *device = mRenderer->getDevice();
517
shannon.woods@transgaming.com5b2d8552013-02-28 23:12:32 +0000518 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
519 rtvDesc.Format = mRenderTargetFormat;
520 rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
Nicolas Capensfa7b76d2014-03-31 14:51:45 -0400521 rtvDesc.Texture2D.MipSlice = mTopLevel + level;
shannon.woods@transgaming.com7e232852013-02-28 23:06:15 +0000522
shannon.woods@transgaming.com5b2d8552013-02-28 23:12:32 +0000523 ID3D11RenderTargetView *rtv;
Geoff Lang644bbf22013-09-17 17:02:43 -0400524 HRESULT result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv);
shannon.woods@transgaming.com5b2d8552013-02-28 23:12:32 +0000525
526 if (result == E_OUTOFMEMORY)
527 {
shannon.woods@transgaming.com5b2d8552013-02-28 23:12:32 +0000528 return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
529 }
530 ASSERT(SUCCEEDED(result));
531
Jamie Madillb16b8ed2013-10-24 17:49:45 -0400532 mRenderTarget[level] = new RenderTarget11(mRenderer, rtv, mTexture, srv, getLevelWidth(level), getLevelHeight(level), 1);
Geoff Lang2916b302013-11-28 13:41:10 -0500533
534 // RenderTarget will take ownership of these resources
535 SafeRelease(rtv);
shannon.woods@transgaming.com5b2d8552013-02-28 23:12:32 +0000536 }
537 else if (mDepthStencilFormat != DXGI_FORMAT_UNKNOWN)
538 {
Geoff Lang644bbf22013-09-17 17:02:43 -0400539 ID3D11Device *device = mRenderer->getDevice();
540
shannon.woods@transgaming.com5b2d8552013-02-28 23:12:32 +0000541 D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
542 dsvDesc.Format = mDepthStencilFormat;
543 dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
Nicolas Capensfa7b76d2014-03-31 14:51:45 -0400544 dsvDesc.Texture2D.MipSlice = mTopLevel + level;
shannon.woods@transgaming.com5b2d8552013-02-28 23:12:32 +0000545 dsvDesc.Flags = 0;
546
547 ID3D11DepthStencilView *dsv;
Geoff Lang644bbf22013-09-17 17:02:43 -0400548 HRESULT result = device->CreateDepthStencilView(mTexture, &dsvDesc, &dsv);
shannon.woods@transgaming.com5b2d8552013-02-28 23:12:32 +0000549
550 if (result == E_OUTOFMEMORY)
551 {
Geoff Langea228632013-07-30 15:17:12 -0400552 SafeRelease(srv);
shannon.woods@transgaming.com5b2d8552013-02-28 23:12:32 +0000553 return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
554 }
555 ASSERT(SUCCEEDED(result));
556
Jamie Madillb16b8ed2013-10-24 17:49:45 -0400557 mRenderTarget[level] = new RenderTarget11(mRenderer, dsv, mTexture, srv, getLevelWidth(level), getLevelHeight(level), 1);
Geoff Lang2916b302013-11-28 13:41:10 -0500558
559 // RenderTarget will take ownership of these resources
560 SafeRelease(dsv);
shannon.woods@transgaming.com5b2d8552013-02-28 23:12:32 +0000561 }
562 else
563 {
564 UNREACHABLE();
565 }
shannon.woods@transgaming.com858d32f2013-01-25 21:49:59 +0000566 }
567
568 return mRenderTarget[level];
shannon.woods@transgaming.com4b472352013-01-25 21:14:56 +0000569 }
570 else
571 {
shannon.woods@transgaming.com858d32f2013-01-25 21:49:59 +0000572 return NULL;
shannon.woods@transgaming.com4b472352013-01-25 21:14:56 +0000573 }
daniel@transgaming.com4834ee22013-01-11 04:06:16 +0000574}
575
Nicolas Capens1d31aca2014-04-03 12:45:07 -0400576ID3D11ShaderResourceView *TextureStorage11_2D::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture)
577{
578 D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
579 srvDesc.Format = format;
580 srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
581 srvDesc.Texture2D.MostDetailedMip = mTopLevel + baseLevel;
582 srvDesc.Texture2D.MipLevels = mipLevels;
583
584 ID3D11ShaderResourceView *SRV = NULL;
585
586 ID3D11Device *device = mRenderer->getDevice();
587 HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, &SRV);
588
589 if (result == E_OUTOFMEMORY)
590 {
591 gl::error(GL_OUT_OF_MEMORY);
592 }
593 ASSERT(SUCCEEDED(result));
594
595 return SRV;
daniel@transgaming.comb50d5302013-01-11 04:07:29 +0000596}
597
daniel@transgaming.com4834ee22013-01-11 04:06:16 +0000598void TextureStorage11_2D::generateMipmap(int level)
599{
Geoff Lang644bbf22013-09-17 17:02:43 -0400600 invalidateSwizzleCacheLevel(level);
601
shannon.woods@transgaming.com85bdfce2013-01-25 21:51:07 +0000602 RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTarget(level - 1));
603 RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTarget(level));
604
605 generateMipmapLayer(source, dest);
daniel@transgaming.com4834ee22013-01-11 04:06:16 +0000606}
607
Nicolas Capens41d9f7e2014-04-11 17:32:55 -0400608ID3D11Resource *TextureStorage11_2D::getSwizzleTexture()
Geoff Lang644bbf22013-09-17 17:02:43 -0400609{
610 if (!mSwizzleTexture)
611 {
612 ID3D11Device *device = mRenderer->getDevice();
613
614 D3D11_TEXTURE2D_DESC desc;
615 desc.Width = mTextureWidth;
616 desc.Height = mTextureHeight;
Nicolas Capensbf712d02014-03-31 14:23:35 -0400617 desc.MipLevels = mMipLevels;
Geoff Lang644bbf22013-09-17 17:02:43 -0400618 desc.ArraySize = 1;
619 desc.Format = mSwizzleTextureFormat;
620 desc.SampleDesc.Count = 1;
621 desc.SampleDesc.Quality = 0;
622 desc.Usage = D3D11_USAGE_DEFAULT;
623 desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
624 desc.CPUAccessFlags = 0;
625 desc.MiscFlags = 0;
626
627 HRESULT result = device->CreateTexture2D(&desc, NULL, &mSwizzleTexture);
628
629 if (result == E_OUTOFMEMORY)
630 {
631 return gl::error(GL_OUT_OF_MEMORY, static_cast<ID3D11Texture2D*>(NULL));
632 }
633 ASSERT(SUCCEEDED(result));
634 }
635
636 return mSwizzleTexture;
637}
638
639ID3D11RenderTargetView *TextureStorage11_2D::getSwizzleRenderTarget(int mipLevel)
640{
Nicolas Capensbf712d02014-03-31 14:23:35 -0400641 if (mipLevel >= 0 && mipLevel < getLevelCount())
Geoff Lang644bbf22013-09-17 17:02:43 -0400642 {
643 if (!mSwizzleRenderTargets[mipLevel])
644 {
Nicolas Capens41d9f7e2014-04-11 17:32:55 -0400645 ID3D11Resource *swizzleTexture = getSwizzleTexture();
Geoff Lang644bbf22013-09-17 17:02:43 -0400646 if (!swizzleTexture)
647 {
648 return NULL;
649 }
650
651 ID3D11Device *device = mRenderer->getDevice();
652
653 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
654 rtvDesc.Format = mSwizzleRenderTargetFormat;
655 rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
Nicolas Capensfa7b76d2014-03-31 14:51:45 -0400656 rtvDesc.Texture2D.MipSlice = mTopLevel + mipLevel;
Geoff Lang644bbf22013-09-17 17:02:43 -0400657
658 HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]);
Geoff Langcebb5aa2014-04-07 14:13:40 -0400659 if (result == E_OUTOFMEMORY)
660 {
661 return gl::error(GL_OUT_OF_MEMORY, static_cast<ID3D11RenderTargetView*>(NULL));
662 }
663 ASSERT(SUCCEEDED(result));
Geoff Lang644bbf22013-09-17 17:02:43 -0400664 }
665
666 return mSwizzleRenderTargets[mipLevel];
667 }
668 else
669 {
670 return NULL;
671 }
672}
673
Geoff Lang644bbf22013-09-17 17:02:43 -0400674unsigned int TextureStorage11_2D::getTextureLevelDepth(int mipLevel) const
675{
676 return 1;
677}
678
Nicolas Capensbf712d02014-03-31 14:23:35 -0400679TextureStorage11_Cube::TextureStorage11_Cube(Renderer *renderer, GLenum internalformat, bool renderTarget, int size, int levels)
Geoff Lange4a492b2014-06-19 14:14:41 -0400680 : TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderTarget))
daniel@transgaming.comb2151e52013-01-11 04:06:24 +0000681{
shannon.woods%transgaming.com@gtempaccount.com2058d642013-04-13 03:42:50 +0000682 mTexture = NULL;
Geoff Lang644bbf22013-09-17 17:02:43 -0400683 mSwizzleTexture = NULL;
Nicolas Capense47e7362014-03-27 13:34:56 -0400684
Geoff Lang644bbf22013-09-17 17:02:43 -0400685 for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
daniel@transgaming.com5cdd0582013-01-11 04:07:35 +0000686 {
Geoff Lang644bbf22013-09-17 17:02:43 -0400687 mSwizzleRenderTargets[level] = NULL;
688 for (unsigned int face = 0; face < 6; face++)
shannon.woods@transgaming.com858d32f2013-01-25 21:49:59 +0000689 {
Geoff Lang644bbf22013-09-17 17:02:43 -0400690 mRenderTarget[face][level] = NULL;
shannon.woods@transgaming.com858d32f2013-01-25 21:49:59 +0000691 }
daniel@transgaming.com5cdd0582013-01-11 04:07:35 +0000692 }
693
Geoff Lange4a492b2014-06-19 14:14:41 -0400694 mTextureFormat = gl_d3d11::GetTexFormat(internalformat);
695 mShaderResourceFormat = gl_d3d11::GetSRVFormat(internalformat);
696 mDepthStencilFormat = gl_d3d11::GetDSVFormat(internalformat);
697 mRenderTargetFormat = gl_d3d11::GetRTVFormat(internalformat);
698 mSwizzleTextureFormat = gl_d3d11::GetSwizzleTexFormat(internalformat);
699 mSwizzleShaderResourceFormat = gl_d3d11::GetSwizzleSRVFormat(internalformat);
700 mSwizzleRenderTargetFormat = gl_d3d11::GetSwizzleRTVFormat(internalformat);
shannon.woods@transgaming.com5b2d8552013-02-28 23:12:32 +0000701
daniel@transgaming.comb2151e52013-01-11 04:06:24 +0000702 // if the size is not positive this should be treated as an incomplete texture
703 // we handle that here by skipping the d3d texture creation
704 if (size > 0)
705 {
706 // adjust size if needed for compressed textures
707 int height = size;
Nicolas Capensf61738a2014-03-31 14:50:18 -0400708 d3d11::MakeValidSize(false, mTextureFormat, &size, &height, &mTopLevel);
daniel@transgaming.comb2151e52013-01-11 04:06:24 +0000709
710 ID3D11Device *device = mRenderer->getDevice();
711
712 D3D11_TEXTURE2D_DESC desc;
713 desc.Width = size;
714 desc.Height = size;
Nicolas Capensbf712d02014-03-31 14:23:35 -0400715 desc.MipLevels = ((levels > 0) ? (mTopLevel + levels) : 0);
daniel@transgaming.comb2151e52013-01-11 04:06:24 +0000716 desc.ArraySize = 6;
shannon.woods@transgaming.com5b2d8552013-02-28 23:12:32 +0000717 desc.Format = mTextureFormat;
daniel@transgaming.comb2151e52013-01-11 04:06:24 +0000718 desc.SampleDesc.Count = 1;
719 desc.SampleDesc.Quality = 0;
720 desc.Usage = D3D11_USAGE_DEFAULT;
721 desc.BindFlags = getBindFlags();
722 desc.CPUAccessFlags = 0;
723 desc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
724
725 HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture);
726
727 if (FAILED(result))
728 {
729 ASSERT(result == E_OUTOFMEMORY);
730 ERR("Creating image failed.");
shannon.woods@transgaming.com779aa262013-02-28 23:04:58 +0000731 gl::error(GL_OUT_OF_MEMORY);
daniel@transgaming.comb2151e52013-01-11 04:06:24 +0000732 }
daniel@transgaming.comb1154552013-01-11 04:11:02 +0000733 else
734 {
735 mTexture->GetDesc(&desc);
736 mMipLevels = desc.MipLevels;
shannon.woods@transgaming.com858d32f2013-01-25 21:49:59 +0000737 mTextureWidth = desc.Width;
738 mTextureHeight = desc.Height;
shannon.woods%transgaming.com@gtempaccount.com2058d642013-04-13 03:42:50 +0000739 mTextureDepth = 1;
daniel@transgaming.comb1154552013-01-11 04:11:02 +0000740 }
daniel@transgaming.comb2151e52013-01-11 04:06:24 +0000741 }
daniel@transgaming.comb2151e52013-01-11 04:06:24 +0000742}
743
744TextureStorage11_Cube::~TextureStorage11_Cube()
745{
Geoff Langea228632013-07-30 15:17:12 -0400746 SafeRelease(mTexture);
Geoff Lang644bbf22013-09-17 17:02:43 -0400747 SafeRelease(mSwizzleTexture);
Nicolas Capense47e7362014-03-27 13:34:56 -0400748
Geoff Lang644bbf22013-09-17 17:02:43 -0400749 for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
shannon.woods@transgaming.com4b472352013-01-25 21:14:56 +0000750 {
Geoff Lang644bbf22013-09-17 17:02:43 -0400751 SafeRelease(mSwizzleRenderTargets[level]);
752 for (unsigned int face = 0; face < 6; face++)
shannon.woods@transgaming.com4b472352013-01-25 21:14:56 +0000753 {
Geoff Lang644bbf22013-09-17 17:02:43 -0400754 SafeDelete(mRenderTarget[face][level]);
shannon.woods@transgaming.com4b472352013-01-25 21:14:56 +0000755 }
756 }
daniel@transgaming.comb2151e52013-01-11 04:06:24 +0000757}
758
759TextureStorage11_Cube *TextureStorage11_Cube::makeTextureStorage11_Cube(TextureStorage *storage)
760{
apatrick@chromium.org8b400b12013-01-30 21:53:40 +0000761 ASSERT(HAS_DYNAMIC_TYPE(TextureStorage11_Cube*, storage));
daniel@transgaming.comb2151e52013-01-11 04:06:24 +0000762 return static_cast<TextureStorage11_Cube*>(storage);
763}
764
Nicolas Capens76b258f2014-04-03 10:59:42 -0400765ID3D11Resource *TextureStorage11_Cube::getResource() const
shannon.woods%transgaming.com@gtempaccount.com2058d642013-04-13 03:42:50 +0000766{
767 return mTexture;
768}
769
Nicolas Capensb13f8662013-06-04 13:30:19 -0400770RenderTarget *TextureStorage11_Cube::getRenderTargetFace(GLenum faceTarget, int level)
daniel@transgaming.comb2151e52013-01-11 04:06:24 +0000771{
Nicolas Capensbf712d02014-03-31 14:23:35 -0400772 if (level >= 0 && level < getLevelCount())
shannon.woods@transgaming.com4b472352013-01-25 21:14:56 +0000773 {
Jamie Madillf8bdfeb2014-07-31 18:31:28 +0000774 int faceIndex = TextureD3D_Cube::targetToIndex(faceTarget);
Jamie Madill2db197c2013-10-24 17:49:35 -0400775 if (!mRenderTarget[faceIndex][level])
shannon.woods@transgaming.com858d32f2013-01-25 21:49:59 +0000776 {
777 ID3D11Device *device = mRenderer->getDevice();
778 HRESULT result;
779
shannon.woods@transgaming.com5b2d8552013-02-28 23:12:32 +0000780 D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
781 srvDesc.Format = mShaderResourceFormat;
Shannon Woodsbfc93bb2013-10-09 11:36:53 -0400782 srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; // Will be used with Texture2D sampler, not TextureCube
Nicolas Capensfa7b76d2014-03-31 14:51:45 -0400783 srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + level;
shannon.woods@transgaming.com5b2d8552013-02-28 23:12:32 +0000784 srvDesc.Texture2DArray.MipLevels = 1;
Jamie Madill2db197c2013-10-24 17:49:35 -0400785 srvDesc.Texture2DArray.FirstArraySlice = faceIndex;
shannon.woods@transgaming.com5b2d8552013-02-28 23:12:32 +0000786 srvDesc.Texture2DArray.ArraySize = 1;
787
788 ID3D11ShaderResourceView *srv;
789 result = device->CreateShaderResourceView(mTexture, &srvDesc, &srv);
790
791 if (result == E_OUTOFMEMORY)
792 {
793 return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
794 }
795 ASSERT(SUCCEEDED(result));
796
797 if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN)
shannon.woods@transgaming.com858d32f2013-01-25 21:49:59 +0000798 {
799 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
shannon.woods@transgaming.com5b2d8552013-02-28 23:12:32 +0000800 rtvDesc.Format = mRenderTargetFormat;
shannon.woods@transgaming.com858d32f2013-01-25 21:49:59 +0000801 rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
Nicolas Capensfa7b76d2014-03-31 14:51:45 -0400802 rtvDesc.Texture2DArray.MipSlice = mTopLevel + level;
Jamie Madill2db197c2013-10-24 17:49:35 -0400803 rtvDesc.Texture2DArray.FirstArraySlice = faceIndex;
shannon.woods@transgaming.com858d32f2013-01-25 21:49:59 +0000804 rtvDesc.Texture2DArray.ArraySize = 1;
805
806 ID3D11RenderTargetView *rtv;
807 result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv);
808
809 if (result == E_OUTOFMEMORY)
810 {
Geoff Langea228632013-07-30 15:17:12 -0400811 SafeRelease(srv);
shannon.woods@transgaming.com779aa262013-02-28 23:04:58 +0000812 return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000813 }
814 ASSERT(SUCCEEDED(result));
815
Jamie Madillb16b8ed2013-10-24 17:49:45 -0400816 mRenderTarget[faceIndex][level] = new RenderTarget11(mRenderer, rtv, mTexture, srv, getLevelWidth(level), getLevelHeight(level), 1);
Geoff Lang2916b302013-11-28 13:41:10 -0500817
818 // RenderTarget will take ownership of these resources
819 SafeRelease(rtv);
820 SafeRelease(srv);
shannon.woods@transgaming.com858d32f2013-01-25 21:49:59 +0000821 }
shannon.woods@transgaming.com5b2d8552013-02-28 23:12:32 +0000822 else if (mDepthStencilFormat != DXGI_FORMAT_UNKNOWN)
shannon.woods@transgaming.com858d32f2013-01-25 21:49:59 +0000823 {
shannon.woods@transgaming.com5b2d8552013-02-28 23:12:32 +0000824 D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
Geoff Lang12949242013-07-29 15:22:42 -0400825 dsvDesc.Format = mDepthStencilFormat;
shannon.woods@transgaming.com5b2d8552013-02-28 23:12:32 +0000826 dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY;
Geoff Lang12949242013-07-29 15:22:42 -0400827 dsvDesc.Flags = 0;
Nicolas Capensfa7b76d2014-03-31 14:51:45 -0400828 dsvDesc.Texture2DArray.MipSlice = mTopLevel + level;
Jamie Madill2db197c2013-10-24 17:49:35 -0400829 dsvDesc.Texture2DArray.FirstArraySlice = faceIndex;
shannon.woods@transgaming.com5b2d8552013-02-28 23:12:32 +0000830 dsvDesc.Texture2DArray.ArraySize = 1;
831
832 ID3D11DepthStencilView *dsv;
833 result = device->CreateDepthStencilView(mTexture, &dsvDesc, &dsv);
834
835 if (result == E_OUTOFMEMORY)
836 {
Geoff Langea228632013-07-30 15:17:12 -0400837 SafeRelease(srv);
shannon.woods@transgaming.com5b2d8552013-02-28 23:12:32 +0000838 return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
839 }
840 ASSERT(SUCCEEDED(result));
841
Jamie Madillb16b8ed2013-10-24 17:49:45 -0400842 mRenderTarget[faceIndex][level] = new RenderTarget11(mRenderer, dsv, mTexture, srv, getLevelWidth(level), getLevelHeight(level), 1);
Geoff Lang2916b302013-11-28 13:41:10 -0500843
844 // RenderTarget will take ownership of these resources
845 SafeRelease(dsv);
846 SafeRelease(srv);
shannon.woods@transgaming.com858d32f2013-01-25 21:49:59 +0000847 }
shannon.woods@transgaming.com5b2d8552013-02-28 23:12:32 +0000848 else
849 {
850 UNREACHABLE();
851 }
shannon.woods@transgaming.com858d32f2013-01-25 21:49:59 +0000852 }
853
Jamie Madill2db197c2013-10-24 17:49:35 -0400854 return mRenderTarget[faceIndex][level];
shannon.woods@transgaming.com4b472352013-01-25 21:14:56 +0000855 }
856 else
857 {
shannon.woods@transgaming.com858d32f2013-01-25 21:49:59 +0000858 return NULL;
shannon.woods@transgaming.com4b472352013-01-25 21:14:56 +0000859 }
daniel@transgaming.comb2151e52013-01-11 04:06:24 +0000860}
861
Nicolas Capense83fb002014-04-11 17:28:13 -0400862ID3D11ShaderResourceView *TextureStorage11_Cube::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture)
Nicolas Capens1d31aca2014-04-03 12:45:07 -0400863{
864 D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
865 srvDesc.Format = format;
866
Nicolas Capense83fb002014-04-11 17:28:13 -0400867 // Unnormalized integer cube maps are not supported by DX11; we emulate them as an array of six 2D textures
868 bool unnormalizedInteger = (d3d11::GetComponentType(mTextureFormat) == GL_INT ||
869 d3d11::GetComponentType(mTextureFormat) == GL_UNSIGNED_INT);
870
871 if(unnormalizedInteger)
Nicolas Capens1d31aca2014-04-03 12:45:07 -0400872 {
873 srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
874 srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + baseLevel;
875 srvDesc.Texture2DArray.MipLevels = 1;
876 srvDesc.Texture2DArray.FirstArraySlice = 0;
877 srvDesc.Texture2DArray.ArraySize = 6;
878 }
879 else
880 {
881 srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
882 srvDesc.TextureCube.MipLevels = mipLevels;
883 srvDesc.TextureCube.MostDetailedMip = mTopLevel + baseLevel;
884 }
885
886 ID3D11ShaderResourceView *SRV = NULL;
887
888 ID3D11Device *device = mRenderer->getDevice();
889 HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, &SRV);
890
891 if (result == E_OUTOFMEMORY)
892 {
893 gl::error(GL_OUT_OF_MEMORY);
894 }
895 ASSERT(SUCCEEDED(result));
896
897 return SRV;
daniel@transgaming.comb50d5302013-01-11 04:07:29 +0000898}
899
Jamie Madill2db197c2013-10-24 17:49:35 -0400900void TextureStorage11_Cube::generateMipmap(int faceIndex, int level)
daniel@transgaming.comb2151e52013-01-11 04:06:24 +0000901{
Geoff Lang644bbf22013-09-17 17:02:43 -0400902 invalidateSwizzleCacheLevel(level);
903
Jamie Madill2db197c2013-10-24 17:49:35 -0400904 RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTargetFace(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, level - 1));
905 RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTargetFace(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, level));
shannon.woods@transgaming.com85bdfce2013-01-25 21:51:07 +0000906
907 generateMipmapLayer(source, dest);
daniel@transgaming.comb2151e52013-01-11 04:06:24 +0000908}
909
Nicolas Capens41d9f7e2014-04-11 17:32:55 -0400910ID3D11Resource *TextureStorage11_Cube::getSwizzleTexture()
Geoff Lang644bbf22013-09-17 17:02:43 -0400911{
912 if (!mSwizzleTexture)
913 {
914 ID3D11Device *device = mRenderer->getDevice();
915
916 D3D11_TEXTURE2D_DESC desc;
917 desc.Width = mTextureWidth;
918 desc.Height = mTextureHeight;
Nicolas Capensbf712d02014-03-31 14:23:35 -0400919 desc.MipLevels = mMipLevels;
Geoff Lang644bbf22013-09-17 17:02:43 -0400920 desc.ArraySize = 6;
921 desc.Format = mSwizzleTextureFormat;
922 desc.SampleDesc.Count = 1;
923 desc.SampleDesc.Quality = 0;
924 desc.Usage = D3D11_USAGE_DEFAULT;
925 desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
926 desc.CPUAccessFlags = 0;
927 desc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
928
929 HRESULT result = device->CreateTexture2D(&desc, NULL, &mSwizzleTexture);
930
931 if (result == E_OUTOFMEMORY)
932 {
933 return gl::error(GL_OUT_OF_MEMORY, static_cast<ID3D11Texture2D*>(NULL));
934 }
935 ASSERT(SUCCEEDED(result));
936 }
937
938 return mSwizzleTexture;
939}
940
941ID3D11RenderTargetView *TextureStorage11_Cube::getSwizzleRenderTarget(int mipLevel)
942{
Nicolas Capensbf712d02014-03-31 14:23:35 -0400943 if (mipLevel >= 0 && mipLevel < getLevelCount())
Geoff Lang644bbf22013-09-17 17:02:43 -0400944 {
945 if (!mSwizzleRenderTargets[mipLevel])
946 {
Nicolas Capens41d9f7e2014-04-11 17:32:55 -0400947 ID3D11Resource *swizzleTexture = getSwizzleTexture();
Geoff Lang644bbf22013-09-17 17:02:43 -0400948 if (!swizzleTexture)
949 {
950 return NULL;
951 }
952
953 ID3D11Device *device = mRenderer->getDevice();
954
955 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
956 rtvDesc.Format = mSwizzleRenderTargetFormat;
957 rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
Nicolas Capensfa7b76d2014-03-31 14:51:45 -0400958 rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel;
Geoff Lang644bbf22013-09-17 17:02:43 -0400959 rtvDesc.Texture2DArray.FirstArraySlice = 0;
960 rtvDesc.Texture2DArray.ArraySize = 6;
961
962 HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]);
Geoff Langcebb5aa2014-04-07 14:13:40 -0400963
964 if (result == E_OUTOFMEMORY)
965 {
966 return gl::error(GL_OUT_OF_MEMORY, static_cast<ID3D11RenderTargetView*>(NULL));
967 }
968 ASSERT(SUCCEEDED(result));
Geoff Lang644bbf22013-09-17 17:02:43 -0400969 }
970
971 return mSwizzleRenderTargets[mipLevel];
972 }
973 else
974 {
975 return NULL;
976 }
977}
978
Geoff Lang644bbf22013-09-17 17:02:43 -0400979unsigned int TextureStorage11_Cube::getTextureLevelDepth(int mipLevel) const
980{
981 return 6;
982}
983
Nicolas Capensbf712d02014-03-31 14:23:35 -0400984TextureStorage11_3D::TextureStorage11_3D(Renderer *renderer, GLenum internalformat, bool renderTarget,
985 GLsizei width, GLsizei height, GLsizei depth, int levels)
Geoff Lange4a492b2014-06-19 14:14:41 -0400986 : TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderTarget))
shannon.woods%transgaming.com@gtempaccount.com2058d642013-04-13 03:42:50 +0000987{
988 mTexture = NULL;
Geoff Lang644bbf22013-09-17 17:02:43 -0400989 mSwizzleTexture = NULL;
Nicolas Capense47e7362014-03-27 13:34:56 -0400990
shannonwoods@chromium.org15a8b1f2013-05-30 00:03:54 +0000991 for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
992 {
993 mLevelRenderTargets[i] = NULL;
Geoff Lang644bbf22013-09-17 17:02:43 -0400994 mSwizzleRenderTargets[i] = NULL;
shannonwoods@chromium.org15a8b1f2013-05-30 00:03:54 +0000995 }
996
Geoff Lange4a492b2014-06-19 14:14:41 -0400997 mTextureFormat = gl_d3d11::GetTexFormat(internalformat);
998 mShaderResourceFormat = gl_d3d11::GetSRVFormat(internalformat);
999 mDepthStencilFormat = gl_d3d11::GetDSVFormat(internalformat);
1000 mRenderTargetFormat = gl_d3d11::GetRTVFormat(internalformat);
1001 mSwizzleTextureFormat = gl_d3d11::GetSwizzleTexFormat(internalformat);
1002 mSwizzleShaderResourceFormat = gl_d3d11::GetSwizzleSRVFormat(internalformat);
1003 mSwizzleRenderTargetFormat = gl_d3d11::GetSwizzleRTVFormat(internalformat);
shannon.woods%transgaming.com@gtempaccount.com2058d642013-04-13 03:42:50 +00001004
1005 // If the width, height or depth are not positive this should be treated as an incomplete texture
1006 // we handle that here by skipping the d3d texture creation
1007 if (width > 0 && height > 0 && depth > 0)
1008 {
1009 // adjust size if needed for compressed textures
Nicolas Capensf61738a2014-03-31 14:50:18 -04001010 d3d11::MakeValidSize(false, mTextureFormat, &width, &height, &mTopLevel);
shannon.woods%transgaming.com@gtempaccount.com2058d642013-04-13 03:42:50 +00001011
1012 ID3D11Device *device = mRenderer->getDevice();
1013
1014 D3D11_TEXTURE3D_DESC desc;
1015 desc.Width = width;
1016 desc.Height = height;
1017 desc.Depth = depth;
Nicolas Capensbf712d02014-03-31 14:23:35 -04001018 desc.MipLevels = ((levels > 0) ? (mTopLevel + levels) : 0);
shannon.woods%transgaming.com@gtempaccount.com2058d642013-04-13 03:42:50 +00001019 desc.Format = mTextureFormat;
1020 desc.Usage = D3D11_USAGE_DEFAULT;
1021 desc.BindFlags = getBindFlags();
1022 desc.CPUAccessFlags = 0;
1023 desc.MiscFlags = 0;
1024
1025 HRESULT result = device->CreateTexture3D(&desc, NULL, &mTexture);
1026
1027 // this can happen from windows TDR
1028 if (d3d11::isDeviceLostError(result))
1029 {
1030 mRenderer->notifyDeviceLost();
1031 gl::error(GL_OUT_OF_MEMORY);
1032 }
1033 else if (FAILED(result))
1034 {
1035 ASSERT(result == E_OUTOFMEMORY);
1036 ERR("Creating image failed.");
1037 gl::error(GL_OUT_OF_MEMORY);
1038 }
1039 else
1040 {
1041 mTexture->GetDesc(&desc);
1042 mMipLevels = desc.MipLevels;
1043 mTextureWidth = desc.Width;
1044 mTextureHeight = desc.Height;
1045 mTextureDepth = desc.Depth;
1046 }
1047 }
1048}
1049
1050TextureStorage11_3D::~TextureStorage11_3D()
1051{
Geoff Langea228632013-07-30 15:17:12 -04001052 SafeRelease(mTexture);
Geoff Lang644bbf22013-09-17 17:02:43 -04001053 SafeRelease(mSwizzleTexture);
Nicolas Capense47e7362014-03-27 13:34:56 -04001054
Geoff Langea228632013-07-30 15:17:12 -04001055 for (RenderTargetMap::iterator i = mLevelLayerRenderTargets.begin(); i != mLevelLayerRenderTargets.end(); i++)
shannon.woods%transgaming.com@gtempaccount.com2058d642013-04-13 03:42:50 +00001056 {
Geoff Langea228632013-07-30 15:17:12 -04001057 SafeDelete(i->second);
shannon.woods%transgaming.com@gtempaccount.com63b3b8f2013-04-13 03:43:26 +00001058 }
shannonwoods@chromium.org15a8b1f2013-05-30 00:03:54 +00001059 mLevelLayerRenderTargets.clear();
1060
1061 for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
1062 {
Geoff Langea228632013-07-30 15:17:12 -04001063 SafeDelete(mLevelRenderTargets[i]);
Geoff Lang644bbf22013-09-17 17:02:43 -04001064 SafeRelease(mSwizzleRenderTargets[i]);
shannonwoods@chromium.org15a8b1f2013-05-30 00:03:54 +00001065 }
shannon.woods%transgaming.com@gtempaccount.com2058d642013-04-13 03:42:50 +00001066}
1067
1068TextureStorage11_3D *TextureStorage11_3D::makeTextureStorage11_3D(TextureStorage *storage)
1069{
1070 ASSERT(HAS_DYNAMIC_TYPE(TextureStorage11_3D*, storage));
1071 return static_cast<TextureStorage11_3D*>(storage);
1072}
1073
Nicolas Capens76b258f2014-04-03 10:59:42 -04001074ID3D11Resource *TextureStorage11_3D::getResource() const
shannon.woods%transgaming.com@gtempaccount.com2058d642013-04-13 03:42:50 +00001075{
1076 return mTexture;
1077}
1078
Nicolas Capens1d31aca2014-04-03 12:45:07 -04001079ID3D11ShaderResourceView *TextureStorage11_3D::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture)
1080{
1081 D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
1082 srvDesc.Format = format;
1083 srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D;
1084 srvDesc.Texture3D.MostDetailedMip = baseLevel;
1085 srvDesc.Texture3D.MipLevels = mipLevels;
1086
1087 ID3D11ShaderResourceView *SRV = NULL;
1088
1089 ID3D11Device *device = mRenderer->getDevice();
1090 HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, &SRV);
1091
1092 if (result == E_OUTOFMEMORY)
1093 {
1094 gl::error(GL_OUT_OF_MEMORY);
1095 }
1096 ASSERT(SUCCEEDED(result));
1097
1098 return SRV;
shannon.woods%transgaming.com@gtempaccount.com2058d642013-04-13 03:42:50 +00001099}
1100
shannonwoods@chromium.org15a8b1f2013-05-30 00:03:54 +00001101RenderTarget *TextureStorage11_3D::getRenderTarget(int mipLevel)
1102{
Nicolas Capensbf712d02014-03-31 14:23:35 -04001103 if (mipLevel >= 0 && mipLevel < getLevelCount())
shannonwoods@chromium.org15a8b1f2013-05-30 00:03:54 +00001104 {
1105 if (!mLevelRenderTargets[mipLevel])
1106 {
Geoff Lang644bbf22013-09-17 17:02:43 -04001107 ID3D11ShaderResourceView *srv = getSRVLevel(mipLevel);
1108 if (!srv)
shannonwoods@chromium.org15a8b1f2013-05-30 00:03:54 +00001109 {
Geoff Lang644bbf22013-09-17 17:02:43 -04001110 return NULL;
shannonwoods@chromium.org15a8b1f2013-05-30 00:03:54 +00001111 }
shannonwoods@chromium.org15a8b1f2013-05-30 00:03:54 +00001112
1113 if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN)
1114 {
Geoff Lang644bbf22013-09-17 17:02:43 -04001115 ID3D11Device *device = mRenderer->getDevice();
1116
shannonwoods@chromium.org15a8b1f2013-05-30 00:03:54 +00001117 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
1118 rtvDesc.Format = mRenderTargetFormat;
1119 rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D;
Nicolas Capensfa7b76d2014-03-31 14:51:45 -04001120 rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel;
shannonwoods@chromium.org15a8b1f2013-05-30 00:03:54 +00001121 rtvDesc.Texture3D.FirstWSlice = 0;
1122 rtvDesc.Texture3D.WSize = -1;
1123
1124 ID3D11RenderTargetView *rtv;
Geoff Lang644bbf22013-09-17 17:02:43 -04001125 HRESULT result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv);
shannonwoods@chromium.org15a8b1f2013-05-30 00:03:54 +00001126
1127 if (result == E_OUTOFMEMORY)
1128 {
Geoff Langea228632013-07-30 15:17:12 -04001129 SafeRelease(srv);
shannonwoods@chromium.org15a8b1f2013-05-30 00:03:54 +00001130 return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
1131 }
1132 ASSERT(SUCCEEDED(result));
1133
Jamie Madillb16b8ed2013-10-24 17:49:45 -04001134 mLevelRenderTargets[mipLevel] = new RenderTarget11(mRenderer, rtv, mTexture, srv, getLevelWidth(mipLevel), getLevelHeight(mipLevel), getLevelDepth(mipLevel));
Geoff Lang2916b302013-11-28 13:41:10 -05001135
1136 // RenderTarget will take ownership of these resources
1137 SafeRelease(rtv);
shannonwoods@chromium.org15a8b1f2013-05-30 00:03:54 +00001138 }
1139 else
1140 {
1141 UNREACHABLE();
1142 }
1143 }
1144
1145 return mLevelRenderTargets[mipLevel];
1146 }
1147 else
1148 {
1149 return NULL;
1150 }
1151}
1152
shannon.woods%transgaming.com@gtempaccount.com63b3b8f2013-04-13 03:43:26 +00001153RenderTarget *TextureStorage11_3D::getRenderTargetLayer(int mipLevel, int layer)
1154{
Nicolas Capensbf712d02014-03-31 14:23:35 -04001155 if (mipLevel >= 0 && mipLevel < getLevelCount())
shannon.woods%transgaming.com@gtempaccount.com63b3b8f2013-04-13 03:43:26 +00001156 {
1157 LevelLayerKey key(mipLevel, layer);
shannonwoods@chromium.org15a8b1f2013-05-30 00:03:54 +00001158 if (mLevelLayerRenderTargets.find(key) == mLevelLayerRenderTargets.end())
shannon.woods%transgaming.com@gtempaccount.com63b3b8f2013-04-13 03:43:26 +00001159 {
1160 ID3D11Device *device = mRenderer->getDevice();
1161 HRESULT result;
1162
1163 // TODO, what kind of SRV is expected here?
1164 ID3D11ShaderResourceView *srv = NULL;
1165
1166 if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN)
1167 {
1168 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
1169 rtvDesc.Format = mRenderTargetFormat;
1170 rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D;
Nicolas Capensfa7b76d2014-03-31 14:51:45 -04001171 rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel;
shannon.woods%transgaming.com@gtempaccount.com63b3b8f2013-04-13 03:43:26 +00001172 rtvDesc.Texture3D.FirstWSlice = layer;
1173 rtvDesc.Texture3D.WSize = 1;
1174
1175 ID3D11RenderTargetView *rtv;
1176 result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv);
1177
1178 if (result == E_OUTOFMEMORY)
1179 {
Geoff Langea228632013-07-30 15:17:12 -04001180 SafeRelease(srv);
shannon.woods%transgaming.com@gtempaccount.com63b3b8f2013-04-13 03:43:26 +00001181 return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
1182 }
1183 ASSERT(SUCCEEDED(result));
1184
Jamie Madillb16b8ed2013-10-24 17:49:45 -04001185 mLevelLayerRenderTargets[key] = new RenderTarget11(mRenderer, rtv, mTexture, srv, getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1);
Geoff Lang2916b302013-11-28 13:41:10 -05001186
1187 // RenderTarget will take ownership of these resources
1188 SafeRelease(rtv);
1189 SafeRelease(srv);
shannon.woods%transgaming.com@gtempaccount.com63b3b8f2013-04-13 03:43:26 +00001190 }
1191 else
1192 {
1193 UNREACHABLE();
1194 }
1195 }
1196
shannonwoods@chromium.org15a8b1f2013-05-30 00:03:54 +00001197 return mLevelLayerRenderTargets[key];
shannon.woods%transgaming.com@gtempaccount.com63b3b8f2013-04-13 03:43:26 +00001198 }
1199 else
1200 {
1201 return NULL;
1202 }
1203}
1204
shannon.woods%transgaming.com@gtempaccount.com2058d642013-04-13 03:42:50 +00001205void TextureStorage11_3D::generateMipmap(int level)
1206{
Geoff Lang644bbf22013-09-17 17:02:43 -04001207 invalidateSwizzleCacheLevel(level);
1208
shannonwoods@chromium.org37b8a912013-05-30 00:04:21 +00001209 RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTarget(level - 1));
1210 RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTarget(level));
1211
1212 generateMipmapLayer(source, dest);
shannon.woods%transgaming.com@gtempaccount.com2058d642013-04-13 03:42:50 +00001213}
1214
Nicolas Capens41d9f7e2014-04-11 17:32:55 -04001215ID3D11Resource *TextureStorage11_3D::getSwizzleTexture()
Geoff Lang644bbf22013-09-17 17:02:43 -04001216{
1217 if (!mSwizzleTexture)
1218 {
1219 ID3D11Device *device = mRenderer->getDevice();
1220
1221 D3D11_TEXTURE3D_DESC desc;
1222 desc.Width = mTextureWidth;
1223 desc.Height = mTextureHeight;
1224 desc.Depth = mTextureDepth;
Nicolas Capensbf712d02014-03-31 14:23:35 -04001225 desc.MipLevels = mMipLevels;
Geoff Lang644bbf22013-09-17 17:02:43 -04001226 desc.Format = mSwizzleTextureFormat;
1227 desc.Usage = D3D11_USAGE_DEFAULT;
1228 desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
1229 desc.CPUAccessFlags = 0;
1230 desc.MiscFlags = 0;
1231
1232 HRESULT result = device->CreateTexture3D(&desc, NULL, &mSwizzleTexture);
1233
1234 if (result == E_OUTOFMEMORY)
1235 {
1236 return gl::error(GL_OUT_OF_MEMORY, static_cast<ID3D11Texture3D*>(NULL));
1237 }
1238 ASSERT(SUCCEEDED(result));
1239 }
1240
1241 return mSwizzleTexture;
1242}
1243
1244ID3D11RenderTargetView *TextureStorage11_3D::getSwizzleRenderTarget(int mipLevel)
1245{
Nicolas Capensbf712d02014-03-31 14:23:35 -04001246 if (mipLevel >= 0 && mipLevel < getLevelCount())
Geoff Lang644bbf22013-09-17 17:02:43 -04001247 {
1248 if (!mSwizzleRenderTargets[mipLevel])
1249 {
Nicolas Capens41d9f7e2014-04-11 17:32:55 -04001250 ID3D11Resource *swizzleTexture = getSwizzleTexture();
Geoff Lang644bbf22013-09-17 17:02:43 -04001251 if (!swizzleTexture)
1252 {
1253 return NULL;
1254 }
1255
1256 ID3D11Device *device = mRenderer->getDevice();
1257
1258 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
1259 rtvDesc.Format = mSwizzleRenderTargetFormat;
1260 rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D;
Nicolas Capensfa7b76d2014-03-31 14:51:45 -04001261 rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel;
Geoff Lang644bbf22013-09-17 17:02:43 -04001262 rtvDesc.Texture3D.FirstWSlice = 0;
1263 rtvDesc.Texture3D.WSize = -1;
1264
1265 HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]);
Geoff Langcebb5aa2014-04-07 14:13:40 -04001266
1267 if (result == E_OUTOFMEMORY)
1268 {
1269 return gl::error(GL_OUT_OF_MEMORY, static_cast<ID3D11RenderTargetView*>(NULL));
1270 }
1271 ASSERT(SUCCEEDED(result));
Geoff Lang644bbf22013-09-17 17:02:43 -04001272 }
1273
1274 return mSwizzleRenderTargets[mipLevel];
1275 }
1276 else
1277 {
1278 return NULL;
1279 }
1280}
1281
Geoff Lang644bbf22013-09-17 17:02:43 -04001282unsigned int TextureStorage11_3D::getTextureLevelDepth(int mipLevel) const
1283{
1284 return std::max(mTextureDepth >> mipLevel, 1U);
1285}
1286
1287
Nicolas Capensbf712d02014-03-31 14:23:35 -04001288TextureStorage11_2DArray::TextureStorage11_2DArray(Renderer *renderer, GLenum internalformat, bool renderTarget,
1289 GLsizei width, GLsizei height, GLsizei depth, int levels)
Geoff Lange4a492b2014-06-19 14:14:41 -04001290 : TextureStorage11(renderer, GetTextureBindFlags(internalformat, renderTarget))
shannon.woods%transgaming.com@gtempaccount.com96973372013-04-13 03:45:39 +00001291{
1292 mTexture = NULL;
Geoff Lang644bbf22013-09-17 17:02:43 -04001293 mSwizzleTexture = NULL;
Nicolas Capense47e7362014-03-27 13:34:56 -04001294
Geoff Lang644bbf22013-09-17 17:02:43 -04001295 for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
1296 {
Geoff Lang644bbf22013-09-17 17:02:43 -04001297 mSwizzleRenderTargets[level] = NULL;
1298 }
shannon.woods%transgaming.com@gtempaccount.com96973372013-04-13 03:45:39 +00001299
Geoff Lange4a492b2014-06-19 14:14:41 -04001300 mTextureFormat = gl_d3d11::GetTexFormat(internalformat);
1301 mShaderResourceFormat = gl_d3d11::GetSRVFormat(internalformat);
1302 mDepthStencilFormat = gl_d3d11::GetDSVFormat(internalformat);
1303 mRenderTargetFormat = gl_d3d11::GetRTVFormat(internalformat);
1304 mSwizzleTextureFormat = gl_d3d11::GetSwizzleTexFormat(internalformat);
1305 mSwizzleShaderResourceFormat = gl_d3d11::GetSwizzleSRVFormat(internalformat);
1306 mSwizzleRenderTargetFormat = gl_d3d11::GetSwizzleRTVFormat(internalformat);
shannon.woods%transgaming.com@gtempaccount.com96973372013-04-13 03:45:39 +00001307
shannonwoods@chromium.orgd38d66e2013-05-30 00:09:16 +00001308 // if the width, height or depth is not positive this should be treated as an incomplete texture
shannon.woods%transgaming.com@gtempaccount.com96973372013-04-13 03:45:39 +00001309 // we handle that here by skipping the d3d texture creation
1310 if (width > 0 && height > 0 && depth > 0)
1311 {
1312 // adjust size if needed for compressed textures
Nicolas Capensf61738a2014-03-31 14:50:18 -04001313 d3d11::MakeValidSize(false, mTextureFormat, &width, &height, &mTopLevel);
shannon.woods%transgaming.com@gtempaccount.com96973372013-04-13 03:45:39 +00001314
1315 ID3D11Device *device = mRenderer->getDevice();
1316
1317 D3D11_TEXTURE2D_DESC desc;
1318 desc.Width = width;
1319 desc.Height = height;
Nicolas Capensbf712d02014-03-31 14:23:35 -04001320 desc.MipLevels = ((levels > 0) ? (mTopLevel + levels) : 0);
shannon.woods%transgaming.com@gtempaccount.com96973372013-04-13 03:45:39 +00001321 desc.ArraySize = depth;
1322 desc.Format = mTextureFormat;
1323 desc.SampleDesc.Count = 1;
1324 desc.SampleDesc.Quality = 0;
1325 desc.Usage = D3D11_USAGE_DEFAULT;
1326 desc.BindFlags = getBindFlags();
1327 desc.CPUAccessFlags = 0;
1328 desc.MiscFlags = 0;
1329
1330 HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture);
1331
1332 // this can happen from windows TDR
1333 if (d3d11::isDeviceLostError(result))
1334 {
1335 mRenderer->notifyDeviceLost();
1336 gl::error(GL_OUT_OF_MEMORY);
1337 }
1338 else if (FAILED(result))
1339 {
1340 ASSERT(result == E_OUTOFMEMORY);
1341 ERR("Creating image failed.");
1342 gl::error(GL_OUT_OF_MEMORY);
1343 }
1344 else
1345 {
1346 mTexture->GetDesc(&desc);
1347 mMipLevels = desc.MipLevels;
1348 mTextureWidth = desc.Width;
1349 mTextureHeight = desc.Height;
1350 mTextureDepth = desc.ArraySize;
1351 }
1352 }
1353}
1354
1355TextureStorage11_2DArray::~TextureStorage11_2DArray()
1356{
Geoff Langea228632013-07-30 15:17:12 -04001357 SafeRelease(mTexture);
Geoff Lang644bbf22013-09-17 17:02:43 -04001358 SafeRelease(mSwizzleTexture);
Nicolas Capense47e7362014-03-27 13:34:56 -04001359
Geoff Lang644bbf22013-09-17 17:02:43 -04001360 for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
1361 {
Geoff Lang644bbf22013-09-17 17:02:43 -04001362 SafeRelease(mSwizzleRenderTargets[level]);
1363 }
shannon.woods%transgaming.com@gtempaccount.com96973372013-04-13 03:45:39 +00001364
Geoff Langea228632013-07-30 15:17:12 -04001365 for (RenderTargetMap::iterator i = mRenderTargets.begin(); i != mRenderTargets.end(); i++)
shannon.woods%transgaming.com@gtempaccount.com96973372013-04-13 03:45:39 +00001366 {
Geoff Langea228632013-07-30 15:17:12 -04001367 SafeDelete(i->second);
shannon.woods%transgaming.com@gtempaccount.com96973372013-04-13 03:45:39 +00001368 }
1369 mRenderTargets.clear();
1370}
1371
1372TextureStorage11_2DArray *TextureStorage11_2DArray::makeTextureStorage11_2DArray(TextureStorage *storage)
1373{
1374 ASSERT(HAS_DYNAMIC_TYPE(TextureStorage11_2DArray*, storage));
1375 return static_cast<TextureStorage11_2DArray*>(storage);
1376}
1377
Nicolas Capens76b258f2014-04-03 10:59:42 -04001378ID3D11Resource *TextureStorage11_2DArray::getResource() const
shannon.woods%transgaming.com@gtempaccount.com96973372013-04-13 03:45:39 +00001379{
1380 return mTexture;
1381}
1382
Nicolas Capens1d31aca2014-04-03 12:45:07 -04001383ID3D11ShaderResourceView *TextureStorage11_2DArray::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture)
1384{
1385 D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
1386 srvDesc.Format = format;
1387 srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
1388 srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + baseLevel;
1389 srvDesc.Texture2DArray.MipLevels = mipLevels;
1390 srvDesc.Texture2DArray.FirstArraySlice = 0;
1391 srvDesc.Texture2DArray.ArraySize = mTextureDepth;
1392
1393 ID3D11ShaderResourceView *SRV = NULL;
1394
1395 ID3D11Device *device = mRenderer->getDevice();
1396 HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, &SRV);
1397
1398 if (result == E_OUTOFMEMORY)
1399 {
1400 gl::error(GL_OUT_OF_MEMORY);
1401 }
1402 ASSERT(SUCCEEDED(result));
1403
1404 return SRV;
shannon.woods%transgaming.com@gtempaccount.com96973372013-04-13 03:45:39 +00001405}
1406
1407RenderTarget *TextureStorage11_2DArray::getRenderTargetLayer(int mipLevel, int layer)
1408{
Nicolas Capensbf712d02014-03-31 14:23:35 -04001409 if (mipLevel >= 0 && mipLevel < getLevelCount())
shannon.woods%transgaming.com@gtempaccount.com96973372013-04-13 03:45:39 +00001410 {
1411 LevelLayerKey key(mipLevel, layer);
1412 if (mRenderTargets.find(key) == mRenderTargets.end())
1413 {
1414 ID3D11Device *device = mRenderer->getDevice();
1415 HRESULT result;
1416
shannonwoods@chromium.org30aa1a92013-05-30 00:03:13 +00001417 D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
1418 srvDesc.Format = mShaderResourceFormat;
1419 srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
Nicolas Capensfa7b76d2014-03-31 14:51:45 -04001420 srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + mipLevel;
shannonwoods@chromium.org30aa1a92013-05-30 00:03:13 +00001421 srvDesc.Texture2DArray.MipLevels = 1;
1422 srvDesc.Texture2DArray.FirstArraySlice = layer;
1423 srvDesc.Texture2DArray.ArraySize = 1;
1424
1425 ID3D11ShaderResourceView *srv;
1426 result = device->CreateShaderResourceView(mTexture, &srvDesc, &srv);
1427
1428 if (result == E_OUTOFMEMORY)
1429 {
1430 return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
1431 }
1432 ASSERT(SUCCEEDED(result));
shannon.woods%transgaming.com@gtempaccount.com96973372013-04-13 03:45:39 +00001433
1434 if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN)
1435 {
1436 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
1437 rtvDesc.Format = mRenderTargetFormat;
1438 rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
Nicolas Capensfa7b76d2014-03-31 14:51:45 -04001439 rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel;
shannon.woods%transgaming.com@gtempaccount.com96973372013-04-13 03:45:39 +00001440 rtvDesc.Texture2DArray.FirstArraySlice = layer;
1441 rtvDesc.Texture2DArray.ArraySize = 1;
1442
1443 ID3D11RenderTargetView *rtv;
1444 result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv);
1445
1446 if (result == E_OUTOFMEMORY)
1447 {
1448 SafeRelease(srv);
1449 return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
1450 }
1451 ASSERT(SUCCEEDED(result));
1452
Jamie Madillb16b8ed2013-10-24 17:49:45 -04001453 mRenderTargets[key] = new RenderTarget11(mRenderer, rtv, mTexture, srv, getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1);
Geoff Lang2916b302013-11-28 13:41:10 -05001454
1455 // RenderTarget will take ownership of these resources
1456 SafeRelease(rtv);
1457 SafeRelease(srv);
shannon.woods%transgaming.com@gtempaccount.com96973372013-04-13 03:45:39 +00001458 }
1459 else
1460 {
1461 UNREACHABLE();
1462 }
1463 }
1464
1465 return mRenderTargets[key];
1466 }
1467 else
1468 {
1469 return NULL;
1470 }
1471}
1472
1473void TextureStorage11_2DArray::generateMipmap(int level)
1474{
Geoff Lang644bbf22013-09-17 17:02:43 -04001475 invalidateSwizzleCacheLevel(level);
shannonwoods@chromium.org30aa1a92013-05-30 00:03:13 +00001476 for (unsigned int layer = 0; layer < mTextureDepth; layer++)
1477 {
1478 RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTargetLayer(level - 1, layer));
1479 RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTargetLayer(level, layer));
1480
1481 generateMipmapLayer(source, dest);
1482 }
shannon.woods%transgaming.com@gtempaccount.com96973372013-04-13 03:45:39 +00001483}
1484
Nicolas Capens41d9f7e2014-04-11 17:32:55 -04001485ID3D11Resource *TextureStorage11_2DArray::getSwizzleTexture()
Geoff Lang644bbf22013-09-17 17:02:43 -04001486{
1487 if (!mSwizzleTexture)
1488 {
1489 ID3D11Device *device = mRenderer->getDevice();
1490
1491 D3D11_TEXTURE2D_DESC desc;
1492 desc.Width = mTextureWidth;
1493 desc.Height = mTextureHeight;
Nicolas Capensbf712d02014-03-31 14:23:35 -04001494 desc.MipLevels = mMipLevels;
Geoff Lang644bbf22013-09-17 17:02:43 -04001495 desc.ArraySize = mTextureDepth;
1496 desc.Format = mSwizzleTextureFormat;
1497 desc.SampleDesc.Count = 1;
1498 desc.SampleDesc.Quality = 0;
1499 desc.Usage = D3D11_USAGE_DEFAULT;
1500 desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
1501 desc.CPUAccessFlags = 0;
1502 desc.MiscFlags = 0;
1503
1504 HRESULT result = device->CreateTexture2D(&desc, NULL, &mSwizzleTexture);
1505
1506 if (result == E_OUTOFMEMORY)
1507 {
1508 return gl::error(GL_OUT_OF_MEMORY, static_cast<ID3D11Texture2D*>(NULL));
1509 }
1510 ASSERT(SUCCEEDED(result));
1511 }
1512
1513 return mSwizzleTexture;
1514}
1515
1516ID3D11RenderTargetView *TextureStorage11_2DArray::getSwizzleRenderTarget(int mipLevel)
1517{
Nicolas Capensbf712d02014-03-31 14:23:35 -04001518 if (mipLevel >= 0 && mipLevel < getLevelCount())
Geoff Lang644bbf22013-09-17 17:02:43 -04001519 {
1520 if (!mSwizzleRenderTargets[mipLevel])
1521 {
Nicolas Capens41d9f7e2014-04-11 17:32:55 -04001522 ID3D11Resource *swizzleTexture = getSwizzleTexture();
Geoff Lang644bbf22013-09-17 17:02:43 -04001523 if (!swizzleTexture)
1524 {
1525 return NULL;
1526 }
1527
1528 ID3D11Device *device = mRenderer->getDevice();
1529
1530 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
1531 rtvDesc.Format = mSwizzleRenderTargetFormat;
1532 rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
Nicolas Capensfa7b76d2014-03-31 14:51:45 -04001533 rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel;
Geoff Lang644bbf22013-09-17 17:02:43 -04001534 rtvDesc.Texture2DArray.FirstArraySlice = 0;
1535 rtvDesc.Texture2DArray.ArraySize = mTextureDepth;
1536
1537 HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]);
Geoff Langcebb5aa2014-04-07 14:13:40 -04001538
1539 if (result == E_OUTOFMEMORY)
1540 {
1541 return gl::error(GL_OUT_OF_MEMORY, static_cast<ID3D11RenderTargetView*>(NULL));
1542 }
1543 ASSERT(SUCCEEDED(result));
Geoff Lang644bbf22013-09-17 17:02:43 -04001544 }
1545
1546 return mSwizzleRenderTargets[mipLevel];
1547 }
1548 else
1549 {
1550 return NULL;
1551 }
1552}
1553
Geoff Lang644bbf22013-09-17 17:02:43 -04001554unsigned int TextureStorage11_2DArray::getTextureLevelDepth(int mipLevel) const
1555{
1556 return mTextureDepth;
1557}
1558
daniel@transgaming.comb2151e52013-01-11 04:06:24 +00001559}