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