xref: /aosp_15_r20/external/angle/src/libANGLE/renderer/d3d/TextureD3D.h (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1 //
2 // Copyright 2014 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 // TextureD3D.h: Implementations of the Texture interfaces shared betweeen the D3D backends.
8 
9 #ifndef LIBANGLE_RENDERER_D3D_TEXTURED3D_H_
10 #define LIBANGLE_RENDERER_D3D_TEXTURED3D_H_
11 
12 #include "common/Color.h"
13 #include "libANGLE/Constants.h"
14 #include "libANGLE/Stream.h"
15 #include "libANGLE/angletypes.h"
16 #include "libANGLE/renderer/TextureImpl.h"
17 #include "libANGLE/renderer/d3d/RendererD3D.h"
18 #include "libANGLE/renderer/d3d/TextureStorage.h"
19 
20 namespace gl
21 {
22 class Framebuffer;
23 }
24 
25 namespace rx
26 {
27 class EGLImageD3D;
28 class ImageD3D;
29 class RendererD3D;
30 class RenderTargetD3D;
31 class TextureStorage;
32 
33 class TextureD3D : public TextureImpl, public angle::ObserverInterface
34 {
35   public:
36     TextureD3D(const gl::TextureState &data, RendererD3D *renderer);
37     ~TextureD3D() override;
38 
39     void onDestroy(const gl::Context *context) override;
40 
41     angle::Result getNativeTexture(const gl::Context *context, TextureStorage **outStorage);
42 
hasDirtyImages()43     bool hasDirtyImages() const { return mDirtyImages; }
resetDirty()44     void resetDirty() { mDirtyImages = false; }
45 
46     virtual ImageD3D *getImage(const gl::ImageIndex &index) const = 0;
47     virtual GLsizei getLayerCount(int level) const                = 0;
48 
49     angle::Result getImageAndSyncFromStorage(const gl::Context *context,
50                                              const gl::ImageIndex &index,
51                                              ImageD3D **outImage);
52 
53     GLint getBaseLevelWidth() const;
54     GLint getBaseLevelHeight() const;
55     GLenum getBaseLevelInternalFormat() const;
56 
57     angle::Result setStorage(const gl::Context *context,
58                              gl::TextureType type,
59                              size_t levels,
60                              GLenum internalFormat,
61                              const gl::Extents &size) override;
62 
63     angle::Result setStorageMultisample(const gl::Context *context,
64                                         gl::TextureType type,
65                                         GLsizei samples,
66                                         GLint internalformat,
67                                         const gl::Extents &size,
68                                         bool fixedSampleLocations) override;
69 
70     angle::Result setBuffer(const gl::Context *context, GLenum internalFormat) override;
71 
72     angle::Result setStorageExternalMemory(const gl::Context *context,
73                                            gl::TextureType type,
74                                            size_t levels,
75                                            GLenum internalFormat,
76                                            const gl::Extents &size,
77                                            gl::MemoryObject *memoryObject,
78                                            GLuint64 offset,
79                                            GLbitfield createFlags,
80                                            GLbitfield usageFlags,
81                                            const void *imageCreateInfoPNext) override;
82 
isImmutable()83     bool isImmutable() const { return mImmutable; }
84 
85     virtual angle::Result getRenderTarget(const gl::Context *context,
86                                           const gl::ImageIndex &index,
87                                           GLsizei samples,
88                                           RenderTargetD3D **outRT) = 0;
89 
90     // Returns an iterator over all "Images" for this particular Texture.
91     virtual gl::ImageIndexIterator imageIterator() const = 0;
92 
93     // Returns an ImageIndex for a particular "Image". 3D Textures do not have images for
94     // slices of their depth texures, so 3D textures ignore the layer parameter.
95     virtual gl::ImageIndex getImageIndex(GLint mip, GLint layer) const = 0;
96     virtual bool isValidIndex(const gl::ImageIndex &index) const       = 0;
97 
98     angle::Result setImageExternal(const gl::Context *context,
99                                    gl::TextureType type,
100                                    egl::Stream *stream,
101                                    const egl::Stream::GLTextureDescription &desc) override;
102     angle::Result generateMipmap(const gl::Context *context) override;
hasStorage()103     bool hasStorage() const { return mTexStorage != nullptr; }
104     TextureStorage *getStorage();
105     ImageD3D *getBaseLevelImage() const;
106 
107     angle::Result getAttachmentRenderTarget(const gl::Context *context,
108                                             GLenum binding,
109                                             const gl::ImageIndex &imageIndex,
110                                             GLsizei samples,
111                                             FramebufferAttachmentRenderTarget **rtOut) override;
112 
113     angle::Result setBaseLevel(const gl::Context *context, GLuint baseLevel) override;
114 
115     angle::Result syncState(const gl::Context *context,
116                             const gl::Texture::DirtyBits &dirtyBits,
117                             gl::Command source) override;
118 
119     angle::Result initializeContents(const gl::Context *context,
120                                      GLenum binding,
121                                      const gl::ImageIndex &imageIndex) override;
122 
123     GLsizei getRenderToTextureSamples();
124 
125     angle::Result ensureUnorderedAccess(const gl::Context *context);
126     angle::Result onLabelUpdate(const gl::Context *context) override;
127 
128     // ObserverInterface implementation.
129     void onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) override;
130 
131   protected:
132     angle::Result setImageImpl(const gl::Context *context,
133                                const gl::ImageIndex &index,
134                                GLenum type,
135                                const gl::PixelUnpackState &unpack,
136                                gl::Buffer *unpackBuffer,
137                                const uint8_t *pixels,
138                                ptrdiff_t layerOffset);
139     angle::Result subImage(const gl::Context *context,
140                            const gl::ImageIndex &index,
141                            const gl::Box &area,
142                            GLenum format,
143                            GLenum type,
144                            const gl::PixelUnpackState &unpack,
145                            gl::Buffer *unpackBuffer,
146                            const uint8_t *pixels,
147                            ptrdiff_t layerOffset);
148     angle::Result setCompressedImageImpl(const gl::Context *context,
149                                          const gl::ImageIndex &index,
150                                          const gl::PixelUnpackState &unpack,
151                                          const uint8_t *pixels,
152                                          ptrdiff_t layerOffset);
153     angle::Result subImageCompressed(const gl::Context *context,
154                                      const gl::ImageIndex &index,
155                                      const gl::Box &area,
156                                      GLenum format,
157                                      const gl::PixelUnpackState &unpack,
158                                      const uint8_t *pixels,
159                                      ptrdiff_t layerOffset);
160     bool isFastUnpackable(const gl::Buffer *unpackBuffer,
161                           const gl::PixelUnpackState &unpack,
162                           GLenum sizedInternalFormat);
163     angle::Result fastUnpackPixels(const gl::Context *context,
164                                    const gl::PixelUnpackState &unpack,
165                                    gl::Buffer *unpackBuffer,
166                                    const uint8_t *pixels,
167                                    const gl::Box &destArea,
168                                    GLenum sizedInternalFormat,
169                                    GLenum type,
170                                    RenderTargetD3D *destRenderTarget);
171 
172     GLint getLevelZeroWidth() const;
173     GLint getLevelZeroHeight() const;
174     virtual GLint getLevelZeroDepth() const;
175 
176     GLint creationLevels(GLsizei width, GLsizei height, GLsizei depth) const;
177     virtual angle::Result initMipmapImages(const gl::Context *context) = 0;
178     bool isBaseImageZeroSize() const;
179     virtual bool isImageComplete(const gl::ImageIndex &index) const = 0;
180 
181     bool canCreateRenderTargetForImage(const gl::ImageIndex &index) const;
182     angle::Result ensureBindFlags(const gl::Context *context, BindFlags bindFlags);
183     angle::Result ensureRenderTarget(const gl::Context *context);
184 
185     virtual angle::Result createCompleteStorage(const gl::Context *context,
186                                                 BindFlags bindFlags,
187                                                 TexStoragePointer *outTexStorage) const = 0;
188     virtual angle::Result setCompleteTexStorage(const gl::Context *context,
189                                                 TextureStorage *newCompleteTexStorage)  = 0;
190     angle::Result commitRegion(const gl::Context *context,
191                                const gl::ImageIndex &index,
192                                const gl::Box &region);
193 
194     angle::Result releaseTexStorage(const gl::Context *context,
195                                     const gl::TexLevelMask &copyStorageToImagesMask);
196 
getBaseLevel()197     GLuint getBaseLevel() const { return mBaseLevel; }
198 
199     virtual void markAllImagesDirty() = 0;
200 
201     GLint getBaseLevelDepth() const;
202 
203     RendererD3D *mRenderer;
204 
205     bool mDirtyImages;
206 
207     bool mImmutable;
208     TextureStorage *mTexStorage;
209     angle::ObserverBinding mTexStorageObserverBinding;
210 
211   private:
212     virtual angle::Result initializeStorage(const gl::Context *context, BindFlags bindFlags) = 0;
213 
214     virtual angle::Result updateStorage(const gl::Context *context) = 0;
215 
216     bool shouldUseSetData(const ImageD3D *image) const;
217 
218     angle::Result generateMipmapUsingImages(const gl::Context *context, const GLuint maxLevel);
219 
220     GLuint mBaseLevel;
221 };
222 
223 class TextureD3D_2D : public TextureD3D
224 {
225   public:
226     TextureD3D_2D(const gl::TextureState &data, RendererD3D *renderer);
227     ~TextureD3D_2D() override;
228 
229     void onDestroy(const gl::Context *context) override;
230 
231     ImageD3D *getImage(int level, int layer) const;
232     ImageD3D *getImage(const gl::ImageIndex &index) const override;
233     GLsizei getLayerCount(int level) const override;
234 
235     GLsizei getWidth(GLint level) const;
236     GLsizei getHeight(GLint level) const;
237     GLenum getInternalFormat(GLint level) const;
238     bool isDepth(GLint level) const;
239     bool isSRGB(GLint level) const;
240 
241     angle::Result setImage(const gl::Context *context,
242                            const gl::ImageIndex &index,
243                            GLenum internalFormat,
244                            const gl::Extents &size,
245                            GLenum format,
246                            GLenum type,
247                            const gl::PixelUnpackState &unpack,
248                            gl::Buffer *unpackBuffer,
249                            const uint8_t *pixels) override;
250     angle::Result setSubImage(const gl::Context *context,
251                               const gl::ImageIndex &index,
252                               const gl::Box &area,
253                               GLenum format,
254                               GLenum type,
255                               const gl::PixelUnpackState &unpack,
256                               gl::Buffer *unpackBuffer,
257                               const uint8_t *pixels) override;
258 
259     angle::Result setCompressedImage(const gl::Context *context,
260                                      const gl::ImageIndex &index,
261                                      GLenum internalFormat,
262                                      const gl::Extents &size,
263                                      const gl::PixelUnpackState &unpack,
264                                      size_t imageSize,
265                                      const uint8_t *pixels) override;
266     angle::Result setCompressedSubImage(const gl::Context *context,
267                                         const gl::ImageIndex &index,
268                                         const gl::Box &area,
269                                         GLenum format,
270                                         const gl::PixelUnpackState &unpack,
271                                         size_t imageSize,
272                                         const uint8_t *pixels) override;
273 
274     angle::Result copyImage(const gl::Context *context,
275                             const gl::ImageIndex &index,
276                             const gl::Rectangle &sourceArea,
277                             GLenum internalFormat,
278                             gl::Framebuffer *source) override;
279     angle::Result copySubImage(const gl::Context *context,
280                                const gl::ImageIndex &index,
281                                const gl::Offset &destOffset,
282                                const gl::Rectangle &sourceArea,
283                                gl::Framebuffer *source) override;
284 
285     angle::Result copyTexture(const gl::Context *context,
286                               const gl::ImageIndex &index,
287                               GLenum internalFormat,
288                               GLenum type,
289                               GLint sourceLevel,
290                               bool unpackFlipY,
291                               bool unpackPremultiplyAlpha,
292                               bool unpackUnmultiplyAlpha,
293                               const gl::Texture *source) override;
294     angle::Result copySubTexture(const gl::Context *context,
295                                  const gl::ImageIndex &index,
296                                  const gl::Offset &destOffset,
297                                  GLint sourceLevel,
298                                  const gl::Box &sourceBox,
299                                  bool unpackFlipY,
300                                  bool unpackPremultiplyAlpha,
301                                  bool unpackUnmultiplyAlpha,
302                                  const gl::Texture *source) override;
303     angle::Result copyCompressedTexture(const gl::Context *context,
304                                         const gl::Texture *source) override;
305 
306     angle::Result setStorage(const gl::Context *context,
307                              gl::TextureType type,
308                              size_t levels,
309                              GLenum internalFormat,
310                              const gl::Extents &size) override;
311 
312     angle::Result bindTexImage(const gl::Context *context, egl::Surface *surface) override;
313     angle::Result releaseTexImage(const gl::Context *context) override;
314 
315     angle::Result setEGLImageTarget(const gl::Context *context,
316                                     gl::TextureType type,
317                                     egl::Image *image) override;
318 
319     angle::Result getRenderTarget(const gl::Context *context,
320                                   const gl::ImageIndex &index,
321                                   GLsizei samples,
322                                   RenderTargetD3D **outRT) override;
323 
324     gl::ImageIndexIterator imageIterator() const override;
325     gl::ImageIndex getImageIndex(GLint mip, GLint layer) const override;
326     bool isValidIndex(const gl::ImageIndex &index) const override;
327 
328   protected:
329     void markAllImagesDirty() override;
330 
331   private:
332     angle::Result initializeStorage(const gl::Context *context, BindFlags bindFlags) override;
333     angle::Result createCompleteStorage(const gl::Context *context,
334                                         BindFlags bindFlags,
335                                         TexStoragePointer *outTexStorage) const override;
336     angle::Result setCompleteTexStorage(const gl::Context *context,
337                                         TextureStorage *newCompleteTexStorage) override;
338 
339     angle::Result updateStorage(const gl::Context *context) override;
340     angle::Result initMipmapImages(const gl::Context *context) override;
341 
342     bool isValidLevel(int level) const;
343     bool isLevelComplete(int level) const;
344     bool isImageComplete(const gl::ImageIndex &index) const override;
345 
346     angle::Result updateStorageLevel(const gl::Context *context, int level);
347 
348     angle::Result redefineImage(const gl::Context *context,
349                                 size_t level,
350                                 GLenum internalformat,
351                                 const gl::Extents &size,
352                                 bool forceRelease);
353 
354     bool mEGLImageTarget;
355     gl::TexLevelArray<std::unique_ptr<ImageD3D>> mImageArray;
356 };
357 
358 class TextureD3D_Cube : public TextureD3D
359 {
360   public:
361     TextureD3D_Cube(const gl::TextureState &data, RendererD3D *renderer);
362     ~TextureD3D_Cube() override;
363 
364     void onDestroy(const gl::Context *context) override;
365 
366     ImageD3D *getImage(int level, int layer) const;
367     ImageD3D *getImage(const gl::ImageIndex &index) const override;
368     GLsizei getLayerCount(int level) const override;
369 
370     GLenum getInternalFormat(GLint level, GLint layer) const;
371     bool isDepth(GLint level, GLint layer) const;
372     bool isSRGB(GLint level, GLint layer) const;
373 
374     angle::Result setImage(const gl::Context *context,
375                            const gl::ImageIndex &index,
376                            GLenum internalFormat,
377                            const gl::Extents &size,
378                            GLenum format,
379                            GLenum type,
380                            const gl::PixelUnpackState &unpack,
381                            gl::Buffer *unpackBuffer,
382                            const uint8_t *pixels) override;
383     angle::Result setSubImage(const gl::Context *context,
384                               const gl::ImageIndex &index,
385                               const gl::Box &area,
386                               GLenum format,
387                               GLenum type,
388                               const gl::PixelUnpackState &unpack,
389                               gl::Buffer *unpackBuffer,
390                               const uint8_t *pixels) override;
391 
392     angle::Result setCompressedImage(const gl::Context *context,
393                                      const gl::ImageIndex &index,
394                                      GLenum internalFormat,
395                                      const gl::Extents &size,
396                                      const gl::PixelUnpackState &unpack,
397                                      size_t imageSize,
398                                      const uint8_t *pixels) override;
399     angle::Result setCompressedSubImage(const gl::Context *context,
400                                         const gl::ImageIndex &index,
401                                         const gl::Box &area,
402                                         GLenum format,
403                                         const gl::PixelUnpackState &unpack,
404                                         size_t imageSize,
405                                         const uint8_t *pixels) override;
406 
407     angle::Result copyImage(const gl::Context *context,
408                             const gl::ImageIndex &index,
409                             const gl::Rectangle &sourceArea,
410                             GLenum internalFormat,
411                             gl::Framebuffer *source) override;
412     angle::Result copySubImage(const gl::Context *context,
413                                const gl::ImageIndex &index,
414                                const gl::Offset &destOffset,
415                                const gl::Rectangle &sourceArea,
416                                gl::Framebuffer *source) override;
417 
418     angle::Result copyTexture(const gl::Context *context,
419                               const gl::ImageIndex &index,
420                               GLenum internalFormat,
421                               GLenum type,
422                               GLint sourceLevel,
423                               bool unpackFlipY,
424                               bool unpackPremultiplyAlpha,
425                               bool unpackUnmultiplyAlpha,
426                               const gl::Texture *source) override;
427     angle::Result copySubTexture(const gl::Context *context,
428                                  const gl::ImageIndex &index,
429                                  const gl::Offset &destOffset,
430                                  GLint sourceLevel,
431                                  const gl::Box &sourceBox,
432                                  bool unpackFlipY,
433                                  bool unpackPremultiplyAlpha,
434                                  bool unpackUnmultiplyAlpha,
435                                  const gl::Texture *source) override;
436 
437     angle::Result setStorage(const gl::Context *context,
438                              gl::TextureType type,
439                              size_t levels,
440                              GLenum internalFormat,
441                              const gl::Extents &size) override;
442 
443     angle::Result bindTexImage(const gl::Context *context, egl::Surface *surface) override;
444     angle::Result releaseTexImage(const gl::Context *context) override;
445 
446     angle::Result setEGLImageTarget(const gl::Context *context,
447                                     gl::TextureType type,
448                                     egl::Image *image) override;
449 
450     angle::Result getRenderTarget(const gl::Context *context,
451                                   const gl::ImageIndex &index,
452                                   GLsizei samples,
453                                   RenderTargetD3D **outRT) override;
454 
455     gl::ImageIndexIterator imageIterator() const override;
456     gl::ImageIndex getImageIndex(GLint mip, GLint layer) const override;
457     bool isValidIndex(const gl::ImageIndex &index) const override;
458 
459   protected:
460     void markAllImagesDirty() override;
461 
462   private:
463     angle::Result initializeStorage(const gl::Context *context, BindFlags bindFlags) override;
464     angle::Result createCompleteStorage(const gl::Context *context,
465                                         BindFlags bindFlags,
466                                         TexStoragePointer *outTexStorage) const override;
467     angle::Result setCompleteTexStorage(const gl::Context *context,
468                                         TextureStorage *newCompleteTexStorage) override;
469 
470     angle::Result updateStorage(const gl::Context *context) override;
471     angle::Result initMipmapImages(const gl::Context *context) override;
472 
473     bool isValidFaceLevel(int faceIndex, int level) const;
474     bool isFaceLevelComplete(int faceIndex, int level) const;
475     bool isCubeComplete() const;
476     bool isImageComplete(const gl::ImageIndex &index) const override;
477     angle::Result updateStorageFaceLevel(const gl::Context *context, int faceIndex, int level);
478 
479     angle::Result redefineImage(const gl::Context *context,
480                                 int faceIndex,
481                                 GLint level,
482                                 GLenum internalformat,
483                                 const gl::Extents &size,
484                                 bool forceRelease);
485 
486     std::array<gl::TexLevelArray<std::unique_ptr<ImageD3D>>, 6> mImageArray;
487 };
488 
489 class TextureD3D_3D : public TextureD3D
490 {
491   public:
492     TextureD3D_3D(const gl::TextureState &data, RendererD3D *renderer);
493     ~TextureD3D_3D() override;
494 
495     void onDestroy(const gl::Context *context) override;
496 
497     ImageD3D *getImage(int level, int layer) const;
498     ImageD3D *getImage(const gl::ImageIndex &index) const override;
499     GLsizei getLayerCount(int level) const override;
500 
501     GLsizei getWidth(GLint level) const;
502     GLsizei getHeight(GLint level) const;
503     GLsizei getDepth(GLint level) const;
504     GLenum getInternalFormat(GLint level) const;
505     bool isDepth(GLint level) const;
506     bool isSRGB(GLint level) const;
507 
508     angle::Result setImage(const gl::Context *context,
509                            const gl::ImageIndex &index,
510                            GLenum internalFormat,
511                            const gl::Extents &size,
512                            GLenum format,
513                            GLenum type,
514                            const gl::PixelUnpackState &unpack,
515                            gl::Buffer *unpackBuffer,
516                            const uint8_t *pixels) override;
517     angle::Result setSubImage(const gl::Context *context,
518                               const gl::ImageIndex &index,
519                               const gl::Box &area,
520                               GLenum format,
521                               GLenum type,
522                               const gl::PixelUnpackState &unpack,
523                               gl::Buffer *unpackBuffer,
524                               const uint8_t *pixels) override;
525 
526     angle::Result setCompressedImage(const gl::Context *context,
527                                      const gl::ImageIndex &index,
528                                      GLenum internalFormat,
529                                      const gl::Extents &size,
530                                      const gl::PixelUnpackState &unpack,
531                                      size_t imageSize,
532                                      const uint8_t *pixels) override;
533     angle::Result setCompressedSubImage(const gl::Context *context,
534                                         const gl::ImageIndex &index,
535                                         const gl::Box &area,
536                                         GLenum format,
537                                         const gl::PixelUnpackState &unpack,
538                                         size_t imageSize,
539                                         const uint8_t *pixels) override;
540 
541     angle::Result copyImage(const gl::Context *context,
542                             const gl::ImageIndex &index,
543                             const gl::Rectangle &sourceArea,
544                             GLenum internalFormat,
545                             gl::Framebuffer *source) override;
546     angle::Result copySubImage(const gl::Context *context,
547                                const gl::ImageIndex &index,
548                                const gl::Offset &destOffset,
549                                const gl::Rectangle &sourceArea,
550                                gl::Framebuffer *source) override;
551 
552     angle::Result copyTexture(const gl::Context *context,
553                               const gl::ImageIndex &index,
554                               GLenum internalFormat,
555                               GLenum type,
556                               GLint sourceLevel,
557                               bool unpackFlipY,
558                               bool unpackPremultiplyAlpha,
559                               bool unpackUnmultiplyAlpha,
560                               const gl::Texture *source) override;
561     angle::Result copySubTexture(const gl::Context *context,
562                                  const gl::ImageIndex &index,
563                                  const gl::Offset &destOffset,
564                                  GLint sourceLevel,
565                                  const gl::Box &sourceBox,
566                                  bool unpackFlipY,
567                                  bool unpackPremultiplyAlpha,
568                                  bool unpackUnmultiplyAlpha,
569                                  const gl::Texture *source) override;
570 
571     angle::Result setStorage(const gl::Context *context,
572                              gl::TextureType type,
573                              size_t levels,
574                              GLenum internalFormat,
575                              const gl::Extents &size) override;
576 
577     angle::Result bindTexImage(const gl::Context *context, egl::Surface *surface) override;
578     angle::Result releaseTexImage(const gl::Context *context) override;
579 
580     angle::Result setEGLImageTarget(const gl::Context *context,
581                                     gl::TextureType type,
582                                     egl::Image *image) override;
583 
584     angle::Result getRenderTarget(const gl::Context *context,
585                                   const gl::ImageIndex &index,
586                                   GLsizei samples,
587                                   RenderTargetD3D **outRT) override;
588 
589     gl::ImageIndexIterator imageIterator() const override;
590     gl::ImageIndex getImageIndex(GLint mip, GLint layer) const override;
591     bool isValidIndex(const gl::ImageIndex &index) const override;
592 
593   protected:
594     void markAllImagesDirty() override;
595     GLint getLevelZeroDepth() const override;
596 
597   private:
598     angle::Result initializeStorage(const gl::Context *context, BindFlags bindFlags) override;
599     angle::Result createCompleteStorage(const gl::Context *context,
600                                         BindFlags bindFlags,
601                                         TexStoragePointer *outStorage) const override;
602     angle::Result setCompleteTexStorage(const gl::Context *context,
603                                         TextureStorage *newCompleteTexStorage) override;
604 
605     angle::Result updateStorage(const gl::Context *context) override;
606     angle::Result initMipmapImages(const gl::Context *context) override;
607 
608     bool isValidLevel(int level) const;
609     bool isLevelComplete(int level) const;
610     bool isImageComplete(const gl::ImageIndex &index) const override;
611     angle::Result updateStorageLevel(const gl::Context *context, int level);
612 
613     angle::Result redefineImage(const gl::Context *context,
614                                 GLint level,
615                                 GLenum internalformat,
616                                 const gl::Extents &size,
617                                 bool forceRelease);
618 
619     gl::TexLevelArray<std::unique_ptr<ImageD3D>> mImageArray;
620 };
621 
622 class TextureD3D_2DArray : public TextureD3D
623 {
624   public:
625     TextureD3D_2DArray(const gl::TextureState &data, RendererD3D *renderer);
626     ~TextureD3D_2DArray() override;
627 
628     void onDestroy(const gl::Context *context) override;
629 
630     virtual ImageD3D *getImage(int level, int layer) const;
631     ImageD3D *getImage(const gl::ImageIndex &index) const override;
632     GLsizei getLayerCount(int level) const override;
633 
634     GLsizei getWidth(GLint level) const;
635     GLsizei getHeight(GLint level) const;
636     GLenum getInternalFormat(GLint level) const;
637     bool isDepth(GLint level) const;
638 
639     angle::Result setImage(const gl::Context *context,
640                            const gl::ImageIndex &index,
641                            GLenum internalFormat,
642                            const gl::Extents &size,
643                            GLenum format,
644                            GLenum type,
645                            const gl::PixelUnpackState &unpack,
646                            gl::Buffer *unpackBuffer,
647                            const uint8_t *pixels) override;
648     angle::Result setSubImage(const gl::Context *context,
649                               const gl::ImageIndex &index,
650                               const gl::Box &area,
651                               GLenum format,
652                               GLenum type,
653                               const gl::PixelUnpackState &unpack,
654                               gl::Buffer *unpackBuffer,
655                               const uint8_t *pixels) override;
656 
657     angle::Result setCompressedImage(const gl::Context *context,
658                                      const gl::ImageIndex &index,
659                                      GLenum internalFormat,
660                                      const gl::Extents &size,
661                                      const gl::PixelUnpackState &unpack,
662                                      size_t imageSize,
663                                      const uint8_t *pixels) override;
664     angle::Result setCompressedSubImage(const gl::Context *context,
665                                         const gl::ImageIndex &index,
666                                         const gl::Box &area,
667                                         GLenum format,
668                                         const gl::PixelUnpackState &unpack,
669                                         size_t imageSize,
670                                         const uint8_t *pixels) override;
671 
672     angle::Result copyImage(const gl::Context *context,
673                             const gl::ImageIndex &index,
674                             const gl::Rectangle &sourceArea,
675                             GLenum internalFormat,
676                             gl::Framebuffer *source) override;
677     angle::Result copySubImage(const gl::Context *context,
678                                const gl::ImageIndex &index,
679                                const gl::Offset &destOffset,
680                                const gl::Rectangle &sourceArea,
681                                gl::Framebuffer *source) override;
682 
683     angle::Result copyTexture(const gl::Context *context,
684                               const gl::ImageIndex &index,
685                               GLenum internalFormat,
686                               GLenum type,
687                               GLint sourceLevel,
688                               bool unpackFlipY,
689                               bool unpackPremultiplyAlpha,
690                               bool unpackUnmultiplyAlpha,
691                               const gl::Texture *source) override;
692     angle::Result copySubTexture(const gl::Context *context,
693                                  const gl::ImageIndex &index,
694                                  const gl::Offset &destOffset,
695                                  GLint sourceLevel,
696                                  const gl::Box &sourceBox,
697                                  bool unpackFlipY,
698                                  bool unpackPremultiplyAlpha,
699                                  bool unpackUnmultiplyAlpha,
700                                  const gl::Texture *source) override;
701 
702     angle::Result setStorage(const gl::Context *context,
703                              gl::TextureType type,
704                              size_t levels,
705                              GLenum internalFormat,
706                              const gl::Extents &size) override;
707 
708     angle::Result bindTexImage(const gl::Context *context, egl::Surface *surface) override;
709     angle::Result releaseTexImage(const gl::Context *context) override;
710 
711     angle::Result setEGLImageTarget(const gl::Context *context,
712                                     gl::TextureType type,
713                                     egl::Image *image) override;
714 
715     angle::Result getRenderTarget(const gl::Context *context,
716                                   const gl::ImageIndex &index,
717                                   GLsizei samples,
718                                   RenderTargetD3D **outRT) override;
719 
720     gl::ImageIndexIterator imageIterator() const override;
721     gl::ImageIndex getImageIndex(GLint mip, GLint layer) const override;
722     bool isValidIndex(const gl::ImageIndex &index) const override;
723 
724   protected:
725     void markAllImagesDirty() override;
726 
727   private:
728     angle::Result initializeStorage(const gl::Context *context, BindFlags bindFlags) override;
729     angle::Result createCompleteStorage(const gl::Context *context,
730                                         BindFlags bindFlags,
731                                         TexStoragePointer *outStorage) const override;
732     angle::Result setCompleteTexStorage(const gl::Context *context,
733                                         TextureStorage *newCompleteTexStorage) override;
734 
735     angle::Result updateStorage(const gl::Context *context) override;
736     angle::Result initMipmapImages(const gl::Context *context) override;
737 
738     bool isValidLevel(int level) const;
739     bool isLevelComplete(int level) const;
740     bool isImageComplete(const gl::ImageIndex &index) const override;
741     bool isSRGB(GLint level) const;
742     angle::Result updateStorageLevel(const gl::Context *context, int level);
743 
744     void deleteImages();
745     angle::Result redefineImage(const gl::Context *context,
746                                 GLint level,
747                                 GLenum internalformat,
748                                 const gl::Extents &size,
749                                 bool forceRelease);
750 
751     // Storing images as an array of single depth textures since D3D11 treats each array level of a
752     // Texture2D object as a separate subresource.  Each layer would have to be looped over
753     // to update all the texture layers since they cannot all be updated at once and it makes the
754     // most sense for the Image class to not have to worry about layer subresource as well as mip
755     // subresources.
756     GLsizei mLayerCounts[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
757     ImageD3D **mImageArray[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
758 };
759 
760 // Base class for immutable textures. These don't support manipulation of individual texture images.
761 class TextureD3DImmutableBase : public TextureD3D
762 {
763   public:
764     TextureD3DImmutableBase(const gl::TextureState &data, RendererD3D *renderer);
765     ~TextureD3DImmutableBase() override;
766 
767     ImageD3D *getImage(const gl::ImageIndex &index) const override;
768     angle::Result setImage(const gl::Context *context,
769                            const gl::ImageIndex &index,
770                            GLenum internalFormat,
771                            const gl::Extents &size,
772                            GLenum format,
773                            GLenum type,
774                            const gl::PixelUnpackState &unpack,
775                            gl::Buffer *unpackBuffer,
776                            const uint8_t *pixels) override;
777     angle::Result setSubImage(const gl::Context *context,
778                               const gl::ImageIndex &index,
779                               const gl::Box &area,
780                               GLenum format,
781                               GLenum type,
782                               const gl::PixelUnpackState &unpack,
783                               gl::Buffer *unpackBuffer,
784                               const uint8_t *pixels) override;
785 
786     angle::Result setCompressedImage(const gl::Context *context,
787                                      const gl::ImageIndex &index,
788                                      GLenum internalFormat,
789                                      const gl::Extents &size,
790                                      const gl::PixelUnpackState &unpack,
791                                      size_t imageSize,
792                                      const uint8_t *pixels) override;
793     angle::Result setCompressedSubImage(const gl::Context *context,
794                                         const gl::ImageIndex &index,
795                                         const gl::Box &area,
796                                         GLenum format,
797                                         const gl::PixelUnpackState &unpack,
798                                         size_t imageSize,
799                                         const uint8_t *pixels) override;
800 
801     angle::Result copyImage(const gl::Context *context,
802                             const gl::ImageIndex &index,
803                             const gl::Rectangle &sourceArea,
804                             GLenum internalFormat,
805                             gl::Framebuffer *source) override;
806     angle::Result copySubImage(const gl::Context *context,
807                                const gl::ImageIndex &index,
808                                const gl::Offset &destOffset,
809                                const gl::Rectangle &sourceArea,
810                                gl::Framebuffer *source) override;
811 
812     angle::Result bindTexImage(const gl::Context *context, egl::Surface *surface) override;
813     angle::Result releaseTexImage(const gl::Context *context) override;
814 };
815 
816 class TextureD3D_External : public TextureD3DImmutableBase
817 {
818   public:
819     TextureD3D_External(const gl::TextureState &data, RendererD3D *renderer);
820     ~TextureD3D_External() override;
821 
822     GLsizei getLayerCount(int level) const override;
823 
824     angle::Result setImageExternal(const gl::Context *context,
825                                    gl::TextureType type,
826                                    egl::Stream *stream,
827                                    const egl::Stream::GLTextureDescription &desc) override;
828 
829     angle::Result setEGLImageTarget(const gl::Context *context,
830                                     gl::TextureType type,
831                                     egl::Image *image) override;
832 
833     angle::Result getRenderTarget(const gl::Context *context,
834                                   const gl::ImageIndex &index,
835                                   GLsizei samples,
836                                   RenderTargetD3D **outRT) override;
837 
838     gl::ImageIndexIterator imageIterator() const override;
839     gl::ImageIndex getImageIndex(GLint mip, GLint layer) const override;
840     bool isValidIndex(const gl::ImageIndex &index) const override;
841 
842   protected:
843     void markAllImagesDirty() override;
844 
845   private:
846     angle::Result initializeStorage(const gl::Context *context, BindFlags bindFlags) override;
847     angle::Result createCompleteStorage(const gl::Context *context,
848                                         BindFlags bindFlags,
849                                         TexStoragePointer *outTexStorage) const override;
850     angle::Result setCompleteTexStorage(const gl::Context *context,
851                                         TextureStorage *newCompleteTexStorage) override;
852 
853     angle::Result updateStorage(const gl::Context *context) override;
854     angle::Result initMipmapImages(const gl::Context *context) override;
855 
856     bool isImageComplete(const gl::ImageIndex &index) const override;
857 };
858 
859 class TextureD3D_2DMultisample : public TextureD3DImmutableBase
860 {
861   public:
862     TextureD3D_2DMultisample(const gl::TextureState &data, RendererD3D *renderer);
863     ~TextureD3D_2DMultisample() override;
864 
865     angle::Result setStorageMultisample(const gl::Context *context,
866                                         gl::TextureType type,
867                                         GLsizei samples,
868                                         GLint internalformat,
869                                         const gl::Extents &size,
870                                         bool fixedSampleLocations) override;
871 
872     angle::Result setEGLImageTarget(const gl::Context *context,
873                                     gl::TextureType type,
874                                     egl::Image *image) override;
875 
876     angle::Result getRenderTarget(const gl::Context *context,
877                                   const gl::ImageIndex &index,
878                                   GLsizei samples,
879                                   RenderTargetD3D **outRT) override;
880 
881     gl::ImageIndexIterator imageIterator() const override;
882     gl::ImageIndex getImageIndex(GLint mip, GLint layer) const override;
883     bool isValidIndex(const gl::ImageIndex &index) const override;
884 
885     GLsizei getLayerCount(int level) const override;
886 
887   protected:
888     void markAllImagesDirty() override;
889 
890     angle::Result setCompleteTexStorage(const gl::Context *context,
891                                         TextureStorage *newCompleteTexStorage) override;
892 
893     angle::Result updateStorage(const gl::Context *context) override;
894 
895   private:
896     angle::Result initializeStorage(const gl::Context *context, BindFlags bindFlags) override;
897     angle::Result createCompleteStorage(const gl::Context *context,
898                                         BindFlags bindFlags,
899                                         TexStoragePointer *outTexStorage) const override;
900     angle::Result initMipmapImages(const gl::Context *context) override;
901 
902     bool isImageComplete(const gl::ImageIndex &index) const override;
903 };
904 
905 class TextureD3D_2DMultisampleArray : public TextureD3DImmutableBase
906 {
907   public:
908     TextureD3D_2DMultisampleArray(const gl::TextureState &data, RendererD3D *renderer);
909     ~TextureD3D_2DMultisampleArray() override;
910 
911     angle::Result setStorageMultisample(const gl::Context *context,
912                                         gl::TextureType type,
913                                         GLsizei samples,
914                                         GLint internalformat,
915                                         const gl::Extents &size,
916                                         bool fixedSampleLocations) override;
917 
918     angle::Result setEGLImageTarget(const gl::Context *context,
919                                     gl::TextureType type,
920                                     egl::Image *image) override;
921 
922     angle::Result getRenderTarget(const gl::Context *context,
923                                   const gl::ImageIndex &index,
924                                   GLsizei samples,
925                                   RenderTargetD3D **outRT) override;
926 
927     gl::ImageIndexIterator imageIterator() const override;
928     gl::ImageIndex getImageIndex(GLint mip, GLint layer) const override;
929     bool isValidIndex(const gl::ImageIndex &index) const override;
930 
931     GLsizei getLayerCount(int level) const override;
932 
933   protected:
934     void markAllImagesDirty() override;
935 
936     angle::Result setCompleteTexStorage(const gl::Context *context,
937                                         TextureStorage *newCompleteTexStorage) override;
938 
939     angle::Result updateStorage(const gl::Context *context) override;
940 
941   private:
942     angle::Result initializeStorage(const gl::Context *context, BindFlags bindFlags) override;
943     angle::Result createCompleteStorage(const gl::Context *context,
944                                         BindFlags bindFlags,
945                                         TexStoragePointer *outTexStorage) const override;
946     angle::Result initMipmapImages(const gl::Context *context) override;
947 
948     bool isImageComplete(const gl::ImageIndex &index) const override;
949 
950     GLsizei mLayerCount;
951 };
952 
953 class TextureD3D_Buffer : public TextureD3D
954 {
955   public:
956     TextureD3D_Buffer(const gl::TextureState &data, RendererD3D *renderer);
957     ~TextureD3D_Buffer() override;
958 
959     ImageD3D *getImage(const gl::ImageIndex &index) const override;
960 
961     angle::Result setBuffer(const gl::Context *context, GLenum internalFormat) override;
962 
963     angle::Result setImage(const gl::Context *context,
964                            const gl::ImageIndex &index,
965                            GLenum internalFormat,
966                            const gl::Extents &size,
967                            GLenum format,
968                            GLenum type,
969                            const gl::PixelUnpackState &unpack,
970                            gl::Buffer *unpackBuffer,
971                            const uint8_t *pixels) override;
972     angle::Result setSubImage(const gl::Context *context,
973                               const gl::ImageIndex &index,
974                               const gl::Box &area,
975                               GLenum format,
976                               GLenum type,
977                               const gl::PixelUnpackState &unpack,
978                               gl::Buffer *unpackBuffer,
979                               const uint8_t *pixels) override;
980 
981     angle::Result setCompressedImage(const gl::Context *context,
982                                      const gl::ImageIndex &index,
983                                      GLenum internalFormat,
984                                      const gl::Extents &size,
985                                      const gl::PixelUnpackState &unpack,
986                                      size_t imageSize,
987                                      const uint8_t *pixels) override;
988     angle::Result setCompressedSubImage(const gl::Context *context,
989                                         const gl::ImageIndex &index,
990                                         const gl::Box &area,
991                                         GLenum format,
992                                         const gl::PixelUnpackState &unpack,
993                                         size_t imageSize,
994                                         const uint8_t *pixels) override;
995 
996     angle::Result copyImage(const gl::Context *context,
997                             const gl::ImageIndex &index,
998                             const gl::Rectangle &sourceArea,
999                             GLenum internalFormat,
1000                             gl::Framebuffer *source) override;
1001     angle::Result copySubImage(const gl::Context *context,
1002                                const gl::ImageIndex &index,
1003                                const gl::Offset &destOffset,
1004                                const gl::Rectangle &sourceArea,
1005                                gl::Framebuffer *source) override;
1006 
1007     angle::Result bindTexImage(const gl::Context *context, egl::Surface *surface) override;
1008     angle::Result releaseTexImage(const gl::Context *context) override;
1009 
1010     angle::Result setEGLImageTarget(const gl::Context *context,
1011                                     gl::TextureType type,
1012                                     egl::Image *image) override;
1013 
1014     angle::Result getRenderTarget(const gl::Context *context,
1015                                   const gl::ImageIndex &index,
1016                                   GLsizei samples,
1017                                   RenderTargetD3D **outRT) override;
1018 
1019     GLsizei getLayerCount(int level) const override;
1020 
1021     angle::Result syncState(const gl::Context *context,
1022                             const gl::Texture::DirtyBits &dirtyBits,
1023                             gl::Command source) override;
1024 
1025     gl::ImageIndexIterator imageIterator() const override;
1026     gl::ImageIndex getImageIndex(GLint mip, GLint layer) const override;
1027     bool isValidIndex(const gl::ImageIndex &index) const override;
1028 
1029   protected:
1030     void markAllImagesDirty() override;
1031 
1032   private:
1033     angle::Result initializeStorage(const gl::Context *context, BindFlags bindFlags) override;
1034     angle::Result createCompleteStorage(const gl::Context *context,
1035                                         BindFlags bindFlags,
1036                                         TexStoragePointer *outTexStorage) const override;
1037     angle::Result setCompleteTexStorage(const gl::Context *context,
1038                                         TextureStorage *newCompleteTexStorage) override;
1039 
1040     angle::Result updateStorage(const gl::Context *context) override;
1041     angle::Result initMipmapImages(const gl::Context *context) override;
1042 
1043     bool isImageComplete(const gl::ImageIndex &index) const override;
1044 
1045     GLenum mInternalFormat;
1046 };
1047 }  // namespace rx
1048 
1049 #endif  // LIBANGLE_RENDERER_D3D_TEXTURED3D_H_
1050