• 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 onDestroy(const gl::Context *context) override;
487 
488     angle::Result getSubresourceIndex(const gl::Context *context,
489                                       const gl::ImageIndex &index,
490                                       UINT *outSubresourceIndex) const override;
491     angle::Result getResource(const gl::Context *context,
492                               const TextureHelper11 **outResource) override;
493     angle::Result getSRVForSampler(const gl::Context *context,
494                                    const gl::TextureState &textureState,
495                                    const gl::SamplerState &sampler,
496                                    const d3d11::SharedSRV **outSRV) override;
497     angle::Result getMippedResource(const gl::Context *context,
498                                     const TextureHelper11 **outResource) override;
499     angle::Result findRenderTarget(const gl::Context *context,
500                                    const gl::ImageIndex &index,
501                                    GLsizei samples,
502                                    RenderTargetD3D **outRT) const override;
503     angle::Result getRenderTarget(const gl::Context *context,
504                                   const gl::ImageIndex &index,
505                                   GLsizei samples,
506                                   RenderTargetD3D **outRT) override;
507 
508     angle::Result copyToStorage(const gl::Context *context, TextureStorage *destStorage) override;
509 
510     angle::Result useLevelZeroWorkaroundTexture(const gl::Context *context,
511                                                 bool useLevelZeroTexture) override;
512     void onLabelUpdate() override;
513 
514     void associateImage(Image11 *image, const gl::ImageIndex &index) override;
515     void disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage) override;
516     void verifyAssociatedImageValid(const gl::ImageIndex &index, Image11 *expectedImage) override;
517     angle::Result releaseAssociatedImage(const gl::Context *context,
518                                          const gl::ImageIndex &index,
519                                          Image11 *incomingImage) override;
520 
521   protected:
522     angle::Result getSwizzleTexture(const gl::Context *context,
523                                     const TextureHelper11 **outTexture) override;
524     angle::Result getSwizzleRenderTarget(const gl::Context *context,
525                                          int mipLevel,
526                                          const d3d11::RenderTargetView **outRTV) override;
527 
528   private:
529     // Check if the EGL image's render target has been updated due to orphaning and delete
530     // any SRVs and other resources based on the image's old render target.
531     angle::Result checkForUpdatedRenderTarget(const gl::Context *context);
532 
533     angle::Result createSRVForSampler(const gl::Context *context,
534                                       int baseLevel,
535                                       int mipLevels,
536                                       DXGI_FORMAT format,
537                                       const TextureHelper11 &texture,
538                                       d3d11::SharedSRV *outSRV) override;
539 
540     angle::Result getImageRenderTarget(const gl::Context *context, RenderTarget11 **outRT) const;
541 
542     EGLImageD3D *mImage;
543     uintptr_t mCurrentRenderTarget;
544 
545     // Swizzle-related variables
546     TextureHelper11 mSwizzleTexture;
547     std::vector<d3d11::RenderTargetView> mSwizzleRenderTargets;
548 
549     Image11 *mAssociatedImage;
550 };
551 
552 class TextureStorage11_Cube : public TextureStorage11
553 {
554   public:
555     TextureStorage11_Cube(Renderer11 *renderer,
556                           GLenum internalformat,
557                           bool renderTarget,
558                           int size,
559                           int levels,
560                           bool hintLevelZeroOnly,
561                           const std::string &label);
562     ~TextureStorage11_Cube() override;
563 
564     angle::Result onDestroy(const gl::Context *context) override;
565 
566     angle::Result getSubresourceIndex(const gl::Context *context,
567                                       const gl::ImageIndex &index,
568                                       UINT *outSubresourceIndex) const override;
569 
570     angle::Result getResource(const gl::Context *context,
571                               const TextureHelper11 **outResource) override;
572     angle::Result getMippedResource(const gl::Context *context,
573                                     const TextureHelper11 **outResource) override;
574     angle::Result findRenderTarget(const gl::Context *context,
575                                    const gl::ImageIndex &index,
576                                    GLsizei samples,
577                                    RenderTargetD3D **outRT) const override;
578     angle::Result getRenderTarget(const gl::Context *context,
579                                   const gl::ImageIndex &index,
580                                   GLsizei samples,
581                                   RenderTargetD3D **outRT) override;
582 
583     angle::Result copyToStorage(const gl::Context *context, TextureStorage *destStorage) override;
584 
585     void associateImage(Image11 *image, const gl::ImageIndex &index) override;
586     void disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage) override;
587     void verifyAssociatedImageValid(const gl::ImageIndex &index, Image11 *expectedImage) override;
588     angle::Result releaseAssociatedImage(const gl::Context *context,
589                                          const gl::ImageIndex &index,
590                                          Image11 *incomingImage) override;
591 
592     angle::Result useLevelZeroWorkaroundTexture(const gl::Context *context,
593                                                 bool useLevelZeroTexture) override;
594     void onLabelUpdate() override;
595 
596   protected:
597     angle::Result getSwizzleTexture(const gl::Context *context,
598                                     const TextureHelper11 **outTexture) override;
599     angle::Result getSwizzleRenderTarget(const gl::Context *context,
600                                          int mipLevel,
601                                          const d3d11::RenderTargetView **outRTV) override;
602 
603     angle::Result ensureDropStencilTexture(const gl::Context *context,
604                                            DropStencil *dropStencilOut) override;
605 
606     angle::Result ensureTextureExists(const gl::Context *context, int mipLevels);
607 
608     angle::Result resolveTexture(const gl::Context *context) override;
609 
610   private:
611     angle::Result createSRVForSampler(const gl::Context *context,
612                                       int baseLevel,
613                                       int mipLevels,
614                                       DXGI_FORMAT format,
615                                       const TextureHelper11 &texture,
616                                       d3d11::SharedSRV *outSRV) override;
617     angle::Result createSRVForImage(const gl::Context *context,
618                                     int level,
619                                     DXGI_FORMAT format,
620                                     const TextureHelper11 &texture,
621                                     d3d11::SharedSRV *outSRV) override;
622     angle::Result createUAVForImage(const gl::Context *context,
623                                     int level,
624                                     DXGI_FORMAT format,
625                                     const TextureHelper11 &texture,
626                                     d3d11::SharedUAV *outUAV) override;
627     angle::Result createRenderTargetSRV(const gl::Context *context,
628                                         const TextureHelper11 &texture,
629                                         const gl::ImageIndex &index,
630                                         DXGI_FORMAT resourceFormat,
631                                         d3d11::SharedSRV *srv) const;
632 
633     TextureHelper11 mTexture;
634     CubeFaceArray<gl::TexLevelArray<std::unique_ptr<RenderTarget11>>> mRenderTarget;
635 
636     // Level-zero workaround members. See TextureStorage11_2D's workaround members for a
637     // description.
638     TextureHelper11 mLevelZeroTexture;
639     CubeFaceArray<std::unique_ptr<RenderTarget11>> mLevelZeroRenderTarget;
640     bool mUseLevelZeroTexture;
641 
642     TextureHelper11 mSwizzleTexture;
643     gl::TexLevelArray<d3d11::RenderTargetView> mSwizzleRenderTargets;
644 
645     CubeFaceArray<gl::TexLevelArray<Image11 *>> mAssociatedImages;
646 };
647 
648 class TextureStorage11_3D : public TextureStorage11
649 {
650   public:
651     TextureStorage11_3D(Renderer11 *renderer,
652                         GLenum internalformat,
653                         bool renderTarget,
654                         GLsizei width,
655                         GLsizei height,
656                         GLsizei depth,
657                         int levels,
658                         const std::string &label);
659     ~TextureStorage11_3D() override;
660 
661     angle::Result onDestroy(const gl::Context *context) override;
662 
663     angle::Result getResource(const gl::Context *context,
664                               const TextureHelper11 **outResource) override;
665 
666     // Handles both layer and non-layer RTs
667     angle::Result findRenderTarget(const gl::Context *context,
668                                    const gl::ImageIndex &index,
669                                    GLsizei samples,
670                                    RenderTargetD3D **outRT) const override;
671     angle::Result getRenderTarget(const gl::Context *context,
672                                   const gl::ImageIndex &index,
673                                   GLsizei samples,
674                                   RenderTargetD3D **outRT) override;
675 
676     void associateImage(Image11 *image, const gl::ImageIndex &index) override;
677     void disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage) override;
678     void verifyAssociatedImageValid(const gl::ImageIndex &index, Image11 *expectedImage) override;
679     angle::Result releaseAssociatedImage(const gl::Context *context,
680                                          const gl::ImageIndex &index,
681                                          Image11 *incomingImage) override;
682     void onLabelUpdate() override;
683 
684   protected:
685     angle::Result getSwizzleTexture(const gl::Context *context,
686                                     const TextureHelper11 **outTexture) override;
687     angle::Result getSwizzleRenderTarget(const gl::Context *context,
688                                          int mipLevel,
689                                          const d3d11::RenderTargetView **outRTV) override;
690 
691   private:
692     angle::Result createSRVForSampler(const gl::Context *context,
693                                       int baseLevel,
694                                       int mipLevels,
695                                       DXGI_FORMAT format,
696                                       const TextureHelper11 &texture,
697                                       d3d11::SharedSRV *outSRV) override;
698     angle::Result createSRVForImage(const gl::Context *context,
699                                     int level,
700                                     DXGI_FORMAT format,
701                                     const TextureHelper11 &texture,
702                                     d3d11::SharedSRV *outSRV) override;
703     angle::Result createUAVForImage(const gl::Context *context,
704                                     int level,
705                                     DXGI_FORMAT format,
706                                     const TextureHelper11 &texture,
707                                     d3d11::SharedUAV *outUAV) override;
708 
709     typedef std::pair<int, int> LevelLayerKey;
710     std::map<LevelLayerKey, std::unique_ptr<RenderTarget11>> mLevelLayerRenderTargets;
711 
712     gl::TexLevelArray<std::unique_ptr<RenderTarget11>> mLevelRenderTargets;
713 
714     TextureHelper11 mTexture;
715     TextureHelper11 mSwizzleTexture;
716     gl::TexLevelArray<d3d11::RenderTargetView> mSwizzleRenderTargets;
717 
718     gl::TexLevelArray<Image11 *> mAssociatedImages;
719 };
720 
721 class TextureStorage11_2DArray : public TextureStorage11
722 {
723   public:
724     TextureStorage11_2DArray(Renderer11 *renderer,
725                              GLenum internalformat,
726                              bool renderTarget,
727                              GLsizei width,
728                              GLsizei height,
729                              GLsizei depth,
730                              int levels,
731                              const std::string &label);
732     ~TextureStorage11_2DArray() override;
733 
734     angle::Result onDestroy(const gl::Context *context) override;
735 
736     angle::Result getResource(const gl::Context *context,
737                               const TextureHelper11 **outResource) override;
738     angle::Result findRenderTarget(const gl::Context *context,
739                                    const gl::ImageIndex &index,
740                                    GLsizei samples,
741                                    RenderTargetD3D **outRT) const override;
742     angle::Result getRenderTarget(const gl::Context *context,
743                                   const gl::ImageIndex &index,
744                                   GLsizei samples,
745                                   RenderTargetD3D **outRT) override;
746 
747     void associateImage(Image11 *image, const gl::ImageIndex &index) override;
748     void disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage) override;
749     void verifyAssociatedImageValid(const gl::ImageIndex &index, Image11 *expectedImage) override;
750     angle::Result releaseAssociatedImage(const gl::Context *context,
751                                          const gl::ImageIndex &index,
752                                          Image11 *incomingImage) override;
753     void onLabelUpdate() override;
754 
755     struct LevelLayerRangeKey
756     {
LevelLayerRangeKeyLevelLayerRangeKey757         LevelLayerRangeKey(int mipLevelIn, int layerIn, int numLayersIn)
758             : mipLevel(mipLevelIn), layer(layerIn), numLayers(numLayersIn)
759         {}
760         bool operator<(const LevelLayerRangeKey &other) const
761         {
762             if (mipLevel != other.mipLevel)
763             {
764                 return mipLevel < other.mipLevel;
765             }
766             if (layer != other.layer)
767             {
768                 return layer < other.layer;
769             }
770             return numLayers < other.numLayers;
771         }
772         int mipLevel;
773         int layer;
774         int numLayers;
775     };
776 
777   protected:
778     angle::Result getSwizzleTexture(const gl::Context *context,
779                                     const TextureHelper11 **outTexture) override;
780     angle::Result getSwizzleRenderTarget(const gl::Context *context,
781                                          int mipLevel,
782                                          const d3d11::RenderTargetView **outRTV) override;
783 
784     angle::Result ensureDropStencilTexture(const gl::Context *context,
785                                            DropStencil *dropStencilOut) override;
786 
787   private:
788     angle::Result createSRVForSampler(const gl::Context *context,
789                                       int baseLevel,
790                                       int mipLevels,
791                                       DXGI_FORMAT format,
792                                       const TextureHelper11 &texture,
793                                       d3d11::SharedSRV *outSRV) override;
794     angle::Result createSRVForImage(const gl::Context *context,
795                                     int level,
796                                     DXGI_FORMAT format,
797                                     const TextureHelper11 &texture,
798                                     d3d11::SharedSRV *outSRV) override;
799     angle::Result createUAVForImage(const gl::Context *context,
800                                     int level,
801                                     DXGI_FORMAT format,
802                                     const TextureHelper11 &texture,
803                                     d3d11::SharedUAV *outUAV) override;
804     angle::Result createRenderTargetSRV(const gl::Context *context,
805                                         const TextureHelper11 &texture,
806                                         const gl::ImageIndex &index,
807                                         DXGI_FORMAT resourceFormat,
808                                         d3d11::SharedSRV *srv) const;
809 
810     std::map<LevelLayerRangeKey, std::unique_ptr<RenderTarget11>> mRenderTargets;
811 
812     TextureHelper11 mTexture;
813 
814     TextureHelper11 mSwizzleTexture;
815     gl::TexLevelArray<d3d11::RenderTargetView> mSwizzleRenderTargets;
816 
817     typedef std::map<LevelLayerRangeKey, Image11 *> ImageMap;
818     ImageMap mAssociatedImages;
819 };
820 
821 class TextureStorage11_2DMultisample final : public TextureStorage11ImmutableBase
822 {
823   public:
824     TextureStorage11_2DMultisample(Renderer11 *renderer,
825                                    GLenum internalformat,
826                                    GLsizei width,
827                                    GLsizei height,
828                                    int levels,
829                                    int samples,
830                                    bool fixedSampleLocations,
831                                    const std::string &label);
832     ~TextureStorage11_2DMultisample() override;
833 
834     angle::Result onDestroy(const gl::Context *context) override;
835 
836     angle::Result getResource(const gl::Context *context,
837                               const TextureHelper11 **outResource) override;
838     angle::Result findRenderTarget(const gl::Context *context,
839                                    const gl::ImageIndex &index,
840                                    GLsizei samples,
841                                    RenderTargetD3D **outRT) const override;
842     angle::Result getRenderTarget(const gl::Context *context,
843                                   const gl::ImageIndex &index,
844                                   GLsizei samples,
845                                   RenderTargetD3D **outRT) override;
846 
847     angle::Result copyToStorage(const gl::Context *context, TextureStorage *destStorage) override;
848     void onLabelUpdate() override;
849 
850   protected:
851     angle::Result getSwizzleTexture(const gl::Context *context,
852                                     const TextureHelper11 **outTexture) override;
853     angle::Result getSwizzleRenderTarget(const gl::Context *context,
854                                          int mipLevel,
855                                          const d3d11::RenderTargetView **outRTV) override;
856 
857     angle::Result ensureDropStencilTexture(const gl::Context *context,
858                                            DropStencil *dropStencilOut) override;
859 
860     angle::Result ensureTextureExists(const gl::Context *context, int mipLevels);
861 
862   private:
863     angle::Result createSRVForSampler(const gl::Context *context,
864                                       int baseLevel,
865                                       int mipLevels,
866                                       DXGI_FORMAT format,
867                                       const TextureHelper11 &texture,
868                                       d3d11::SharedSRV *outSRV) override;
869 
870     TextureHelper11 mTexture;
871     std::unique_ptr<RenderTarget11> mRenderTarget;
872 
873     unsigned int mSamples;
874     GLboolean mFixedSampleLocations;
875 };
876 
877 class TextureStorage11_2DMultisampleArray final : public TextureStorage11ImmutableBase
878 {
879   public:
880     TextureStorage11_2DMultisampleArray(Renderer11 *renderer,
881                                         GLenum internalformat,
882                                         GLsizei width,
883                                         GLsizei height,
884                                         GLsizei depth,
885                                         int levels,
886                                         int samples,
887                                         bool fixedSampleLocations,
888                                         const std::string &label);
889     ~TextureStorage11_2DMultisampleArray() override;
890 
891     angle::Result onDestroy(const gl::Context *context) override;
892 
893     angle::Result getResource(const gl::Context *context,
894                               const TextureHelper11 **outResource) override;
895     angle::Result findRenderTarget(const gl::Context *context,
896                                    const gl::ImageIndex &index,
897                                    GLsizei samples,
898                                    RenderTargetD3D **outRT) const override;
899     angle::Result getRenderTarget(const gl::Context *context,
900                                   const gl::ImageIndex &index,
901                                   GLsizei samples,
902                                   RenderTargetD3D **outRT) override;
903 
904     angle::Result copyToStorage(const gl::Context *context, TextureStorage *destStorage) override;
905     void onLabelUpdate() override;
906 
907   protected:
908     angle::Result getSwizzleTexture(const gl::Context *context,
909                                     const TextureHelper11 **outTexture) override;
910     angle::Result getSwizzleRenderTarget(const gl::Context *context,
911                                          int mipLevel,
912                                          const d3d11::RenderTargetView **outRTV) override;
913 
914     angle::Result ensureDropStencilTexture(const gl::Context *context,
915                                            DropStencil *dropStencilOut) override;
916 
917     angle::Result ensureTextureExists(const gl::Context *context, int mipLevels);
918 
919   private:
920     angle::Result createRenderTargetSRV(const gl::Context *context,
921                                         const TextureHelper11 &texture,
922                                         const gl::ImageIndex &index,
923                                         DXGI_FORMAT resourceFormat,
924                                         d3d11::SharedSRV *srv) const;
925 
926     angle::Result createSRVForSampler(const gl::Context *context,
927                                       int baseLevel,
928                                       int mipLevels,
929                                       DXGI_FORMAT format,
930                                       const TextureHelper11 &texture,
931                                       d3d11::SharedSRV *outSRV) override;
932 
933     TextureHelper11 mTexture;
934     std::map<TextureStorage11_2DArray::LevelLayerRangeKey, std::unique_ptr<RenderTarget11>>
935         mRenderTargets;
936 
937     unsigned int mSamples;
938     GLboolean mFixedSampleLocations;
939 };
940 }  // namespace rx
941 
942 #endif  // LIBANGLE_RENDERER_D3D_D3D11_TEXTURESTORAGE11_H_
943