2 // Copyright (c) 2002-2013 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.
7 // Texture.h: Defines the abstract gl::Texture class and its concrete derived
8 // classes Texture2D and TextureCubeMap. Implements GL texture objects and
9 // related functionality. [OpenGL ES 2.0.24] section 3.7 page 63.
11 #ifndef LIBGLESV2_TEXTURE_H_
12 #define LIBGLESV2_TEXTURE_H_
16 #include <GLES3/gl3.h>
17 #include <GLES2/gl2.h>
19 #include "common/debug.h"
20 #include "common/RefCountObject.h"
21 #include "libGLESv2/angletypes.h"
22 #include "libGLESv2/RenderbufferProxySet.h"
32 class TextureStorageInterface;
33 class TextureStorageInterface2D;
34 class TextureStorageInterfaceCube;
35 class TextureStorageInterface3D;
36 class TextureStorageInterface2DArray;
44 class FramebufferAttachment;
48 // These are the maximums the implementation can support
49 // The actual GL caps are limited by the device caps
50 // and should be queried from the Context
51 IMPLEMENTATION_MAX_2D_TEXTURE_SIZE = 16384,
52 IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE = 16384,
53 IMPLEMENTATION_MAX_3D_TEXTURE_SIZE = 2048,
54 IMPLEMENTATION_MAX_2D_ARRAY_TEXTURE_LAYERS = 2048,
56 IMPLEMENTATION_MAX_TEXTURE_LEVELS = 15 // 1+log2 of MAX_TEXTURE_SIZE
59 bool IsMipmapFiltered(const SamplerState &samplerState);
61 class Texture : public RefCountObject
64 Texture(rx::Renderer *renderer, GLuint id, GLenum target);
68 void addProxyRef(const FramebufferAttachment *proxy);
69 void releaseProxy(const FramebufferAttachment *proxy);
71 GLenum getTarget() const;
73 void setMinFilter(GLenum filter);
74 void setMagFilter(GLenum filter);
75 void setWrapS(GLenum wrap);
76 void setWrapT(GLenum wrap);
77 void setWrapR(GLenum wrap);
78 void setMaxAnisotropy(float textureMaxAnisotropy, float contextMaxAnisotropy);
79 void setCompareMode(GLenum mode);
80 void setCompareFunc(GLenum func);
81 void setSwizzleRed(GLenum swizzle);
82 void setSwizzleGreen(GLenum swizzle);
83 void setSwizzleBlue(GLenum swizzle);
84 void setSwizzleAlpha(GLenum swizzle);
85 void setBaseLevel(GLint baseLevel);
86 void setMaxLevel(GLint maxLevel);
87 void setMinLod(GLfloat minLod);
88 void setMaxLod(GLfloat maxLod);
89 void setUsage(GLenum usage);
91 GLenum getMinFilter() const;
92 GLenum getMagFilter() const;
93 GLenum getWrapS() const;
94 GLenum getWrapT() const;
95 GLenum getWrapR() const;
96 float getMaxAnisotropy() const;
97 GLenum getSwizzleRed() const;
98 GLenum getSwizzleGreen() const;
99 GLenum getSwizzleBlue() const;
100 GLenum getSwizzleAlpha() const;
101 GLint getBaseLevel() const;
102 GLint getMaxLevel() const;
103 GLfloat getMinLod() const;
104 GLfloat getMaxLod() const;
105 bool isSwizzled() const;
106 void getSamplerState(SamplerState *sampler);
107 GLenum getUsage() const;
109 GLint getBaseLevelWidth() const;
110 GLint getBaseLevelHeight() const;
111 GLint getBaseLevelDepth() const;
112 GLenum getBaseLevelInternalFormat() const;
114 virtual bool isSamplerComplete(const SamplerState &samplerState) const = 0;
116 rx::TextureStorageInterface *getNativeTexture();
118 virtual void generateMipmaps() = 0;
119 virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source) = 0;
121 bool hasDirtyParameters() const;
122 bool hasDirtyImages() const;
124 unsigned int getTextureSerial();
126 bool isImmutable() const;
127 int immutableLevelCount();
129 static const GLuint INCOMPLETE_TEXTURE_ID = static_cast<GLuint>(-1); // Every texture takes an id at creation time. The value is arbitrary because it is never registered with the resource manager.
132 void setImage(const PixelUnpackState &unpack, GLenum type, const void *pixels, rx::Image *image);
133 bool subImage(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
134 GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels, rx::Image *image);
135 void setCompressedImage(GLsizei imageSize, const void *pixels, rx::Image *image);
136 bool subImageCompressed(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
137 GLenum format, GLsizei imageSize, const void *pixels, rx::Image *image);
138 bool isFastUnpackable(const PixelUnpackState &unpack, GLenum sizedInternalFormat);
139 bool fastUnpackPixels(const PixelUnpackState &unpack, const void *pixels, const Box &destArea,
140 GLenum sizedInternalFormat, GLenum type, rx::RenderTarget *destRenderTarget);
142 GLint creationLevels(GLsizei width, GLsizei height, GLsizei depth) const;
143 int mipLevels() const;
145 virtual void initializeStorage(bool renderTarget) = 0;
146 virtual void updateStorage() = 0;
147 virtual bool ensureRenderTarget() = 0;
149 rx::Renderer *mRenderer;
151 SamplerState mSamplerState;
160 // A specific internal reference count is kept for colorbuffer proxy references,
161 // because, as the renderbuffer acting as proxy will maintain a binding pointer
162 // back to this texture, there would be a circular reference if we used a binding
163 // pointer here. This reference count will cause the pointer to be set to NULL if
164 // the count drops to zero, but will not cause deletion of the FramebufferAttachment.
165 RenderbufferProxySet mRenderbufferProxies;
168 DISALLOW_COPY_AND_ASSIGN(Texture);
170 virtual rx::TextureStorageInterface *getBaseLevelStorage() = 0;
171 virtual const rx::Image *getBaseLevelImage() const = 0;
174 class Texture2D : public Texture
177 Texture2D(rx::Renderer *renderer, GLuint id);
181 GLsizei getWidth(GLint level) const;
182 GLsizei getHeight(GLint level) const;
183 GLenum getInternalFormat(GLint level) const;
184 GLenum getActualFormat(GLint level) const;
185 bool isCompressed(GLint level) const;
186 bool isDepth(GLint level) const;
188 void setImage(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
189 void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);
190 void subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
191 void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels);
192 void copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
193 virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
194 void storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
196 virtual bool isSamplerComplete(const SamplerState &samplerState) const;
197 virtual void bindTexImage(egl::Surface *surface);
198 virtual void releaseTexImage();
200 virtual void generateMipmaps();
202 FramebufferAttachment *getAttachment(GLint level);
203 unsigned int getRenderTargetSerial(GLint level);
206 friend class Texture2DAttachment;
207 rx::RenderTarget *getRenderTarget(GLint level);
208 rx::RenderTarget *getDepthSencil(GLint level);
211 DISALLOW_COPY_AND_ASSIGN(Texture2D);
213 virtual void initializeStorage(bool renderTarget);
214 rx::TextureStorageInterface2D *createCompleteStorage(bool renderTarget) const;
215 void setCompleteTexStorage(rx::TextureStorageInterface2D *newCompleteTexStorage);
217 virtual void updateStorage();
218 virtual bool ensureRenderTarget();
219 virtual rx::TextureStorageInterface *getBaseLevelStorage();
220 virtual const rx::Image *getBaseLevelImage() const;
222 bool isMipmapComplete() const;
223 bool isValidLevel(int level) const;
224 bool isLevelComplete(int level) const;
225 void updateStorageLevel(int level);
227 void redefineImage(GLint level, GLenum internalformat, GLsizei width, GLsizei height);
228 void commitRect(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
230 rx::Image *mImageArray[IMPLEMENTATION_MAX_TEXTURE_LEVELS];
232 rx::TextureStorageInterface2D *mTexStorage;
233 egl::Surface *mSurface;
236 class TextureCubeMap : public Texture
239 TextureCubeMap(rx::Renderer *renderer, GLuint id);
243 GLsizei getWidth(GLenum target, GLint level) const;
244 GLsizei getHeight(GLenum target, GLint level) const;
245 GLenum getInternalFormat(GLenum target, GLint level) const;
246 GLenum getActualFormat(GLenum target, GLint level) const;
247 bool isCompressed(GLenum target, GLint level) const;
248 bool isDepth(GLenum target, GLint level) const;
250 void setImagePosX(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
251 void setImageNegX(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
252 void setImagePosY(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
253 void setImageNegY(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
254 void setImagePosZ(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
255 void setImageNegZ(GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
257 void setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);
259 void subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
260 void subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels);
261 void copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
262 virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
263 void storage(GLsizei levels, GLenum internalformat, GLsizei size);
265 virtual bool isSamplerComplete(const SamplerState &samplerState) const;
266 bool isCubeComplete() const;
268 virtual void generateMipmaps();
270 FramebufferAttachment *getAttachment(GLenum target, GLint level);
271 unsigned int getRenderTargetSerial(GLenum target, GLint level);
273 static int targetToIndex(GLenum target);
276 friend class TextureCubeMapAttachment;
277 rx::RenderTarget *getRenderTarget(GLenum target, GLint level);
278 rx::RenderTarget *getDepthStencil(GLenum target, GLint level);
281 DISALLOW_COPY_AND_ASSIGN(TextureCubeMap);
283 virtual void initializeStorage(bool renderTarget);
284 rx::TextureStorageInterfaceCube *createCompleteStorage(bool renderTarget) const;
285 void setCompleteTexStorage(rx::TextureStorageInterfaceCube *newCompleteTexStorage);
287 virtual void updateStorage();
288 virtual bool ensureRenderTarget();
289 virtual rx::TextureStorageInterface *getBaseLevelStorage();
290 virtual const rx::Image *getBaseLevelImage() const;
292 bool isMipmapCubeComplete() const;
293 bool isValidFaceLevel(int faceIndex, int level) const;
294 bool isFaceLevelComplete(int faceIndex, int level) const;
295 void updateStorageFaceLevel(int faceIndex, int level);
297 void setImage(int faceIndex, GLint level, GLsizei width, GLsizei height, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
298 void commitRect(int faceIndex, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
299 void redefineImage(int faceIndex, GLint level, GLenum internalformat, GLsizei width, GLsizei height);
301 rx::Image *mImageArray[6][IMPLEMENTATION_MAX_TEXTURE_LEVELS];
303 rx::TextureStorageInterfaceCube *mTexStorage;
306 class Texture3D : public Texture
309 Texture3D(rx::Renderer *renderer, GLuint id);
313 GLsizei getWidth(GLint level) const;
314 GLsizei getHeight(GLint level) const;
315 GLsizei getDepth(GLint level) const;
316 GLenum getInternalFormat(GLint level) const;
317 GLenum getActualFormat(GLint level) const;
318 bool isCompressed(GLint level) const;
319 bool isDepth(GLint level) const;
321 void setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
322 void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels);
323 void subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
324 void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels);
325 void storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
327 virtual void generateMipmaps();
328 virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
330 virtual bool isSamplerComplete(const SamplerState &samplerState) const;
331 virtual bool isMipmapComplete() const;
333 FramebufferAttachment *getAttachment(GLint level, GLint layer);
334 unsigned int getRenderTargetSerial(GLint level, GLint layer);
337 friend class Texture3DAttachment;
338 rx::RenderTarget *getRenderTarget(GLint level);
339 rx::RenderTarget *getRenderTarget(GLint level, GLint layer);
340 rx::RenderTarget *getDepthStencil(GLint level, GLint layer);
343 DISALLOW_COPY_AND_ASSIGN(Texture3D);
345 virtual void initializeStorage(bool renderTarget);
346 rx::TextureStorageInterface3D *createCompleteStorage(bool renderTarget) const;
347 void setCompleteTexStorage(rx::TextureStorageInterface3D *newCompleteTexStorage);
349 virtual void updateStorage();
350 virtual bool ensureRenderTarget();
352 virtual rx::TextureStorageInterface *getBaseLevelStorage();
353 virtual const rx::Image *getBaseLevelImage() const;
355 void redefineImage(GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
356 void commitRect(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth);
358 bool isValidLevel(int level) const;
359 bool isLevelComplete(int level) const;
360 void updateStorageLevel(int level);
362 rx::Image *mImageArray[IMPLEMENTATION_MAX_TEXTURE_LEVELS];
364 rx::TextureStorageInterface3D *mTexStorage;
367 class Texture2DArray : public Texture
370 Texture2DArray(rx::Renderer *renderer, GLuint id);
374 GLsizei getWidth(GLint level) const;
375 GLsizei getHeight(GLint level) const;
376 GLsizei getLayers(GLint level) const;
377 GLenum getInternalFormat(GLint level) const;
378 GLenum getActualFormat(GLint level) const;
379 bool isCompressed(GLint level) const;
380 bool isDepth(GLint level) const;
382 void setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum internalFormat, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
383 void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels);
384 void subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const PixelUnpackState &unpack, const void *pixels);
385 void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels);
386 void storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
388 virtual void generateMipmaps();
389 virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
391 virtual bool isSamplerComplete(const SamplerState &samplerState) const;
392 virtual bool isMipmapComplete() const;
394 FramebufferAttachment *getAttachment(GLint level, GLint layer);
395 unsigned int getRenderTargetSerial(GLint level, GLint layer);
398 friend class Texture2DArrayAttachment;
399 rx::RenderTarget *getRenderTarget(GLint level, GLint layer);
400 rx::RenderTarget *getDepthStencil(GLint level, GLint layer);
403 DISALLOW_COPY_AND_ASSIGN(Texture2DArray);
405 virtual void initializeStorage(bool renderTarget);
406 rx::TextureStorageInterface2DArray *createCompleteStorage(bool renderTarget) const;
407 void setCompleteTexStorage(rx::TextureStorageInterface2DArray *newCompleteTexStorage);
409 virtual void updateStorage();
410 virtual bool ensureRenderTarget();
412 virtual rx::TextureStorageInterface *getBaseLevelStorage();
413 virtual const rx::Image *getBaseLevelImage() const;
416 void redefineImage(GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
417 void commitRect(GLint level, GLint xoffset, GLint yoffset, GLint layerTarget, GLsizei width, GLsizei height);
419 bool isValidLevel(int level) const;
420 bool isLevelComplete(int level) const;
421 void updateStorageLevel(int level);
423 // Storing images as an array of single depth textures since D3D11 treats each array level of a
424 // Texture2D object as a separate subresource. Each layer would have to be looped over
425 // to update all the texture layers since they cannot all be updated at once and it makes the most
426 // sense for the Image class to not have to worry about layer subresource as well as mip subresources.
427 GLsizei mLayerCounts[IMPLEMENTATION_MAX_TEXTURE_LEVELS];
428 rx::Image **mImageArray[IMPLEMENTATION_MAX_TEXTURE_LEVELS];
430 rx::TextureStorageInterface2DArray *mTexStorage;
435 #endif // LIBGLESV2_TEXTURE_H_