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