1 //
2 // Copyright 2012 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6
7 // TextureStorage11.cpp: Implements the abstract rx::TextureStorage11 class and its concrete derived
8 // classes TextureStorage11_2D and TextureStorage11_Cube, which act as the interface to the D3D11
9 // texture.
10
11 #include "libANGLE/renderer/d3d/d3d11/TextureStorage11.h"
12
13 #include <tuple>
14
15 #include "common/MemoryBuffer.h"
16 #include "common/utilities.h"
17 #include "libANGLE/Context.h"
18 #include "libANGLE/ImageIndex.h"
19 #include "libANGLE/formatutils.h"
20 #include "libANGLE/renderer/d3d/EGLImageD3D.h"
21 #include "libANGLE/renderer/d3d/TextureD3D.h"
22 #include "libANGLE/renderer/d3d/d3d11/Blit11.h"
23 #include "libANGLE/renderer/d3d/d3d11/Context11.h"
24 #include "libANGLE/renderer/d3d/d3d11/Image11.h"
25 #include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h"
26 #include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
27 #include "libANGLE/renderer/d3d/d3d11/StreamProducerD3DTexture.h"
28 #include "libANGLE/renderer/d3d/d3d11/SwapChain11.h"
29 #include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
30 #include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
31 #include "libANGLE/renderer/d3d/d3d11/texture_format_table.h"
32
33 namespace rx
34 {
SamplerKey()35 TextureStorage11::SamplerKey::SamplerKey()
36 : baseLevel(0), mipLevels(0), swizzle(false), dropStencil(false)
37 {}
38
SamplerKey(int baseLevel,int mipLevels,bool swizzle,bool dropStencil)39 TextureStorage11::SamplerKey::SamplerKey(int baseLevel,
40 int mipLevels,
41 bool swizzle,
42 bool dropStencil)
43 : baseLevel(baseLevel), mipLevels(mipLevels), swizzle(swizzle), dropStencil(dropStencil)
44 {}
45
operator <(const SamplerKey & rhs) const46 bool TextureStorage11::SamplerKey::operator<(const SamplerKey &rhs) const
47 {
48 return std::tie(baseLevel, mipLevels, swizzle, dropStencil) <
49 std::tie(rhs.baseLevel, rhs.mipLevels, rhs.swizzle, rhs.dropStencil);
50 }
51
ImageKey()52 TextureStorage11::ImageKey::ImageKey()
53 : level(0), layered(false), layer(0), access(GL_READ_ONLY), format(GL_R32UI)
54 {}
55
ImageKey(int level,bool layered,int layer,GLenum access,GLenum format)56 TextureStorage11::ImageKey::ImageKey(int level,
57 bool layered,
58 int layer,
59 GLenum access,
60 GLenum format)
61 : level(level), layered(layered), layer(layer), access(access), format(format)
62 {}
63
operator <(const ImageKey & rhs) const64 bool TextureStorage11::ImageKey::operator<(const ImageKey &rhs) const
65 {
66 return std::tie(level, layered, layer, access, format) <
67 std::tie(rhs.level, rhs.layered, rhs.layer, rhs.access, rhs.format);
68 }
69
MultisampledRenderToTextureInfo(const GLsizei samples,const gl::ImageIndex & indexSS,const gl::ImageIndex & indexMS)70 MultisampledRenderToTextureInfo::MultisampledRenderToTextureInfo(const GLsizei samples,
71 const gl::ImageIndex &indexSS,
72 const gl::ImageIndex &indexMS)
73 : samples(samples), indexSS(indexSS), indexMS(indexMS), msTextureNeedsResolve(false)
74 {}
75
~MultisampledRenderToTextureInfo()76 MultisampledRenderToTextureInfo::~MultisampledRenderToTextureInfo() {}
77
TextureStorage11(Renderer11 * renderer,UINT bindFlags,UINT miscFlags,GLenum internalFormat)78 TextureStorage11::TextureStorage11(Renderer11 *renderer,
79 UINT bindFlags,
80 UINT miscFlags,
81 GLenum internalFormat)
82 : mRenderer(renderer),
83 mTopLevel(0),
84 mMipLevels(0),
85 mFormatInfo(d3d11::Format::Get(internalFormat, mRenderer->getRenderer11DeviceCaps())),
86 mTextureWidth(0),
87 mTextureHeight(0),
88 mTextureDepth(0),
89 mDropStencilTexture(),
90 mBindFlags(bindFlags),
91 mMiscFlags(miscFlags)
92 {}
93
~TextureStorage11()94 TextureStorage11::~TextureStorage11()
95 {
96 mSrvCacheForSampler.clear();
97 }
98
GetTextureBindFlags(GLenum internalFormat,const Renderer11DeviceCaps & renderer11DeviceCaps,bool renderTarget)99 DWORD TextureStorage11::GetTextureBindFlags(GLenum internalFormat,
100 const Renderer11DeviceCaps &renderer11DeviceCaps,
101 bool renderTarget)
102 {
103 UINT bindFlags = 0;
104
105 const d3d11::Format &formatInfo = d3d11::Format::Get(internalFormat, renderer11DeviceCaps);
106 if (formatInfo.srvFormat != DXGI_FORMAT_UNKNOWN)
107 {
108 bindFlags |= D3D11_BIND_SHADER_RESOURCE;
109 }
110 if (formatInfo.uavFormat != DXGI_FORMAT_UNKNOWN &&
111 renderer11DeviceCaps.featureLevel >= d3d11_gl::GetMinimumFeatureLevelForES31())
112 {
113 // If we find performance issues later on some specific GPUs, this may be the cause.
114 bindFlags |= D3D11_BIND_UNORDERED_ACCESS;
115 }
116 if (formatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN)
117 {
118 bindFlags |= D3D11_BIND_DEPTH_STENCIL;
119 }
120 if (formatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN && renderTarget)
121 {
122 bindFlags |= D3D11_BIND_RENDER_TARGET;
123 }
124
125 return bindFlags;
126 }
127
GetTextureMiscFlags(GLenum internalFormat,const Renderer11DeviceCaps & renderer11DeviceCaps,bool renderTarget,int levels)128 DWORD TextureStorage11::GetTextureMiscFlags(GLenum internalFormat,
129 const Renderer11DeviceCaps &renderer11DeviceCaps,
130 bool renderTarget,
131 int levels)
132 {
133 UINT miscFlags = 0;
134
135 const d3d11::Format &formatInfo = d3d11::Format::Get(internalFormat, renderer11DeviceCaps);
136 if (renderTarget && levels > 1)
137 {
138 if (d3d11::SupportsMipGen(formatInfo.texFormat, renderer11DeviceCaps.featureLevel))
139 {
140 miscFlags |= D3D11_RESOURCE_MISC_GENERATE_MIPS;
141 }
142 }
143
144 return miscFlags;
145 }
146
getBindFlags() const147 UINT TextureStorage11::getBindFlags() const
148 {
149 return mBindFlags;
150 }
151
getMiscFlags() const152 UINT TextureStorage11::getMiscFlags() const
153 {
154 return mMiscFlags;
155 }
156
getTopLevel() const157 int TextureStorage11::getTopLevel() const
158 {
159 // Applying top level is meant to be encapsulated inside TextureStorage11.
160 UNREACHABLE();
161 return mTopLevel;
162 }
163
isRenderTarget() const164 bool TextureStorage11::isRenderTarget() const
165 {
166 return (mBindFlags & (D3D11_BIND_RENDER_TARGET | D3D11_BIND_DEPTH_STENCIL)) != 0;
167 }
168
isManaged() const169 bool TextureStorage11::isManaged() const
170 {
171 return false;
172 }
173
supportsNativeMipmapFunction() const174 bool TextureStorage11::supportsNativeMipmapFunction() const
175 {
176 return (mMiscFlags & D3D11_RESOURCE_MISC_GENERATE_MIPS) != 0;
177 }
178
getLevelCount() const179 int TextureStorage11::getLevelCount() const
180 {
181 return mMipLevels - mTopLevel;
182 }
183
getLevelWidth(int mipLevel) const184 int TextureStorage11::getLevelWidth(int mipLevel) const
185 {
186 return std::max(static_cast<int>(mTextureWidth) >> mipLevel, 1);
187 }
188
getLevelHeight(int mipLevel) const189 int TextureStorage11::getLevelHeight(int mipLevel) const
190 {
191 return std::max(static_cast<int>(mTextureHeight) >> mipLevel, 1);
192 }
193
getLevelDepth(int mipLevel) const194 int TextureStorage11::getLevelDepth(int mipLevel) const
195 {
196 return std::max(static_cast<int>(mTextureDepth) >> mipLevel, 1);
197 }
198
getMippedResource(const gl::Context * context,const TextureHelper11 ** outResource)199 angle::Result TextureStorage11::getMippedResource(const gl::Context *context,
200 const TextureHelper11 **outResource)
201 {
202 return getResource(context, outResource);
203 }
204
getSubresourceIndex(const gl::Context * context,const gl::ImageIndex & index,UINT * outSubresourceIndex) const205 angle::Result TextureStorage11::getSubresourceIndex(const gl::Context *context,
206 const gl::ImageIndex &index,
207 UINT *outSubresourceIndex) const
208 {
209 UINT mipSlice = static_cast<UINT>(index.getLevelIndex() + mTopLevel);
210 UINT arraySlice = static_cast<UINT>(index.hasLayer() ? index.getLayerIndex() : 0);
211 UINT subresource = D3D11CalcSubresource(mipSlice, arraySlice, mMipLevels);
212 ASSERT(subresource != std::numeric_limits<UINT>::max());
213 *outSubresourceIndex = subresource;
214 return angle::Result::Continue;
215 }
216
getSRVForSampler(const gl::Context * context,const gl::TextureState & textureState,const gl::SamplerState & sampler,const d3d11::SharedSRV ** outSRV)217 angle::Result TextureStorage11::getSRVForSampler(const gl::Context *context,
218 const gl::TextureState &textureState,
219 const gl::SamplerState &sampler,
220 const d3d11::SharedSRV **outSRV)
221 {
222 ANGLE_TRY(resolveTexture(context));
223 // Make sure to add the level offset for our tiny compressed texture workaround
224 const GLuint effectiveBaseLevel = textureState.getEffectiveBaseLevel();
225 const bool swizzleRequired = textureState.swizzleRequired();
226 const bool mipmapping = gl::IsMipmapFiltered(sampler.getMinFilter());
227 unsigned int mipLevels =
228 mipmapping ? (textureState.getEffectiveMaxLevel() - effectiveBaseLevel + 1) : 1;
229
230 // Make sure there's 'mipLevels' mipmap levels below the base level (offset by the top level,
231 // which corresponds to GL level 0)
232 mipLevels = std::min(mipLevels, mMipLevels - mTopLevel - effectiveBaseLevel);
233
234 if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3)
235 {
236 ASSERT(!swizzleRequired);
237 ASSERT(mipLevels == 1 || mipLevels == mMipLevels);
238 }
239
240 if (mRenderer->getFeatures().zeroMaxLodWorkaround.enabled)
241 {
242 // We must ensure that the level zero texture is in sync with mipped texture.
243 ANGLE_TRY(useLevelZeroWorkaroundTexture(context, mipLevels == 1));
244 }
245
246 if (swizzleRequired)
247 {
248 verifySwizzleExists(textureState.getSwizzleState());
249 }
250
251 // We drop the stencil when sampling from the SRV if three conditions hold:
252 // 1. the drop stencil workaround is enabled.
253 const bool emulateTinyStencilTextures =
254 mRenderer->getFeatures().emulateTinyStencilTextures.enabled;
255 // 2. this is a stencil texture.
256 const bool hasStencil = (mFormatInfo.format().stencilBits > 0);
257 // 3. the texture has a 1x1 or 2x2 mip.
258 const int effectiveTopLevel = effectiveBaseLevel + mipLevels - 1;
259 const bool hasSmallMips =
260 (getLevelWidth(effectiveTopLevel) <= 2 || getLevelHeight(effectiveTopLevel) <= 2);
261
262 const bool useDropStencil = (emulateTinyStencilTextures && hasStencil && hasSmallMips);
263 const SamplerKey key(effectiveBaseLevel, mipLevels, swizzleRequired, useDropStencil);
264 if (useDropStencil)
265 {
266 // Ensure drop texture gets created.
267 DropStencil result = DropStencil::CREATED;
268 ANGLE_TRY(ensureDropStencilTexture(context, &result));
269
270 // Clear the SRV cache if necessary.
271 // TODO(jmadill): Re-use find query result.
272 const auto srvEntry = mSrvCacheForSampler.find(key);
273 if (result == DropStencil::CREATED && srvEntry != mSrvCacheForSampler.end())
274 {
275 mSrvCacheForSampler.erase(key);
276 }
277 }
278
279 ANGLE_TRY(getCachedOrCreateSRVForSampler(context, key, outSRV));
280
281 return angle::Result::Continue;
282 }
283
getCachedOrCreateSRVForSampler(const gl::Context * context,const SamplerKey & key,const d3d11::SharedSRV ** outSRV)284 angle::Result TextureStorage11::getCachedOrCreateSRVForSampler(const gl::Context *context,
285 const SamplerKey &key,
286 const d3d11::SharedSRV **outSRV)
287 {
288 auto iter = mSrvCacheForSampler.find(key);
289 if (iter != mSrvCacheForSampler.end())
290 {
291 *outSRV = &iter->second;
292 return angle::Result::Continue;
293 }
294
295 const TextureHelper11 *texture = nullptr;
296 DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN;
297
298 if (key.swizzle)
299 {
300 const auto &swizzleFormat =
301 mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps());
302 ASSERT(!key.dropStencil || swizzleFormat.format().stencilBits == 0);
303 ANGLE_TRY(getSwizzleTexture(context, &texture));
304 format = swizzleFormat.srvFormat;
305 }
306 else if (key.dropStencil)
307 {
308 ASSERT(mDropStencilTexture.valid());
309 texture = &mDropStencilTexture;
310 format = DXGI_FORMAT_R32_FLOAT;
311 }
312 else
313 {
314 ANGLE_TRY(getResource(context, &texture));
315 format = mFormatInfo.srvFormat;
316 }
317
318 d3d11::SharedSRV srv;
319
320 ANGLE_TRY(createSRVForSampler(context, key.baseLevel, key.mipLevels, format, *texture, &srv));
321
322 const auto &insertIt = mSrvCacheForSampler.insert(std::make_pair(key, std::move(srv)));
323 *outSRV = &insertIt.first->second;
324
325 return angle::Result::Continue;
326 }
327
getSRVLevel(const gl::Context * context,int mipLevel,bool blitSRV,const d3d11::SharedSRV ** outSRV)328 angle::Result TextureStorage11::getSRVLevel(const gl::Context *context,
329 int mipLevel,
330 bool blitSRV,
331 const d3d11::SharedSRV **outSRV)
332 {
333 ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
334
335 ANGLE_TRY(resolveTexture(context));
336 auto &levelSRVs = (blitSRV) ? mLevelBlitSRVs : mLevelSRVs;
337 auto &otherLevelSRVs = (blitSRV) ? mLevelSRVs : mLevelBlitSRVs;
338
339 if (!levelSRVs[mipLevel].valid())
340 {
341 // Only create a different SRV for blit if blit format is different from regular srv format
342 if (otherLevelSRVs[mipLevel].valid() && mFormatInfo.srvFormat == mFormatInfo.blitSRVFormat)
343 {
344 levelSRVs[mipLevel] = otherLevelSRVs[mipLevel].makeCopy();
345 }
346 else
347 {
348 const TextureHelper11 *resource = nullptr;
349 ANGLE_TRY(getResource(context, &resource));
350
351 DXGI_FORMAT resourceFormat =
352 blitSRV ? mFormatInfo.blitSRVFormat : mFormatInfo.srvFormat;
353 ANGLE_TRY(createSRVForSampler(context, mipLevel, 1, resourceFormat, *resource,
354 &levelSRVs[mipLevel]));
355 }
356 }
357
358 *outSRV = &levelSRVs[mipLevel];
359 return angle::Result::Continue;
360 }
361
getSRVLevels(const gl::Context * context,GLint baseLevel,GLint maxLevel,const d3d11::SharedSRV ** outSRV)362 angle::Result TextureStorage11::getSRVLevels(const gl::Context *context,
363 GLint baseLevel,
364 GLint maxLevel,
365 const d3d11::SharedSRV **outSRV)
366 {
367 ANGLE_TRY(resolveTexture(context));
368 unsigned int mipLevels = maxLevel - baseLevel + 1;
369
370 // Make sure there's 'mipLevels' mipmap levels below the base level (offset by the top level,
371 // which corresponds to GL level 0)
372 mipLevels = std::min(mipLevels, mMipLevels - mTopLevel - baseLevel);
373
374 if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3)
375 {
376 ASSERT(mipLevels == 1 || mipLevels == mMipLevels);
377 }
378
379 if (mRenderer->getFeatures().zeroMaxLodWorkaround.enabled)
380 {
381 // We must ensure that the level zero texture is in sync with mipped texture.
382 ANGLE_TRY(useLevelZeroWorkaroundTexture(context, mipLevels == 1));
383 }
384
385 // TODO(jmadill): Assert we don't need to drop stencil.
386
387 SamplerKey key(baseLevel, mipLevels, false, false);
388 ANGLE_TRY(getCachedOrCreateSRVForSampler(context, key, outSRV));
389
390 return angle::Result::Continue;
391 }
392
getSRVForImage(const gl::Context * context,const gl::ImageUnit & imageUnit,const d3d11::SharedSRV ** outSRV)393 angle::Result TextureStorage11::getSRVForImage(const gl::Context *context,
394 const gl::ImageUnit &imageUnit,
395 const d3d11::SharedSRV **outSRV)
396 {
397 ANGLE_TRY(resolveTexture(context));
398 // TODO(Xinghua.cao@intel.com): Add solution to handle swizzle required.
399 ImageKey key(imageUnit.level, (imageUnit.layered == GL_TRUE), imageUnit.layer, imageUnit.access,
400 imageUnit.format);
401 ANGLE_TRY(getCachedOrCreateSRVForImage(context, key, outSRV));
402 return angle::Result::Continue;
403 }
404
getCachedOrCreateSRVForImage(const gl::Context * context,const ImageKey & key,const d3d11::SharedSRV ** outSRV)405 angle::Result TextureStorage11::getCachedOrCreateSRVForImage(const gl::Context *context,
406 const ImageKey &key,
407 const d3d11::SharedSRV **outSRV)
408 {
409 auto iter = mSrvCacheForImage.find(key);
410 if (iter != mSrvCacheForImage.end())
411 {
412 *outSRV = &iter->second;
413 return angle::Result::Continue;
414 }
415 const TextureHelper11 *texture = nullptr;
416 ANGLE_TRY(getResource(context, &texture));
417 DXGI_FORMAT format =
418 d3d11::Format::Get(key.format, mRenderer->getRenderer11DeviceCaps()).srvFormat;
419 d3d11::SharedSRV srv;
420 ANGLE_TRY(createSRVForImage(context, key.level, format, *texture, &srv));
421 const auto &insertIt = mSrvCacheForImage.insert(std::make_pair(key, std::move(srv)));
422 *outSRV = &insertIt.first->second;
423 return angle::Result::Continue;
424 }
425
getUAVForImage(const gl::Context * context,const gl::ImageUnit & imageUnit,const d3d11::SharedUAV ** outUAV)426 angle::Result TextureStorage11::getUAVForImage(const gl::Context *context,
427 const gl::ImageUnit &imageUnit,
428 const d3d11::SharedUAV **outUAV)
429 {
430 ANGLE_TRY(resolveTexture(context));
431 // TODO(Xinghua.cao@intel.com): Add solution to handle swizzle required.
432 ImageKey key(imageUnit.level, (imageUnit.layered == GL_TRUE), imageUnit.layer, imageUnit.access,
433 imageUnit.format);
434 ANGLE_TRY(getCachedOrCreateUAVForImage(context, key, outUAV));
435 return angle::Result::Continue;
436 }
437
getCachedOrCreateUAVForImage(const gl::Context * context,const ImageKey & key,const d3d11::SharedUAV ** outUAV)438 angle::Result TextureStorage11::getCachedOrCreateUAVForImage(const gl::Context *context,
439 const ImageKey &key,
440 const d3d11::SharedUAV **outUAV)
441 {
442 auto iter = mUavCacheForImage.find(key);
443 if (iter != mUavCacheForImage.end())
444 {
445 *outUAV = &iter->second;
446 return angle::Result::Continue;
447 }
448 const TextureHelper11 *texture = nullptr;
449 ANGLE_TRY(getResource(context, &texture));
450 DXGI_FORMAT format =
451 d3d11::Format::Get(key.format, mRenderer->getRenderer11DeviceCaps()).uavFormat;
452 d3d11::SharedUAV uav;
453 ANGLE_TRY(createUAVForImage(context, key.level, format, *texture, &uav));
454 const auto &insertIt = mUavCacheForImage.insert(std::make_pair(key, std::move(uav)));
455 *outUAV = &insertIt.first->second;
456 return angle::Result::Continue;
457 }
458
getFormatSet() const459 const d3d11::Format &TextureStorage11::getFormatSet() const
460 {
461 return mFormatInfo;
462 }
463
generateSwizzles(const gl::Context * context,const gl::SwizzleState & swizzleTarget)464 angle::Result TextureStorage11::generateSwizzles(const gl::Context *context,
465 const gl::SwizzleState &swizzleTarget)
466 {
467 ANGLE_TRY(resolveTexture(context));
468 for (int level = 0; level < getLevelCount(); level++)
469 {
470 // Check if the swizzle for this level is out of date
471 if (mSwizzleCache[level] != swizzleTarget)
472 {
473 // Need to re-render the swizzle for this level
474 const d3d11::SharedSRV *sourceSRV = nullptr;
475 ANGLE_TRY(getSRVLevel(context, level, true, &sourceSRV));
476
477 const d3d11::RenderTargetView *destRTV;
478 ANGLE_TRY(getSwizzleRenderTarget(context, level, &destRTV));
479
480 gl::Extents size(getLevelWidth(level), getLevelHeight(level), getLevelDepth(level));
481
482 Blit11 *blitter = mRenderer->getBlitter();
483
484 ANGLE_TRY(blitter->swizzleTexture(context, *sourceSRV, *destRTV, size, swizzleTarget));
485
486 mSwizzleCache[level] = swizzleTarget;
487 }
488 }
489
490 return angle::Result::Continue;
491 }
492
markLevelDirty(int mipLevel)493 void TextureStorage11::markLevelDirty(int mipLevel)
494 {
495 if (mipLevel >= 0 && static_cast<size_t>(mipLevel) < mSwizzleCache.size())
496 {
497 // The default constructor of SwizzleState has GL_INVALID_INDEX for all channels which is
498 // not a valid swizzle combination
499 if (mSwizzleCache[mipLevel] != gl::SwizzleState())
500 {
501 // TODO(jmadill): Invalidate specific swizzle.
502 mRenderer->getStateManager()->invalidateSwizzles();
503 mSwizzleCache[mipLevel] = gl::SwizzleState();
504 }
505 }
506
507 if (mDropStencilTexture.valid())
508 {
509 mDropStencilTexture.reset();
510 }
511 }
512
markDirty()513 void TextureStorage11::markDirty()
514 {
515 for (size_t mipLevel = 0; mipLevel < mSwizzleCache.size(); ++mipLevel)
516 {
517 markLevelDirty(static_cast<int>(mipLevel));
518 }
519 }
520
updateSubresourceLevel(const gl::Context * context,const TextureHelper11 & srcTexture,unsigned int sourceSubresource,const gl::ImageIndex & index,const gl::Box & copyArea)521 angle::Result TextureStorage11::updateSubresourceLevel(const gl::Context *context,
522 const TextureHelper11 &srcTexture,
523 unsigned int sourceSubresource,
524 const gl::ImageIndex &index,
525 const gl::Box ©Area)
526 {
527 ASSERT(srcTexture.valid());
528
529 ANGLE_TRY(resolveTexture(context));
530 const GLint level = index.getLevelIndex();
531
532 markLevelDirty(level);
533
534 gl::Extents texSize(getLevelWidth(level), getLevelHeight(level), getLevelDepth(level));
535
536 bool fullCopy = copyArea.coversSameExtent(texSize);
537
538 const TextureHelper11 *dstTexture = nullptr;
539
540 // If the zero-LOD workaround is active and we want to update a level greater than zero, then we
541 // should update the mipmapped texture, even if mapmaps are currently disabled.
542 if (level > 0 && mRenderer->getFeatures().zeroMaxLodWorkaround.enabled)
543 {
544 ANGLE_TRY(getMippedResource(context, &dstTexture));
545 }
546 else
547 {
548 ANGLE_TRY(getResource(context, &dstTexture));
549 }
550
551 unsigned int dstSubresource = 0;
552 ANGLE_TRY(getSubresourceIndex(context, index, &dstSubresource));
553
554 ASSERT(dstTexture->valid());
555
556 const d3d11::DXGIFormatSize &dxgiFormatSizeInfo =
557 d3d11::GetDXGIFormatSizeInfo(mFormatInfo.texFormat);
558 if (!fullCopy && mFormatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN)
559 {
560 // CopySubresourceRegion cannot copy partial depth stencils, use the blitter instead
561 Blit11 *blitter = mRenderer->getBlitter();
562 return blitter->copyDepthStencil(context, srcTexture, sourceSubresource, copyArea, texSize,
563 *dstTexture, dstSubresource, copyArea, texSize, nullptr);
564 }
565
566 D3D11_BOX srcBox;
567 srcBox.left = copyArea.x;
568 srcBox.top = copyArea.y;
569 srcBox.right =
570 copyArea.x + roundUp(static_cast<UINT>(copyArea.width), dxgiFormatSizeInfo.blockWidth);
571 srcBox.bottom =
572 copyArea.y + roundUp(static_cast<UINT>(copyArea.height), dxgiFormatSizeInfo.blockHeight);
573 srcBox.front = copyArea.z;
574 srcBox.back = copyArea.z + copyArea.depth;
575
576 ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
577
578 deviceContext->CopySubresourceRegion(dstTexture->get(), dstSubresource, copyArea.x, copyArea.y,
579 copyArea.z, srcTexture.get(), sourceSubresource,
580 fullCopy ? nullptr : &srcBox);
581 return angle::Result::Continue;
582 }
583
copySubresourceLevel(const gl::Context * context,const TextureHelper11 & dstTexture,unsigned int dstSubresource,const gl::ImageIndex & index,const gl::Box & region)584 angle::Result TextureStorage11::copySubresourceLevel(const gl::Context *context,
585 const TextureHelper11 &dstTexture,
586 unsigned int dstSubresource,
587 const gl::ImageIndex &index,
588 const gl::Box ®ion)
589 {
590 ASSERT(dstTexture.valid());
591
592 ANGLE_TRY(resolveTexture(context));
593 const TextureHelper11 *srcTexture = nullptr;
594
595 // If the zero-LOD workaround is active and we want to update a level greater than zero, then we
596 // should update the mipmapped texture, even if mapmaps are currently disabled.
597 if (index.getLevelIndex() > 0 && mRenderer->getFeatures().zeroMaxLodWorkaround.enabled)
598 {
599 ANGLE_TRY(getMippedResource(context, &srcTexture));
600 }
601 else
602 {
603 ANGLE_TRY(getResource(context, &srcTexture));
604 }
605
606 ASSERT(srcTexture->valid());
607
608 unsigned int srcSubresource = 0;
609 ANGLE_TRY(getSubresourceIndex(context, index, &srcSubresource));
610
611 ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
612
613 // D3D11 can't perform partial CopySubresourceRegion on depth/stencil textures, so pSrcBox
614 // should be nullptr.
615 D3D11_BOX srcBox;
616 D3D11_BOX *pSrcBox = nullptr;
617 if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3)
618 {
619 GLsizei width = region.width;
620 GLsizei height = region.height;
621 d3d11::MakeValidSize(false, mFormatInfo.texFormat, &width, &height, nullptr);
622
623 // Keep srcbox as nullptr if we're dealing with tiny mips of compressed textures.
624 if (width == region.width && height == region.height)
625 {
626 // However, D3D10Level9 doesn't always perform CopySubresourceRegion correctly unless
627 // the source box is specified. This is okay, since we don't perform
628 // CopySubresourceRegion on depth/stencil textures on 9_3.
629 ASSERT(mFormatInfo.dsvFormat == DXGI_FORMAT_UNKNOWN);
630 srcBox.left = region.x;
631 srcBox.right = region.x + region.width;
632 srcBox.top = region.y;
633 srcBox.bottom = region.y + region.height;
634 srcBox.front = region.z;
635 srcBox.back = region.z + region.depth;
636 pSrcBox = &srcBox;
637 }
638 }
639
640 deviceContext->CopySubresourceRegion(dstTexture.get(), dstSubresource, region.x, region.y,
641 region.z, srcTexture->get(), srcSubresource, pSrcBox);
642
643 return angle::Result::Continue;
644 }
645
generateMipmap(const gl::Context * context,const gl::ImageIndex & sourceIndex,const gl::ImageIndex & destIndex)646 angle::Result TextureStorage11::generateMipmap(const gl::Context *context,
647 const gl::ImageIndex &sourceIndex,
648 const gl::ImageIndex &destIndex)
649 {
650 ASSERT(sourceIndex.getLayerIndex() == destIndex.getLayerIndex());
651
652 ANGLE_TRY(resolveTexture(context));
653 markLevelDirty(destIndex.getLevelIndex());
654
655 RenderTargetD3D *source = nullptr;
656 ANGLE_TRY(getRenderTarget(context, sourceIndex, 0, &source));
657
658 // dest will always have 0 since, we have just released the MS Texture struct
659 RenderTargetD3D *dest = nullptr;
660 ANGLE_TRY(getRenderTarget(context, destIndex, 0, &dest));
661
662 RenderTarget11 *srcRT11 = GetAs<RenderTarget11>(source);
663 RenderTarget11 *dstRT11 = GetAs<RenderTarget11>(dest);
664 const d3d11::SharedSRV &sourceSRV = srcRT11->getBlitShaderResourceView(context);
665 const d3d11::RenderTargetView &destRTV = dstRT11->getRenderTargetView();
666
667 gl::Box sourceArea(0, 0, 0, source->getWidth(), source->getHeight(), source->getDepth());
668 gl::Extents sourceSize(source->getWidth(), source->getHeight(), source->getDepth());
669
670 gl::Box destArea(0, 0, 0, dest->getWidth(), dest->getHeight(), dest->getDepth());
671 gl::Extents destSize(dest->getWidth(), dest->getHeight(), dest->getDepth());
672
673 Blit11 *blitter = mRenderer->getBlitter();
674 const gl::InternalFormat &sourceInternalFormat =
675 gl::GetSizedInternalFormatInfo(source->getInternalFormat());
676 GLenum format = sourceInternalFormat.format;
677 GLenum type = sourceInternalFormat.type;
678 return blitter->copyTexture(context, sourceSRV, sourceArea, sourceSize, format, destRTV,
679 destArea, destSize, nullptr, format, type, GL_LINEAR, false, false,
680 false);
681 }
682
verifySwizzleExists(const gl::SwizzleState & swizzleState)683 void TextureStorage11::verifySwizzleExists(const gl::SwizzleState &swizzleState)
684 {
685 for (unsigned int level = 0; level < mMipLevels; level++)
686 {
687 ASSERT(mSwizzleCache[level] == swizzleState);
688 }
689 }
690
clearSRVCache()691 void TextureStorage11::clearSRVCache()
692 {
693 markDirty();
694 mSrvCacheForSampler.clear();
695
696 for (size_t level = 0; level < mLevelSRVs.size(); level++)
697 {
698 mLevelSRVs[level].reset();
699 mLevelBlitSRVs[level].reset();
700 }
701 }
702
copyToStorage(const gl::Context * context,TextureStorage * destStorage)703 angle::Result TextureStorage11::copyToStorage(const gl::Context *context,
704 TextureStorage *destStorage)
705 {
706 ASSERT(destStorage);
707
708 ANGLE_TRY(resolveTexture(context));
709 const TextureHelper11 *sourceResouce = nullptr;
710 ANGLE_TRY(getResource(context, &sourceResouce));
711
712 TextureStorage11 *dest11 = GetAs<TextureStorage11>(destStorage);
713 const TextureHelper11 *destResource = nullptr;
714 ANGLE_TRY(dest11->getResource(context, &destResource));
715
716 ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext();
717 immediateContext->CopyResource(destResource->get(), sourceResouce->get());
718
719 dest11->markDirty();
720
721 return angle::Result::Continue;
722 }
723
invalidateTextures()724 void TextureStorage11::invalidateTextures()
725 {
726 mRenderer->getStateManager()->invalidateTexturesAndSamplers();
727 }
728
setData(const gl::Context * context,const gl::ImageIndex & index,ImageD3D * image,const gl::Box * destBox,GLenum type,const gl::PixelUnpackState & unpack,const uint8_t * pixelData)729 angle::Result TextureStorage11::setData(const gl::Context *context,
730 const gl::ImageIndex &index,
731 ImageD3D *image,
732 const gl::Box *destBox,
733 GLenum type,
734 const gl::PixelUnpackState &unpack,
735 const uint8_t *pixelData)
736 {
737 ASSERT(!image->isDirty());
738
739 ANGLE_TRY(resolveTexture(context));
740 markLevelDirty(index.getLevelIndex());
741
742 const TextureHelper11 *resource = nullptr;
743 ANGLE_TRY(getResource(context, &resource));
744 ASSERT(resource && resource->valid());
745
746 UINT destSubresource = 0;
747 ANGLE_TRY(getSubresourceIndex(context, index, &destSubresource));
748
749 const gl::InternalFormat &internalFormatInfo =
750 gl::GetInternalFormatInfo(image->getInternalFormat(), type);
751
752 gl::Box levelBox(0, 0, 0, getLevelWidth(index.getLevelIndex()),
753 getLevelHeight(index.getLevelIndex()), getLevelDepth(index.getLevelIndex()));
754 bool fullUpdate = (destBox == nullptr || *destBox == levelBox);
755 ASSERT(internalFormatInfo.depthBits == 0 || fullUpdate);
756
757 // TODO(jmadill): Handle compressed formats
758 // Compressed formats have different load syntax, so we'll have to handle them with slightly
759 // different logic. Will implemnent this in a follow-up patch, and ensure we do not use SetData
760 // with compressed formats in the calling logic.
761 ASSERT(!internalFormatInfo.compressed);
762
763 Context11 *context11 = GetImplAs<Context11>(context);
764
765 const int width = destBox ? destBox->width : static_cast<int>(image->getWidth());
766 const int height = destBox ? destBox->height : static_cast<int>(image->getHeight());
767 const int depth = destBox ? destBox->depth : static_cast<int>(image->getDepth());
768 GLuint srcRowPitch = 0;
769 ANGLE_CHECK_GL_MATH(context11,
770 internalFormatInfo.computeRowPitch(type, width, unpack.alignment,
771 unpack.rowLength, &srcRowPitch));
772 GLuint srcDepthPitch = 0;
773 ANGLE_CHECK_GL_MATH(context11, internalFormatInfo.computeDepthPitch(
774 height, unpack.imageHeight, srcRowPitch, &srcDepthPitch));
775 GLuint srcSkipBytes = 0;
776 ANGLE_CHECK_GL_MATH(
777 context11, internalFormatInfo.computeSkipBytes(type, srcRowPitch, srcDepthPitch, unpack,
778 index.usesTex3D(), &srcSkipBytes));
779
780 const d3d11::Format &d3d11Format =
781 d3d11::Format::Get(image->getInternalFormat(), mRenderer->getRenderer11DeviceCaps());
782 const d3d11::DXGIFormatSize &dxgiFormatInfo =
783 d3d11::GetDXGIFormatSizeInfo(d3d11Format.texFormat);
784
785 const size_t outputPixelSize = dxgiFormatInfo.pixelBytes;
786
787 UINT bufferRowPitch = static_cast<unsigned int>(outputPixelSize) * width;
788 UINT bufferDepthPitch = bufferRowPitch * height;
789
790 const size_t neededSize = bufferDepthPitch * depth;
791 angle::MemoryBuffer *conversionBuffer = nullptr;
792 const uint8_t *data = nullptr;
793
794 LoadImageFunctionInfo loadFunctionInfo = d3d11Format.getLoadFunctions()(type);
795 if (loadFunctionInfo.requiresConversion)
796 {
797 ANGLE_TRY(mRenderer->getScratchMemoryBuffer(context11, neededSize, &conversionBuffer));
798 loadFunctionInfo.loadFunction(width, height, depth, pixelData + srcSkipBytes, srcRowPitch,
799 srcDepthPitch, conversionBuffer->data(), bufferRowPitch,
800 bufferDepthPitch);
801 data = conversionBuffer->data();
802 }
803 else
804 {
805 data = pixelData + srcSkipBytes;
806 bufferRowPitch = srcRowPitch;
807 bufferDepthPitch = srcDepthPitch;
808 }
809
810 ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext();
811
812 if (!fullUpdate)
813 {
814 ASSERT(destBox);
815
816 D3D11_BOX destD3DBox;
817 destD3DBox.left = destBox->x;
818 destD3DBox.right = destBox->x + destBox->width;
819 destD3DBox.top = destBox->y;
820 destD3DBox.bottom = destBox->y + destBox->height;
821 destD3DBox.front = destBox->z;
822 destD3DBox.back = destBox->z + destBox->depth;
823
824 immediateContext->UpdateSubresource(resource->get(), destSubresource, &destD3DBox, data,
825 bufferRowPitch, bufferDepthPitch);
826 }
827 else
828 {
829 immediateContext->UpdateSubresource(resource->get(), destSubresource, nullptr, data,
830 bufferRowPitch, bufferDepthPitch);
831 }
832
833 return angle::Result::Continue;
834 }
835
ensureDropStencilTexture(const gl::Context * context,TextureStorage11::DropStencil * dropStencilOut)836 angle::Result TextureStorage11::ensureDropStencilTexture(
837 const gl::Context *context,
838 TextureStorage11::DropStencil *dropStencilOut)
839 {
840 ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
841 return angle::Result::Stop;
842 }
843
initDropStencilTexture(const gl::Context * context,const gl::ImageIndexIterator & it)844 angle::Result TextureStorage11::initDropStencilTexture(const gl::Context *context,
845 const gl::ImageIndexIterator &it)
846 {
847 const TextureHelper11 *sourceTexture = nullptr;
848 ANGLE_TRY(getResource(context, &sourceTexture));
849
850 gl::ImageIndexIterator itCopy = it;
851
852 while (itCopy.hasNext())
853 {
854 gl::ImageIndex index = itCopy.next();
855 gl::Box wholeArea(0, 0, 0, getLevelWidth(index.getLevelIndex()),
856 getLevelHeight(index.getLevelIndex()), 1);
857 gl::Extents wholeSize(wholeArea.width, wholeArea.height, 1);
858
859 UINT subresource = 0;
860 ANGLE_TRY(getSubresourceIndex(context, index, &subresource));
861
862 ANGLE_TRY(mRenderer->getBlitter()->copyDepthStencil(
863 context, *sourceTexture, subresource, wholeArea, wholeSize, mDropStencilTexture,
864 subresource, wholeArea, wholeSize, nullptr));
865 }
866
867 return angle::Result::Continue;
868 }
869
resolveTextureHelper(const gl::Context * context,const TextureHelper11 & texture)870 angle::Result TextureStorage11::resolveTextureHelper(const gl::Context *context,
871 const TextureHelper11 &texture)
872 {
873 UINT subresourceIndexSS;
874 ANGLE_TRY(getSubresourceIndex(context, mMSTexInfo->indexSS, &subresourceIndexSS));
875 UINT subresourceIndexMS;
876 ANGLE_TRY(getSubresourceIndex(context, mMSTexInfo->indexMS, &subresourceIndexMS));
877 ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
878 const TextureHelper11 *resource = nullptr;
879 ANGLE_TRY(mMSTexInfo->msTex->getResource(context, &resource));
880 deviceContext->ResolveSubresource(texture.get(), subresourceIndexSS, resource->get(),
881 subresourceIndexMS, texture.getFormat());
882 mMSTexInfo->msTextureNeedsResolve = false;
883 return angle::Result::Continue;
884 }
885
releaseMultisampledTexStorageForLevel(size_t level)886 angle::Result TextureStorage11::releaseMultisampledTexStorageForLevel(size_t level)
887 {
888 if (mMSTexInfo && mMSTexInfo->indexSS.getLevelIndex() == static_cast<int>(level))
889 {
890 mMSTexInfo->msTex.reset();
891 onStateChange(angle::SubjectMessage::ContentsChanged);
892 }
893 return angle::Result::Continue;
894 }
895
getRenderToTextureSamples() const896 GLsizei TextureStorage11::getRenderToTextureSamples() const
897 {
898 if (mMSTexInfo)
899 {
900 return mMSTexInfo->samples;
901 }
902 return 0;
903 }
904
findMultisampledRenderTarget(const gl::Context * context,const gl::ImageIndex & index,GLsizei samples,RenderTargetD3D ** outRT) const905 angle::Result TextureStorage11::findMultisampledRenderTarget(const gl::Context *context,
906 const gl::ImageIndex &index,
907 GLsizei samples,
908 RenderTargetD3D **outRT) const
909 {
910 const int level = index.getLevelIndex();
911 if (!mMSTexInfo || level != mMSTexInfo->indexSS.getLevelIndex() ||
912 samples != mMSTexInfo->samples || !mMSTexInfo->msTex)
913 {
914 *outRT = nullptr;
915 return angle::Result::Continue;
916 }
917 RenderTargetD3D *rt;
918 ANGLE_TRY(mMSTexInfo->msTex->findRenderTarget(context, mMSTexInfo->indexMS, samples, &rt));
919 *outRT = rt;
920 return angle::Result::Continue;
921 }
922
getMultisampledRenderTarget(const gl::Context * context,const gl::ImageIndex & index,GLsizei samples,RenderTargetD3D ** outRT)923 angle::Result TextureStorage11::getMultisampledRenderTarget(const gl::Context *context,
924 const gl::ImageIndex &index,
925 GLsizei samples,
926 RenderTargetD3D **outRT)
927 {
928 const int level = index.getLevelIndex();
929 if (!mMSTexInfo || level != mMSTexInfo->indexSS.getLevelIndex() ||
930 samples != mMSTexInfo->samples || !mMSTexInfo->msTex)
931 {
932 // if mMSTexInfo already exists, then we want to resolve and release it
933 // since the mMSTexInfo must be for a different sample count or level
934 ANGLE_TRY(resolveTexture(context));
935
936 // Now we can create a new object for the correct sample and level
937 GLsizei width = getLevelWidth(level);
938 GLsizei height = getLevelHeight(level);
939 GLenum internalFormat = mFormatInfo.internalFormat;
940 std::unique_ptr<TextureStorage11_2DMultisample> texMS(
941 GetAs<TextureStorage11_2DMultisample>(mRenderer->createTextureStorage2DMultisample(
942 internalFormat, width, height, level, samples, true)));
943
944 // make sure multisample object has the blitted information.
945 gl::Rectangle area(0, 0, width, height);
946 RenderTargetD3D *readRenderTarget = nullptr;
947 // use incoming index here since the index will correspond to the single sampled texture
948 ANGLE_TRY(getRenderTarget(context, index, 0, &readRenderTarget));
949 gl::ImageIndex indexMS = gl::ImageIndex::Make2DMultisample();
950 RenderTargetD3D *drawRenderTarget = nullptr;
951 ANGLE_TRY(texMS->getRenderTarget(context, indexMS, samples, &drawRenderTarget));
952
953 // blit SS -> MS
954 // mask: GL_COLOR_BUFFER_BIT, filter: GL_NEAREST
955 ANGLE_TRY(mRenderer->blitRenderbufferRect(context, area, area, readRenderTarget,
956 drawRenderTarget, GL_NEAREST, nullptr, true,
957 false, false));
958 mMSTexInfo = std::make_unique<MultisampledRenderToTextureInfo>(samples, index, indexMS);
959 mMSTexInfo->msTex = std::move(texMS);
960 }
961 RenderTargetD3D *rt;
962 ANGLE_TRY(mMSTexInfo->msTex->getRenderTarget(context, mMSTexInfo->indexMS, samples, &rt));
963 // By returning the multisampled render target to the caller, the render target
964 // is expected to be changed so we need to resolve to a single sampled texture
965 // next time resolveTexture is called.
966 mMSTexInfo->msTextureNeedsResolve = true;
967 *outRT = rt;
968 return angle::Result::Continue;
969 }
970
TextureStorage11_2D(Renderer11 * renderer,SwapChain11 * swapchain)971 TextureStorage11_2D::TextureStorage11_2D(Renderer11 *renderer, SwapChain11 *swapchain)
972 : TextureStorage11(renderer,
973 D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE,
974 0,
975 swapchain->getRenderTargetInternalFormat()),
976 mTexture(swapchain->getOffscreenTexture()),
977 mLevelZeroTexture(),
978 mLevelZeroRenderTarget(nullptr),
979 mUseLevelZeroTexture(false),
980 mSwizzleTexture()
981 {
982 for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
983 {
984 mAssociatedImages[i] = nullptr;
985 mRenderTarget[i] = nullptr;
986 }
987
988 D3D11_TEXTURE2D_DESC texDesc;
989 mTexture.getDesc(&texDesc);
990 mMipLevels = texDesc.MipLevels;
991 mTextureWidth = texDesc.Width;
992 mTextureHeight = texDesc.Height;
993 mTextureDepth = 1;
994 mHasKeyedMutex = (texDesc.MiscFlags & D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX) != 0;
995 }
996
TextureStorage11_2D(Renderer11 * renderer,GLenum internalformat,bool renderTarget,GLsizei width,GLsizei height,int levels,bool hintLevelZeroOnly)997 TextureStorage11_2D::TextureStorage11_2D(Renderer11 *renderer,
998 GLenum internalformat,
999 bool renderTarget,
1000 GLsizei width,
1001 GLsizei height,
1002 int levels,
1003 bool hintLevelZeroOnly)
1004 : TextureStorage11(
1005 renderer,
1006 GetTextureBindFlags(internalformat, renderer->getRenderer11DeviceCaps(), renderTarget),
1007 GetTextureMiscFlags(internalformat,
1008 renderer->getRenderer11DeviceCaps(),
1009 renderTarget,
1010 levels),
1011 internalformat),
1012 mTexture(),
1013 mHasKeyedMutex(false),
1014 mLevelZeroTexture(),
1015 mLevelZeroRenderTarget(nullptr),
1016 mUseLevelZeroTexture(hintLevelZeroOnly && levels > 1),
1017 mSwizzleTexture()
1018 {
1019 for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
1020 {
1021 mAssociatedImages[i] = nullptr;
1022 mRenderTarget[i] = nullptr;
1023 }
1024
1025 d3d11::MakeValidSize(false, mFormatInfo.texFormat, &width, &height, &mTopLevel);
1026 mMipLevels = mTopLevel + levels;
1027 mTextureWidth = width;
1028 mTextureHeight = height;
1029 mTextureDepth = 1;
1030
1031 // The LevelZeroOnly hint should only be true if the zero max LOD workaround is active.
1032 ASSERT(!mUseLevelZeroTexture || mRenderer->getFeatures().zeroMaxLodWorkaround.enabled);
1033 }
1034
onDestroy(const gl::Context * context)1035 angle::Result TextureStorage11_2D::onDestroy(const gl::Context *context)
1036 {
1037 for (unsigned i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
1038 {
1039 if (mAssociatedImages[i] != nullptr)
1040 {
1041 mAssociatedImages[i]->verifyAssociatedStorageValid(this);
1042
1043 // We must let the Images recover their data before we delete it from the
1044 // TextureStorage.
1045 ANGLE_TRY(mAssociatedImages[i]->recoverFromAssociatedStorage(context));
1046 }
1047 }
1048
1049 if (mHasKeyedMutex)
1050 {
1051 // If the keyed mutex is released that will unbind it and cause the state cache to become
1052 // desynchronized.
1053 mRenderer->getStateManager()->invalidateBoundViews();
1054 }
1055
1056 return angle::Result::Continue;
1057 }
1058
~TextureStorage11_2D()1059 TextureStorage11_2D::~TextureStorage11_2D() {}
1060
copyToStorage(const gl::Context * context,TextureStorage * destStorage)1061 angle::Result TextureStorage11_2D::copyToStorage(const gl::Context *context,
1062 TextureStorage *destStorage)
1063 {
1064 ASSERT(destStorage);
1065
1066 TextureStorage11_2D *dest11 = GetAs<TextureStorage11_2D>(destStorage);
1067 ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext();
1068
1069 if (mRenderer->getFeatures().zeroMaxLodWorkaround.enabled)
1070 {
1071 // If either mTexture or mLevelZeroTexture exist, then we need to copy them into the
1072 // corresponding textures in destStorage.
1073 if (mTexture.valid())
1074 {
1075 ANGLE_TRY(dest11->useLevelZeroWorkaroundTexture(context, false));
1076
1077 const TextureHelper11 *destResource = nullptr;
1078 ANGLE_TRY(dest11->getResource(context, &destResource));
1079
1080 immediateContext->CopyResource(destResource->get(), mTexture.get());
1081 }
1082
1083 if (mLevelZeroTexture.valid())
1084 {
1085 ANGLE_TRY(dest11->useLevelZeroWorkaroundTexture(context, true));
1086
1087 const TextureHelper11 *destResource = nullptr;
1088 ANGLE_TRY(dest11->getResource(context, &destResource));
1089
1090 immediateContext->CopyResource(destResource->get(), mLevelZeroTexture.get());
1091 }
1092
1093 return angle::Result::Continue;
1094 }
1095
1096 const TextureHelper11 *sourceResouce = nullptr;
1097 ANGLE_TRY(getResource(context, &sourceResouce));
1098
1099 const TextureHelper11 *destResource = nullptr;
1100 ANGLE_TRY(dest11->getResource(context, &destResource));
1101
1102 immediateContext->CopyResource(destResource->get(), sourceResouce->get());
1103 dest11->markDirty();
1104
1105 return angle::Result::Continue;
1106 }
1107
useLevelZeroWorkaroundTexture(const gl::Context * context,bool useLevelZeroTexture)1108 angle::Result TextureStorage11_2D::useLevelZeroWorkaroundTexture(const gl::Context *context,
1109 bool useLevelZeroTexture)
1110 {
1111 if (useLevelZeroTexture && mMipLevels > 1)
1112 {
1113 if (!mUseLevelZeroTexture && mTexture.valid())
1114 {
1115 ANGLE_TRY(ensureTextureExists(context, 1));
1116
1117 // Pull data back from the mipped texture if necessary.
1118 ASSERT(mLevelZeroTexture.valid());
1119 ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
1120 deviceContext->CopySubresourceRegion(mLevelZeroTexture.get(), 0, 0, 0, 0,
1121 mTexture.get(), 0, nullptr);
1122 }
1123
1124 mUseLevelZeroTexture = true;
1125 }
1126 else
1127 {
1128 if (mUseLevelZeroTexture && mLevelZeroTexture.valid())
1129 {
1130 ANGLE_TRY(ensureTextureExists(context, mMipLevels));
1131
1132 // Pull data back from the level zero texture if necessary.
1133 ASSERT(mTexture.valid());
1134 ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
1135 deviceContext->CopySubresourceRegion(mTexture.get(), 0, 0, 0, 0,
1136 mLevelZeroTexture.get(), 0, nullptr);
1137 }
1138
1139 mUseLevelZeroTexture = false;
1140 }
1141
1142 return angle::Result::Continue;
1143 }
1144
associateImage(Image11 * image,const gl::ImageIndex & index)1145 void TextureStorage11_2D::associateImage(Image11 *image, const gl::ImageIndex &index)
1146 {
1147 const GLint level = index.getLevelIndex();
1148
1149 ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
1150 if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
1151 {
1152 mAssociatedImages[level] = image;
1153 }
1154 }
1155
verifyAssociatedImageValid(const gl::ImageIndex & index,Image11 * expectedImage)1156 void TextureStorage11_2D::verifyAssociatedImageValid(const gl::ImageIndex &index,
1157 Image11 *expectedImage)
1158 {
1159 const GLint level = index.getLevelIndex();
1160
1161 ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
1162 // This validation check should never return false. It means the Image/TextureStorage
1163 // association is broken.
1164 ASSERT(mAssociatedImages[level] == expectedImage);
1165 }
1166
1167 // disassociateImage allows an Image to end its association with a Storage.
disassociateImage(const gl::ImageIndex & index,Image11 * expectedImage)1168 void TextureStorage11_2D::disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage)
1169 {
1170 const GLint level = index.getLevelIndex();
1171
1172 ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
1173 ASSERT(mAssociatedImages[level] == expectedImage);
1174 mAssociatedImages[level] = nullptr;
1175 }
1176
1177 // releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image
1178 // recover its data before ending the association.
releaseAssociatedImage(const gl::Context * context,const gl::ImageIndex & index,Image11 * incomingImage)1179 angle::Result TextureStorage11_2D::releaseAssociatedImage(const gl::Context *context,
1180 const gl::ImageIndex &index,
1181 Image11 *incomingImage)
1182 {
1183 const GLint level = index.getLevelIndex();
1184
1185 ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
1186
1187 if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
1188 {
1189 // No need to let the old Image recover its data, if it is also the incoming Image.
1190 if (mAssociatedImages[level] != nullptr && mAssociatedImages[level] != incomingImage)
1191 {
1192 // Ensure that the Image is still associated with this TextureStorage.
1193 mAssociatedImages[level]->verifyAssociatedStorageValid(this);
1194
1195 // Force the image to recover from storage before its data is overwritten.
1196 // This will reset mAssociatedImages[level] to nullptr too.
1197 ANGLE_TRY(mAssociatedImages[level]->recoverFromAssociatedStorage(context));
1198 }
1199 }
1200
1201 return angle::Result::Continue;
1202 }
1203
getResource(const gl::Context * context,const TextureHelper11 ** outResource)1204 angle::Result TextureStorage11_2D::getResource(const gl::Context *context,
1205 const TextureHelper11 **outResource)
1206 {
1207 if (mUseLevelZeroTexture && mMipLevels > 1)
1208 {
1209 ANGLE_TRY(ensureTextureExists(context, 1));
1210
1211 *outResource = &mLevelZeroTexture;
1212 return angle::Result::Continue;
1213 }
1214
1215 ANGLE_TRY(ensureTextureExists(context, mMipLevels));
1216
1217 *outResource = &mTexture;
1218 return angle::Result::Continue;
1219 }
1220
getMippedResource(const gl::Context * context,const TextureHelper11 ** outResource)1221 angle::Result TextureStorage11_2D::getMippedResource(const gl::Context *context,
1222 const TextureHelper11 **outResource)
1223 {
1224 // This shouldn't be called unless the zero max LOD workaround is active.
1225 ASSERT(mRenderer->getFeatures().zeroMaxLodWorkaround.enabled);
1226
1227 ANGLE_TRY(ensureTextureExists(context, mMipLevels));
1228
1229 *outResource = &mTexture;
1230 return angle::Result::Continue;
1231 }
1232
ensureTextureExists(const gl::Context * context,int mipLevels)1233 angle::Result TextureStorage11_2D::ensureTextureExists(const gl::Context *context, int mipLevels)
1234 {
1235 // If mMipLevels = 1 then always use mTexture rather than mLevelZeroTexture.
1236 ANGLE_TRY(resolveTexture(context));
1237 bool useLevelZeroTexture = mRenderer->getFeatures().zeroMaxLodWorkaround.enabled
1238 ? (mipLevels == 1) && (mMipLevels > 1)
1239 : false;
1240 TextureHelper11 *outputTexture = useLevelZeroTexture ? &mLevelZeroTexture : &mTexture;
1241
1242 // if the width or height is not positive this should be treated as an incomplete texture
1243 // we handle that here by skipping the d3d texture creation
1244 if (!outputTexture->valid() && mTextureWidth > 0 && mTextureHeight > 0)
1245 {
1246 ASSERT(mipLevels > 0);
1247
1248 D3D11_TEXTURE2D_DESC desc;
1249 desc.Width = mTextureWidth; // Compressed texture size constraints?
1250 desc.Height = mTextureHeight;
1251 desc.MipLevels = mipLevels;
1252 desc.ArraySize = 1;
1253 desc.Format = mFormatInfo.texFormat;
1254 desc.SampleDesc.Count = 1;
1255 desc.SampleDesc.Quality = 0;
1256 desc.Usage = D3D11_USAGE_DEFAULT;
1257 desc.BindFlags = getBindFlags();
1258 desc.CPUAccessFlags = 0;
1259 desc.MiscFlags = getMiscFlags();
1260
1261 ANGLE_TRY(mRenderer->allocateTexture(GetImplAs<Context11>(context), desc, mFormatInfo,
1262 outputTexture));
1263
1264 if (useLevelZeroTexture)
1265 {
1266 outputTexture->setDebugName("TexStorage2D.Level0Texture");
1267 }
1268 else
1269 {
1270 outputTexture->setDebugName("TexStorage2D.Texture");
1271 }
1272 }
1273
1274 return angle::Result::Continue;
1275 }
1276
findRenderTarget(const gl::Context * context,const gl::ImageIndex & index,GLsizei samples,RenderTargetD3D ** outRT) const1277 angle::Result TextureStorage11_2D::findRenderTarget(const gl::Context *context,
1278 const gl::ImageIndex &index,
1279 GLsizei samples,
1280 RenderTargetD3D **outRT) const
1281 {
1282 ASSERT(!index.hasLayer());
1283
1284 const int level = index.getLevelIndex();
1285 ASSERT(level >= 0 && level < getLevelCount());
1286
1287 bool needMS = samples > 0;
1288 if (needMS)
1289 {
1290 return findMultisampledRenderTarget(context, index, samples, outRT);
1291 }
1292
1293 ASSERT(outRT);
1294 if (mRenderTarget[level])
1295 {
1296 *outRT = mRenderTarget[level].get();
1297 return angle::Result::Continue;
1298 }
1299
1300 if (mUseLevelZeroTexture)
1301 {
1302 ASSERT(level == 0);
1303 *outRT = mLevelZeroRenderTarget.get();
1304 return angle::Result::Continue;
1305 }
1306
1307 *outRT = nullptr;
1308 return angle::Result::Continue;
1309 }
1310
getRenderTarget(const gl::Context * context,const gl::ImageIndex & index,GLsizei samples,RenderTargetD3D ** outRT)1311 angle::Result TextureStorage11_2D::getRenderTarget(const gl::Context *context,
1312 const gl::ImageIndex &index,
1313 GLsizei samples,
1314 RenderTargetD3D **outRT)
1315 {
1316 ASSERT(!index.hasLayer());
1317
1318 const int level = index.getLevelIndex();
1319 ASSERT(level >= 0 && level < getLevelCount());
1320
1321 bool needMS = samples > 0;
1322 if (needMS)
1323 {
1324 return getMultisampledRenderTarget(context, index, samples, outRT);
1325 }
1326 else
1327 {
1328 ANGLE_TRY(resolveTexture(context));
1329 }
1330
1331 // In GL ES 2.0, the application can only render to level zero of the texture (Section 4.4.3 of
1332 // the GLES 2.0 spec, page 113 of version 2.0.25). Other parts of TextureStorage11_2D could
1333 // create RTVs on non-zero levels of the texture (e.g. generateMipmap).
1334 // On Feature Level 9_3, this is unlikely to be useful. The renderer can't create SRVs on the
1335 // individual levels of the texture, so methods like generateMipmap can't do anything useful
1336 // with non-zero-level RTVs. Therefore if level > 0 on 9_3 then there's almost certainly
1337 // something wrong.
1338 ASSERT(
1339 !(mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3 && level > 0));
1340 ASSERT(outRT);
1341 if (mRenderTarget[level])
1342 {
1343 *outRT = mRenderTarget[level].get();
1344 return angle::Result::Continue;
1345 }
1346
1347 if (mRenderer->getFeatures().zeroMaxLodWorkaround.enabled)
1348 {
1349 ASSERT(level == 0);
1350 ANGLE_TRY(useLevelZeroWorkaroundTexture(context, true));
1351 }
1352
1353 const TextureHelper11 *texture = nullptr;
1354 ANGLE_TRY(getResource(context, &texture));
1355
1356 const d3d11::SharedSRV *srv = nullptr;
1357 ANGLE_TRY(getSRVLevel(context, level, false, &srv));
1358
1359 const d3d11::SharedSRV *blitSRV = nullptr;
1360 ANGLE_TRY(getSRVLevel(context, level, true, &blitSRV));
1361
1362 Context11 *context11 = GetImplAs<Context11>(context);
1363
1364 if (mUseLevelZeroTexture)
1365 {
1366 if (!mLevelZeroRenderTarget)
1367 {
1368 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
1369 rtvDesc.Format = mFormatInfo.rtvFormat;
1370 rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
1371 rtvDesc.Texture2D.MipSlice = mTopLevel + level;
1372
1373 d3d11::RenderTargetView rtv;
1374 ANGLE_TRY(
1375 mRenderer->allocateResource(context11, rtvDesc, mLevelZeroTexture.get(), &rtv));
1376 rtv.setDebugName("TexStorage2D.Level0RTV");
1377
1378 mLevelZeroRenderTarget.reset(new TextureRenderTarget11(
1379 std::move(rtv), mLevelZeroTexture, d3d11::SharedSRV(), d3d11::SharedSRV(),
1380 mFormatInfo.internalFormat, getFormatSet(), getLevelWidth(level),
1381 getLevelHeight(level), 1, 0));
1382 }
1383
1384 *outRT = mLevelZeroRenderTarget.get();
1385 return angle::Result::Continue;
1386 }
1387
1388 if (mFormatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN)
1389 {
1390 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
1391 rtvDesc.Format = mFormatInfo.rtvFormat;
1392 rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
1393 rtvDesc.Texture2D.MipSlice = mTopLevel + level;
1394
1395 d3d11::RenderTargetView rtv;
1396 ANGLE_TRY(mRenderer->allocateResource(context11, rtvDesc, texture->get(), &rtv));
1397 rtv.setDebugName("TexStorage2D.RTV");
1398
1399 mRenderTarget[level].reset(new TextureRenderTarget11(
1400 std::move(rtv), *texture, *srv, *blitSRV, mFormatInfo.internalFormat, getFormatSet(),
1401 getLevelWidth(level), getLevelHeight(level), 1, 0));
1402
1403 *outRT = mRenderTarget[level].get();
1404 return angle::Result::Continue;
1405 }
1406
1407 ASSERT(mFormatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN);
1408
1409 D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
1410 dsvDesc.Format = mFormatInfo.dsvFormat;
1411 dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
1412 dsvDesc.Texture2D.MipSlice = mTopLevel + level;
1413 dsvDesc.Flags = 0;
1414
1415 d3d11::DepthStencilView dsv;
1416 ANGLE_TRY(mRenderer->allocateResource(context11, dsvDesc, texture->get(), &dsv));
1417 dsv.setDebugName("TexStorage2D.DSV");
1418
1419 mRenderTarget[level].reset(new TextureRenderTarget11(
1420 std::move(dsv), *texture, *srv, mFormatInfo.internalFormat, getFormatSet(),
1421 getLevelWidth(level), getLevelHeight(level), 1, 0));
1422
1423 *outRT = mRenderTarget[level].get();
1424 return angle::Result::Continue;
1425 }
1426
createSRVForSampler(const gl::Context * context,int baseLevel,int mipLevels,DXGI_FORMAT format,const TextureHelper11 & texture,d3d11::SharedSRV * outSRV)1427 angle::Result TextureStorage11_2D::createSRVForSampler(const gl::Context *context,
1428 int baseLevel,
1429 int mipLevels,
1430 DXGI_FORMAT format,
1431 const TextureHelper11 &texture,
1432 d3d11::SharedSRV *outSRV)
1433 {
1434 ASSERT(outSRV);
1435
1436 D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
1437 srvDesc.Format = format;
1438 srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
1439 srvDesc.Texture2D.MostDetailedMip = mTopLevel + baseLevel;
1440 srvDesc.Texture2D.MipLevels = mipLevels;
1441
1442 const TextureHelper11 *srvTexture = &texture;
1443
1444 if (mRenderer->getFeatures().zeroMaxLodWorkaround.enabled)
1445 {
1446 ASSERT(mTopLevel == 0);
1447 ASSERT(baseLevel == 0);
1448 // This code also assumes that the incoming texture equals either mLevelZeroTexture or
1449 // mTexture.
1450
1451 if (mipLevels == 1 && mMipLevels > 1)
1452 {
1453 // We must use a SRV on the level-zero-only texture.
1454 ANGLE_TRY(ensureTextureExists(context, 1));
1455 srvTexture = &mLevelZeroTexture;
1456 }
1457 else
1458 {
1459 ASSERT(mipLevels == static_cast<int>(mMipLevels));
1460 ASSERT(mTexture.valid() && texture == mTexture);
1461 srvTexture = &mTexture;
1462 }
1463 }
1464
1465 ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, srvTexture->get(),
1466 outSRV));
1467 outSRV->setDebugName("TexStorage2D.SRV");
1468
1469 return angle::Result::Continue;
1470 }
1471
createSRVForImage(const gl::Context * context,int level,DXGI_FORMAT format,const TextureHelper11 & texture,d3d11::SharedSRV * outSRV)1472 angle::Result TextureStorage11_2D::createSRVForImage(const gl::Context *context,
1473 int level,
1474 DXGI_FORMAT format,
1475 const TextureHelper11 &texture,
1476 d3d11::SharedSRV *outSRV)
1477 {
1478 ASSERT(outSRV);
1479 D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
1480 srvDesc.Format = format;
1481 srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
1482 srvDesc.Texture2D.MostDetailedMip = mTopLevel + level;
1483 srvDesc.Texture2D.MipLevels = 1;
1484 ANGLE_TRY(
1485 mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(), outSRV));
1486 outSRV->setDebugName("TexStorage2D.SRVForImage");
1487 return angle::Result::Continue;
1488 }
1489
createUAVForImage(const gl::Context * context,int level,DXGI_FORMAT format,const TextureHelper11 & texture,d3d11::SharedUAV * outUAV)1490 angle::Result TextureStorage11_2D::createUAVForImage(const gl::Context *context,
1491 int level,
1492 DXGI_FORMAT format,
1493 const TextureHelper11 &texture,
1494 d3d11::SharedUAV *outUAV)
1495 {
1496 ASSERT(outUAV);
1497 D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc;
1498 uavDesc.Format = format;
1499 uavDesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2D;
1500 uavDesc.Texture2D.MipSlice = mTopLevel + level;
1501 ANGLE_TRY(
1502 mRenderer->allocateResource(GetImplAs<Context11>(context), uavDesc, texture.get(), outUAV));
1503 outUAV->setDebugName("TexStorage2D.UAVForImage");
1504 return angle::Result::Continue;
1505 }
1506
getSwizzleTexture(const gl::Context * context,const TextureHelper11 ** outTexture)1507 angle::Result TextureStorage11_2D::getSwizzleTexture(const gl::Context *context,
1508 const TextureHelper11 **outTexture)
1509 {
1510 ASSERT(outTexture);
1511
1512 if (!mSwizzleTexture.valid())
1513 {
1514 const auto &format = mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps());
1515
1516 D3D11_TEXTURE2D_DESC desc;
1517 desc.Width = mTextureWidth;
1518 desc.Height = mTextureHeight;
1519 desc.MipLevels = mMipLevels;
1520 desc.ArraySize = 1;
1521 desc.Format = format.texFormat;
1522 desc.SampleDesc.Count = 1;
1523 desc.SampleDesc.Quality = 0;
1524 desc.Usage = D3D11_USAGE_DEFAULT;
1525 desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
1526 desc.CPUAccessFlags = 0;
1527 desc.MiscFlags = 0;
1528
1529 ANGLE_TRY(mRenderer->allocateTexture(GetImplAs<Context11>(context), desc, format,
1530 &mSwizzleTexture));
1531 mSwizzleTexture.setDebugName("TexStorage2D.SwizzleTexture");
1532 }
1533
1534 *outTexture = &mSwizzleTexture;
1535 return angle::Result::Continue;
1536 }
1537
getSwizzleRenderTarget(const gl::Context * context,int mipLevel,const d3d11::RenderTargetView ** outRTV)1538 angle::Result TextureStorage11_2D::getSwizzleRenderTarget(const gl::Context *context,
1539 int mipLevel,
1540 const d3d11::RenderTargetView **outRTV)
1541 {
1542 ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
1543 ASSERT(outRTV);
1544
1545 if (!mSwizzleRenderTargets[mipLevel].valid())
1546 {
1547 const TextureHelper11 *swizzleTexture = nullptr;
1548 ANGLE_TRY(getSwizzleTexture(context, &swizzleTexture));
1549
1550 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
1551 rtvDesc.Format =
1552 mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps()).rtvFormat;
1553 rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
1554 rtvDesc.Texture2D.MipSlice = mTopLevel + mipLevel;
1555
1556 ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), rtvDesc,
1557 mSwizzleTexture.get(),
1558 &mSwizzleRenderTargets[mipLevel]));
1559 }
1560
1561 *outRTV = &mSwizzleRenderTargets[mipLevel];
1562 return angle::Result::Continue;
1563 }
1564
ensureDropStencilTexture(const gl::Context * context,DropStencil * dropStencilOut)1565 angle::Result TextureStorage11_2D::ensureDropStencilTexture(const gl::Context *context,
1566 DropStencil *dropStencilOut)
1567 {
1568 if (mDropStencilTexture.valid())
1569 {
1570 *dropStencilOut = DropStencil::ALREADY_EXISTS;
1571 return angle::Result::Continue;
1572 }
1573
1574 D3D11_TEXTURE2D_DESC dropDesc = {};
1575 dropDesc.ArraySize = 1;
1576 dropDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_DEPTH_STENCIL;
1577 dropDesc.CPUAccessFlags = 0;
1578 dropDesc.Format = DXGI_FORMAT_R32_TYPELESS;
1579 dropDesc.Height = mTextureHeight;
1580 dropDesc.MipLevels = mMipLevels;
1581 dropDesc.MiscFlags = 0;
1582 dropDesc.SampleDesc.Count = 1;
1583 dropDesc.SampleDesc.Quality = 0;
1584 dropDesc.Usage = D3D11_USAGE_DEFAULT;
1585 dropDesc.Width = mTextureWidth;
1586
1587 const auto &format =
1588 d3d11::Format::Get(GL_DEPTH_COMPONENT32F, mRenderer->getRenderer11DeviceCaps());
1589 ANGLE_TRY(mRenderer->allocateTexture(GetImplAs<Context11>(context), dropDesc, format,
1590 &mDropStencilTexture));
1591 mDropStencilTexture.setDebugName("TexStorage2D.DropStencil");
1592
1593 ANGLE_TRY(initDropStencilTexture(context, gl::ImageIndexIterator::Make2D(0, mMipLevels)));
1594
1595 *dropStencilOut = DropStencil::CREATED;
1596 return angle::Result::Continue;
1597 }
1598
resolveTexture(const gl::Context * context)1599 angle::Result TextureStorage11_2D::resolveTexture(const gl::Context *context)
1600 {
1601 if (mMSTexInfo && mMSTexInfo->msTex && mMSTexInfo->msTextureNeedsResolve)
1602 {
1603 ANGLE_TRY(resolveTextureHelper(context, mTexture));
1604 onStateChange(angle::SubjectMessage::ContentsChanged);
1605 }
1606 return angle::Result::Continue;
1607 }
1608
TextureStorage11_External(Renderer11 * renderer,egl::Stream * stream,const egl::Stream::GLTextureDescription & glDesc)1609 TextureStorage11_External::TextureStorage11_External(
1610 Renderer11 *renderer,
1611 egl::Stream *stream,
1612 const egl::Stream::GLTextureDescription &glDesc)
1613 : TextureStorage11(renderer, D3D11_BIND_SHADER_RESOURCE, 0, glDesc.internalFormat)
1614 {
1615 ASSERT(stream->getProducerType() == egl::Stream::ProducerType::D3D11Texture);
1616 auto *producer = static_cast<StreamProducerD3DTexture *>(stream->getImplementation());
1617 mTexture.set(producer->getD3DTexture(), mFormatInfo);
1618 mSubresourceIndex = producer->getArraySlice();
1619 mTexture.get()->AddRef();
1620 mMipLevels = 1;
1621
1622 D3D11_TEXTURE2D_DESC desc;
1623 mTexture.getDesc(&desc);
1624 mTextureWidth = desc.Width;
1625 mTextureHeight = desc.Height;
1626 mTextureDepth = 1;
1627 mHasKeyedMutex = (desc.MiscFlags & D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX) != 0;
1628 }
1629
onDestroy(const gl::Context * context)1630 angle::Result TextureStorage11_External::onDestroy(const gl::Context *context)
1631 {
1632 if (mHasKeyedMutex)
1633 {
1634 // If the keyed mutex is released that will unbind it and cause the state cache to become
1635 // desynchronized.
1636 mRenderer->getStateManager()->invalidateBoundViews();
1637 }
1638
1639 return angle::Result::Continue;
1640 }
1641
~TextureStorage11_External()1642 TextureStorage11_External::~TextureStorage11_External() {}
1643
copyToStorage(const gl::Context * context,TextureStorage * destStorage)1644 angle::Result TextureStorage11_External::copyToStorage(const gl::Context *context,
1645 TextureStorage *destStorage)
1646 {
1647 UNIMPLEMENTED();
1648 return angle::Result::Continue;
1649 }
1650
associateImage(Image11 * image,const gl::ImageIndex & index)1651 void TextureStorage11_External::associateImage(Image11 *image, const gl::ImageIndex &index)
1652 {
1653 ASSERT(index.getLevelIndex() == 0);
1654 mAssociatedImage = image;
1655 }
1656
verifyAssociatedImageValid(const gl::ImageIndex & index,Image11 * expectedImage)1657 void TextureStorage11_External::verifyAssociatedImageValid(const gl::ImageIndex &index,
1658 Image11 *expectedImage)
1659 {
1660 ASSERT(index.getLevelIndex() == 0 && mAssociatedImage == expectedImage);
1661 }
1662
disassociateImage(const gl::ImageIndex & index,Image11 * expectedImage)1663 void TextureStorage11_External::disassociateImage(const gl::ImageIndex &index,
1664 Image11 *expectedImage)
1665 {
1666 ASSERT(index.getLevelIndex() == 0);
1667 ASSERT(mAssociatedImage == expectedImage);
1668 mAssociatedImage = nullptr;
1669 }
1670
releaseAssociatedImage(const gl::Context * context,const gl::ImageIndex & index,Image11 * incomingImage)1671 angle::Result TextureStorage11_External::releaseAssociatedImage(const gl::Context *context,
1672 const gl::ImageIndex &index,
1673 Image11 *incomingImage)
1674 {
1675 ASSERT(index.getLevelIndex() == 0);
1676
1677 if (mAssociatedImage != nullptr && mAssociatedImage != incomingImage)
1678 {
1679 mAssociatedImage->verifyAssociatedStorageValid(this);
1680
1681 ANGLE_TRY(mAssociatedImage->recoverFromAssociatedStorage(context));
1682 }
1683
1684 return angle::Result::Continue;
1685 }
1686
getResource(const gl::Context * context,const TextureHelper11 ** outResource)1687 angle::Result TextureStorage11_External::getResource(const gl::Context *context,
1688 const TextureHelper11 **outResource)
1689 {
1690 *outResource = &mTexture;
1691 return angle::Result::Continue;
1692 }
1693
getMippedResource(const gl::Context * context,const TextureHelper11 ** outResource)1694 angle::Result TextureStorage11_External::getMippedResource(const gl::Context *context,
1695 const TextureHelper11 **outResource)
1696 {
1697 *outResource = &mTexture;
1698 return angle::Result::Continue;
1699 }
1700
findRenderTarget(const gl::Context * context,const gl::ImageIndex & index,GLsizei samples,RenderTargetD3D ** outRT) const1701 angle::Result TextureStorage11_External::findRenderTarget(const gl::Context *context,
1702 const gl::ImageIndex &index,
1703 GLsizei samples,
1704 RenderTargetD3D **outRT) const
1705 {
1706 // Render targets are not supported for external textures
1707 ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
1708 return angle::Result::Stop;
1709 }
1710
getRenderTarget(const gl::Context * context,const gl::ImageIndex & index,GLsizei samples,RenderTargetD3D ** outRT)1711 angle::Result TextureStorage11_External::getRenderTarget(const gl::Context *context,
1712 const gl::ImageIndex &index,
1713 GLsizei samples,
1714 RenderTargetD3D **outRT)
1715 {
1716 // Render targets are not supported for external textures
1717 ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
1718 return angle::Result::Stop;
1719 }
1720
createSRVForSampler(const gl::Context * context,int baseLevel,int mipLevels,DXGI_FORMAT format,const TextureHelper11 & texture,d3d11::SharedSRV * outSRV)1721 angle::Result TextureStorage11_External::createSRVForSampler(const gl::Context *context,
1722 int baseLevel,
1723 int mipLevels,
1724 DXGI_FORMAT format,
1725 const TextureHelper11 &texture,
1726 d3d11::SharedSRV *outSRV)
1727 {
1728 // Since external textures are treates as non-mipmapped textures, we ignore mipmap levels and
1729 // use the specified subresource ID the storage was created with.
1730 ASSERT(mipLevels == 1);
1731 ASSERT(outSRV);
1732
1733 D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
1734 srvDesc.Format = format;
1735 srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
1736 // subresource index is equal to the mip level for 2D textures
1737 srvDesc.Texture2DArray.MostDetailedMip = 0;
1738 srvDesc.Texture2DArray.MipLevels = 1;
1739 srvDesc.Texture2DArray.FirstArraySlice = mSubresourceIndex;
1740 srvDesc.Texture2DArray.ArraySize = 1;
1741
1742 ANGLE_TRY(
1743 mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(), outSRV));
1744 outSRV->setDebugName("TexStorage2D.SRV");
1745
1746 return angle::Result::Continue;
1747 }
1748
createSRVForImage(const gl::Context * context,int level,DXGI_FORMAT format,const TextureHelper11 & texture,d3d11::SharedSRV * outSRV)1749 angle::Result TextureStorage11_External::createSRVForImage(const gl::Context *context,
1750 int level,
1751 DXGI_FORMAT format,
1752 const TextureHelper11 &texture,
1753 d3d11::SharedSRV *outSRV)
1754 {
1755 ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
1756 return angle::Result::Stop;
1757 }
1758
createUAVForImage(const gl::Context * context,int level,DXGI_FORMAT format,const TextureHelper11 & texture,d3d11::SharedUAV * outUAV)1759 angle::Result TextureStorage11_External::createUAVForImage(const gl::Context *context,
1760 int level,
1761 DXGI_FORMAT format,
1762 const TextureHelper11 &texture,
1763 d3d11::SharedUAV *outUAV)
1764 {
1765 ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
1766 return angle::Result::Stop;
1767 }
1768
getSwizzleTexture(const gl::Context * context,const TextureHelper11 ** outTexture)1769 angle::Result TextureStorage11_External::getSwizzleTexture(const gl::Context *context,
1770 const TextureHelper11 **outTexture)
1771 {
1772 ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
1773 return angle::Result::Stop;
1774 }
1775
getSwizzleRenderTarget(const gl::Context * context,int mipLevel,const d3d11::RenderTargetView ** outRTV)1776 angle::Result TextureStorage11_External::getSwizzleRenderTarget(
1777 const gl::Context *context,
1778 int mipLevel,
1779 const d3d11::RenderTargetView **outRTV)
1780 {
1781 ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
1782 return angle::Result::Stop;
1783 }
1784
TextureStorage11ImmutableBase(Renderer11 * renderer,UINT bindFlags,UINT miscFlags,GLenum internalFormat)1785 TextureStorage11ImmutableBase::TextureStorage11ImmutableBase(Renderer11 *renderer,
1786 UINT bindFlags,
1787 UINT miscFlags,
1788 GLenum internalFormat)
1789 : TextureStorage11(renderer, bindFlags, miscFlags, internalFormat)
1790 {}
1791
associateImage(Image11 *,const gl::ImageIndex &)1792 void TextureStorage11ImmutableBase::associateImage(Image11 *, const gl::ImageIndex &) {}
1793
disassociateImage(const gl::ImageIndex &,Image11 *)1794 void TextureStorage11ImmutableBase::disassociateImage(const gl::ImageIndex &, Image11 *) {}
1795
verifyAssociatedImageValid(const gl::ImageIndex &,Image11 *)1796 void TextureStorage11ImmutableBase::verifyAssociatedImageValid(const gl::ImageIndex &, Image11 *) {}
1797
releaseAssociatedImage(const gl::Context * context,const gl::ImageIndex &,Image11 *)1798 angle::Result TextureStorage11ImmutableBase::releaseAssociatedImage(const gl::Context *context,
1799 const gl::ImageIndex &,
1800 Image11 *)
1801 {
1802 return angle::Result::Continue;
1803 }
1804
createSRVForImage(const gl::Context * context,int level,DXGI_FORMAT format,const TextureHelper11 & texture,d3d11::SharedSRV * outSRV)1805 angle::Result TextureStorage11ImmutableBase::createSRVForImage(const gl::Context *context,
1806 int level,
1807 DXGI_FORMAT format,
1808 const TextureHelper11 &texture,
1809 d3d11::SharedSRV *outSRV)
1810 {
1811 ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
1812 return angle::Result::Stop;
1813 }
1814
createUAVForImage(const gl::Context * context,int level,DXGI_FORMAT format,const TextureHelper11 & texture,d3d11::SharedUAV * outUAV)1815 angle::Result TextureStorage11ImmutableBase::createUAVForImage(const gl::Context *context,
1816 int level,
1817 DXGI_FORMAT format,
1818 const TextureHelper11 &texture,
1819 d3d11::SharedUAV *outUAV)
1820 {
1821 ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
1822 return angle::Result::Stop;
1823 }
1824
TextureStorage11_EGLImage(Renderer11 * renderer,EGLImageD3D * eglImage,RenderTarget11 * renderTarget11)1825 TextureStorage11_EGLImage::TextureStorage11_EGLImage(Renderer11 *renderer,
1826 EGLImageD3D *eglImage,
1827 RenderTarget11 *renderTarget11)
1828 : TextureStorage11ImmutableBase(renderer,
1829 D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE,
1830 0,
1831 renderTarget11->getInternalFormat()),
1832 mImage(eglImage),
1833 mCurrentRenderTarget(0),
1834 mSwizzleTexture(),
1835 mSwizzleRenderTargets(gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
1836 {
1837 mCurrentRenderTarget = reinterpret_cast<uintptr_t>(renderTarget11);
1838
1839 mMipLevels = 1;
1840 mTextureWidth = renderTarget11->getWidth();
1841 mTextureHeight = renderTarget11->getHeight();
1842 mTextureDepth = 1;
1843 }
1844
~TextureStorage11_EGLImage()1845 TextureStorage11_EGLImage::~TextureStorage11_EGLImage() {}
1846
getSubresourceIndex(const gl::Context * context,const gl::ImageIndex & index,UINT * outSubresourceIndex) const1847 angle::Result TextureStorage11_EGLImage::getSubresourceIndex(const gl::Context *context,
1848 const gl::ImageIndex &index,
1849 UINT *outSubresourceIndex) const
1850 {
1851 ASSERT(index.getType() == gl::TextureType::_2D);
1852 ASSERT(index.getLevelIndex() == 0);
1853
1854 RenderTarget11 *renderTarget11 = nullptr;
1855 ANGLE_TRY(getImageRenderTarget(context, &renderTarget11));
1856 *outSubresourceIndex = renderTarget11->getSubresourceIndex();
1857 return angle::Result::Continue;
1858 }
1859
getResource(const gl::Context * context,const TextureHelper11 ** outResource)1860 angle::Result TextureStorage11_EGLImage::getResource(const gl::Context *context,
1861 const TextureHelper11 **outResource)
1862 {
1863 ANGLE_TRY(checkForUpdatedRenderTarget(context));
1864
1865 RenderTarget11 *renderTarget11 = nullptr;
1866 ANGLE_TRY(getImageRenderTarget(context, &renderTarget11));
1867 *outResource = &renderTarget11->getTexture();
1868 return angle::Result::Continue;
1869 }
1870
getSRVForSampler(const gl::Context * context,const gl::TextureState & textureState,const gl::SamplerState & sampler,const d3d11::SharedSRV ** outSRV)1871 angle::Result TextureStorage11_EGLImage::getSRVForSampler(const gl::Context *context,
1872 const gl::TextureState &textureState,
1873 const gl::SamplerState &sampler,
1874 const d3d11::SharedSRV **outSRV)
1875 {
1876 ANGLE_TRY(checkForUpdatedRenderTarget(context));
1877 return TextureStorage11::getSRVForSampler(context, textureState, sampler, outSRV);
1878 }
1879
getMippedResource(const gl::Context * context,const TextureHelper11 **)1880 angle::Result TextureStorage11_EGLImage::getMippedResource(const gl::Context *context,
1881 const TextureHelper11 **)
1882 {
1883 // This shouldn't be called unless the zero max LOD workaround is active.
1884 // EGL images are unavailable in this configuration.
1885 ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
1886 return angle::Result::Stop;
1887 }
1888
findRenderTarget(const gl::Context * context,const gl::ImageIndex & index,GLsizei samples,RenderTargetD3D ** outRT) const1889 angle::Result TextureStorage11_EGLImage::findRenderTarget(const gl::Context *context,
1890 const gl::ImageIndex &index,
1891 GLsizei samples,
1892 RenderTargetD3D **outRT) const
1893 {
1894 // Since the render target of an EGL image will be updated when orphaning, trying to find a
1895 // cache of it can be rarely useful.
1896 ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
1897 return angle::Result::Stop;
1898 }
1899
getRenderTarget(const gl::Context * context,const gl::ImageIndex & index,GLsizei samples,RenderTargetD3D ** outRT)1900 angle::Result TextureStorage11_EGLImage::getRenderTarget(const gl::Context *context,
1901 const gl::ImageIndex &index,
1902 GLsizei samples,
1903 RenderTargetD3D **outRT)
1904 {
1905 ASSERT(!index.hasLayer());
1906 ASSERT(index.getLevelIndex() == 0);
1907
1908 ANGLE_TRY(checkForUpdatedRenderTarget(context));
1909
1910 return mImage->getRenderTarget(context, outRT);
1911 }
1912
copyToStorage(const gl::Context * context,TextureStorage * destStorage)1913 angle::Result TextureStorage11_EGLImage::copyToStorage(const gl::Context *context,
1914 TextureStorage *destStorage)
1915 {
1916 const TextureHelper11 *sourceResouce = nullptr;
1917 ANGLE_TRY(getResource(context, &sourceResouce));
1918
1919 ASSERT(destStorage);
1920 TextureStorage11_2D *dest11 = GetAs<TextureStorage11_2D>(destStorage);
1921 const TextureHelper11 *destResource = nullptr;
1922 ANGLE_TRY(dest11->getResource(context, &destResource));
1923
1924 ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext();
1925 immediateContext->CopyResource(destResource->get(), sourceResouce->get());
1926
1927 dest11->markDirty();
1928
1929 return angle::Result::Continue;
1930 }
1931
useLevelZeroWorkaroundTexture(const gl::Context * context,bool)1932 angle::Result TextureStorage11_EGLImage::useLevelZeroWorkaroundTexture(const gl::Context *context,
1933 bool)
1934 {
1935 ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
1936 return angle::Result::Stop;
1937 }
1938
getSwizzleTexture(const gl::Context * context,const TextureHelper11 ** outTexture)1939 angle::Result TextureStorage11_EGLImage::getSwizzleTexture(const gl::Context *context,
1940 const TextureHelper11 **outTexture)
1941 {
1942 ASSERT(outTexture);
1943
1944 if (!mSwizzleTexture.valid())
1945 {
1946 const auto &format = mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps());
1947
1948 D3D11_TEXTURE2D_DESC desc;
1949 desc.Width = mTextureWidth;
1950 desc.Height = mTextureHeight;
1951 desc.MipLevels = mMipLevels;
1952 desc.ArraySize = 1;
1953 desc.Format = format.texFormat;
1954 desc.SampleDesc.Count = 1;
1955 desc.SampleDesc.Quality = 0;
1956 desc.Usage = D3D11_USAGE_DEFAULT;
1957 desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
1958 desc.CPUAccessFlags = 0;
1959 desc.MiscFlags = 0;
1960
1961 ANGLE_TRY(mRenderer->allocateTexture(GetImplAs<Context11>(context), desc, format,
1962 &mSwizzleTexture));
1963 mSwizzleTexture.setDebugName("TexStorageEGLImage.SwizzleTexture");
1964 }
1965
1966 *outTexture = &mSwizzleTexture;
1967 return angle::Result::Continue;
1968 }
1969
getSwizzleRenderTarget(const gl::Context * context,int mipLevel,const d3d11::RenderTargetView ** outRTV)1970 angle::Result TextureStorage11_EGLImage::getSwizzleRenderTarget(
1971 const gl::Context *context,
1972 int mipLevel,
1973 const d3d11::RenderTargetView **outRTV)
1974 {
1975 ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
1976 ASSERT(outRTV);
1977
1978 if (!mSwizzleRenderTargets[mipLevel].valid())
1979 {
1980 const TextureHelper11 *swizzleTexture = nullptr;
1981 ANGLE_TRY(getSwizzleTexture(context, &swizzleTexture));
1982
1983 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
1984 rtvDesc.Format =
1985 mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps()).rtvFormat;
1986 rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
1987 rtvDesc.Texture2D.MipSlice = mTopLevel + mipLevel;
1988
1989 ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), rtvDesc,
1990 mSwizzleTexture.get(),
1991 &mSwizzleRenderTargets[mipLevel]));
1992 }
1993
1994 *outRTV = &mSwizzleRenderTargets[mipLevel];
1995 return angle::Result::Continue;
1996 }
1997
checkForUpdatedRenderTarget(const gl::Context * context)1998 angle::Result TextureStorage11_EGLImage::checkForUpdatedRenderTarget(const gl::Context *context)
1999 {
2000 RenderTarget11 *renderTarget11 = nullptr;
2001 ANGLE_TRY(getImageRenderTarget(context, &renderTarget11));
2002
2003 if (mCurrentRenderTarget != reinterpret_cast<uintptr_t>(renderTarget11))
2004 {
2005 clearSRVCache();
2006 mCurrentRenderTarget = reinterpret_cast<uintptr_t>(renderTarget11);
2007 }
2008
2009 return angle::Result::Continue;
2010 }
2011
createSRVForSampler(const gl::Context * context,int baseLevel,int mipLevels,DXGI_FORMAT format,const TextureHelper11 & texture,d3d11::SharedSRV * outSRV)2012 angle::Result TextureStorage11_EGLImage::createSRVForSampler(const gl::Context *context,
2013 int baseLevel,
2014 int mipLevels,
2015 DXGI_FORMAT format,
2016 const TextureHelper11 &texture,
2017 d3d11::SharedSRV *outSRV)
2018 {
2019 ASSERT(baseLevel == 0);
2020 ASSERT(mipLevels == 1);
2021 ASSERT(outSRV);
2022
2023 // Create a new SRV only for the swizzle texture. Otherwise just return the Image's
2024 // RenderTarget's SRV.
2025 if (texture == mSwizzleTexture)
2026 {
2027 D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
2028 srvDesc.Format = format;
2029 srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
2030 srvDesc.Texture2D.MostDetailedMip = mTopLevel + baseLevel;
2031 srvDesc.Texture2D.MipLevels = mipLevels;
2032
2033 ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(),
2034 outSRV));
2035 outSRV->setDebugName("TexStorageEGLImage.SRV");
2036 }
2037 else
2038 {
2039 RenderTarget11 *renderTarget = nullptr;
2040 ANGLE_TRY(getImageRenderTarget(context, &renderTarget));
2041
2042 ASSERT(texture == renderTarget->getTexture());
2043
2044 *outSRV = renderTarget->getShaderResourceView(context).makeCopy();
2045 }
2046
2047 return angle::Result::Continue;
2048 }
2049
getImageRenderTarget(const gl::Context * context,RenderTarget11 ** outRT) const2050 angle::Result TextureStorage11_EGLImage::getImageRenderTarget(const gl::Context *context,
2051 RenderTarget11 **outRT) const
2052 {
2053 RenderTargetD3D *renderTargetD3D = nullptr;
2054 ANGLE_TRY(mImage->getRenderTarget(context, &renderTargetD3D));
2055 *outRT = GetAs<RenderTarget11>(renderTargetD3D);
2056 return angle::Result::Continue;
2057 }
2058
TextureStorage11_Cube(Renderer11 * renderer,GLenum internalformat,bool renderTarget,int size,int levels,bool hintLevelZeroOnly)2059 TextureStorage11_Cube::TextureStorage11_Cube(Renderer11 *renderer,
2060 GLenum internalformat,
2061 bool renderTarget,
2062 int size,
2063 int levels,
2064 bool hintLevelZeroOnly)
2065 : TextureStorage11(
2066 renderer,
2067 GetTextureBindFlags(internalformat, renderer->getRenderer11DeviceCaps(), renderTarget),
2068 GetTextureMiscFlags(internalformat,
2069 renderer->getRenderer11DeviceCaps(),
2070 renderTarget,
2071 levels),
2072 internalformat),
2073 mTexture(),
2074 mLevelZeroTexture(),
2075 mUseLevelZeroTexture(hintLevelZeroOnly && levels > 1),
2076 mSwizzleTexture()
2077 {
2078 for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
2079 {
2080 for (unsigned int face = 0; face < gl::kCubeFaceCount; face++)
2081 {
2082 mAssociatedImages[face][level] = nullptr;
2083 mRenderTarget[face][level] = nullptr;
2084 }
2085 }
2086
2087 for (unsigned int face = 0; face < gl::kCubeFaceCount; face++)
2088 {
2089 mLevelZeroRenderTarget[face] = nullptr;
2090 }
2091
2092 // adjust size if needed for compressed textures
2093 int height = size;
2094 d3d11::MakeValidSize(false, mFormatInfo.texFormat, &size, &height, &mTopLevel);
2095
2096 mMipLevels = mTopLevel + levels;
2097 mTextureWidth = size;
2098 mTextureHeight = size;
2099 mTextureDepth = 1;
2100
2101 // The LevelZeroOnly hint should only be true if the zero max LOD workaround is active.
2102 ASSERT(!mUseLevelZeroTexture || mRenderer->getFeatures().zeroMaxLodWorkaround.enabled);
2103 }
2104
onDestroy(const gl::Context * context)2105 angle::Result TextureStorage11_Cube::onDestroy(const gl::Context *context)
2106 {
2107 for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
2108 {
2109 for (unsigned int face = 0; face < gl::kCubeFaceCount; face++)
2110 {
2111 if (mAssociatedImages[face][level] != nullptr)
2112 {
2113 mAssociatedImages[face][level]->verifyAssociatedStorageValid(this);
2114
2115 // We must let the Images recover their data before we delete it from the
2116 // TextureStorage.
2117 ANGLE_TRY(mAssociatedImages[face][level]->recoverFromAssociatedStorage(context));
2118 }
2119 }
2120 }
2121
2122 return angle::Result::Continue;
2123 }
2124
~TextureStorage11_Cube()2125 TextureStorage11_Cube::~TextureStorage11_Cube() {}
2126
getSubresourceIndex(const gl::Context * context,const gl::ImageIndex & index,UINT * outSubresourceIndex) const2127 angle::Result TextureStorage11_Cube::getSubresourceIndex(const gl::Context *context,
2128 const gl::ImageIndex &index,
2129 UINT *outSubresourceIndex) const
2130 {
2131 UINT arraySlice = index.cubeMapFaceIndex();
2132 if (mRenderer->getFeatures().zeroMaxLodWorkaround.enabled && mUseLevelZeroTexture &&
2133 index.getLevelIndex() == 0)
2134 {
2135 UINT subresource = D3D11CalcSubresource(0, arraySlice, 1);
2136 ASSERT(subresource != std::numeric_limits<UINT>::max());
2137 *outSubresourceIndex = subresource;
2138 }
2139 else
2140 {
2141 UINT mipSlice = static_cast<UINT>(index.getLevelIndex() + mTopLevel);
2142 UINT subresource = D3D11CalcSubresource(mipSlice, arraySlice, mMipLevels);
2143 ASSERT(subresource != std::numeric_limits<UINT>::max());
2144 *outSubresourceIndex = subresource;
2145 }
2146 return angle::Result::Continue;
2147 }
2148
copyToStorage(const gl::Context * context,TextureStorage * destStorage)2149 angle::Result TextureStorage11_Cube::copyToStorage(const gl::Context *context,
2150 TextureStorage *destStorage)
2151 {
2152 ASSERT(destStorage);
2153
2154 TextureStorage11_Cube *dest11 = GetAs<TextureStorage11_Cube>(destStorage);
2155
2156 if (mRenderer->getFeatures().zeroMaxLodWorkaround.enabled)
2157 {
2158 ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext();
2159
2160 // If either mTexture or mLevelZeroTexture exist, then we need to copy them into the
2161 // corresponding textures in destStorage.
2162 if (mTexture.valid())
2163 {
2164 ANGLE_TRY(dest11->useLevelZeroWorkaroundTexture(context, false));
2165
2166 const TextureHelper11 *destResource = nullptr;
2167 ANGLE_TRY(dest11->getResource(context, &destResource));
2168
2169 immediateContext->CopyResource(destResource->get(), mTexture.get());
2170 }
2171
2172 if (mLevelZeroTexture.valid())
2173 {
2174 ANGLE_TRY(dest11->useLevelZeroWorkaroundTexture(context, true));
2175
2176 const TextureHelper11 *destResource = nullptr;
2177 ANGLE_TRY(dest11->getResource(context, &destResource));
2178
2179 immediateContext->CopyResource(destResource->get(), mLevelZeroTexture.get());
2180 }
2181 }
2182 else
2183 {
2184 const TextureHelper11 *sourceResouce = nullptr;
2185 ANGLE_TRY(getResource(context, &sourceResouce));
2186
2187 const TextureHelper11 *destResource = nullptr;
2188 ANGLE_TRY(dest11->getResource(context, &destResource));
2189
2190 ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext();
2191 immediateContext->CopyResource(destResource->get(), sourceResouce->get());
2192 }
2193
2194 dest11->markDirty();
2195
2196 return angle::Result::Continue;
2197 }
2198
useLevelZeroWorkaroundTexture(const gl::Context * context,bool useLevelZeroTexture)2199 angle::Result TextureStorage11_Cube::useLevelZeroWorkaroundTexture(const gl::Context *context,
2200 bool useLevelZeroTexture)
2201 {
2202 if (useLevelZeroTexture && mMipLevels > 1)
2203 {
2204 if (!mUseLevelZeroTexture && mTexture.valid())
2205 {
2206 ANGLE_TRY(ensureTextureExists(context, 1));
2207
2208 // Pull data back from the mipped texture if necessary.
2209 ASSERT(mLevelZeroTexture.valid());
2210 ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
2211
2212 for (int face = 0; face < 6; face++)
2213 {
2214 deviceContext->CopySubresourceRegion(mLevelZeroTexture.get(),
2215 D3D11CalcSubresource(0, face, 1), 0, 0, 0,
2216 mTexture.get(), face * mMipLevels, nullptr);
2217 }
2218 }
2219
2220 mUseLevelZeroTexture = true;
2221 }
2222 else
2223 {
2224 if (mUseLevelZeroTexture && mLevelZeroTexture.valid())
2225 {
2226 ANGLE_TRY(ensureTextureExists(context, mMipLevels));
2227
2228 // Pull data back from the level zero texture if necessary.
2229 ASSERT(mTexture.valid());
2230 ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
2231
2232 for (int face = 0; face < 6; face++)
2233 {
2234 deviceContext->CopySubresourceRegion(mTexture.get(),
2235 D3D11CalcSubresource(0, face, mMipLevels), 0,
2236 0, 0, mLevelZeroTexture.get(), face, nullptr);
2237 }
2238 }
2239
2240 mUseLevelZeroTexture = false;
2241 }
2242
2243 return angle::Result::Continue;
2244 }
2245
associateImage(Image11 * image,const gl::ImageIndex & index)2246 void TextureStorage11_Cube::associateImage(Image11 *image, const gl::ImageIndex &index)
2247 {
2248 const GLint level = index.getLevelIndex();
2249 const GLint layerTarget = index.cubeMapFaceIndex();
2250
2251 ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
2252 ASSERT(0 <= layerTarget && layerTarget < static_cast<GLint>(gl::kCubeFaceCount));
2253
2254 if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
2255 {
2256 if (0 <= layerTarget && layerTarget < static_cast<GLint>(gl::kCubeFaceCount))
2257 {
2258 mAssociatedImages[layerTarget][level] = image;
2259 }
2260 }
2261 }
2262
verifyAssociatedImageValid(const gl::ImageIndex & index,Image11 * expectedImage)2263 void TextureStorage11_Cube::verifyAssociatedImageValid(const gl::ImageIndex &index,
2264 Image11 *expectedImage)
2265 {
2266 const GLint level = index.getLevelIndex();
2267 const GLint layerTarget = index.cubeMapFaceIndex();
2268
2269 ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
2270 ASSERT(0 <= layerTarget && layerTarget < static_cast<GLint>(gl::kCubeFaceCount));
2271 // This validation check should never return false. It means the Image/TextureStorage
2272 // association is broken.
2273 ASSERT(mAssociatedImages[layerTarget][level] == expectedImage);
2274 }
2275
2276 // disassociateImage allows an Image to end its association with a Storage.
disassociateImage(const gl::ImageIndex & index,Image11 * expectedImage)2277 void TextureStorage11_Cube::disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage)
2278 {
2279 const GLint level = index.getLevelIndex();
2280 const GLint layerTarget = index.cubeMapFaceIndex();
2281
2282 ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
2283 ASSERT(0 <= layerTarget && layerTarget < static_cast<GLint>(gl::kCubeFaceCount));
2284 ASSERT(mAssociatedImages[layerTarget][level] == expectedImage);
2285 mAssociatedImages[layerTarget][level] = nullptr;
2286 }
2287
2288 // releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image
2289 // recover its data before ending the association.
releaseAssociatedImage(const gl::Context * context,const gl::ImageIndex & index,Image11 * incomingImage)2290 angle::Result TextureStorage11_Cube::releaseAssociatedImage(const gl::Context *context,
2291 const gl::ImageIndex &index,
2292 Image11 *incomingImage)
2293 {
2294 const GLint level = index.getLevelIndex();
2295 const GLint layerTarget = index.cubeMapFaceIndex();
2296
2297 ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
2298 ASSERT(0 <= layerTarget && layerTarget < static_cast<GLint>(gl::kCubeFaceCount));
2299
2300 if ((0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
2301 {
2302 if (0 <= layerTarget && layerTarget < static_cast<GLint>(gl::kCubeFaceCount))
2303 {
2304 // No need to let the old Image recover its data, if it is also the incoming Image.
2305 if (mAssociatedImages[layerTarget][level] != nullptr &&
2306 mAssociatedImages[layerTarget][level] != incomingImage)
2307 {
2308 // Ensure that the Image is still associated with this TextureStorage.
2309 mAssociatedImages[layerTarget][level]->verifyAssociatedStorageValid(this);
2310
2311 // Force the image to recover from storage before its data is overwritten.
2312 // This will reset mAssociatedImages[level] to nullptr too.
2313 ANGLE_TRY(
2314 mAssociatedImages[layerTarget][level]->recoverFromAssociatedStorage(context));
2315 }
2316 }
2317 }
2318
2319 return angle::Result::Continue;
2320 }
2321
getResource(const gl::Context * context,const TextureHelper11 ** outResource)2322 angle::Result TextureStorage11_Cube::getResource(const gl::Context *context,
2323 const TextureHelper11 **outResource)
2324 {
2325 if (mUseLevelZeroTexture && mMipLevels > 1)
2326 {
2327 ANGLE_TRY(ensureTextureExists(context, 1));
2328 *outResource = &mLevelZeroTexture;
2329 }
2330 else
2331 {
2332 ANGLE_TRY(ensureTextureExists(context, mMipLevels));
2333 *outResource = &mTexture;
2334 }
2335 return angle::Result::Continue;
2336 }
2337
getMippedResource(const gl::Context * context,const TextureHelper11 ** outResource)2338 angle::Result TextureStorage11_Cube::getMippedResource(const gl::Context *context,
2339 const TextureHelper11 **outResource)
2340 {
2341 // This shouldn't be called unless the zero max LOD workaround is active.
2342 ASSERT(mRenderer->getFeatures().zeroMaxLodWorkaround.enabled);
2343
2344 ANGLE_TRY(ensureTextureExists(context, mMipLevels));
2345 *outResource = &mTexture;
2346 return angle::Result::Continue;
2347 }
2348
ensureTextureExists(const gl::Context * context,int mipLevels)2349 angle::Result TextureStorage11_Cube::ensureTextureExists(const gl::Context *context, int mipLevels)
2350 {
2351 // If mMipLevels = 1 then always use mTexture rather than mLevelZeroTexture.
2352 ANGLE_TRY(resolveTexture(context));
2353 bool useLevelZeroTexture = mRenderer->getFeatures().zeroMaxLodWorkaround.enabled
2354 ? (mipLevels == 1) && (mMipLevels > 1)
2355 : false;
2356 TextureHelper11 *outputTexture = useLevelZeroTexture ? &mLevelZeroTexture : &mTexture;
2357
2358 // if the size is not positive this should be treated as an incomplete texture
2359 // we handle that here by skipping the d3d texture creation
2360 if (!outputTexture->valid() && mTextureWidth > 0 && mTextureHeight > 0)
2361 {
2362 ASSERT(mMipLevels > 0);
2363
2364 D3D11_TEXTURE2D_DESC desc;
2365 desc.Width = mTextureWidth;
2366 desc.Height = mTextureHeight;
2367 desc.MipLevels = mipLevels;
2368 desc.ArraySize = gl::kCubeFaceCount;
2369 desc.Format = mFormatInfo.texFormat;
2370 desc.SampleDesc.Count = 1;
2371 desc.SampleDesc.Quality = 0;
2372 desc.Usage = D3D11_USAGE_DEFAULT;
2373 desc.BindFlags = getBindFlags();
2374 desc.CPUAccessFlags = 0;
2375 desc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE | getMiscFlags();
2376
2377 ANGLE_TRY(mRenderer->allocateTexture(GetImplAs<Context11>(context), desc, mFormatInfo,
2378 outputTexture));
2379 outputTexture->setDebugName("TexStorageCube.Texture");
2380 }
2381
2382 return angle::Result::Continue;
2383 }
2384
findRenderTarget(const gl::Context * context,const gl::ImageIndex & index,GLsizei samples,RenderTargetD3D ** outRT) const2385 angle::Result TextureStorage11_Cube::findRenderTarget(const gl::Context *context,
2386 const gl::ImageIndex &index,
2387 GLsizei samples,
2388 RenderTargetD3D **outRT) const
2389 {
2390 const int faceIndex = index.cubeMapFaceIndex();
2391 const int level = index.getLevelIndex();
2392
2393 ASSERT(level >= 0 && level < getLevelCount());
2394 ASSERT(faceIndex >= 0 && faceIndex < static_cast<GLint>(gl::kCubeFaceCount));
2395
2396 bool needMS = samples > 0;
2397 if (needMS)
2398 {
2399 return findMultisampledRenderTarget(context, index, samples, outRT);
2400 }
2401
2402 if (!mRenderTarget[faceIndex][level])
2403 {
2404 if (mUseLevelZeroTexture)
2405 {
2406 ASSERT(index.getLevelIndex() == 0);
2407 ASSERT(outRT);
2408 *outRT = mLevelZeroRenderTarget[faceIndex].get();
2409 return angle::Result::Continue;
2410 }
2411 }
2412
2413 ASSERT(outRT);
2414 *outRT = mRenderTarget[faceIndex][level].get();
2415 return angle::Result::Continue;
2416 }
2417
createRenderTargetSRV(const gl::Context * context,const TextureHelper11 & texture,const gl::ImageIndex & index,DXGI_FORMAT resourceFormat,d3d11::SharedSRV * srv) const2418 angle::Result TextureStorage11_Cube::createRenderTargetSRV(const gl::Context *context,
2419 const TextureHelper11 &texture,
2420 const gl::ImageIndex &index,
2421 DXGI_FORMAT resourceFormat,
2422 d3d11::SharedSRV *srv) const
2423 {
2424 D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
2425 srvDesc.Format = resourceFormat;
2426 srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + index.getLevelIndex();
2427 srvDesc.Texture2DArray.MipLevels = 1;
2428 srvDesc.Texture2DArray.FirstArraySlice = index.cubeMapFaceIndex();
2429 srvDesc.Texture2DArray.ArraySize = 1;
2430
2431 if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_10_0)
2432 {
2433 srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
2434 }
2435 else
2436 {
2437 // Will be used with Texture2D sampler, not TextureCube
2438 srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
2439 }
2440
2441 ANGLE_TRY(
2442 mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(), srv));
2443 return angle::Result::Continue;
2444 }
2445
getRenderTarget(const gl::Context * context,const gl::ImageIndex & index,GLsizei samples,RenderTargetD3D ** outRT)2446 angle::Result TextureStorage11_Cube::getRenderTarget(const gl::Context *context,
2447 const gl::ImageIndex &index,
2448 GLsizei samples,
2449 RenderTargetD3D **outRT)
2450 {
2451 const int faceIndex = index.cubeMapFaceIndex();
2452 const int level = index.getLevelIndex();
2453
2454 ASSERT(level >= 0 && level < getLevelCount());
2455 ASSERT(faceIndex >= 0 && faceIndex < static_cast<GLint>(gl::kCubeFaceCount));
2456
2457 bool needMS = samples > 0;
2458 if (needMS)
2459 {
2460 return getMultisampledRenderTarget(context, index, samples, outRT);
2461 }
2462 else
2463 {
2464 ANGLE_TRY(resolveTexture(context));
2465 }
2466
2467 Context11 *context11 = GetImplAs<Context11>(context);
2468
2469 if (!mRenderTarget[faceIndex][level])
2470 {
2471 if (mRenderer->getFeatures().zeroMaxLodWorkaround.enabled)
2472 {
2473 ASSERT(index.getLevelIndex() == 0);
2474 ANGLE_TRY(useLevelZeroWorkaroundTexture(context, true));
2475 }
2476
2477 const TextureHelper11 *texture = nullptr;
2478 ANGLE_TRY(getResource(context, &texture));
2479
2480 if (mUseLevelZeroTexture)
2481 {
2482 if (!mLevelZeroRenderTarget[faceIndex])
2483 {
2484 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
2485 rtvDesc.Format = mFormatInfo.rtvFormat;
2486 rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
2487 rtvDesc.Texture2DArray.MipSlice = mTopLevel + level;
2488 rtvDesc.Texture2DArray.FirstArraySlice = faceIndex;
2489 rtvDesc.Texture2DArray.ArraySize = 1;
2490
2491 d3d11::RenderTargetView rtv;
2492 ANGLE_TRY(
2493 mRenderer->allocateResource(context11, rtvDesc, mLevelZeroTexture.get(), &rtv));
2494
2495 mLevelZeroRenderTarget[faceIndex].reset(new TextureRenderTarget11(
2496 std::move(rtv), mLevelZeroTexture, d3d11::SharedSRV(), d3d11::SharedSRV(),
2497 mFormatInfo.internalFormat, getFormatSet(), getLevelWidth(level),
2498 getLevelHeight(level), 1, 0));
2499 }
2500
2501 ASSERT(outRT);
2502 *outRT = mLevelZeroRenderTarget[faceIndex].get();
2503 return angle::Result::Continue;
2504 }
2505
2506 d3d11::SharedSRV srv;
2507 ANGLE_TRY(createRenderTargetSRV(context, *texture, index, mFormatInfo.srvFormat, &srv));
2508 d3d11::SharedSRV blitSRV;
2509 if (mFormatInfo.blitSRVFormat != mFormatInfo.srvFormat)
2510 {
2511 ANGLE_TRY(createRenderTargetSRV(context, *texture, index, mFormatInfo.blitSRVFormat,
2512 &blitSRV));
2513 }
2514 else
2515 {
2516 blitSRV = srv.makeCopy();
2517 }
2518
2519 srv.setDebugName("TexStorageCube.RenderTargetSRV");
2520
2521 if (mFormatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN)
2522 {
2523 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
2524 rtvDesc.Format = mFormatInfo.rtvFormat;
2525 rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
2526 rtvDesc.Texture2DArray.MipSlice = mTopLevel + level;
2527 rtvDesc.Texture2DArray.FirstArraySlice = faceIndex;
2528 rtvDesc.Texture2DArray.ArraySize = 1;
2529
2530 d3d11::RenderTargetView rtv;
2531 ANGLE_TRY(mRenderer->allocateResource(context11, rtvDesc, texture->get(), &rtv));
2532 rtv.setDebugName("TexStorageCube.RenderTargetRTV");
2533
2534 mRenderTarget[faceIndex][level].reset(new TextureRenderTarget11(
2535 std::move(rtv), *texture, srv, blitSRV, mFormatInfo.internalFormat, getFormatSet(),
2536 getLevelWidth(level), getLevelHeight(level), 1, 0));
2537 }
2538 else if (mFormatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN)
2539 {
2540 D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
2541 dsvDesc.Format = mFormatInfo.dsvFormat;
2542 dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY;
2543 dsvDesc.Flags = 0;
2544 dsvDesc.Texture2DArray.MipSlice = mTopLevel + level;
2545 dsvDesc.Texture2DArray.FirstArraySlice = faceIndex;
2546 dsvDesc.Texture2DArray.ArraySize = 1;
2547
2548 d3d11::DepthStencilView dsv;
2549 ANGLE_TRY(mRenderer->allocateResource(context11, dsvDesc, texture->get(), &dsv));
2550 dsv.setDebugName("TexStorageCube.RenderTargetDSV");
2551
2552 mRenderTarget[faceIndex][level].reset(new TextureRenderTarget11(
2553 std::move(dsv), *texture, srv, mFormatInfo.internalFormat, getFormatSet(),
2554 getLevelWidth(level), getLevelHeight(level), 1, 0));
2555 }
2556 else
2557 {
2558 UNREACHABLE();
2559 }
2560 }
2561
2562 ASSERT(outRT);
2563 *outRT = mRenderTarget[faceIndex][level].get();
2564 return angle::Result::Continue;
2565 }
2566
createSRVForSampler(const gl::Context * context,int baseLevel,int mipLevels,DXGI_FORMAT format,const TextureHelper11 & texture,d3d11::SharedSRV * outSRV)2567 angle::Result TextureStorage11_Cube::createSRVForSampler(const gl::Context *context,
2568 int baseLevel,
2569 int mipLevels,
2570 DXGI_FORMAT format,
2571 const TextureHelper11 &texture,
2572 d3d11::SharedSRV *outSRV)
2573 {
2574 ASSERT(outSRV);
2575
2576 D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
2577 srvDesc.Format = format;
2578
2579 // Unnormalized integer cube maps are not supported by DX11; we emulate them as an array of six
2580 // 2D textures
2581 const GLenum componentType = d3d11::GetComponentType(format);
2582 if (componentType == GL_INT || componentType == GL_UNSIGNED_INT)
2583 {
2584 srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
2585 srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + baseLevel;
2586 srvDesc.Texture2DArray.MipLevels = mipLevels;
2587 srvDesc.Texture2DArray.FirstArraySlice = 0;
2588 srvDesc.Texture2DArray.ArraySize = gl::kCubeFaceCount;
2589 }
2590 else
2591 {
2592 srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
2593 srvDesc.TextureCube.MipLevels = mipLevels;
2594 srvDesc.TextureCube.MostDetailedMip = mTopLevel + baseLevel;
2595 }
2596
2597 const TextureHelper11 *srvTexture = &texture;
2598
2599 if (mRenderer->getFeatures().zeroMaxLodWorkaround.enabled)
2600 {
2601 ASSERT(mTopLevel == 0);
2602 ASSERT(baseLevel == 0);
2603 // This code also assumes that the incoming texture equals either mLevelZeroTexture or
2604 // mTexture.
2605
2606 if (mipLevels == 1 && mMipLevels > 1)
2607 {
2608 // We must use a SRV on the level-zero-only texture.
2609 ANGLE_TRY(ensureTextureExists(context, 1));
2610 srvTexture = &mLevelZeroTexture;
2611 }
2612 else
2613 {
2614 ASSERT(mipLevels == static_cast<int>(mMipLevels));
2615 ASSERT(mTexture.valid() && texture == mTexture);
2616 srvTexture = &mTexture;
2617 }
2618 }
2619
2620 ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, srvTexture->get(),
2621 outSRV));
2622 outSRV->setDebugName("TexStorageCube.SRV");
2623
2624 return angle::Result::Continue;
2625 }
2626
createSRVForImage(const gl::Context * context,int level,DXGI_FORMAT format,const TextureHelper11 & texture,d3d11::SharedSRV * outSRV)2627 angle::Result TextureStorage11_Cube::createSRVForImage(const gl::Context *context,
2628 int level,
2629 DXGI_FORMAT format,
2630 const TextureHelper11 &texture,
2631 d3d11::SharedSRV *outSRV)
2632 {
2633 ASSERT(outSRV);
2634 D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
2635 srvDesc.Format = format;
2636 srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
2637 srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + level;
2638 srvDesc.Texture2DArray.MipLevels = 1;
2639 srvDesc.Texture2DArray.FirstArraySlice = 0;
2640 srvDesc.Texture2DArray.ArraySize = gl::kCubeFaceCount;
2641 ANGLE_TRY(
2642 mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(), outSRV));
2643 outSRV->setDebugName("TexStorageCube.SRVForImage");
2644 return angle::Result::Continue;
2645 }
2646
createUAVForImage(const gl::Context * context,int level,DXGI_FORMAT format,const TextureHelper11 & texture,d3d11::SharedUAV * outUAV)2647 angle::Result TextureStorage11_Cube::createUAVForImage(const gl::Context *context,
2648 int level,
2649 DXGI_FORMAT format,
2650 const TextureHelper11 &texture,
2651 d3d11::SharedUAV *outUAV)
2652 {
2653 ASSERT(outUAV);
2654 D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc;
2655 uavDesc.Format = format;
2656 uavDesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2DARRAY;
2657 uavDesc.Texture2DArray.MipSlice = mTopLevel + level;
2658 uavDesc.Texture2DArray.FirstArraySlice = 0;
2659 uavDesc.Texture2DArray.ArraySize = gl::kCubeFaceCount;
2660 ANGLE_TRY(
2661 mRenderer->allocateResource(GetImplAs<Context11>(context), uavDesc, texture.get(), outUAV));
2662 outUAV->setDebugName("TexStorageCube.UAVForImage");
2663 return angle::Result::Continue;
2664 }
2665
getSwizzleTexture(const gl::Context * context,const TextureHelper11 ** outTexture)2666 angle::Result TextureStorage11_Cube::getSwizzleTexture(const gl::Context *context,
2667 const TextureHelper11 **outTexture)
2668 {
2669 ASSERT(outTexture);
2670
2671 if (!mSwizzleTexture.valid())
2672 {
2673 const auto &format = mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps());
2674
2675 D3D11_TEXTURE2D_DESC desc;
2676 desc.Width = mTextureWidth;
2677 desc.Height = mTextureHeight;
2678 desc.MipLevels = mMipLevels;
2679 desc.ArraySize = gl::kCubeFaceCount;
2680 desc.Format = format.texFormat;
2681 desc.SampleDesc.Count = 1;
2682 desc.SampleDesc.Quality = 0;
2683 desc.Usage = D3D11_USAGE_DEFAULT;
2684 desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
2685 desc.CPUAccessFlags = 0;
2686 desc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
2687
2688 ANGLE_TRY(mRenderer->allocateTexture(GetImplAs<Context11>(context), desc, format,
2689 &mSwizzleTexture));
2690 mSwizzleTexture.setDebugName("TexStorageCube.SwizzleTexture");
2691 }
2692
2693 *outTexture = &mSwizzleTexture;
2694 return angle::Result::Continue;
2695 }
2696
getSwizzleRenderTarget(const gl::Context * context,int mipLevel,const d3d11::RenderTargetView ** outRTV)2697 angle::Result TextureStorage11_Cube::getSwizzleRenderTarget(const gl::Context *context,
2698 int mipLevel,
2699 const d3d11::RenderTargetView **outRTV)
2700 {
2701 ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
2702 ASSERT(outRTV);
2703
2704 if (!mSwizzleRenderTargets[mipLevel].valid())
2705 {
2706 const TextureHelper11 *swizzleTexture = nullptr;
2707 ANGLE_TRY(getSwizzleTexture(context, &swizzleTexture));
2708
2709 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
2710 rtvDesc.Format =
2711 mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps()).rtvFormat;
2712 rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
2713 rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel;
2714 rtvDesc.Texture2DArray.FirstArraySlice = 0;
2715 rtvDesc.Texture2DArray.ArraySize = gl::kCubeFaceCount;
2716
2717 ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), rtvDesc,
2718 mSwizzleTexture.get(),
2719 &mSwizzleRenderTargets[mipLevel]));
2720 }
2721
2722 *outRTV = &mSwizzleRenderTargets[mipLevel];
2723 return angle::Result::Continue;
2724 }
2725
ensureDropStencilTexture(const gl::Context * context,DropStencil * dropStencilOut)2726 angle::Result TextureStorage11_Cube::ensureDropStencilTexture(const gl::Context *context,
2727 DropStencil *dropStencilOut)
2728 {
2729 if (mDropStencilTexture.valid())
2730 {
2731 *dropStencilOut = DropStencil::ALREADY_EXISTS;
2732 return angle::Result::Continue;
2733 }
2734
2735 D3D11_TEXTURE2D_DESC dropDesc = {};
2736 dropDesc.ArraySize = 6;
2737 dropDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_DEPTH_STENCIL;
2738 dropDesc.CPUAccessFlags = 0;
2739 dropDesc.Format = DXGI_FORMAT_R32_TYPELESS;
2740 dropDesc.Height = mTextureHeight;
2741 dropDesc.MipLevels = mMipLevels;
2742 dropDesc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
2743 dropDesc.SampleDesc.Count = 1;
2744 dropDesc.SampleDesc.Quality = 0;
2745 dropDesc.Usage = D3D11_USAGE_DEFAULT;
2746 dropDesc.Width = mTextureWidth;
2747
2748 const auto &format =
2749 d3d11::Format::Get(GL_DEPTH_COMPONENT32F, mRenderer->getRenderer11DeviceCaps());
2750 ANGLE_TRY(mRenderer->allocateTexture(GetImplAs<Context11>(context), dropDesc, format,
2751 &mDropStencilTexture));
2752 mDropStencilTexture.setDebugName("TexStorageCube.DropStencil");
2753
2754 ANGLE_TRY(initDropStencilTexture(context, gl::ImageIndexIterator::MakeCube(0, mMipLevels)));
2755
2756 *dropStencilOut = DropStencil::CREATED;
2757 return angle::Result::Continue;
2758 }
2759
resolveTexture(const gl::Context * context)2760 angle::Result TextureStorage11_Cube::resolveTexture(const gl::Context *context)
2761 {
2762 if (mMSTexInfo && mMSTexInfo->msTex && mMSTexInfo->msTextureNeedsResolve)
2763 {
2764 ANGLE_TRY(resolveTextureHelper(context, mTexture));
2765 onStateChange(angle::SubjectMessage::ContentsChanged);
2766 }
2767 return angle::Result::Continue;
2768 }
2769
TextureStorage11_3D(Renderer11 * renderer,GLenum internalformat,bool renderTarget,GLsizei width,GLsizei height,GLsizei depth,int levels)2770 TextureStorage11_3D::TextureStorage11_3D(Renderer11 *renderer,
2771 GLenum internalformat,
2772 bool renderTarget,
2773 GLsizei width,
2774 GLsizei height,
2775 GLsizei depth,
2776 int levels)
2777 : TextureStorage11(
2778 renderer,
2779 GetTextureBindFlags(internalformat, renderer->getRenderer11DeviceCaps(), renderTarget),
2780 GetTextureMiscFlags(internalformat,
2781 renderer->getRenderer11DeviceCaps(),
2782 renderTarget,
2783 levels),
2784 internalformat)
2785 {
2786 for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
2787 {
2788 mAssociatedImages[i] = nullptr;
2789 mLevelRenderTargets[i] = nullptr;
2790 }
2791
2792 // adjust size if needed for compressed textures
2793 d3d11::MakeValidSize(false, mFormatInfo.texFormat, &width, &height, &mTopLevel);
2794
2795 mMipLevels = mTopLevel + levels;
2796 mTextureWidth = width;
2797 mTextureHeight = height;
2798 mTextureDepth = depth;
2799 }
2800
onDestroy(const gl::Context * context)2801 angle::Result TextureStorage11_3D::onDestroy(const gl::Context *context)
2802 {
2803 for (unsigned i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
2804 {
2805 if (mAssociatedImages[i] != nullptr)
2806 {
2807 mAssociatedImages[i]->verifyAssociatedStorageValid(this);
2808
2809 // We must let the Images recover their data before we delete it from the
2810 // TextureStorage.
2811 ANGLE_TRY(mAssociatedImages[i]->recoverFromAssociatedStorage(context));
2812 }
2813 }
2814
2815 return angle::Result::Continue;
2816 }
2817
~TextureStorage11_3D()2818 TextureStorage11_3D::~TextureStorage11_3D() {}
2819
associateImage(Image11 * image,const gl::ImageIndex & index)2820 void TextureStorage11_3D::associateImage(Image11 *image, const gl::ImageIndex &index)
2821 {
2822 const GLint level = index.getLevelIndex();
2823
2824 ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
2825
2826 if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
2827 {
2828 mAssociatedImages[level] = image;
2829 }
2830 }
2831
verifyAssociatedImageValid(const gl::ImageIndex & index,Image11 * expectedImage)2832 void TextureStorage11_3D::verifyAssociatedImageValid(const gl::ImageIndex &index,
2833 Image11 *expectedImage)
2834 {
2835 const GLint level = index.getLevelIndex();
2836
2837 ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
2838 // This validation check should never return false. It means the Image/TextureStorage
2839 // association is broken.
2840 ASSERT(mAssociatedImages[level] == expectedImage);
2841 }
2842
2843 // disassociateImage allows an Image to end its association with a Storage.
disassociateImage(const gl::ImageIndex & index,Image11 * expectedImage)2844 void TextureStorage11_3D::disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage)
2845 {
2846 const GLint level = index.getLevelIndex();
2847
2848 ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
2849 ASSERT(mAssociatedImages[level] == expectedImage);
2850 mAssociatedImages[level] = nullptr;
2851 }
2852
2853 // releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image
2854 // recover its data before ending the association.
releaseAssociatedImage(const gl::Context * context,const gl::ImageIndex & index,Image11 * incomingImage)2855 angle::Result TextureStorage11_3D::releaseAssociatedImage(const gl::Context *context,
2856 const gl::ImageIndex &index,
2857 Image11 *incomingImage)
2858 {
2859 const GLint level = index.getLevelIndex();
2860
2861 ASSERT((0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS));
2862
2863 if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
2864 {
2865 // No need to let the old Image recover its data, if it is also the incoming Image.
2866 if (mAssociatedImages[level] != nullptr && mAssociatedImages[level] != incomingImage)
2867 {
2868 // Ensure that the Image is still associated with this TextureStorage.
2869 mAssociatedImages[level]->verifyAssociatedStorageValid(this);
2870
2871 // Force the image to recover from storage before its data is overwritten.
2872 // This will reset mAssociatedImages[level] to nullptr too.
2873 ANGLE_TRY(mAssociatedImages[level]->recoverFromAssociatedStorage(context));
2874 }
2875 }
2876
2877 return angle::Result::Continue;
2878 }
2879
getResource(const gl::Context * context,const TextureHelper11 ** outResource)2880 angle::Result TextureStorage11_3D::getResource(const gl::Context *context,
2881 const TextureHelper11 **outResource)
2882 {
2883 // If the width, height or depth are not positive this should be treated as an incomplete
2884 // texture. We handle that here by skipping the d3d texture creation.
2885 if (!mTexture.valid() && mTextureWidth > 0 && mTextureHeight > 0 && mTextureDepth > 0)
2886 {
2887 ASSERT(mMipLevels > 0);
2888
2889 D3D11_TEXTURE3D_DESC desc;
2890 desc.Width = mTextureWidth;
2891 desc.Height = mTextureHeight;
2892 desc.Depth = mTextureDepth;
2893 desc.MipLevels = mMipLevels;
2894 desc.Format = mFormatInfo.texFormat;
2895 desc.Usage = D3D11_USAGE_DEFAULT;
2896 desc.BindFlags = getBindFlags();
2897 desc.CPUAccessFlags = 0;
2898 desc.MiscFlags = getMiscFlags();
2899
2900 ANGLE_TRY(mRenderer->allocateTexture(GetImplAs<Context11>(context), desc, mFormatInfo,
2901 &mTexture));
2902 mTexture.setDebugName("TexStorage3D.Texture");
2903 }
2904
2905 *outResource = &mTexture;
2906 return angle::Result::Continue;
2907 }
2908
createSRVForSampler(const gl::Context * context,int baseLevel,int mipLevels,DXGI_FORMAT format,const TextureHelper11 & texture,d3d11::SharedSRV * outSRV)2909 angle::Result TextureStorage11_3D::createSRVForSampler(const gl::Context *context,
2910 int baseLevel,
2911 int mipLevels,
2912 DXGI_FORMAT format,
2913 const TextureHelper11 &texture,
2914 d3d11::SharedSRV *outSRV)
2915 {
2916 ASSERT(outSRV);
2917
2918 D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
2919 srvDesc.Format = format;
2920 srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D;
2921 srvDesc.Texture3D.MostDetailedMip = baseLevel;
2922 srvDesc.Texture3D.MipLevels = mipLevels;
2923
2924 ANGLE_TRY(
2925 mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(), outSRV));
2926 outSRV->setDebugName("TexStorage3D.SRV");
2927
2928 return angle::Result::Continue;
2929 }
2930
createSRVForImage(const gl::Context * context,int level,DXGI_FORMAT format,const TextureHelper11 & texture,d3d11::SharedSRV * outSRV)2931 angle::Result TextureStorage11_3D::createSRVForImage(const gl::Context *context,
2932 int level,
2933 DXGI_FORMAT format,
2934 const TextureHelper11 &texture,
2935 d3d11::SharedSRV *outSRV)
2936 {
2937 ASSERT(outSRV);
2938 D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
2939 srvDesc.Format = format;
2940 srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D;
2941 srvDesc.Texture3D.MostDetailedMip = mTopLevel + level;
2942 srvDesc.Texture3D.MipLevels = 1;
2943 ANGLE_TRY(
2944 mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(), outSRV));
2945 outSRV->setDebugName("TexStorage3D.SRVForImage");
2946 return angle::Result::Continue;
2947 }
2948
createUAVForImage(const gl::Context * context,int level,DXGI_FORMAT format,const TextureHelper11 & texture,d3d11::SharedUAV * outUAV)2949 angle::Result TextureStorage11_3D::createUAVForImage(const gl::Context *context,
2950 int level,
2951 DXGI_FORMAT format,
2952 const TextureHelper11 &texture,
2953 d3d11::SharedUAV *outUAV)
2954 {
2955 ASSERT(outUAV);
2956 D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc;
2957 uavDesc.Format = format;
2958 uavDesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE3D;
2959 uavDesc.Texture3D.MipSlice = mTopLevel + level;
2960 uavDesc.Texture3D.FirstWSlice = 0;
2961 uavDesc.Texture3D.WSize = mTextureDepth;
2962 ANGLE_TRY(
2963 mRenderer->allocateResource(GetImplAs<Context11>(context), uavDesc, texture.get(), outUAV));
2964 outUAV->setDebugName("TexStorage3D.UAVForImage");
2965 return angle::Result::Continue;
2966 }
2967
findRenderTarget(const gl::Context * context,const gl::ImageIndex & index,GLsizei samples,RenderTargetD3D ** outRT) const2968 angle::Result TextureStorage11_3D::findRenderTarget(const gl::Context *context,
2969 const gl::ImageIndex &index,
2970 GLsizei samples,
2971 RenderTargetD3D **outRT) const
2972 {
2973 const int mipLevel = index.getLevelIndex();
2974 ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
2975
2976 if (!index.hasLayer())
2977 {
2978 ASSERT(outRT);
2979 *outRT = mLevelRenderTargets[mipLevel].get();
2980 return angle::Result::Continue;
2981 }
2982
2983 const int layer = index.getLayerIndex();
2984
2985 LevelLayerKey key(mipLevel, layer);
2986 if (mLevelLayerRenderTargets.find(key) == mLevelLayerRenderTargets.end())
2987 {
2988 ASSERT(outRT);
2989 *outRT = nullptr;
2990 return angle::Result::Continue;
2991 }
2992
2993 ASSERT(outRT);
2994 *outRT = mLevelLayerRenderTargets.at(key).get();
2995 return angle::Result::Continue;
2996 }
2997
getRenderTarget(const gl::Context * context,const gl::ImageIndex & index,GLsizei samples,RenderTargetD3D ** outRT)2998 angle::Result TextureStorage11_3D::getRenderTarget(const gl::Context *context,
2999 const gl::ImageIndex &index,
3000 GLsizei samples,
3001 RenderTargetD3D **outRT)
3002 {
3003 const int mipLevel = index.getLevelIndex();
3004 ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
3005
3006 ASSERT(mFormatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN);
3007
3008 Context11 *context11 = GetImplAs<Context11>(context);
3009
3010 if (!index.hasLayer())
3011 {
3012 if (!mLevelRenderTargets[mipLevel])
3013 {
3014 const TextureHelper11 *texture = nullptr;
3015 ANGLE_TRY(getResource(context, &texture));
3016
3017 const d3d11::SharedSRV *srv = nullptr;
3018 ANGLE_TRY(getSRVLevel(context, mipLevel, false, &srv));
3019
3020 const d3d11::SharedSRV *blitSRV = nullptr;
3021 ANGLE_TRY(getSRVLevel(context, mipLevel, true, &blitSRV));
3022
3023 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
3024 rtvDesc.Format = mFormatInfo.rtvFormat;
3025 rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D;
3026 rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel;
3027 rtvDesc.Texture3D.FirstWSlice = 0;
3028 rtvDesc.Texture3D.WSize = static_cast<UINT>(-1);
3029
3030 d3d11::RenderTargetView rtv;
3031 ANGLE_TRY(mRenderer->allocateResource(context11, rtvDesc, texture->get(), &rtv));
3032 rtv.setDebugName("TexStorage3D.RTV");
3033
3034 mLevelRenderTargets[mipLevel].reset(new TextureRenderTarget11(
3035 std::move(rtv), *texture, *srv, *blitSRV, mFormatInfo.internalFormat,
3036 getFormatSet(), getLevelWidth(mipLevel), getLevelHeight(mipLevel),
3037 getLevelDepth(mipLevel), 0));
3038 }
3039
3040 ASSERT(outRT);
3041 *outRT = mLevelRenderTargets[mipLevel].get();
3042 return angle::Result::Continue;
3043 }
3044
3045 const int layer = index.getLayerIndex();
3046
3047 LevelLayerKey key(mipLevel, layer);
3048 if (mLevelLayerRenderTargets.find(key) == mLevelLayerRenderTargets.end())
3049 {
3050 const TextureHelper11 *texture = nullptr;
3051 ANGLE_TRY(getResource(context, &texture));
3052
3053 // TODO, what kind of SRV is expected here?
3054 const d3d11::SharedSRV srv;
3055 const d3d11::SharedSRV blitSRV;
3056
3057 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
3058 rtvDesc.Format = mFormatInfo.rtvFormat;
3059 rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D;
3060 rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel;
3061 rtvDesc.Texture3D.FirstWSlice = layer;
3062 rtvDesc.Texture3D.WSize = 1;
3063
3064 d3d11::RenderTargetView rtv;
3065 ANGLE_TRY(mRenderer->allocateResource(context11, rtvDesc, texture->get(), &rtv));
3066 rtv.setDebugName("TexStorage3D.LayerRTV");
3067
3068 mLevelLayerRenderTargets[key].reset(new TextureRenderTarget11(
3069 std::move(rtv), *texture, srv, blitSRV, mFormatInfo.internalFormat, getFormatSet(),
3070 getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1, 0));
3071 }
3072
3073 ASSERT(outRT);
3074 *outRT = mLevelLayerRenderTargets[key].get();
3075 return angle::Result::Continue;
3076 }
3077
getSwizzleTexture(const gl::Context * context,const TextureHelper11 ** outTexture)3078 angle::Result TextureStorage11_3D::getSwizzleTexture(const gl::Context *context,
3079 const TextureHelper11 **outTexture)
3080 {
3081 ASSERT(outTexture);
3082
3083 if (!mSwizzleTexture.valid())
3084 {
3085 const auto &format = mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps());
3086
3087 D3D11_TEXTURE3D_DESC desc;
3088 desc.Width = mTextureWidth;
3089 desc.Height = mTextureHeight;
3090 desc.Depth = mTextureDepth;
3091 desc.MipLevels = mMipLevels;
3092 desc.Format = format.texFormat;
3093 desc.Usage = D3D11_USAGE_DEFAULT;
3094 desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
3095 desc.CPUAccessFlags = 0;
3096 desc.MiscFlags = 0;
3097
3098 ANGLE_TRY(mRenderer->allocateTexture(GetImplAs<Context11>(context), desc, format,
3099 &mSwizzleTexture));
3100 mSwizzleTexture.setDebugName("TexStorage3D.SwizzleTexture");
3101 }
3102
3103 *outTexture = &mSwizzleTexture;
3104 return angle::Result::Continue;
3105 }
3106
getSwizzleRenderTarget(const gl::Context * context,int mipLevel,const d3d11::RenderTargetView ** outRTV)3107 angle::Result TextureStorage11_3D::getSwizzleRenderTarget(const gl::Context *context,
3108 int mipLevel,
3109 const d3d11::RenderTargetView **outRTV)
3110 {
3111 ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
3112 ASSERT(outRTV);
3113
3114 if (!mSwizzleRenderTargets[mipLevel].valid())
3115 {
3116 const TextureHelper11 *swizzleTexture = nullptr;
3117 ANGLE_TRY(getSwizzleTexture(context, &swizzleTexture));
3118
3119 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
3120 rtvDesc.Format =
3121 mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps()).rtvFormat;
3122 rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D;
3123 rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel;
3124 rtvDesc.Texture3D.FirstWSlice = 0;
3125 rtvDesc.Texture3D.WSize = static_cast<UINT>(-1);
3126
3127 ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), rtvDesc,
3128 mSwizzleTexture.get(),
3129 &mSwizzleRenderTargets[mipLevel]));
3130 mSwizzleRenderTargets[mipLevel].setDebugName("TexStorage3D.SwizzleRTV");
3131 }
3132
3133 *outRTV = &mSwizzleRenderTargets[mipLevel];
3134 return angle::Result::Continue;
3135 }
3136
TextureStorage11_2DArray(Renderer11 * renderer,GLenum internalformat,bool renderTarget,GLsizei width,GLsizei height,GLsizei depth,int levels)3137 TextureStorage11_2DArray::TextureStorage11_2DArray(Renderer11 *renderer,
3138 GLenum internalformat,
3139 bool renderTarget,
3140 GLsizei width,
3141 GLsizei height,
3142 GLsizei depth,
3143 int levels)
3144 : TextureStorage11(
3145 renderer,
3146 GetTextureBindFlags(internalformat, renderer->getRenderer11DeviceCaps(), renderTarget),
3147 GetTextureMiscFlags(internalformat,
3148 renderer->getRenderer11DeviceCaps(),
3149 renderTarget,
3150 levels),
3151 internalformat)
3152 {
3153 // adjust size if needed for compressed textures
3154 d3d11::MakeValidSize(false, mFormatInfo.texFormat, &width, &height, &mTopLevel);
3155
3156 mMipLevels = mTopLevel + levels;
3157 mTextureWidth = width;
3158 mTextureHeight = height;
3159 mTextureDepth = depth;
3160 }
3161
onDestroy(const gl::Context * context)3162 angle::Result TextureStorage11_2DArray::onDestroy(const gl::Context *context)
3163 {
3164 for (auto iter : mAssociatedImages)
3165 {
3166 if (iter.second)
3167 {
3168 iter.second->verifyAssociatedStorageValid(this);
3169
3170 // We must let the Images recover their data before we delete it from the
3171 // TextureStorage.
3172 ANGLE_TRY(iter.second->recoverFromAssociatedStorage(context));
3173 }
3174 }
3175 mAssociatedImages.clear();
3176
3177 return angle::Result::Continue;
3178 }
3179
~TextureStorage11_2DArray()3180 TextureStorage11_2DArray::~TextureStorage11_2DArray() {}
3181
associateImage(Image11 * image,const gl::ImageIndex & index)3182 void TextureStorage11_2DArray::associateImage(Image11 *image, const gl::ImageIndex &index)
3183 {
3184 const GLint level = index.getLevelIndex();
3185 const GLint layerTarget = index.getLayerIndex();
3186 const GLint numLayers = index.getLayerCount();
3187
3188 ASSERT(0 <= level && level < getLevelCount());
3189
3190 if (0 <= level && level < getLevelCount())
3191 {
3192 LevelLayerRangeKey key(level, layerTarget, numLayers);
3193 mAssociatedImages[key] = image;
3194 }
3195 }
3196
verifyAssociatedImageValid(const gl::ImageIndex & index,Image11 * expectedImage)3197 void TextureStorage11_2DArray::verifyAssociatedImageValid(const gl::ImageIndex &index,
3198 Image11 *expectedImage)
3199 {
3200 const GLint level = index.getLevelIndex();
3201 const GLint layerTarget = index.getLayerIndex();
3202 const GLint numLayers = index.getLayerCount();
3203
3204 LevelLayerRangeKey key(level, layerTarget, numLayers);
3205
3206 // This validation check should never return false. It means the Image/TextureStorage
3207 // association is broken.
3208 bool retValue = (mAssociatedImages.find(key) != mAssociatedImages.end() &&
3209 (mAssociatedImages[key] == expectedImage));
3210 ASSERT(retValue);
3211 }
3212
3213 // disassociateImage allows an Image to end its association with a Storage.
disassociateImage(const gl::ImageIndex & index,Image11 * expectedImage)3214 void TextureStorage11_2DArray::disassociateImage(const gl::ImageIndex &index,
3215 Image11 *expectedImage)
3216 {
3217 const GLint level = index.getLevelIndex();
3218 const GLint layerTarget = index.getLayerIndex();
3219 const GLint numLayers = index.getLayerCount();
3220
3221 LevelLayerRangeKey key(level, layerTarget, numLayers);
3222
3223 bool imageAssociationCorrect = (mAssociatedImages.find(key) != mAssociatedImages.end() &&
3224 (mAssociatedImages[key] == expectedImage));
3225 ASSERT(imageAssociationCorrect);
3226 mAssociatedImages[key] = nullptr;
3227 }
3228
3229 // releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image
3230 // recover its data before ending the association.
releaseAssociatedImage(const gl::Context * context,const gl::ImageIndex & index,Image11 * incomingImage)3231 angle::Result TextureStorage11_2DArray::releaseAssociatedImage(const gl::Context *context,
3232 const gl::ImageIndex &index,
3233 Image11 *incomingImage)
3234 {
3235 const GLint level = index.getLevelIndex();
3236 const GLint layerTarget = index.getLayerIndex();
3237 const GLint numLayers = index.getLayerCount();
3238
3239 LevelLayerRangeKey key(level, layerTarget, numLayers);
3240
3241 if (mAssociatedImages.find(key) != mAssociatedImages.end())
3242 {
3243 if (mAssociatedImages[key] != nullptr && mAssociatedImages[key] != incomingImage)
3244 {
3245 // Ensure that the Image is still associated with this TextureStorage.
3246 mAssociatedImages[key]->verifyAssociatedStorageValid(this);
3247
3248 // Force the image to recover from storage before its data is overwritten.
3249 // This will reset mAssociatedImages[level] to nullptr too.
3250 ANGLE_TRY(mAssociatedImages[key]->recoverFromAssociatedStorage(context));
3251 }
3252 }
3253
3254 return angle::Result::Continue;
3255 }
3256
getResource(const gl::Context * context,const TextureHelper11 ** outResource)3257 angle::Result TextureStorage11_2DArray::getResource(const gl::Context *context,
3258 const TextureHelper11 **outResource)
3259 {
3260 // if the width, height or depth is not positive this should be treated as an incomplete texture
3261 // we handle that here by skipping the d3d texture creation
3262 if (!mTexture.valid() && mTextureWidth > 0 && mTextureHeight > 0 && mTextureDepth > 0)
3263 {
3264 ASSERT(mMipLevels > 0);
3265
3266 D3D11_TEXTURE2D_DESC desc;
3267 desc.Width = mTextureWidth;
3268 desc.Height = mTextureHeight;
3269 desc.MipLevels = mMipLevels;
3270 desc.ArraySize = mTextureDepth;
3271 desc.Format = mFormatInfo.texFormat;
3272 desc.SampleDesc.Count = 1;
3273 desc.SampleDesc.Quality = 0;
3274 desc.Usage = D3D11_USAGE_DEFAULT;
3275 desc.BindFlags = getBindFlags();
3276 desc.CPUAccessFlags = 0;
3277 desc.MiscFlags = getMiscFlags();
3278
3279 ANGLE_TRY(mRenderer->allocateTexture(GetImplAs<Context11>(context), desc, mFormatInfo,
3280 &mTexture));
3281 mTexture.setDebugName("TexStorage2DArray.Texture");
3282 }
3283
3284 *outResource = &mTexture;
3285 return angle::Result::Continue;
3286 }
3287
createSRVForSampler(const gl::Context * context,int baseLevel,int mipLevels,DXGI_FORMAT format,const TextureHelper11 & texture,d3d11::SharedSRV * outSRV)3288 angle::Result TextureStorage11_2DArray::createSRVForSampler(const gl::Context *context,
3289 int baseLevel,
3290 int mipLevels,
3291 DXGI_FORMAT format,
3292 const TextureHelper11 &texture,
3293 d3d11::SharedSRV *outSRV)
3294 {
3295 D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
3296 srvDesc.Format = format;
3297 srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
3298 srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + baseLevel;
3299 srvDesc.Texture2DArray.MipLevels = mipLevels;
3300 srvDesc.Texture2DArray.FirstArraySlice = 0;
3301 srvDesc.Texture2DArray.ArraySize = mTextureDepth;
3302
3303 ANGLE_TRY(
3304 mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(), outSRV));
3305 outSRV->setDebugName("TexStorage2DArray.SRV");
3306
3307 return angle::Result::Continue;
3308 }
3309
createSRVForImage(const gl::Context * context,int level,DXGI_FORMAT format,const TextureHelper11 & texture,d3d11::SharedSRV * outSRV)3310 angle::Result TextureStorage11_2DArray::createSRVForImage(const gl::Context *context,
3311 int level,
3312 DXGI_FORMAT format,
3313 const TextureHelper11 &texture,
3314 d3d11::SharedSRV *outSRV)
3315 {
3316 ASSERT(outSRV);
3317 D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
3318 srvDesc.Format = format;
3319 srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
3320 srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + level;
3321 srvDesc.Texture2DArray.MipLevels = 1;
3322 srvDesc.Texture2DArray.FirstArraySlice = 0;
3323 srvDesc.Texture2DArray.ArraySize = mTextureDepth;
3324 ANGLE_TRY(
3325 mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(), outSRV));
3326 outSRV->setDebugName("TexStorage2DArray.SRVForImage");
3327 return angle::Result::Continue;
3328 }
3329
createUAVForImage(const gl::Context * context,int level,DXGI_FORMAT format,const TextureHelper11 & texture,d3d11::SharedUAV * outUAV)3330 angle::Result TextureStorage11_2DArray::createUAVForImage(const gl::Context *context,
3331 int level,
3332 DXGI_FORMAT format,
3333 const TextureHelper11 &texture,
3334 d3d11::SharedUAV *outUAV)
3335 {
3336 ASSERT(outUAV);
3337 D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc;
3338 uavDesc.Format = format;
3339 uavDesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2DARRAY;
3340 uavDesc.Texture2DArray.MipSlice = mTopLevel + level;
3341 uavDesc.Texture2DArray.FirstArraySlice = 0;
3342 uavDesc.Texture2DArray.ArraySize = mTextureDepth;
3343 ANGLE_TRY(
3344 mRenderer->allocateResource(GetImplAs<Context11>(context), uavDesc, texture.get(), outUAV));
3345 outUAV->setDebugName("TexStorage2DArray.UAVForImage");
3346 return angle::Result::Continue;
3347 }
3348
findRenderTarget(const gl::Context * context,const gl::ImageIndex & index,GLsizei samples,RenderTargetD3D ** outRT) const3349 angle::Result TextureStorage11_2DArray::findRenderTarget(const gl::Context *context,
3350 const gl::ImageIndex &index,
3351 GLsizei samples,
3352 RenderTargetD3D **outRT) const
3353 {
3354 ASSERT(index.hasLayer());
3355
3356 const int mipLevel = index.getLevelIndex();
3357 const int layer = index.getLayerIndex();
3358 const int numLayers = index.getLayerCount();
3359
3360 ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
3361
3362 LevelLayerRangeKey key(mipLevel, layer, numLayers);
3363 if (mRenderTargets.find(key) == mRenderTargets.end())
3364 {
3365 ASSERT(outRT);
3366 *outRT = nullptr;
3367 return angle::Result::Continue;
3368 }
3369
3370 ASSERT(outRT);
3371 *outRT = mRenderTargets.at(key).get();
3372 return angle::Result::Continue;
3373 }
3374
createRenderTargetSRV(const gl::Context * context,const TextureHelper11 & texture,const gl::ImageIndex & index,DXGI_FORMAT resourceFormat,d3d11::SharedSRV * srv) const3375 angle::Result TextureStorage11_2DArray::createRenderTargetSRV(const gl::Context *context,
3376 const TextureHelper11 &texture,
3377 const gl::ImageIndex &index,
3378 DXGI_FORMAT resourceFormat,
3379 d3d11::SharedSRV *srv) const
3380 {
3381 D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
3382 srvDesc.Format = resourceFormat;
3383 srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
3384 srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + index.getLevelIndex();
3385 srvDesc.Texture2DArray.MipLevels = 1;
3386 srvDesc.Texture2DArray.FirstArraySlice = index.getLayerIndex();
3387 srvDesc.Texture2DArray.ArraySize = index.getLayerCount();
3388
3389 ANGLE_TRY(
3390 mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(), srv));
3391
3392 return angle::Result::Continue;
3393 }
3394
getRenderTarget(const gl::Context * context,const gl::ImageIndex & index,GLsizei samples,RenderTargetD3D ** outRT)3395 angle::Result TextureStorage11_2DArray::getRenderTarget(const gl::Context *context,
3396 const gl::ImageIndex &index,
3397 GLsizei samples,
3398 RenderTargetD3D **outRT)
3399 {
3400 ASSERT(index.hasLayer());
3401
3402 const int mipLevel = index.getLevelIndex();
3403 const int layer = index.getLayerIndex();
3404 const int numLayers = index.getLayerCount();
3405
3406 ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
3407
3408 LevelLayerRangeKey key(mipLevel, layer, numLayers);
3409 if (mRenderTargets.find(key) == mRenderTargets.end())
3410 {
3411 const TextureHelper11 *texture = nullptr;
3412 ANGLE_TRY(getResource(context, &texture));
3413 d3d11::SharedSRV srv;
3414 ANGLE_TRY(createRenderTargetSRV(context, *texture, index, mFormatInfo.srvFormat, &srv));
3415 d3d11::SharedSRV blitSRV;
3416 if (mFormatInfo.blitSRVFormat != mFormatInfo.srvFormat)
3417 {
3418 ANGLE_TRY(createRenderTargetSRV(context, *texture, index, mFormatInfo.blitSRVFormat,
3419 &blitSRV));
3420 }
3421 else
3422 {
3423 blitSRV = srv.makeCopy();
3424 }
3425
3426 srv.setDebugName("TexStorage2DArray.RenderTargetSRV");
3427
3428 if (mFormatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN)
3429 {
3430 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
3431 rtvDesc.Format = mFormatInfo.rtvFormat;
3432 rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
3433 rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel;
3434 rtvDesc.Texture2DArray.FirstArraySlice = layer;
3435 rtvDesc.Texture2DArray.ArraySize = numLayers;
3436
3437 d3d11::RenderTargetView rtv;
3438 ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), rtvDesc,
3439 texture->get(), &rtv));
3440 rtv.setDebugName("TexStorage2DArray.RenderTargetRTV");
3441
3442 mRenderTargets[key].reset(new TextureRenderTarget11(
3443 std::move(rtv), *texture, srv, blitSRV, mFormatInfo.internalFormat, getFormatSet(),
3444 getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1, 0));
3445 }
3446 else
3447 {
3448 ASSERT(mFormatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN);
3449
3450 D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
3451 dsvDesc.Format = mFormatInfo.dsvFormat;
3452 dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY;
3453 dsvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel;
3454 dsvDesc.Texture2DArray.FirstArraySlice = layer;
3455 dsvDesc.Texture2DArray.ArraySize = numLayers;
3456 dsvDesc.Flags = 0;
3457
3458 d3d11::DepthStencilView dsv;
3459 ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), dsvDesc,
3460 texture->get(), &dsv));
3461 dsv.setDebugName("TexStorage2DArray.RenderTargetDSV");
3462
3463 mRenderTargets[key].reset(new TextureRenderTarget11(
3464 std::move(dsv), *texture, srv, mFormatInfo.internalFormat, getFormatSet(),
3465 getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1, 0));
3466 }
3467 }
3468
3469 ASSERT(outRT);
3470 *outRT = mRenderTargets[key].get();
3471 return angle::Result::Continue;
3472 }
3473
getSwizzleTexture(const gl::Context * context,const TextureHelper11 ** outTexture)3474 angle::Result TextureStorage11_2DArray::getSwizzleTexture(const gl::Context *context,
3475 const TextureHelper11 **outTexture)
3476 {
3477 if (!mSwizzleTexture.valid())
3478 {
3479 const auto &format = mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps());
3480
3481 D3D11_TEXTURE2D_DESC desc;
3482 desc.Width = mTextureWidth;
3483 desc.Height = mTextureHeight;
3484 desc.MipLevels = mMipLevels;
3485 desc.ArraySize = mTextureDepth;
3486 desc.Format = format.texFormat;
3487 desc.SampleDesc.Count = 1;
3488 desc.SampleDesc.Quality = 0;
3489 desc.Usage = D3D11_USAGE_DEFAULT;
3490 desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
3491 desc.CPUAccessFlags = 0;
3492 desc.MiscFlags = 0;
3493
3494 ANGLE_TRY(mRenderer->allocateTexture(GetImplAs<Context11>(context), desc, format,
3495 &mSwizzleTexture));
3496 mSwizzleTexture.setDebugName("TexStorage2DArray.SwizzleTexture");
3497 }
3498
3499 *outTexture = &mSwizzleTexture;
3500 return angle::Result::Continue;
3501 }
3502
getSwizzleRenderTarget(const gl::Context * context,int mipLevel,const d3d11::RenderTargetView ** outRTV)3503 angle::Result TextureStorage11_2DArray::getSwizzleRenderTarget(
3504 const gl::Context *context,
3505 int mipLevel,
3506 const d3d11::RenderTargetView **outRTV)
3507 {
3508 ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
3509 ASSERT(outRTV);
3510
3511 if (!mSwizzleRenderTargets[mipLevel].valid())
3512 {
3513 const TextureHelper11 *swizzleTexture = nullptr;
3514 ANGLE_TRY(getSwizzleTexture(context, &swizzleTexture));
3515
3516 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
3517 rtvDesc.Format =
3518 mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps()).rtvFormat;
3519 rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
3520 rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel;
3521 rtvDesc.Texture2DArray.FirstArraySlice = 0;
3522 rtvDesc.Texture2DArray.ArraySize = mTextureDepth;
3523
3524 ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), rtvDesc,
3525 mSwizzleTexture.get(),
3526 &mSwizzleRenderTargets[mipLevel]));
3527 }
3528
3529 *outRTV = &mSwizzleRenderTargets[mipLevel];
3530 return angle::Result::Continue;
3531 }
3532
ensureDropStencilTexture(const gl::Context * context,DropStencil * dropStencilOut)3533 angle::Result TextureStorage11_2DArray::ensureDropStencilTexture(const gl::Context *context,
3534 DropStencil *dropStencilOut)
3535 {
3536 if (mDropStencilTexture.valid())
3537 {
3538 *dropStencilOut = DropStencil::ALREADY_EXISTS;
3539 return angle::Result::Continue;
3540 }
3541
3542 D3D11_TEXTURE2D_DESC dropDesc = {};
3543 dropDesc.ArraySize = mTextureDepth;
3544 dropDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_DEPTH_STENCIL;
3545 dropDesc.CPUAccessFlags = 0;
3546 dropDesc.Format = DXGI_FORMAT_R32_TYPELESS;
3547 dropDesc.Height = mTextureHeight;
3548 dropDesc.MipLevels = mMipLevels;
3549 dropDesc.MiscFlags = 0;
3550 dropDesc.SampleDesc.Count = 1;
3551 dropDesc.SampleDesc.Quality = 0;
3552 dropDesc.Usage = D3D11_USAGE_DEFAULT;
3553 dropDesc.Width = mTextureWidth;
3554
3555 const auto &format =
3556 d3d11::Format::Get(GL_DEPTH_COMPONENT32F, mRenderer->getRenderer11DeviceCaps());
3557 ANGLE_TRY(mRenderer->allocateTexture(GetImplAs<Context11>(context), dropDesc, format,
3558 &mDropStencilTexture));
3559 mDropStencilTexture.setDebugName("TexStorage2DArray.DropStencil");
3560
3561 std::vector<GLsizei> layerCounts(mMipLevels, mTextureDepth);
3562
3563 ANGLE_TRY(initDropStencilTexture(
3564 context, gl::ImageIndexIterator::Make2DArray(0, mMipLevels, layerCounts.data())));
3565
3566 *dropStencilOut = DropStencil::CREATED;
3567 return angle::Result::Continue;
3568 }
3569
TextureStorage11_2DMultisample(Renderer11 * renderer,GLenum internalformat,GLsizei width,GLsizei height,int levels,int samples,bool fixedSampleLocations)3570 TextureStorage11_2DMultisample::TextureStorage11_2DMultisample(Renderer11 *renderer,
3571 GLenum internalformat,
3572 GLsizei width,
3573 GLsizei height,
3574 int levels,
3575 int samples,
3576 bool fixedSampleLocations)
3577 : TextureStorage11ImmutableBase(
3578 renderer,
3579 GetTextureBindFlags(internalformat, renderer->getRenderer11DeviceCaps(), true),
3580 GetTextureMiscFlags(internalformat, renderer->getRenderer11DeviceCaps(), true, levels),
3581 internalformat),
3582 mTexture(),
3583 mRenderTarget(nullptr)
3584 {
3585 // There are no multisampled compressed formats, so there's no need to adjust texture size
3586 // according to block size.
3587 ASSERT(d3d11::GetDXGIFormatSizeInfo(mFormatInfo.texFormat).blockWidth <= 1);
3588 ASSERT(d3d11::GetDXGIFormatSizeInfo(mFormatInfo.texFormat).blockHeight <= 1);
3589
3590 mMipLevels = 1;
3591 mTextureWidth = width;
3592 mTextureHeight = height;
3593 mTextureDepth = 1;
3594 mSamples = samples;
3595 mFixedSampleLocations = fixedSampleLocations;
3596 }
3597
onDestroy(const gl::Context * context)3598 angle::Result TextureStorage11_2DMultisample::onDestroy(const gl::Context *context)
3599 {
3600 mRenderTarget.reset();
3601 return angle::Result::Continue;
3602 }
3603
~TextureStorage11_2DMultisample()3604 TextureStorage11_2DMultisample::~TextureStorage11_2DMultisample() {}
3605
copyToStorage(const gl::Context * context,TextureStorage * destStorage)3606 angle::Result TextureStorage11_2DMultisample::copyToStorage(const gl::Context *context,
3607 TextureStorage *destStorage)
3608 {
3609 ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
3610 return angle::Result::Stop;
3611 }
3612
getResource(const gl::Context * context,const TextureHelper11 ** outResource)3613 angle::Result TextureStorage11_2DMultisample::getResource(const gl::Context *context,
3614 const TextureHelper11 **outResource)
3615 {
3616 ANGLE_TRY(ensureTextureExists(context, 1));
3617
3618 *outResource = &mTexture;
3619 return angle::Result::Continue;
3620 }
3621
ensureTextureExists(const gl::Context * context,int mipLevels)3622 angle::Result TextureStorage11_2DMultisample::ensureTextureExists(const gl::Context *context,
3623 int mipLevels)
3624 {
3625 // For Multisampled textures, mipLevels always equals 1.
3626 ASSERT(mipLevels == 1);
3627
3628 // if the width or height is not positive this should be treated as an incomplete texture
3629 // we handle that here by skipping the d3d texture creation
3630 if (!mTexture.valid() && mTextureWidth > 0 && mTextureHeight > 0)
3631 {
3632 D3D11_TEXTURE2D_DESC desc;
3633 ZeroMemory(&desc, sizeof(desc));
3634 desc.Width = mTextureWidth; // Compressed texture size constraints?
3635 desc.Height = mTextureHeight;
3636 desc.MipLevels = mipLevels;
3637 desc.ArraySize = 1;
3638 desc.Format = mFormatInfo.texFormat;
3639 desc.Usage = D3D11_USAGE_DEFAULT;
3640 desc.BindFlags = getBindFlags() & ~D3D11_BIND_UNORDERED_ACCESS;
3641 desc.CPUAccessFlags = 0;
3642 desc.MiscFlags = getMiscFlags();
3643
3644 const gl::TextureCaps &textureCaps =
3645 mRenderer->getNativeTextureCaps().get(mFormatInfo.internalFormat);
3646 GLuint supportedSamples = textureCaps.getNearestSamples(mSamples);
3647 desc.SampleDesc.Count = (supportedSamples == 0) ? 1 : supportedSamples;
3648 desc.SampleDesc.Quality = mRenderer->getSampleDescQuality(supportedSamples);
3649
3650 ANGLE_TRY(mRenderer->allocateTexture(GetImplAs<Context11>(context), desc, mFormatInfo,
3651 &mTexture));
3652 mTexture.setDebugName("TexStorage2DMS.Texture");
3653 }
3654
3655 return angle::Result::Continue;
3656 }
3657
findRenderTarget(const gl::Context * context,const gl::ImageIndex & index,GLsizei samples,RenderTargetD3D ** outRT) const3658 angle::Result TextureStorage11_2DMultisample::findRenderTarget(const gl::Context *context,
3659 const gl::ImageIndex &index,
3660 GLsizei samples,
3661 RenderTargetD3D **outRT) const
3662 {
3663 ASSERT(!index.hasLayer());
3664
3665 const int level = index.getLevelIndex();
3666 ASSERT(level == 0);
3667
3668 ASSERT(outRT);
3669 *outRT = mRenderTarget.get();
3670 return angle::Result::Continue;
3671 }
3672
getRenderTarget(const gl::Context * context,const gl::ImageIndex & index,GLsizei samples,RenderTargetD3D ** outRT)3673 angle::Result TextureStorage11_2DMultisample::getRenderTarget(const gl::Context *context,
3674 const gl::ImageIndex &index,
3675 GLsizei samples,
3676 RenderTargetD3D **outRT)
3677 {
3678 ASSERT(!index.hasLayer());
3679
3680 const int level = index.getLevelIndex();
3681 ASSERT(level == 0);
3682
3683 ASSERT(outRT);
3684 if (mRenderTarget)
3685 {
3686 *outRT = mRenderTarget.get();
3687 return angle::Result::Continue;
3688 }
3689
3690 const TextureHelper11 *texture = nullptr;
3691 ANGLE_TRY(getResource(context, &texture));
3692
3693 const d3d11::SharedSRV *srv = nullptr;
3694 ANGLE_TRY(getSRVLevel(context, level, false, &srv));
3695
3696 const d3d11::SharedSRV *blitSRV = nullptr;
3697 ANGLE_TRY(getSRVLevel(context, level, true, &blitSRV));
3698
3699 Context11 *context11 = GetImplAs<Context11>(context);
3700
3701 if (mFormatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN)
3702 {
3703 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
3704 rtvDesc.Format = mFormatInfo.rtvFormat;
3705 rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMS;
3706
3707 d3d11::RenderTargetView rtv;
3708 ANGLE_TRY(mRenderer->allocateResource(context11, rtvDesc, texture->get(), &rtv));
3709
3710 mRenderTarget.reset(new TextureRenderTarget11(
3711 std::move(rtv), *texture, *srv, *blitSRV, mFormatInfo.internalFormat, getFormatSet(),
3712 getLevelWidth(level), getLevelHeight(level), 1, mSamples));
3713
3714 *outRT = mRenderTarget.get();
3715 return angle::Result::Continue;
3716 }
3717
3718 ASSERT(mFormatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN);
3719
3720 D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
3721 dsvDesc.Format = mFormatInfo.dsvFormat;
3722 dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMS;
3723 dsvDesc.Flags = 0;
3724
3725 d3d11::DepthStencilView dsv;
3726 ANGLE_TRY(mRenderer->allocateResource(context11, dsvDesc, texture->get(), &dsv));
3727
3728 mRenderTarget.reset(new TextureRenderTarget11(
3729 std::move(dsv), *texture, *srv, mFormatInfo.internalFormat, getFormatSet(),
3730 getLevelWidth(level), getLevelHeight(level), 1, mSamples));
3731
3732 *outRT = mRenderTarget.get();
3733 return angle::Result::Continue;
3734 }
3735
createSRVForSampler(const gl::Context * context,int baseLevel,int mipLevels,DXGI_FORMAT format,const TextureHelper11 & texture,d3d11::SharedSRV * outSRV)3736 angle::Result TextureStorage11_2DMultisample::createSRVForSampler(const gl::Context *context,
3737 int baseLevel,
3738 int mipLevels,
3739 DXGI_FORMAT format,
3740 const TextureHelper11 &texture,
3741 d3d11::SharedSRV *outSRV)
3742 {
3743 ASSERT(outSRV);
3744
3745 D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
3746 srvDesc.Format = format;
3747 srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMS;
3748
3749 ANGLE_TRY(
3750 mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(), outSRV));
3751 outSRV->setDebugName("TexStorage2DMS.SRV");
3752 return angle::Result::Continue;
3753 }
3754
getSwizzleTexture(const gl::Context * context,const TextureHelper11 ** outTexture)3755 angle::Result TextureStorage11_2DMultisample::getSwizzleTexture(const gl::Context *context,
3756 const TextureHelper11 **outTexture)
3757 {
3758 ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
3759 return angle::Result::Stop;
3760 }
3761
getSwizzleRenderTarget(const gl::Context * context,int mipLevel,const d3d11::RenderTargetView ** outRTV)3762 angle::Result TextureStorage11_2DMultisample::getSwizzleRenderTarget(
3763 const gl::Context *context,
3764 int mipLevel,
3765 const d3d11::RenderTargetView **outRTV)
3766 {
3767 ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
3768 return angle::Result::Stop;
3769 }
3770
ensureDropStencilTexture(const gl::Context * context,DropStencil * dropStencilOut)3771 angle::Result TextureStorage11_2DMultisample::ensureDropStencilTexture(const gl::Context *context,
3772 DropStencil *dropStencilOut)
3773 {
3774 ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
3775 return angle::Result::Stop;
3776 }
3777
TextureStorage11_2DMultisampleArray(Renderer11 * renderer,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth,int levels,int samples,bool fixedSampleLocations)3778 TextureStorage11_2DMultisampleArray::TextureStorage11_2DMultisampleArray(Renderer11 *renderer,
3779 GLenum internalformat,
3780 GLsizei width,
3781 GLsizei height,
3782 GLsizei depth,
3783 int levels,
3784 int samples,
3785 bool fixedSampleLocations)
3786 : TextureStorage11ImmutableBase(
3787 renderer,
3788 GetTextureBindFlags(internalformat, renderer->getRenderer11DeviceCaps(), true),
3789 GetTextureMiscFlags(internalformat, renderer->getRenderer11DeviceCaps(), true, levels),
3790 internalformat),
3791 mTexture()
3792 {
3793 // There are no multisampled compressed formats, so there's no need to adjust texture size
3794 // according to block size.
3795 ASSERT(d3d11::GetDXGIFormatSizeInfo(mFormatInfo.texFormat).blockWidth <= 1);
3796 ASSERT(d3d11::GetDXGIFormatSizeInfo(mFormatInfo.texFormat).blockHeight <= 1);
3797
3798 mMipLevels = 1;
3799 mTextureWidth = width;
3800 mTextureHeight = height;
3801 mTextureDepth = depth;
3802 mSamples = samples;
3803 mFixedSampleLocations = fixedSampleLocations;
3804 }
3805
onDestroy(const gl::Context * context)3806 angle::Result TextureStorage11_2DMultisampleArray::onDestroy(const gl::Context *context)
3807 {
3808 return angle::Result::Continue;
3809 }
3810
~TextureStorage11_2DMultisampleArray()3811 TextureStorage11_2DMultisampleArray::~TextureStorage11_2DMultisampleArray() {}
3812
copyToStorage(const gl::Context * context,TextureStorage * destStorage)3813 angle::Result TextureStorage11_2DMultisampleArray::copyToStorage(const gl::Context *context,
3814 TextureStorage *destStorage)
3815 {
3816 ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
3817 return angle::Result::Stop;
3818 }
3819
getResource(const gl::Context * context,const TextureHelper11 ** outResource)3820 angle::Result TextureStorage11_2DMultisampleArray::getResource(const gl::Context *context,
3821 const TextureHelper11 **outResource)
3822 {
3823 ANGLE_TRY(ensureTextureExists(context, 1));
3824
3825 *outResource = &mTexture;
3826 return angle::Result::Continue;
3827 }
3828
ensureTextureExists(const gl::Context * context,int mipLevels)3829 angle::Result TextureStorage11_2DMultisampleArray::ensureTextureExists(const gl::Context *context,
3830 int mipLevels)
3831 {
3832 // For multisampled textures, mipLevels always equals 1.
3833 ASSERT(mipLevels == 1);
3834
3835 // if the width or height is not positive this should be treated as an incomplete texture
3836 // we handle that here by skipping the d3d texture creation
3837 if (!mTexture.valid() && mTextureWidth > 0 && mTextureHeight > 0)
3838 {
3839 D3D11_TEXTURE2D_DESC desc;
3840 ZeroMemory(&desc, sizeof(desc));
3841 desc.Width = mTextureWidth;
3842 desc.Height = mTextureHeight;
3843 desc.MipLevels = mipLevels;
3844 desc.ArraySize = mTextureDepth;
3845 desc.Format = mFormatInfo.texFormat;
3846 desc.Usage = D3D11_USAGE_DEFAULT;
3847 desc.BindFlags = getBindFlags() & ~D3D11_BIND_UNORDERED_ACCESS;
3848 desc.CPUAccessFlags = 0;
3849 desc.MiscFlags = getMiscFlags();
3850
3851 const gl::TextureCaps &textureCaps =
3852 mRenderer->getNativeTextureCaps().get(mFormatInfo.internalFormat);
3853 GLuint supportedSamples = textureCaps.getNearestSamples(mSamples);
3854 desc.SampleDesc.Count = (supportedSamples == 0) ? 1 : supportedSamples;
3855 desc.SampleDesc.Quality = mRenderer->getSampleDescQuality(supportedSamples);
3856
3857 ANGLE_TRY(mRenderer->allocateTexture(GetImplAs<Context11>(context), desc, mFormatInfo,
3858 &mTexture));
3859 mTexture.setDebugName("TexStorage2DMSArray.Texture");
3860 }
3861
3862 return angle::Result::Continue;
3863 }
3864
findRenderTarget(const gl::Context * context,const gl::ImageIndex & index,GLsizei samples,RenderTargetD3D ** outRT) const3865 angle::Result TextureStorage11_2DMultisampleArray::findRenderTarget(const gl::Context *context,
3866 const gl::ImageIndex &index,
3867 GLsizei samples,
3868 RenderTargetD3D **outRT) const
3869 {
3870 ASSERT(index.hasLayer());
3871
3872 const int mipLevel = index.getLevelIndex();
3873 ASSERT(mipLevel == 0);
3874 const int layer = index.getLayerIndex();
3875 const int numLayers = index.getLayerCount();
3876
3877 ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
3878
3879 TextureStorage11_2DArray::LevelLayerRangeKey key(mipLevel, layer, numLayers);
3880 if (mRenderTargets.find(key) == mRenderTargets.end())
3881 {
3882 ASSERT(outRT);
3883 *outRT = nullptr;
3884 return angle::Result::Continue;
3885 }
3886
3887 ASSERT(outRT);
3888 *outRT = mRenderTargets.at(key).get();
3889 return angle::Result::Continue;
3890 }
3891
createRenderTargetSRV(const gl::Context * context,const TextureHelper11 & texture,const gl::ImageIndex & index,DXGI_FORMAT resourceFormat,d3d11::SharedSRV * srv) const3892 angle::Result TextureStorage11_2DMultisampleArray::createRenderTargetSRV(
3893 const gl::Context *context,
3894 const TextureHelper11 &texture,
3895 const gl::ImageIndex &index,
3896 DXGI_FORMAT resourceFormat,
3897 d3d11::SharedSRV *srv) const
3898 {
3899 D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
3900 srvDesc.Format = resourceFormat;
3901 srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY;
3902 srvDesc.Texture2DMSArray.FirstArraySlice = index.getLayerIndex();
3903 srvDesc.Texture2DMSArray.ArraySize = index.getLayerCount();
3904
3905 ANGLE_TRY(
3906 mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(), srv));
3907
3908 return angle::Result::Continue;
3909 }
3910
getRenderTarget(const gl::Context * context,const gl::ImageIndex & index,GLsizei samples,RenderTargetD3D ** outRT)3911 angle::Result TextureStorage11_2DMultisampleArray::getRenderTarget(const gl::Context *context,
3912 const gl::ImageIndex &index,
3913 GLsizei samples,
3914 RenderTargetD3D **outRT)
3915 {
3916 ASSERT(index.hasLayer());
3917
3918 const int mipLevel = index.getLevelIndex();
3919 ASSERT(mipLevel == 0);
3920 const int layer = index.getLayerIndex();
3921 const int numLayers = index.getLayerCount();
3922
3923 ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
3924
3925 TextureStorage11_2DArray::LevelLayerRangeKey key(mipLevel, layer, numLayers);
3926 if (mRenderTargets.find(key) == mRenderTargets.end())
3927 {
3928 const TextureHelper11 *texture = nullptr;
3929 ANGLE_TRY(getResource(context, &texture));
3930 d3d11::SharedSRV srv;
3931 ANGLE_TRY(createRenderTargetSRV(context, *texture, index, mFormatInfo.srvFormat, &srv));
3932 d3d11::SharedSRV blitSRV;
3933 if (mFormatInfo.blitSRVFormat != mFormatInfo.srvFormat)
3934 {
3935 ANGLE_TRY(createRenderTargetSRV(context, *texture, index, mFormatInfo.blitSRVFormat,
3936 &blitSRV));
3937 }
3938 else
3939 {
3940 blitSRV = srv.makeCopy();
3941 }
3942
3943 srv.setDebugName("TexStorage2DMSArray.RenderTargetSRV");
3944
3945 if (mFormatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN)
3946 {
3947 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
3948 rtvDesc.Format = mFormatInfo.rtvFormat;
3949 rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY;
3950 rtvDesc.Texture2DMSArray.FirstArraySlice = layer;
3951 rtvDesc.Texture2DMSArray.ArraySize = numLayers;
3952
3953 d3d11::RenderTargetView rtv;
3954 ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), rtvDesc,
3955 texture->get(), &rtv));
3956 rtv.setDebugName("TexStorage2DMSArray.RenderTargetRTV");
3957
3958 mRenderTargets[key].reset(new TextureRenderTarget11(
3959 std::move(rtv), *texture, srv, blitSRV, mFormatInfo.internalFormat, getFormatSet(),
3960 getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1, mSamples));
3961 }
3962 else
3963 {
3964 ASSERT(mFormatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN);
3965
3966 D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
3967 dsvDesc.Format = mFormatInfo.dsvFormat;
3968 dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY;
3969 dsvDesc.Texture2DMSArray.FirstArraySlice = layer;
3970 dsvDesc.Texture2DMSArray.ArraySize = numLayers;
3971 dsvDesc.Flags = 0;
3972
3973 d3d11::DepthStencilView dsv;
3974 ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), dsvDesc,
3975 texture->get(), &dsv));
3976 dsv.setDebugName("TexStorage2DMSArray.RenderTargetDSV");
3977
3978 mRenderTargets[key].reset(new TextureRenderTarget11(
3979 std::move(dsv), *texture, srv, mFormatInfo.internalFormat, getFormatSet(),
3980 getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1, mSamples));
3981 }
3982 }
3983
3984 ASSERT(outRT);
3985 *outRT = mRenderTargets[key].get();
3986 return angle::Result::Continue;
3987 }
3988
createSRVForSampler(const gl::Context * context,int baseLevel,int mipLevels,DXGI_FORMAT format,const TextureHelper11 & texture,d3d11::SharedSRV * outSRV)3989 angle::Result TextureStorage11_2DMultisampleArray::createSRVForSampler(
3990 const gl::Context *context,
3991 int baseLevel,
3992 int mipLevels,
3993 DXGI_FORMAT format,
3994 const TextureHelper11 &texture,
3995 d3d11::SharedSRV *outSRV)
3996 {
3997 ASSERT(outSRV);
3998
3999 D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
4000 srvDesc.Format = format;
4001 srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY;
4002 srvDesc.Texture2DMSArray.FirstArraySlice = 0;
4003 srvDesc.Texture2DMSArray.ArraySize = mTextureDepth;
4004
4005 ANGLE_TRY(
4006 mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(), outSRV));
4007 outSRV->setDebugName("TexStorage2DMSArray.SRV");
4008 return angle::Result::Continue;
4009 }
4010
getSwizzleTexture(const gl::Context * context,const TextureHelper11 ** outTexture)4011 angle::Result TextureStorage11_2DMultisampleArray::getSwizzleTexture(
4012 const gl::Context *context,
4013 const TextureHelper11 **outTexture)
4014 {
4015 ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
4016 return angle::Result::Stop;
4017 }
4018
getSwizzleRenderTarget(const gl::Context * context,int mipLevel,const d3d11::RenderTargetView ** outRTV)4019 angle::Result TextureStorage11_2DMultisampleArray::getSwizzleRenderTarget(
4020 const gl::Context *context,
4021 int mipLevel,
4022 const d3d11::RenderTargetView **outRTV)
4023 {
4024 ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
4025 return angle::Result::Stop;
4026 }
4027
ensureDropStencilTexture(const gl::Context * context,DropStencil * dropStencilOut)4028 angle::Result TextureStorage11_2DMultisampleArray::ensureDropStencilTexture(
4029 const gl::Context *context,
4030 DropStencil *dropStencilOut)
4031 {
4032 ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
4033 return angle::Result::Stop;
4034 }
4035
4036 } // namespace rx
4037