1 // 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. 5 // 6 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. 10 11 #ifndef LIBGLESV2_TEXTURE_H_ 12 #define LIBGLESV2_TEXTURE_H_ 13 14 #include <vector> 15 16 #include <GLES3/gl3.h> 17 #include <GLES2/gl2.h> 18 19 #include "common/debug.h" 20 #include "common/RefCountObject.h" 21 #include "libGLESv2/angletypes.h" 22 #include "libGLESv2/RenderbufferProxySet.h" 23 24 namespace egl 25 { 26 class Surface; 27 } 28 29 namespace rx 30 { 31 class Renderer; 32 class TextureStorageInterface; 33 class TextureStorageInterface2D; 34 class TextureStorageInterfaceCube; 35 class TextureStorageInterface3D; 36 class TextureStorageInterface2DArray; 37 class RenderTarget; 38 class Image; 39 } 40 41 namespace gl 42 { 43 class Framebuffer; 44 class FramebufferAttachment; 45 46 enum 47 { 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, 55 56 IMPLEMENTATION_MAX_TEXTURE_LEVELS = 15 // 1+log2 of MAX_TEXTURE_SIZE 57 }; 58 59 bool IsMipmapFiltered(const SamplerState &samplerState); 60 61 class Texture : public RefCountObject 62 { 63 public: 64 Texture(rx::Renderer *renderer, GLuint id, GLenum target); 65 66 virtual ~Texture(); 67 68 void addProxyRef(const FramebufferAttachment *proxy); 69 void releaseProxy(const FramebufferAttachment *proxy); 70 71 GLenum getTarget() const; 72 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); 90 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; 108 109 GLint getBaseLevelWidth() const; 110 GLint getBaseLevelHeight() const; 111 GLint getBaseLevelDepth() const; 112 GLenum getBaseLevelInternalFormat() const; 113 114 virtual bool isSamplerComplete(const SamplerState &samplerState) const = 0; 115 116 rx::TextureStorageInterface *getNativeTexture(); 117 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; 120 121 bool hasDirtyParameters() const; 122 bool hasDirtyImages() const; 123 void resetDirty(); 124 unsigned int getTextureSerial(); 125 126 bool isImmutable() const; 127 int immutableLevelCount(); 128 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. 130 131 protected: 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); 141 142 GLint creationLevels(GLsizei width, GLsizei height, GLsizei depth) const; 143 int mipLevels() const; 144 145 virtual void initializeStorage(bool renderTarget) = 0; 146 virtual void updateStorage() = 0; 147 virtual bool ensureRenderTarget() = 0; 148 149 rx::Renderer *mRenderer; 150 151 SamplerState mSamplerState; 152 GLenum mUsage; 153 154 bool mDirtyImages; 155 156 bool mImmutable; 157 158 GLenum mTarget; 159 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; 166 167 private: 168 DISALLOW_COPY_AND_ASSIGN(Texture); 169 170 virtual rx::TextureStorageInterface *getBaseLevelStorage() = 0; 171 virtual const rx::Image *getBaseLevelImage() const = 0; 172 }; 173 174 class Texture2D : public Texture 175 { 176 public: 177 Texture2D(rx::Renderer *renderer, GLuint id); 178 179 ~Texture2D(); 180 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; 187 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); 195 196 virtual bool isSamplerComplete(const SamplerState &samplerState) const; 197 virtual void bindTexImage(egl::Surface *surface); 198 virtual void releaseTexImage(); 199 200 virtual void generateMipmaps(); 201 202 FramebufferAttachment *getAttachment(GLint level); 203 unsigned int getRenderTargetSerial(GLint level); 204 205 protected: 206 friend class Texture2DAttachment; 207 rx::RenderTarget *getRenderTarget(GLint level); 208 rx::RenderTarget *getDepthSencil(GLint level); 209 210 private: 211 DISALLOW_COPY_AND_ASSIGN(Texture2D); 212 213 virtual void initializeStorage(bool renderTarget); 214 rx::TextureStorageInterface2D *createCompleteStorage(bool renderTarget) const; 215 void setCompleteTexStorage(rx::TextureStorageInterface2D *newCompleteTexStorage); 216 217 virtual void updateStorage(); 218 virtual bool ensureRenderTarget(); 219 virtual rx::TextureStorageInterface *getBaseLevelStorage(); 220 virtual const rx::Image *getBaseLevelImage() const; 221 222 bool isMipmapComplete() const; 223 bool isValidLevel(int level) const; 224 bool isLevelComplete(int level) const; 225 void updateStorageLevel(int level); 226 227 void redefineImage(GLint level, GLenum internalformat, GLsizei width, GLsizei height); 228 void commitRect(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height); 229 230 rx::Image *mImageArray[IMPLEMENTATION_MAX_TEXTURE_LEVELS]; 231 232 rx::TextureStorageInterface2D *mTexStorage; 233 egl::Surface *mSurface; 234 }; 235 236 class TextureCubeMap : public Texture 237 { 238 public: 239 TextureCubeMap(rx::Renderer *renderer, GLuint id); 240 241 ~TextureCubeMap(); 242 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; 249 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); 256 257 void setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels); 258 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); 264 265 virtual bool isSamplerComplete(const SamplerState &samplerState) const; 266 bool isCubeComplete() const; 267 268 virtual void generateMipmaps(); 269 270 FramebufferAttachment *getAttachment(GLenum target, GLint level); 271 unsigned int getRenderTargetSerial(GLenum target, GLint level); 272 273 static int targetToIndex(GLenum target); 274 275 protected: 276 friend class TextureCubeMapAttachment; 277 rx::RenderTarget *getRenderTarget(GLenum target, GLint level); 278 rx::RenderTarget *getDepthStencil(GLenum target, GLint level); 279 280 private: 281 DISALLOW_COPY_AND_ASSIGN(TextureCubeMap); 282 283 virtual void initializeStorage(bool renderTarget); 284 rx::TextureStorageInterfaceCube *createCompleteStorage(bool renderTarget) const; 285 void setCompleteTexStorage(rx::TextureStorageInterfaceCube *newCompleteTexStorage); 286 287 virtual void updateStorage(); 288 virtual bool ensureRenderTarget(); 289 virtual rx::TextureStorageInterface *getBaseLevelStorage(); 290 virtual const rx::Image *getBaseLevelImage() const; 291 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); 296 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); 300 301 rx::Image *mImageArray[6][IMPLEMENTATION_MAX_TEXTURE_LEVELS]; 302 303 rx::TextureStorageInterfaceCube *mTexStorage; 304 }; 305 306 class Texture3D : public Texture 307 { 308 public: 309 Texture3D(rx::Renderer *renderer, GLuint id); 310 311 ~Texture3D(); 312 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; 320 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); 326 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); 329 330 virtual bool isSamplerComplete(const SamplerState &samplerState) const; 331 virtual bool isMipmapComplete() const; 332 333 FramebufferAttachment *getAttachment(GLint level, GLint layer); 334 unsigned int getRenderTargetSerial(GLint level, GLint layer); 335 336 protected: 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); 341 342 private: 343 DISALLOW_COPY_AND_ASSIGN(Texture3D); 344 345 virtual void initializeStorage(bool renderTarget); 346 rx::TextureStorageInterface3D *createCompleteStorage(bool renderTarget) const; 347 void setCompleteTexStorage(rx::TextureStorageInterface3D *newCompleteTexStorage); 348 349 virtual void updateStorage(); 350 virtual bool ensureRenderTarget(); 351 352 virtual rx::TextureStorageInterface *getBaseLevelStorage(); 353 virtual const rx::Image *getBaseLevelImage() const; 354 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); 357 358 bool isValidLevel(int level) const; 359 bool isLevelComplete(int level) const; 360 void updateStorageLevel(int level); 361 362 rx::Image *mImageArray[IMPLEMENTATION_MAX_TEXTURE_LEVELS]; 363 364 rx::TextureStorageInterface3D *mTexStorage; 365 }; 366 367 class Texture2DArray : public Texture 368 { 369 public: 370 Texture2DArray(rx::Renderer *renderer, GLuint id); 371 372 ~Texture2DArray(); 373 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; 381 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); 387 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); 390 391 virtual bool isSamplerComplete(const SamplerState &samplerState) const; 392 virtual bool isMipmapComplete() const; 393 394 FramebufferAttachment *getAttachment(GLint level, GLint layer); 395 unsigned int getRenderTargetSerial(GLint level, GLint layer); 396 397 protected: 398 friend class Texture2DArrayAttachment; 399 rx::RenderTarget *getRenderTarget(GLint level, GLint layer); 400 rx::RenderTarget *getDepthStencil(GLint level, GLint layer); 401 402 private: 403 DISALLOW_COPY_AND_ASSIGN(Texture2DArray); 404 405 virtual void initializeStorage(bool renderTarget); 406 rx::TextureStorageInterface2DArray *createCompleteStorage(bool renderTarget) const; 407 void setCompleteTexStorage(rx::TextureStorageInterface2DArray *newCompleteTexStorage); 408 409 virtual void updateStorage(); 410 virtual bool ensureRenderTarget(); 411 412 virtual rx::TextureStorageInterface *getBaseLevelStorage(); 413 virtual const rx::Image *getBaseLevelImage() const; 414 415 void deleteImages(); 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); 418 419 bool isValidLevel(int level) const; 420 bool isLevelComplete(int level) const; 421 void updateStorageLevel(int level); 422 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]; 429 430 rx::TextureStorageInterface2DArray *mTexStorage; 431 }; 432 433 } 434 435 #endif // LIBGLESV2_TEXTURE_H_ 436