xref: /aosp_15_r20/external/angle/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.h (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.h: Defines 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 #ifndef LIBANGLE_RENDERER_D3D_D3D11_TEXTURESTORAGE11_H_
12 #define LIBANGLE_RENDERER_D3D_D3D11_TEXTURESTORAGE11_H_
13 
14 #include "libANGLE/Error.h"
15 #include "libANGLE/Texture.h"
16 #include "libANGLE/renderer/d3d/TextureStorage.h"
17 #include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
18 #include "libANGLE/renderer/d3d/d3d11/texture_format_table.h"
19 
20 #include <array>
21 #include <map>
22 
23 namespace gl
24 {
25 class ImageIndex;
26 }  // namespace gl
27 
28 namespace rx
29 {
30 class EGLImageD3D;
31 class RenderTargetD3D;
32 class RenderTarget11;
33 class Renderer11;
34 class SwapChain11;
35 class Image11;
36 struct Renderer11DeviceCaps;
37 class TextureStorage11_2DMultisample;
38 
39 template <typename T>
40 using CubeFaceArray = std::array<T, gl::kCubeFaceCount>;
41 
42 struct MultisampledRenderToTextureInfo
43 {
44     MultisampledRenderToTextureInfo(const GLsizei samples,
45                                     const gl::ImageIndex &indexSS,
46                                     const gl::ImageIndex &indexMS);
47     ~MultisampledRenderToTextureInfo();
48 
49     // How many samples the multisampled texture contains
50     GLsizei samples;
51     // This is the image index for the single sampled texture
52     // This will hold the relevant level information
53     gl::ImageIndex indexSS;
54     // This is the image index for the multisampled texture
55     // For multisampled indexes, there is no level Index since they should
56     // account for the entire level.
57     gl::ImageIndex indexMS;
58     // True when multisampled texture has been written to and needs to be
59     // resolved to the single sampled texture
60     bool msTextureNeedsResolve;
61     std::unique_ptr<TextureStorage11_2DMultisample> msTex;
62 };
63 
64 class TextureStorage11 : public TextureStorage
65 {
66   public:
67     ~TextureStorage11() override;
68 
69     static DWORD GetTextureBindFlags(GLenum internalFormat,
70                                      const Renderer11DeviceCaps &renderer11DeviceCaps,
71                                      BindFlags flags);
72     static DWORD GetTextureMiscFlags(GLenum internalFormat,
73                                      const Renderer11DeviceCaps &renderer11DeviceCaps,
74                                      BindFlags flags,
75                                      int levels);
76 
77     UINT getBindFlags() const;
78     UINT getMiscFlags() const;
79     const d3d11::Format &getFormatSet() const;
80     angle::Result getSRVLevels(const gl::Context *context,
81                                GLint baseLevel,
82                                GLint maxLevel,
83                                bool forceLinearSampler,
84                                const d3d11::SharedSRV **outSRV);
85     angle::Result generateSwizzles(const gl::Context *context,
86                                    const gl::TextureState &textureState);
87     void markLevelDirty(int mipLevel);
88     void markDirty();
89 
90     angle::Result updateSubresourceLevel(const gl::Context *context,
91                                          const TextureHelper11 &texture,
92                                          unsigned int sourceSubresource,
93                                          const gl::ImageIndex &index,
94                                          const gl::Box &copyArea);
95 
96     angle::Result copySubresourceLevel(const gl::Context *context,
97                                        const TextureHelper11 &dstTexture,
98                                        unsigned int dstSubresource,
99                                        const gl::ImageIndex &index,
100                                        const gl::Box &region);
101 
102     // TextureStorage virtual functions
103     int getTopLevel() const override;
104     bool isRenderTarget() const override;
105     bool isManaged() const override;
106     bool supportsNativeMipmapFunction() const override;
107     int getLevelCount() const override;
isUnorderedAccess()108     bool isUnorderedAccess() const override { return mBindFlags & D3D11_BIND_UNORDERED_ACCESS; }
109     bool isMultiplanar(const gl::Context *context) override;
110     bool requiresTypelessTextureFormat() const;
111     angle::Result generateMipmap(const gl::Context *context,
112                                  const gl::ImageIndex &sourceIndex,
113                                  const gl::ImageIndex &destIndex) override;
114     angle::Result copyToStorage(const gl::Context *context, TextureStorage *destStorage) override;
115     angle::Result setData(const gl::Context *context,
116                           const gl::ImageIndex &index,
117                           ImageD3D *image,
118                           const gl::Box *destBox,
119                           GLenum type,
120                           const gl::PixelUnpackState &unpack,
121                           const uint8_t *pixelData) override;
122     void invalidateTextures() override;
123 
124     virtual angle::Result getSRVForSampler(const gl::Context *context,
125                                            const gl::TextureState &textureState,
126                                            const gl::SamplerState &sampler,
127                                            const d3d11::SharedSRV **outSRV);
128     angle::Result getSRVForImage(const gl::Context *context,
129                                  const gl::ImageUnit &imageUnit,
130                                  const d3d11::SharedSRV **outSRV);
131     angle::Result getUAVForImage(const gl::Context *context,
132                                  const gl::ImageUnit &imageUnit,
133                                  const d3d11::SharedUAV **outUAV);
134     virtual angle::Result getSubresourceIndex(const gl::Context *context,
135                                               const gl::ImageIndex &index,
136                                               UINT *outSubresourceIndex) const;
137     virtual angle::Result getResource(const gl::Context *context,
138                                       const TextureHelper11 **outResource)              = 0;
139     virtual void associateImage(Image11 *image, const gl::ImageIndex &index)            = 0;
140     virtual void disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage) = 0;
141     virtual void verifyAssociatedImageValid(const gl::ImageIndex &index,
142                                             Image11 *expectedImage)                     = 0;
143     virtual angle::Result releaseAssociatedImage(const gl::Context *context,
144                                                  const gl::ImageIndex &index,
145                                                  Image11 *incomingImage)                = 0;
146 
147     GLsizei getRenderToTextureSamples() const override;
148 
149   protected:
150     TextureStorage11(Renderer11 *renderer,
151                      UINT bindFlags,
152                      UINT miscFlags,
153                      GLenum internalFormat,
154                      const std::string &label);
155     int getLevelWidth(int mipLevel) const;
156     int getLevelHeight(int mipLevel) const;
157     int getLevelDepth(int mipLevel) const;
158 
159     // Some classes (e.g. TextureStorage11_2D) will override getMippedResource.
160     virtual angle::Result getMippedResource(const gl::Context *context,
161                                             const TextureHelper11 **outResource);
162 
163     virtual angle::Result getSwizzleTexture(const gl::Context *context,
164                                             const TextureHelper11 **outTexture)          = 0;
165     virtual angle::Result getSwizzleRenderTarget(const gl::Context *context,
166                                                  int mipLevel,
167                                                  const d3d11::RenderTargetView **outRTV) = 0;
168 
169     enum class SRVType
170     {
171         Sample,
172         Blit,
173         Stencil
174     };
175     angle::Result getSRVLevel(const gl::Context *context,
176                               int mipLevel,
177                               SRVType srvType,
178                               const d3d11::SharedSRV **outSRV);
179 
180     // Get a version of a depth texture with only depth information, not stencil.
181     enum DropStencil
182     {
183         CREATED,
184         ALREADY_EXISTS
185     };
186     virtual angle::Result ensureDropStencilTexture(const gl::Context *context,
187                                                    DropStencil *dropStencilOut);
188     angle::Result initDropStencilTexture(const gl::Context *context,
189                                          const gl::ImageIndexIterator &it);
190 
191     // The baseLevel parameter should *not* have mTopLevel applied.
192     virtual angle::Result createSRVForSampler(const gl::Context *context,
193                                               int baseLevel,
194                                               int mipLevels,
195                                               DXGI_FORMAT format,
196                                               const TextureHelper11 &texture,
197                                               d3d11::SharedSRV *outSRV) = 0;
198     virtual angle::Result createSRVForImage(const gl::Context *context,
199                                             int level,
200                                             DXGI_FORMAT format,
201                                             const TextureHelper11 &texture,
202                                             d3d11::SharedSRV *outSRV)   = 0;
203     virtual angle::Result createUAVForImage(const gl::Context *context,
204                                             int level,
205                                             DXGI_FORMAT format,
206                                             const TextureHelper11 &texture,
207                                             d3d11::SharedUAV *outUAV)   = 0;
208 
209     void verifySwizzleExists(const gl::SwizzleState &swizzleState);
210 
211     // Clear all cached non-swizzle SRVs and invalidate the swizzle cache.
212     void clearSRVCache();
213 
214     // Helper for resolving MS shadowed texture
215     angle::Result resolveTextureHelper(const gl::Context *context, const TextureHelper11 &texture);
216     angle::Result releaseMultisampledTexStorageForLevel(size_t level) override;
217     angle::Result findMultisampledRenderTarget(const gl::Context *context,
218                                                const gl::ImageIndex &index,
219                                                GLsizei samples,
220                                                RenderTargetD3D **outRT) const;
221     angle::Result getMultisampledRenderTarget(const gl::Context *context,
222                                               const gl::ImageIndex &index,
223                                               GLsizei samples,
224                                               RenderTargetD3D **outRT);
225 
226     Renderer11 *mRenderer;
227     int mTopLevel;
228     unsigned int mMipLevels;
229 
230     const d3d11::Format &mFormatInfo;
231     unsigned int mTextureWidth;
232     unsigned int mTextureHeight;
233     unsigned int mTextureDepth;
234 
235     gl::TexLevelArray<gl::SwizzleState> mSwizzleCache;
236     TextureHelper11 mDropStencilTexture;
237 
238     std::unique_ptr<MultisampledRenderToTextureInfo> mMSTexInfo;
239 
240   private:
241     const UINT mBindFlags;
242     const UINT mMiscFlags;
243 
244     struct SamplerKey
245     {
246         SamplerKey();
247         SamplerKey(int baseLevel,
248                    int mipLevels,
249                    bool swizzle,
250                    bool dropStencil,
251                    bool forceLinearSampler);
252 
253         bool operator<(const SamplerKey &rhs) const;
254 
255         int baseLevel;
256         int mipLevels;
257         bool swizzle;
258         bool dropStencil;
259         bool forceLinearSampler;
260     };
261 
262     angle::Result getCachedOrCreateSRVForSampler(const gl::Context *context,
263                                                  const SamplerKey &key,
264                                                  const d3d11::SharedSRV **outSRV);
265 
266     using SRVCacheForSampler = std::map<SamplerKey, d3d11::SharedSRV>;
267     SRVCacheForSampler mSrvCacheForSampler;
268 
269     struct ImageKey
270     {
271         ImageKey();
272         ImageKey(int level, bool layered, int layer, GLenum access, GLenum format);
273         bool operator<(const ImageKey &rhs) const;
274         int level;
275         bool layered;
276         int layer;
277         GLenum access;
278         GLenum format;
279     };
280 
281     angle::Result getCachedOrCreateSRVForImage(const gl::Context *context,
282                                                const ImageKey &key,
283                                                const d3d11::SharedSRV **outSRV);
284     angle::Result getCachedOrCreateUAVForImage(const gl::Context *context,
285                                                const ImageKey &key,
286                                                const d3d11::SharedUAV **outUAV);
287 
288     using SRVCacheForImage = std::map<ImageKey, d3d11::SharedSRV>;
289     SRVCacheForImage mSrvCacheForImage;
290     using UAVCacheForImage = std::map<ImageKey, d3d11::SharedUAV>;
291     UAVCacheForImage mUavCacheForImage;
292 
293     gl::TexLevelArray<d3d11::SharedSRV> mLevelSRVs;
294     gl::TexLevelArray<d3d11::SharedSRV> mLevelBlitSRVs;
295     gl::TexLevelArray<d3d11::SharedSRV> mLevelStencilSRVs;
296 };
297 
298 class TextureStorage11_2D : public TextureStorage11
299 {
300   public:
301     TextureStorage11_2D(Renderer11 *renderer, SwapChain11 *swapchain, const std::string &label);
302     TextureStorage11_2D(Renderer11 *renderer,
303                         GLenum internalformat,
304                         BindFlags bindFlags,
305                         GLsizei width,
306                         GLsizei height,
307                         int levels,
308                         const std::string &label,
309                         bool hintLevelZeroOnly = false);
310     ~TextureStorage11_2D() override;
311 
312     angle::Result onDestroy(const gl::Context *context) override;
313 
314     angle::Result getResource(const gl::Context *context,
315                               const TextureHelper11 **outResource) override;
316     angle::Result getMippedResource(const gl::Context *context,
317                                     const TextureHelper11 **outResource) override;
318     angle::Result findRenderTarget(const gl::Context *context,
319                                    const gl::ImageIndex &index,
320                                    GLsizei samples,
321                                    RenderTargetD3D **outRT) const override;
322     angle::Result getRenderTarget(const gl::Context *context,
323                                   const gl::ImageIndex &index,
324                                   GLsizei samples,
325                                   RenderTargetD3D **outRT) override;
326 
327     angle::Result copyToStorage(const gl::Context *context, TextureStorage *destStorage) override;
328 
329     void associateImage(Image11 *image, const gl::ImageIndex &index) override;
330     void disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage) override;
331     void verifyAssociatedImageValid(const gl::ImageIndex &index, Image11 *expectedImage) override;
332     angle::Result releaseAssociatedImage(const gl::Context *context,
333                                          const gl::ImageIndex &index,
334                                          Image11 *incomingImage) override;
335 
336     angle::Result useLevelZeroWorkaroundTexture(const gl::Context *context,
337                                                 bool useLevelZeroTexture) override;
338     void onLabelUpdate() override;
339 
340   protected:
341     angle::Result getSwizzleTexture(const gl::Context *context,
342                                     const TextureHelper11 **outTexture) override;
343     angle::Result getSwizzleRenderTarget(const gl::Context *context,
344                                          int mipLevel,
345                                          const d3d11::RenderTargetView **outRTV) override;
346 
347     angle::Result ensureDropStencilTexture(const gl::Context *context,
348                                            DropStencil *dropStencilOut) override;
349 
350     angle::Result ensureTextureExists(const gl::Context *context, int mipLevels);
351 
352     angle::Result resolveTexture(const gl::Context *context) override;
353 
354   private:
355     angle::Result createSRVForSampler(const gl::Context *context,
356                                       int baseLevel,
357                                       int mipLevels,
358                                       DXGI_FORMAT format,
359                                       const TextureHelper11 &texture,
360                                       d3d11::SharedSRV *outSRV) override;
361     angle::Result createSRVForImage(const gl::Context *context,
362                                     int level,
363                                     DXGI_FORMAT format,
364                                     const TextureHelper11 &texture,
365                                     d3d11::SharedSRV *outSRV) override;
366     angle::Result createUAVForImage(const gl::Context *context,
367                                     int level,
368                                     DXGI_FORMAT format,
369                                     const TextureHelper11 &texture,
370                                     d3d11::SharedUAV *outUAV) override;
371 
372     TextureHelper11 mTexture;
373     gl::TexLevelArray<std::unique_ptr<RenderTarget11>> mRenderTarget;
374     bool mHasKeyedMutex;
375 
376     // These are members related to the zero max-LOD workaround.
377     // D3D11 Feature Level 9_3 can't disable mipmaps on a mipmapped texture (i.e. solely sample from
378     // level zero). These members are used to work around this limitation. Usually only mTexture XOR
379     // mLevelZeroTexture will exist. For example, if an app creates a texture with only one level,
380     // then 9_3 will only create mLevelZeroTexture. However, in some scenarios, both textures have
381     // to be created. This incurs additional memory overhead. One example of this is an application
382     // that creates a texture, calls glGenerateMipmap, and then disables mipmaps on the texture. A
383     // more likely example is an app that creates an empty texture, renders to it, and then calls
384     // glGenerateMipmap
385     // TODO: In this rendering scenario, release the mLevelZeroTexture after mTexture has been
386     // created to save memory.
387     TextureHelper11 mLevelZeroTexture;
388     std::unique_ptr<RenderTarget11> mLevelZeroRenderTarget;
389     bool mUseLevelZeroTexture;
390 
391     // Swizzle-related variables
392     TextureHelper11 mSwizzleTexture;
393     gl::TexLevelArray<d3d11::RenderTargetView> mSwizzleRenderTargets;
394 
395     gl::TexLevelArray<Image11 *> mAssociatedImages;
396 };
397 
398 class TextureStorage11_External : public TextureStorage11
399 {
400   public:
401     TextureStorage11_External(Renderer11 *renderer,
402                               egl::Stream *stream,
403                               const egl::Stream::GLTextureDescription &glDesc,
404                               const std::string &label);
405     ~TextureStorage11_External() override;
406 
407     angle::Result onDestroy(const gl::Context *context) override;
408 
409     angle::Result getResource(const gl::Context *context,
410                               const TextureHelper11 **outResource) override;
411     angle::Result getMippedResource(const gl::Context *context,
412                                     const TextureHelper11 **outResource) override;
413     angle::Result findRenderTarget(const gl::Context *context,
414                                    const gl::ImageIndex &index,
415                                    GLsizei samples,
416                                    RenderTargetD3D **outRT) const override;
417     angle::Result getRenderTarget(const gl::Context *context,
418                                   const gl::ImageIndex &index,
419                                   GLsizei samples,
420                                   RenderTargetD3D **outRT) override;
421 
422     angle::Result copyToStorage(const gl::Context *context, TextureStorage *destStorage) override;
423 
424     void associateImage(Image11 *image, const gl::ImageIndex &index) override;
425     void disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage) override;
426     void verifyAssociatedImageValid(const gl::ImageIndex &index, Image11 *expectedImage) override;
427     angle::Result releaseAssociatedImage(const gl::Context *context,
428                                          const gl::ImageIndex &index,
429                                          Image11 *incomingImage) override;
430     void onLabelUpdate() override;
431 
432   protected:
433     angle::Result getSwizzleTexture(const gl::Context *context,
434                                     const TextureHelper11 **outTexture) override;
435     angle::Result getSwizzleRenderTarget(const gl::Context *context,
436                                          int mipLevel,
437                                          const d3d11::RenderTargetView **outRTV) override;
438 
439   private:
440     angle::Result createSRVForSampler(const gl::Context *context,
441                                       int baseLevel,
442                                       int mipLevels,
443                                       DXGI_FORMAT format,
444                                       const TextureHelper11 &texture,
445                                       d3d11::SharedSRV *outSRV) override;
446     angle::Result createSRVForImage(const gl::Context *context,
447                                     int level,
448                                     DXGI_FORMAT format,
449                                     const TextureHelper11 &texture,
450                                     d3d11::SharedSRV *outSRV) override;
451     angle::Result createUAVForImage(const gl::Context *context,
452                                     int level,
453                                     DXGI_FORMAT format,
454                                     const TextureHelper11 &texture,
455                                     d3d11::SharedUAV *outUAV) override;
456 
457     TextureHelper11 mTexture;
458     int mSubresourceIndex;
459     bool mHasKeyedMutex;
460 
461     Image11 *mAssociatedImage;
462 };
463 
464 // A base class for texture storage classes where the associated images are not changed, nor are
465 // they accessible as images in GLES3.1+ shaders.
466 class TextureStorage11ImmutableBase : public TextureStorage11
467 {
468   public:
469     TextureStorage11ImmutableBase(Renderer11 *renderer,
470                                   UINT bindFlags,
471                                   UINT miscFlags,
472                                   GLenum internalFormat,
473                                   const std::string &label);
474 
475     void associateImage(Image11 *image, const gl::ImageIndex &index) override;
476     void disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage) override;
477     void verifyAssociatedImageValid(const gl::ImageIndex &index, Image11 *expectedImage) override;
478     angle::Result releaseAssociatedImage(const gl::Context *context,
479                                          const gl::ImageIndex &index,
480                                          Image11 *incomingImage) override;
481 
482     angle::Result createSRVForImage(const gl::Context *context,
483                                     int level,
484                                     DXGI_FORMAT format,
485                                     const TextureHelper11 &texture,
486                                     d3d11::SharedSRV *outSRV) override;
487     angle::Result createUAVForImage(const gl::Context *context,
488                                     int level,
489                                     DXGI_FORMAT format,
490                                     const TextureHelper11 &texture,
491                                     d3d11::SharedUAV *outUAV) override;
492 };
493 
494 class TextureStorage11_EGLImage final : public TextureStorage11ImmutableBase
495 {
496   public:
497     TextureStorage11_EGLImage(Renderer11 *renderer,
498                               EGLImageD3D *eglImage,
499                               RenderTarget11 *renderTarget11,
500                               const std::string &label);
501     ~TextureStorage11_EGLImage() override;
502 
503     angle::Result onDestroy(const gl::Context *context) override;
504 
505     angle::Result getSubresourceIndex(const gl::Context *context,
506                                       const gl::ImageIndex &index,
507                                       UINT *outSubresourceIndex) const override;
508     angle::Result getResource(const gl::Context *context,
509                               const TextureHelper11 **outResource) override;
510     angle::Result getSRVForSampler(const gl::Context *context,
511                                    const gl::TextureState &textureState,
512                                    const gl::SamplerState &sampler,
513                                    const d3d11::SharedSRV **outSRV) override;
514     angle::Result getMippedResource(const gl::Context *context,
515                                     const TextureHelper11 **outResource) override;
516     angle::Result findRenderTarget(const gl::Context *context,
517                                    const gl::ImageIndex &index,
518                                    GLsizei samples,
519                                    RenderTargetD3D **outRT) const override;
520     angle::Result getRenderTarget(const gl::Context *context,
521                                   const gl::ImageIndex &index,
522                                   GLsizei samples,
523                                   RenderTargetD3D **outRT) override;
524 
525     angle::Result copyToStorage(const gl::Context *context, TextureStorage *destStorage) override;
526 
527     angle::Result useLevelZeroWorkaroundTexture(const gl::Context *context,
528                                                 bool useLevelZeroTexture) override;
529     void onLabelUpdate() override;
530 
531     void associateImage(Image11 *image, const gl::ImageIndex &index) override;
532     void disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage) override;
533     void verifyAssociatedImageValid(const gl::ImageIndex &index, Image11 *expectedImage) override;
534     angle::Result releaseAssociatedImage(const gl::Context *context,
535                                          const gl::ImageIndex &index,
536                                          Image11 *incomingImage) override;
537 
538   protected:
539     angle::Result getSwizzleTexture(const gl::Context *context,
540                                     const TextureHelper11 **outTexture) override;
541     angle::Result getSwizzleRenderTarget(const gl::Context *context,
542                                          int mipLevel,
543                                          const d3d11::RenderTargetView **outRTV) override;
544 
545   private:
546     // Check if the EGL image's render target has been updated due to orphaning and delete
547     // any SRVs and other resources based on the image's old render target.
548     angle::Result checkForUpdatedRenderTarget(const gl::Context *context);
549 
550     angle::Result createSRVForSampler(const gl::Context *context,
551                                       int baseLevel,
552                                       int mipLevels,
553                                       DXGI_FORMAT format,
554                                       const TextureHelper11 &texture,
555                                       d3d11::SharedSRV *outSRV) override;
556 
557     angle::Result getImageRenderTarget(const gl::Context *context, RenderTarget11 **outRT) const;
558 
559     EGLImageD3D *mImage;
560     uintptr_t mCurrentRenderTarget;
561 
562     // Swizzle-related variables
563     TextureHelper11 mSwizzleTexture;
564     std::vector<d3d11::RenderTargetView> mSwizzleRenderTargets;
565 
566     Image11 *mAssociatedImage;
567 };
568 
569 class TextureStorage11_Cube : public TextureStorage11
570 {
571   public:
572     TextureStorage11_Cube(Renderer11 *renderer,
573                           GLenum internalformat,
574                           BindFlags bindFlags,
575                           int size,
576                           int levels,
577                           bool hintLevelZeroOnly,
578                           const std::string &label);
579     ~TextureStorage11_Cube() override;
580 
581     angle::Result onDestroy(const gl::Context *context) override;
582 
583     angle::Result getSubresourceIndex(const gl::Context *context,
584                                       const gl::ImageIndex &index,
585                                       UINT *outSubresourceIndex) const override;
586 
587     angle::Result getResource(const gl::Context *context,
588                               const TextureHelper11 **outResource) override;
589     angle::Result getMippedResource(const gl::Context *context,
590                                     const TextureHelper11 **outResource) override;
591     angle::Result findRenderTarget(const gl::Context *context,
592                                    const gl::ImageIndex &index,
593                                    GLsizei samples,
594                                    RenderTargetD3D **outRT) const override;
595     angle::Result getRenderTarget(const gl::Context *context,
596                                   const gl::ImageIndex &index,
597                                   GLsizei samples,
598                                   RenderTargetD3D **outRT) override;
599 
600     angle::Result copyToStorage(const gl::Context *context, TextureStorage *destStorage) override;
601 
602     void associateImage(Image11 *image, const gl::ImageIndex &index) override;
603     void disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage) override;
604     void verifyAssociatedImageValid(const gl::ImageIndex &index, Image11 *expectedImage) override;
605     angle::Result releaseAssociatedImage(const gl::Context *context,
606                                          const gl::ImageIndex &index,
607                                          Image11 *incomingImage) override;
608 
609     angle::Result useLevelZeroWorkaroundTexture(const gl::Context *context,
610                                                 bool useLevelZeroTexture) override;
611     void onLabelUpdate() override;
612 
613   protected:
614     angle::Result getSwizzleTexture(const gl::Context *context,
615                                     const TextureHelper11 **outTexture) override;
616     angle::Result getSwizzleRenderTarget(const gl::Context *context,
617                                          int mipLevel,
618                                          const d3d11::RenderTargetView **outRTV) override;
619 
620     angle::Result ensureDropStencilTexture(const gl::Context *context,
621                                            DropStencil *dropStencilOut) override;
622 
623     angle::Result ensureTextureExists(const gl::Context *context, int mipLevels);
624 
625     angle::Result resolveTexture(const gl::Context *context) override;
626 
627   private:
628     angle::Result createSRVForSampler(const gl::Context *context,
629                                       int baseLevel,
630                                       int mipLevels,
631                                       DXGI_FORMAT format,
632                                       const TextureHelper11 &texture,
633                                       d3d11::SharedSRV *outSRV) override;
634     angle::Result createSRVForImage(const gl::Context *context,
635                                     int level,
636                                     DXGI_FORMAT format,
637                                     const TextureHelper11 &texture,
638                                     d3d11::SharedSRV *outSRV) override;
639     angle::Result createUAVForImage(const gl::Context *context,
640                                     int level,
641                                     DXGI_FORMAT format,
642                                     const TextureHelper11 &texture,
643                                     d3d11::SharedUAV *outUAV) override;
644     angle::Result createRenderTargetSRV(const gl::Context *context,
645                                         const TextureHelper11 &texture,
646                                         const gl::ImageIndex &index,
647                                         DXGI_FORMAT resourceFormat,
648                                         d3d11::SharedSRV *srv) const;
649 
650     TextureHelper11 mTexture;
651     CubeFaceArray<gl::TexLevelArray<std::unique_ptr<RenderTarget11>>> mRenderTarget;
652 
653     // Level-zero workaround members. See TextureStorage11_2D's workaround members for a
654     // description.
655     TextureHelper11 mLevelZeroTexture;
656     CubeFaceArray<std::unique_ptr<RenderTarget11>> mLevelZeroRenderTarget;
657     bool mUseLevelZeroTexture;
658 
659     TextureHelper11 mSwizzleTexture;
660     gl::TexLevelArray<d3d11::RenderTargetView> mSwizzleRenderTargets;
661 
662     CubeFaceArray<gl::TexLevelArray<Image11 *>> mAssociatedImages;
663 };
664 
665 class TextureStorage11_3D : public TextureStorage11
666 {
667   public:
668     TextureStorage11_3D(Renderer11 *renderer,
669                         GLenum internalformat,
670                         BindFlags bindFlags,
671                         GLsizei width,
672                         GLsizei height,
673                         GLsizei depth,
674                         int levels,
675                         const std::string &label);
676     ~TextureStorage11_3D() override;
677 
678     angle::Result onDestroy(const gl::Context *context) override;
679 
680     angle::Result getResource(const gl::Context *context,
681                               const TextureHelper11 **outResource) override;
682 
683     // Handles both layer and non-layer RTs
684     angle::Result findRenderTarget(const gl::Context *context,
685                                    const gl::ImageIndex &index,
686                                    GLsizei samples,
687                                    RenderTargetD3D **outRT) const override;
688     angle::Result getRenderTarget(const gl::Context *context,
689                                   const gl::ImageIndex &index,
690                                   GLsizei samples,
691                                   RenderTargetD3D **outRT) override;
692 
693     void associateImage(Image11 *image, const gl::ImageIndex &index) override;
694     void disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage) override;
695     void verifyAssociatedImageValid(const gl::ImageIndex &index, Image11 *expectedImage) override;
696     angle::Result releaseAssociatedImage(const gl::Context *context,
697                                          const gl::ImageIndex &index,
698                                          Image11 *incomingImage) override;
699     void onLabelUpdate() override;
700 
701   protected:
702     angle::Result getSwizzleTexture(const gl::Context *context,
703                                     const TextureHelper11 **outTexture) override;
704     angle::Result getSwizzleRenderTarget(const gl::Context *context,
705                                          int mipLevel,
706                                          const d3d11::RenderTargetView **outRTV) override;
707 
708   private:
709     angle::Result createSRVForSampler(const gl::Context *context,
710                                       int baseLevel,
711                                       int mipLevels,
712                                       DXGI_FORMAT format,
713                                       const TextureHelper11 &texture,
714                                       d3d11::SharedSRV *outSRV) override;
715     angle::Result createSRVForImage(const gl::Context *context,
716                                     int level,
717                                     DXGI_FORMAT format,
718                                     const TextureHelper11 &texture,
719                                     d3d11::SharedSRV *outSRV) override;
720     angle::Result createUAVForImage(const gl::Context *context,
721                                     int level,
722                                     DXGI_FORMAT format,
723                                     const TextureHelper11 &texture,
724                                     d3d11::SharedUAV *outUAV) override;
725 
726     typedef std::pair<int, int> LevelLayerKey;
727     std::map<LevelLayerKey, std::unique_ptr<RenderTarget11>> mLevelLayerRenderTargets;
728 
729     gl::TexLevelArray<std::unique_ptr<RenderTarget11>> mLevelRenderTargets;
730 
731     TextureHelper11 mTexture;
732     TextureHelper11 mSwizzleTexture;
733     gl::TexLevelArray<d3d11::RenderTargetView> mSwizzleRenderTargets;
734 
735     gl::TexLevelArray<Image11 *> mAssociatedImages;
736 };
737 
738 class TextureStorage11_2DArray : public TextureStorage11
739 {
740   public:
741     TextureStorage11_2DArray(Renderer11 *renderer,
742                              GLenum internalformat,
743                              BindFlags bindFlags,
744                              GLsizei width,
745                              GLsizei height,
746                              GLsizei depth,
747                              int levels,
748                              const std::string &label);
749     ~TextureStorage11_2DArray() override;
750 
751     angle::Result onDestroy(const gl::Context *context) override;
752 
753     angle::Result getResource(const gl::Context *context,
754                               const TextureHelper11 **outResource) override;
755     angle::Result findRenderTarget(const gl::Context *context,
756                                    const gl::ImageIndex &index,
757                                    GLsizei samples,
758                                    RenderTargetD3D **outRT) const override;
759     angle::Result getRenderTarget(const gl::Context *context,
760                                   const gl::ImageIndex &index,
761                                   GLsizei samples,
762                                   RenderTargetD3D **outRT) override;
763 
764     void associateImage(Image11 *image, const gl::ImageIndex &index) override;
765     void disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage) override;
766     void verifyAssociatedImageValid(const gl::ImageIndex &index, Image11 *expectedImage) override;
767     angle::Result releaseAssociatedImage(const gl::Context *context,
768                                          const gl::ImageIndex &index,
769                                          Image11 *incomingImage) override;
770     void onLabelUpdate() override;
771 
772     struct LevelLayerRangeKey
773     {
LevelLayerRangeKeyLevelLayerRangeKey774         LevelLayerRangeKey(int mipLevelIn, int layerIn, int numLayersIn)
775             : mipLevel(mipLevelIn), layer(layerIn), numLayers(numLayersIn)
776         {}
777         bool operator<(const LevelLayerRangeKey &other) const
778         {
779             if (mipLevel != other.mipLevel)
780             {
781                 return mipLevel < other.mipLevel;
782             }
783             if (layer != other.layer)
784             {
785                 return layer < other.layer;
786             }
787             return numLayers < other.numLayers;
788         }
789         int mipLevel;
790         int layer;
791         int numLayers;
792     };
793 
794   protected:
795     angle::Result getSwizzleTexture(const gl::Context *context,
796                                     const TextureHelper11 **outTexture) override;
797     angle::Result getSwizzleRenderTarget(const gl::Context *context,
798                                          int mipLevel,
799                                          const d3d11::RenderTargetView **outRTV) override;
800 
801     angle::Result ensureDropStencilTexture(const gl::Context *context,
802                                            DropStencil *dropStencilOut) override;
803 
804   private:
805     angle::Result createSRVForSampler(const gl::Context *context,
806                                       int baseLevel,
807                                       int mipLevels,
808                                       DXGI_FORMAT format,
809                                       const TextureHelper11 &texture,
810                                       d3d11::SharedSRV *outSRV) override;
811     angle::Result createSRVForImage(const gl::Context *context,
812                                     int level,
813                                     DXGI_FORMAT format,
814                                     const TextureHelper11 &texture,
815                                     d3d11::SharedSRV *outSRV) override;
816     angle::Result createUAVForImage(const gl::Context *context,
817                                     int level,
818                                     DXGI_FORMAT format,
819                                     const TextureHelper11 &texture,
820                                     d3d11::SharedUAV *outUAV) override;
821     angle::Result createRenderTargetSRV(const gl::Context *context,
822                                         const TextureHelper11 &texture,
823                                         const gl::ImageIndex &index,
824                                         DXGI_FORMAT resourceFormat,
825                                         d3d11::SharedSRV *srv) const;
826 
827     std::map<LevelLayerRangeKey, std::unique_ptr<RenderTarget11>> mRenderTargets;
828 
829     TextureHelper11 mTexture;
830 
831     TextureHelper11 mSwizzleTexture;
832     gl::TexLevelArray<d3d11::RenderTargetView> mSwizzleRenderTargets;
833 
834     typedef std::map<LevelLayerRangeKey, Image11 *> ImageMap;
835     ImageMap mAssociatedImages;
836 };
837 
838 class TextureStorage11_2DMultisample final : public TextureStorage11ImmutableBase
839 {
840   public:
841     TextureStorage11_2DMultisample(Renderer11 *renderer,
842                                    GLenum internalformat,
843                                    GLsizei width,
844                                    GLsizei height,
845                                    int levels,
846                                    int samples,
847                                    bool fixedSampleLocations,
848                                    const std::string &label);
849     ~TextureStorage11_2DMultisample() override;
850 
851     angle::Result onDestroy(const gl::Context *context) override;
852 
853     angle::Result getResource(const gl::Context *context,
854                               const TextureHelper11 **outResource) override;
855     angle::Result findRenderTarget(const gl::Context *context,
856                                    const gl::ImageIndex &index,
857                                    GLsizei samples,
858                                    RenderTargetD3D **outRT) const override;
859     angle::Result getRenderTarget(const gl::Context *context,
860                                   const gl::ImageIndex &index,
861                                   GLsizei samples,
862                                   RenderTargetD3D **outRT) override;
863 
864     angle::Result copyToStorage(const gl::Context *context, TextureStorage *destStorage) override;
865     void onLabelUpdate() override;
866 
867   protected:
868     angle::Result getSwizzleTexture(const gl::Context *context,
869                                     const TextureHelper11 **outTexture) override;
870     angle::Result getSwizzleRenderTarget(const gl::Context *context,
871                                          int mipLevel,
872                                          const d3d11::RenderTargetView **outRTV) override;
873 
874     angle::Result ensureDropStencilTexture(const gl::Context *context,
875                                            DropStencil *dropStencilOut) override;
876 
877     angle::Result ensureTextureExists(const gl::Context *context, int mipLevels);
878 
879   private:
880     angle::Result createSRVForSampler(const gl::Context *context,
881                                       int baseLevel,
882                                       int mipLevels,
883                                       DXGI_FORMAT format,
884                                       const TextureHelper11 &texture,
885                                       d3d11::SharedSRV *outSRV) override;
886 
887     TextureHelper11 mTexture;
888     std::unique_ptr<RenderTarget11> mRenderTarget;
889 
890     unsigned int mSamples;
891     GLboolean mFixedSampleLocations;
892 };
893 
894 class TextureStorage11_2DMultisampleArray final : public TextureStorage11ImmutableBase
895 {
896   public:
897     TextureStorage11_2DMultisampleArray(Renderer11 *renderer,
898                                         GLenum internalformat,
899                                         GLsizei width,
900                                         GLsizei height,
901                                         GLsizei depth,
902                                         int levels,
903                                         int samples,
904                                         bool fixedSampleLocations,
905                                         const std::string &label);
906     ~TextureStorage11_2DMultisampleArray() override;
907 
908     angle::Result onDestroy(const gl::Context *context) override;
909 
910     angle::Result getResource(const gl::Context *context,
911                               const TextureHelper11 **outResource) override;
912     angle::Result findRenderTarget(const gl::Context *context,
913                                    const gl::ImageIndex &index,
914                                    GLsizei samples,
915                                    RenderTargetD3D **outRT) const override;
916     angle::Result getRenderTarget(const gl::Context *context,
917                                   const gl::ImageIndex &index,
918                                   GLsizei samples,
919                                   RenderTargetD3D **outRT) override;
920 
921     angle::Result copyToStorage(const gl::Context *context, TextureStorage *destStorage) override;
922     void onLabelUpdate() override;
923 
924   protected:
925     angle::Result getSwizzleTexture(const gl::Context *context,
926                                     const TextureHelper11 **outTexture) override;
927     angle::Result getSwizzleRenderTarget(const gl::Context *context,
928                                          int mipLevel,
929                                          const d3d11::RenderTargetView **outRTV) override;
930 
931     angle::Result ensureDropStencilTexture(const gl::Context *context,
932                                            DropStencil *dropStencilOut) override;
933 
934     angle::Result ensureTextureExists(const gl::Context *context, int mipLevels);
935 
936   private:
937     angle::Result createRenderTargetSRV(const gl::Context *context,
938                                         const TextureHelper11 &texture,
939                                         const gl::ImageIndex &index,
940                                         DXGI_FORMAT resourceFormat,
941                                         d3d11::SharedSRV *srv) const;
942 
943     angle::Result createSRVForSampler(const gl::Context *context,
944                                       int baseLevel,
945                                       int mipLevels,
946                                       DXGI_FORMAT format,
947                                       const TextureHelper11 &texture,
948                                       d3d11::SharedSRV *outSRV) override;
949 
950     TextureHelper11 mTexture;
951     std::map<TextureStorage11_2DArray::LevelLayerRangeKey, std::unique_ptr<RenderTarget11>>
952         mRenderTargets;
953 
954     unsigned int mSamples;
955     GLboolean mFixedSampleLocations;
956 };
957 
958 class TextureStorage11_Buffer : public TextureStorage11
959 {
960   public:
961     TextureStorage11_Buffer(Renderer11 *renderer,
962                             const gl::OffsetBindingPointer<gl::Buffer> &buffer,
963                             GLenum internalFormat,
964                             const std::string &label);
965     ~TextureStorage11_Buffer() override;
966 
967     angle::Result getResource(const gl::Context *context,
968                               const TextureHelper11 **outResource) override;
969     angle::Result getMippedResource(const gl::Context *context,
970                                     const TextureHelper11 **outResource) override;
971     angle::Result findRenderTarget(const gl::Context *context,
972                                    const gl::ImageIndex &index,
973                                    GLsizei samples,
974                                    RenderTargetD3D **outRT) const override;
975     angle::Result getRenderTarget(const gl::Context *context,
976                                   const gl::ImageIndex &index,
977                                   GLsizei samples,
978                                   RenderTargetD3D **outRT) override;
979 
980     void onLabelUpdate() override;
981 
982     void associateImage(Image11 *image, const gl::ImageIndex &index) override;
983     void disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage) override;
984     void verifyAssociatedImageValid(const gl::ImageIndex &index, Image11 *expectedImage) override;
985     angle::Result releaseAssociatedImage(const gl::Context *context,
986                                          const gl::ImageIndex &index,
987                                          Image11 *incomingImage) override;
988 
989   protected:
990     angle::Result getSwizzleTexture(const gl::Context *context,
991                                     const TextureHelper11 **outTexture) override;
992     angle::Result getSwizzleRenderTarget(const gl::Context *context,
993                                          int mipLevel,
994                                          const d3d11::RenderTargetView **outRTV) override;
995 
996   private:
997     angle::Result createSRVForSampler(const gl::Context *context,
998                                       int baseLevel,
999                                       int mipLevels,
1000                                       DXGI_FORMAT format,
1001                                       const TextureHelper11 &texture,
1002                                       d3d11::SharedSRV *outSRV) override;
1003     angle::Result createSRVForImage(const gl::Context *context,
1004                                     int level,
1005                                     DXGI_FORMAT format,
1006                                     const TextureHelper11 &texture,
1007                                     d3d11::SharedSRV *outSRV) override;
1008     angle::Result createUAVForImage(const gl::Context *context,
1009                                     int level,
1010                                     DXGI_FORMAT format,
1011                                     const TextureHelper11 &texture,
1012                                     d3d11::SharedUAV *outUAV) override;
1013 
1014     angle::Result initTexture(const gl::Context *context);
1015 
1016     TextureHelper11 mTexture;
1017     const gl::OffsetBindingPointer<gl::Buffer> &mBuffer;
1018     GLint64 mDataSize;
1019 };
1020 }  // namespace rx
1021 
1022 #endif  // LIBANGLE_RENDERER_D3D_D3D11_TEXTURESTORAGE11_H_
1023