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