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