• 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     void onLabelUpdate() override;
322 
323   protected:
324     angle::Result getSwizzleTexture(const gl::Context *context,
325                                     const TextureHelper11 **outTexture) override;
326     angle::Result getSwizzleRenderTarget(const gl::Context *context,
327                                          int mipLevel,
328                                          const d3d11::RenderTargetView **outRTV) override;
329 
330     angle::Result ensureDropStencilTexture(const gl::Context *context,
331                                            DropStencil *dropStencilOut) override;
332 
333     angle::Result ensureTextureExists(const gl::Context *context, int mipLevels);
334 
335     angle::Result resolveTexture(const gl::Context *context) override;
336 
337   private:
338     angle::Result createSRVForSampler(const gl::Context *context,
339                                       int baseLevel,
340                                       int mipLevels,
341                                       DXGI_FORMAT format,
342                                       const TextureHelper11 &texture,
343                                       d3d11::SharedSRV *outSRV) override;
344     angle::Result createSRVForImage(const gl::Context *context,
345                                     int level,
346                                     DXGI_FORMAT format,
347                                     const TextureHelper11 &texture,
348                                     d3d11::SharedSRV *outSRV) override;
349     angle::Result createUAVForImage(const gl::Context *context,
350                                     int level,
351                                     DXGI_FORMAT format,
352                                     const TextureHelper11 &texture,
353                                     d3d11::SharedUAV *outUAV) override;
354 
355     TextureHelper11 mTexture;
356     gl::TexLevelArray<std::unique_ptr<RenderTarget11>> mRenderTarget;
357     bool mHasKeyedMutex;
358 
359     // These are members related to the zero max-LOD workaround.
360     // D3D11 Feature Level 9_3 can't disable mipmaps on a mipmapped texture (i.e. solely sample from
361     // level zero). These members are used to work around this limitation. Usually only mTexture XOR
362     // mLevelZeroTexture will exist. For example, if an app creates a texture with only one level,
363     // then 9_3 will only create mLevelZeroTexture. However, in some scenarios, both textures have
364     // to be created. This incurs additional memory overhead. One example of this is an application
365     // that creates a texture, calls glGenerateMipmap, and then disables mipmaps on the texture. A
366     // more likely example is an app that creates an empty texture, renders to it, and then calls
367     // glGenerateMipmap
368     // TODO: In this rendering scenario, release the mLevelZeroTexture after mTexture has been
369     // created to save memory.
370     TextureHelper11 mLevelZeroTexture;
371     std::unique_ptr<RenderTarget11> mLevelZeroRenderTarget;
372     bool mUseLevelZeroTexture;
373 
374     // Swizzle-related variables
375     TextureHelper11 mSwizzleTexture;
376     gl::TexLevelArray<d3d11::RenderTargetView> mSwizzleRenderTargets;
377 
378     gl::TexLevelArray<Image11 *> mAssociatedImages;
379 };
380 
381 class TextureStorage11_External : public TextureStorage11
382 {
383   public:
384     TextureStorage11_External(Renderer11 *renderer,
385                               egl::Stream *stream,
386                               const egl::Stream::GLTextureDescription &glDesc,
387                               const std::string &label);
388     ~TextureStorage11_External() override;
389 
390     angle::Result onDestroy(const gl::Context *context) override;
391 
392     angle::Result getResource(const gl::Context *context,
393                               const TextureHelper11 **outResource) override;
394     angle::Result getMippedResource(const gl::Context *context,
395                                     const TextureHelper11 **outResource) override;
396     angle::Result findRenderTarget(const gl::Context *context,
397                                    const gl::ImageIndex &index,
398                                    GLsizei samples,
399                                    RenderTargetD3D **outRT) const override;
400     angle::Result getRenderTarget(const gl::Context *context,
401                                   const gl::ImageIndex &index,
402                                   GLsizei samples,
403                                   RenderTargetD3D **outRT) override;
404 
405     angle::Result copyToStorage(const gl::Context *context, TextureStorage *destStorage) override;
406 
407     void associateImage(Image11 *image, const gl::ImageIndex &index) override;
408     void disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage) override;
409     void verifyAssociatedImageValid(const gl::ImageIndex &index, Image11 *expectedImage) override;
410     angle::Result releaseAssociatedImage(const gl::Context *context,
411                                          const gl::ImageIndex &index,
412                                          Image11 *incomingImage) override;
413     void onLabelUpdate() override;
414 
415   protected:
416     angle::Result getSwizzleTexture(const gl::Context *context,
417                                     const TextureHelper11 **outTexture) override;
418     angle::Result getSwizzleRenderTarget(const gl::Context *context,
419                                          int mipLevel,
420                                          const d3d11::RenderTargetView **outRTV) override;
421 
422   private:
423     angle::Result createSRVForSampler(const gl::Context *context,
424                                       int baseLevel,
425                                       int mipLevels,
426                                       DXGI_FORMAT format,
427                                       const TextureHelper11 &texture,
428                                       d3d11::SharedSRV *outSRV) override;
429     angle::Result createSRVForImage(const gl::Context *context,
430                                     int level,
431                                     DXGI_FORMAT format,
432                                     const TextureHelper11 &texture,
433                                     d3d11::SharedSRV *outSRV) override;
434     angle::Result createUAVForImage(const gl::Context *context,
435                                     int level,
436                                     DXGI_FORMAT format,
437                                     const TextureHelper11 &texture,
438                                     d3d11::SharedUAV *outUAV) override;
439 
440     TextureHelper11 mTexture;
441     int mSubresourceIndex;
442     bool mHasKeyedMutex;
443 
444     Image11 *mAssociatedImage;
445 };
446 
447 // A base class for texture storage classes where the associated images are not changed, nor are
448 // they accessible as images in GLES3.1+ shaders.
449 class TextureStorage11ImmutableBase : public TextureStorage11
450 {
451   public:
452     TextureStorage11ImmutableBase(Renderer11 *renderer,
453                                   UINT bindFlags,
454                                   UINT miscFlags,
455                                   GLenum internalFormat,
456                                   const std::string &label);
457 
458     void associateImage(Image11 *image, const gl::ImageIndex &index) override;
459     void disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage) override;
460     void verifyAssociatedImageValid(const gl::ImageIndex &index, Image11 *expectedImage) override;
461     angle::Result releaseAssociatedImage(const gl::Context *context,
462                                          const gl::ImageIndex &index,
463                                          Image11 *incomingImage) override;
464 
465     angle::Result createSRVForImage(const gl::Context *context,
466                                     int level,
467                                     DXGI_FORMAT format,
468                                     const TextureHelper11 &texture,
469                                     d3d11::SharedSRV *outSRV) override;
470     angle::Result createUAVForImage(const gl::Context *context,
471                                     int level,
472                                     DXGI_FORMAT format,
473                                     const TextureHelper11 &texture,
474                                     d3d11::SharedUAV *outUAV) override;
475 };
476 
477 class TextureStorage11_EGLImage final : public TextureStorage11ImmutableBase
478 {
479   public:
480     TextureStorage11_EGLImage(Renderer11 *renderer,
481                               EGLImageD3D *eglImage,
482                               RenderTarget11 *renderTarget11,
483                               const std::string &label);
484     ~TextureStorage11_EGLImage() override;
485 
486     angle::Result getSubresourceIndex(const gl::Context *context,
487                                       const gl::ImageIndex &index,
488                                       UINT *outSubresourceIndex) const override;
489     angle::Result getResource(const gl::Context *context,
490                               const TextureHelper11 **outResource) override;
491     angle::Result getSRVForSampler(const gl::Context *context,
492                                    const gl::TextureState &textureState,
493                                    const gl::SamplerState &sampler,
494                                    const d3d11::SharedSRV **outSRV) override;
495     angle::Result getMippedResource(const gl::Context *context,
496                                     const TextureHelper11 **outResource) override;
497     angle::Result findRenderTarget(const gl::Context *context,
498                                    const gl::ImageIndex &index,
499                                    GLsizei samples,
500                                    RenderTargetD3D **outRT) const override;
501     angle::Result getRenderTarget(const gl::Context *context,
502                                   const gl::ImageIndex &index,
503                                   GLsizei samples,
504                                   RenderTargetD3D **outRT) override;
505 
506     angle::Result copyToStorage(const gl::Context *context, TextureStorage *destStorage) override;
507 
508     angle::Result useLevelZeroWorkaroundTexture(const gl::Context *context,
509                                                 bool useLevelZeroTexture) override;
510     void onLabelUpdate() override;
511 
512   protected:
513     angle::Result getSwizzleTexture(const gl::Context *context,
514                                     const TextureHelper11 **outTexture) override;
515     angle::Result getSwizzleRenderTarget(const gl::Context *context,
516                                          int mipLevel,
517                                          const d3d11::RenderTargetView **outRTV) override;
518 
519   private:
520     // Check if the EGL image's render target has been updated due to orphaning and delete
521     // any SRVs and other resources based on the image's old render target.
522     angle::Result checkForUpdatedRenderTarget(const gl::Context *context);
523 
524     angle::Result createSRVForSampler(const gl::Context *context,
525                                       int baseLevel,
526                                       int mipLevels,
527                                       DXGI_FORMAT format,
528                                       const TextureHelper11 &texture,
529                                       d3d11::SharedSRV *outSRV) override;
530 
531     angle::Result getImageRenderTarget(const gl::Context *context, RenderTarget11 **outRT) const;
532 
533     EGLImageD3D *mImage;
534     uintptr_t mCurrentRenderTarget;
535 
536     // Swizzle-related variables
537     TextureHelper11 mSwizzleTexture;
538     std::vector<d3d11::RenderTargetView> mSwizzleRenderTargets;
539 };
540 
541 class TextureStorage11_Cube : public TextureStorage11
542 {
543   public:
544     TextureStorage11_Cube(Renderer11 *renderer,
545                           GLenum internalformat,
546                           bool renderTarget,
547                           int size,
548                           int levels,
549                           bool hintLevelZeroOnly,
550                           const std::string &label);
551     ~TextureStorage11_Cube() override;
552 
553     angle::Result onDestroy(const gl::Context *context) override;
554 
555     angle::Result getSubresourceIndex(const gl::Context *context,
556                                       const gl::ImageIndex &index,
557                                       UINT *outSubresourceIndex) const override;
558 
559     angle::Result getResource(const gl::Context *context,
560                               const TextureHelper11 **outResource) override;
561     angle::Result getMippedResource(const gl::Context *context,
562                                     const TextureHelper11 **outResource) override;
563     angle::Result findRenderTarget(const gl::Context *context,
564                                    const gl::ImageIndex &index,
565                                    GLsizei samples,
566                                    RenderTargetD3D **outRT) const override;
567     angle::Result getRenderTarget(const gl::Context *context,
568                                   const gl::ImageIndex &index,
569                                   GLsizei samples,
570                                   RenderTargetD3D **outRT) override;
571 
572     angle::Result copyToStorage(const gl::Context *context, TextureStorage *destStorage) override;
573 
574     void associateImage(Image11 *image, const gl::ImageIndex &index) override;
575     void disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage) override;
576     void verifyAssociatedImageValid(const gl::ImageIndex &index, Image11 *expectedImage) override;
577     angle::Result releaseAssociatedImage(const gl::Context *context,
578                                          const gl::ImageIndex &index,
579                                          Image11 *incomingImage) override;
580 
581     angle::Result useLevelZeroWorkaroundTexture(const gl::Context *context,
582                                                 bool useLevelZeroTexture) override;
583     void onLabelUpdate() override;
584 
585   protected:
586     angle::Result getSwizzleTexture(const gl::Context *context,
587                                     const TextureHelper11 **outTexture) override;
588     angle::Result getSwizzleRenderTarget(const gl::Context *context,
589                                          int mipLevel,
590                                          const d3d11::RenderTargetView **outRTV) override;
591 
592     angle::Result ensureDropStencilTexture(const gl::Context *context,
593                                            DropStencil *dropStencilOut) override;
594 
595     angle::Result ensureTextureExists(const gl::Context *context, int mipLevels);
596 
597     angle::Result resolveTexture(const gl::Context *context) override;
598 
599   private:
600     angle::Result createSRVForSampler(const gl::Context *context,
601                                       int baseLevel,
602                                       int mipLevels,
603                                       DXGI_FORMAT format,
604                                       const TextureHelper11 &texture,
605                                       d3d11::SharedSRV *outSRV) override;
606     angle::Result createSRVForImage(const gl::Context *context,
607                                     int level,
608                                     DXGI_FORMAT format,
609                                     const TextureHelper11 &texture,
610                                     d3d11::SharedSRV *outSRV) override;
611     angle::Result createUAVForImage(const gl::Context *context,
612                                     int level,
613                                     DXGI_FORMAT format,
614                                     const TextureHelper11 &texture,
615                                     d3d11::SharedUAV *outUAV) override;
616     angle::Result createRenderTargetSRV(const gl::Context *context,
617                                         const TextureHelper11 &texture,
618                                         const gl::ImageIndex &index,
619                                         DXGI_FORMAT resourceFormat,
620                                         d3d11::SharedSRV *srv) const;
621 
622     TextureHelper11 mTexture;
623     CubeFaceArray<gl::TexLevelArray<std::unique_ptr<RenderTarget11>>> mRenderTarget;
624 
625     // Level-zero workaround members. See TextureStorage11_2D's workaround members for a
626     // description.
627     TextureHelper11 mLevelZeroTexture;
628     CubeFaceArray<std::unique_ptr<RenderTarget11>> mLevelZeroRenderTarget;
629     bool mUseLevelZeroTexture;
630 
631     TextureHelper11 mSwizzleTexture;
632     gl::TexLevelArray<d3d11::RenderTargetView> mSwizzleRenderTargets;
633 
634     CubeFaceArray<gl::TexLevelArray<Image11 *>> mAssociatedImages;
635 };
636 
637 class TextureStorage11_3D : public TextureStorage11
638 {
639   public:
640     TextureStorage11_3D(Renderer11 *renderer,
641                         GLenum internalformat,
642                         bool renderTarget,
643                         GLsizei width,
644                         GLsizei height,
645                         GLsizei depth,
646                         int levels,
647                         const std::string &label);
648     ~TextureStorage11_3D() override;
649 
650     angle::Result onDestroy(const gl::Context *context) override;
651 
652     angle::Result getResource(const gl::Context *context,
653                               const TextureHelper11 **outResource) override;
654 
655     // Handles both layer and non-layer RTs
656     angle::Result findRenderTarget(const gl::Context *context,
657                                    const gl::ImageIndex &index,
658                                    GLsizei samples,
659                                    RenderTargetD3D **outRT) const override;
660     angle::Result getRenderTarget(const gl::Context *context,
661                                   const gl::ImageIndex &index,
662                                   GLsizei samples,
663                                   RenderTargetD3D **outRT) override;
664 
665     void associateImage(Image11 *image, const gl::ImageIndex &index) override;
666     void disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage) override;
667     void verifyAssociatedImageValid(const gl::ImageIndex &index, Image11 *expectedImage) override;
668     angle::Result releaseAssociatedImage(const gl::Context *context,
669                                          const gl::ImageIndex &index,
670                                          Image11 *incomingImage) override;
671     void onLabelUpdate() override;
672 
673   protected:
674     angle::Result getSwizzleTexture(const gl::Context *context,
675                                     const TextureHelper11 **outTexture) override;
676     angle::Result getSwizzleRenderTarget(const gl::Context *context,
677                                          int mipLevel,
678                                          const d3d11::RenderTargetView **outRTV) override;
679 
680   private:
681     angle::Result createSRVForSampler(const gl::Context *context,
682                                       int baseLevel,
683                                       int mipLevels,
684                                       DXGI_FORMAT format,
685                                       const TextureHelper11 &texture,
686                                       d3d11::SharedSRV *outSRV) override;
687     angle::Result createSRVForImage(const gl::Context *context,
688                                     int level,
689                                     DXGI_FORMAT format,
690                                     const TextureHelper11 &texture,
691                                     d3d11::SharedSRV *outSRV) override;
692     angle::Result createUAVForImage(const gl::Context *context,
693                                     int level,
694                                     DXGI_FORMAT format,
695                                     const TextureHelper11 &texture,
696                                     d3d11::SharedUAV *outUAV) override;
697 
698     typedef std::pair<int, int> LevelLayerKey;
699     std::map<LevelLayerKey, std::unique_ptr<RenderTarget11>> mLevelLayerRenderTargets;
700 
701     gl::TexLevelArray<std::unique_ptr<RenderTarget11>> mLevelRenderTargets;
702 
703     TextureHelper11 mTexture;
704     TextureHelper11 mSwizzleTexture;
705     gl::TexLevelArray<d3d11::RenderTargetView> mSwizzleRenderTargets;
706 
707     gl::TexLevelArray<Image11 *> mAssociatedImages;
708 };
709 
710 class TextureStorage11_2DArray : public TextureStorage11
711 {
712   public:
713     TextureStorage11_2DArray(Renderer11 *renderer,
714                              GLenum internalformat,
715                              bool renderTarget,
716                              GLsizei width,
717                              GLsizei height,
718                              GLsizei depth,
719                              int levels,
720                              const std::string &label);
721     ~TextureStorage11_2DArray() override;
722 
723     angle::Result onDestroy(const gl::Context *context) override;
724 
725     angle::Result getResource(const gl::Context *context,
726                               const TextureHelper11 **outResource) override;
727     angle::Result findRenderTarget(const gl::Context *context,
728                                    const gl::ImageIndex &index,
729                                    GLsizei samples,
730                                    RenderTargetD3D **outRT) const override;
731     angle::Result getRenderTarget(const gl::Context *context,
732                                   const gl::ImageIndex &index,
733                                   GLsizei samples,
734                                   RenderTargetD3D **outRT) override;
735 
736     void associateImage(Image11 *image, const gl::ImageIndex &index) override;
737     void disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage) override;
738     void verifyAssociatedImageValid(const gl::ImageIndex &index, Image11 *expectedImage) override;
739     angle::Result releaseAssociatedImage(const gl::Context *context,
740                                          const gl::ImageIndex &index,
741                                          Image11 *incomingImage) override;
742     void onLabelUpdate() override;
743 
744     struct LevelLayerRangeKey
745     {
LevelLayerRangeKeyLevelLayerRangeKey746         LevelLayerRangeKey(int mipLevelIn, int layerIn, int numLayersIn)
747             : mipLevel(mipLevelIn), layer(layerIn), numLayers(numLayersIn)
748         {}
749         bool operator<(const LevelLayerRangeKey &other) const
750         {
751             if (mipLevel != other.mipLevel)
752             {
753                 return mipLevel < other.mipLevel;
754             }
755             if (layer != other.layer)
756             {
757                 return layer < other.layer;
758             }
759             return numLayers < other.numLayers;
760         }
761         int mipLevel;
762         int layer;
763         int numLayers;
764     };
765 
766   protected:
767     angle::Result getSwizzleTexture(const gl::Context *context,
768                                     const TextureHelper11 **outTexture) override;
769     angle::Result getSwizzleRenderTarget(const gl::Context *context,
770                                          int mipLevel,
771                                          const d3d11::RenderTargetView **outRTV) override;
772 
773     angle::Result ensureDropStencilTexture(const gl::Context *context,
774                                            DropStencil *dropStencilOut) override;
775 
776   private:
777     angle::Result createSRVForSampler(const gl::Context *context,
778                                       int baseLevel,
779                                       int mipLevels,
780                                       DXGI_FORMAT format,
781                                       const TextureHelper11 &texture,
782                                       d3d11::SharedSRV *outSRV) override;
783     angle::Result createSRVForImage(const gl::Context *context,
784                                     int level,
785                                     DXGI_FORMAT format,
786                                     const TextureHelper11 &texture,
787                                     d3d11::SharedSRV *outSRV) override;
788     angle::Result createUAVForImage(const gl::Context *context,
789                                     int level,
790                                     DXGI_FORMAT format,
791                                     const TextureHelper11 &texture,
792                                     d3d11::SharedUAV *outUAV) override;
793     angle::Result createRenderTargetSRV(const gl::Context *context,
794                                         const TextureHelper11 &texture,
795                                         const gl::ImageIndex &index,
796                                         DXGI_FORMAT resourceFormat,
797                                         d3d11::SharedSRV *srv) const;
798 
799     std::map<LevelLayerRangeKey, std::unique_ptr<RenderTarget11>> mRenderTargets;
800 
801     TextureHelper11 mTexture;
802 
803     TextureHelper11 mSwizzleTexture;
804     gl::TexLevelArray<d3d11::RenderTargetView> mSwizzleRenderTargets;
805 
806     typedef std::map<LevelLayerRangeKey, Image11 *> ImageMap;
807     ImageMap mAssociatedImages;
808 };
809 
810 class TextureStorage11_2DMultisample final : public TextureStorage11ImmutableBase
811 {
812   public:
813     TextureStorage11_2DMultisample(Renderer11 *renderer,
814                                    GLenum internalformat,
815                                    GLsizei width,
816                                    GLsizei height,
817                                    int levels,
818                                    int samples,
819                                    bool fixedSampleLocations,
820                                    const std::string &label);
821     ~TextureStorage11_2DMultisample() override;
822 
823     angle::Result onDestroy(const gl::Context *context) override;
824 
825     angle::Result getResource(const gl::Context *context,
826                               const TextureHelper11 **outResource) override;
827     angle::Result findRenderTarget(const gl::Context *context,
828                                    const gl::ImageIndex &index,
829                                    GLsizei samples,
830                                    RenderTargetD3D **outRT) const override;
831     angle::Result getRenderTarget(const gl::Context *context,
832                                   const gl::ImageIndex &index,
833                                   GLsizei samples,
834                                   RenderTargetD3D **outRT) override;
835 
836     angle::Result copyToStorage(const gl::Context *context, TextureStorage *destStorage) override;
837     void onLabelUpdate() override;
838 
839   protected:
840     angle::Result getSwizzleTexture(const gl::Context *context,
841                                     const TextureHelper11 **outTexture) override;
842     angle::Result getSwizzleRenderTarget(const gl::Context *context,
843                                          int mipLevel,
844                                          const d3d11::RenderTargetView **outRTV) override;
845 
846     angle::Result ensureDropStencilTexture(const gl::Context *context,
847                                            DropStencil *dropStencilOut) override;
848 
849     angle::Result ensureTextureExists(const gl::Context *context, int mipLevels);
850 
851   private:
852     angle::Result createSRVForSampler(const gl::Context *context,
853                                       int baseLevel,
854                                       int mipLevels,
855                                       DXGI_FORMAT format,
856                                       const TextureHelper11 &texture,
857                                       d3d11::SharedSRV *outSRV) override;
858 
859     TextureHelper11 mTexture;
860     std::unique_ptr<RenderTarget11> mRenderTarget;
861 
862     unsigned int mSamples;
863     GLboolean mFixedSampleLocations;
864 };
865 
866 class TextureStorage11_2DMultisampleArray final : public TextureStorage11ImmutableBase
867 {
868   public:
869     TextureStorage11_2DMultisampleArray(Renderer11 *renderer,
870                                         GLenum internalformat,
871                                         GLsizei width,
872                                         GLsizei height,
873                                         GLsizei depth,
874                                         int levels,
875                                         int samples,
876                                         bool fixedSampleLocations,
877                                         const std::string &label);
878     ~TextureStorage11_2DMultisampleArray() override;
879 
880     angle::Result onDestroy(const gl::Context *context) override;
881 
882     angle::Result getResource(const gl::Context *context,
883                               const TextureHelper11 **outResource) override;
884     angle::Result findRenderTarget(const gl::Context *context,
885                                    const gl::ImageIndex &index,
886                                    GLsizei samples,
887                                    RenderTargetD3D **outRT) const override;
888     angle::Result getRenderTarget(const gl::Context *context,
889                                   const gl::ImageIndex &index,
890                                   GLsizei samples,
891                                   RenderTargetD3D **outRT) override;
892 
893     angle::Result copyToStorage(const gl::Context *context, TextureStorage *destStorage) override;
894     void onLabelUpdate() override;
895 
896   protected:
897     angle::Result getSwizzleTexture(const gl::Context *context,
898                                     const TextureHelper11 **outTexture) override;
899     angle::Result getSwizzleRenderTarget(const gl::Context *context,
900                                          int mipLevel,
901                                          const d3d11::RenderTargetView **outRTV) override;
902 
903     angle::Result ensureDropStencilTexture(const gl::Context *context,
904                                            DropStencil *dropStencilOut) override;
905 
906     angle::Result ensureTextureExists(const gl::Context *context, int mipLevels);
907 
908   private:
909     angle::Result createRenderTargetSRV(const gl::Context *context,
910                                         const TextureHelper11 &texture,
911                                         const gl::ImageIndex &index,
912                                         DXGI_FORMAT resourceFormat,
913                                         d3d11::SharedSRV *srv) const;
914 
915     angle::Result createSRVForSampler(const gl::Context *context,
916                                       int baseLevel,
917                                       int mipLevels,
918                                       DXGI_FORMAT format,
919                                       const TextureHelper11 &texture,
920                                       d3d11::SharedSRV *outSRV) override;
921 
922     TextureHelper11 mTexture;
923     std::map<TextureStorage11_2DArray::LevelLayerRangeKey, std::unique_ptr<RenderTarget11>>
924         mRenderTargets;
925 
926     unsigned int mSamples;
927     GLboolean mFixedSampleLocations;
928 };
929 }  // namespace rx
930 
931 #endif  // LIBANGLE_RENDERER_D3D_D3D11_TEXTURESTORAGE11_H_
932