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