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