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 gl::Texture class [OpenGL ES 2.0.24] section 3.7 page 63. 8 9 #ifndef LIBANGLE_TEXTURE_H_ 10 #define LIBANGLE_TEXTURE_H_ 11 12 #include <vector> 13 #include <map> 14 15 #include "angle_gl.h" 16 #include "common/Optional.h" 17 #include "common/debug.h" 18 #include "libANGLE/Caps.h" 19 #include "libANGLE/Constants.h" 20 #include "libANGLE/Debug.h" 21 #include "libANGLE/Error.h" 22 #include "libANGLE/FramebufferAttachment.h" 23 #include "libANGLE/Image.h" 24 #include "libANGLE/Stream.h" 25 #include "libANGLE/angletypes.h" 26 #include "libANGLE/formatutils.h" 27 28 namespace egl 29 { 30 class Surface; 31 class Stream; 32 } 33 34 namespace rx 35 { 36 class GLImplFactory; 37 class TextureImpl; 38 class TextureGL; 39 } 40 41 namespace gl 42 { 43 class ContextState; 44 class Framebuffer; 45 class Sampler; 46 class Texture; 47 48 bool IsMipmapFiltered(const SamplerState &samplerState); 49 50 struct ImageDesc final 51 { 52 ImageDesc(); 53 ImageDesc(const Extents &size, const Format &format, const InitState initState); 54 ImageDesc(const Extents &size, 55 const Format &format, 56 const GLsizei samples, 57 const bool fixedSampleLocations, 58 const InitState initState); 59 60 ImageDesc(const ImageDesc &other) = default; 61 ImageDesc &operator=(const ImageDesc &other) = default; 62 63 Extents size; 64 Format format; 65 GLsizei samples; 66 bool fixedSampleLocations; 67 68 // Needed for robust resource initialization. 69 InitState initState; 70 }; 71 72 struct SwizzleState final 73 { 74 SwizzleState(); 75 SwizzleState(GLenum red, GLenum green, GLenum blue, GLenum alpha); 76 SwizzleState(const SwizzleState &other) = default; 77 SwizzleState &operator=(const SwizzleState &other) = default; 78 79 bool swizzleRequired() const; 80 81 bool operator==(const SwizzleState &other) const; 82 bool operator!=(const SwizzleState &other) const; 83 84 GLenum swizzleRed; 85 GLenum swizzleGreen; 86 GLenum swizzleBlue; 87 GLenum swizzleAlpha; 88 }; 89 90 // State from Table 6.9 (state per texture object) in the OpenGL ES 3.0.2 spec. 91 struct TextureState final : private angle::NonCopyable 92 { 93 TextureState(GLenum target); 94 ~TextureState(); 95 96 bool swizzleRequired() const; 97 GLuint getEffectiveBaseLevel() const; 98 GLuint getEffectiveMaxLevel() const; 99 100 // Returns the value called "q" in the GLES 3.0.4 spec section 3.8.10. 101 GLuint getMipmapMaxLevel() const; 102 103 // Returns true if base level changed. 104 bool setBaseLevel(GLuint baseLevel); 105 bool setMaxLevel(GLuint maxLevel); 106 107 bool isCubeComplete() const; 108 109 const ImageDesc &getImageDesc(GLenum target, size_t level) const; 110 const ImageDesc &getImageDesc(const ImageIndex &imageIndex) const; 111 getTargetfinal112 GLenum getTarget() const { return mTarget; } getSwizzleStatefinal113 const SwizzleState &getSwizzleState() const { return mSwizzleState; } getSamplerStatefinal114 const SamplerState &getSamplerState() const { return mSamplerState; } getUsagefinal115 GLenum getUsage() const { return mUsage; } 116 117 private: 118 // Texture needs access to the ImageDesc functions. 119 friend class Texture; 120 // TODO(jmadill): Remove TextureGL from friends. 121 friend class rx::TextureGL; 122 friend bool operator==(const TextureState &a, const TextureState &b); 123 124 bool computeSamplerCompleteness(const SamplerState &samplerState, 125 const ContextState &data) const; 126 bool computeMipmapCompleteness() const; 127 bool computeLevelCompleteness(GLenum target, size_t level) const; 128 129 GLenum getBaseImageTarget() const; 130 131 void setImageDesc(GLenum target, size_t level, const ImageDesc &desc); 132 void setImageDescChain(GLuint baselevel, 133 GLuint maxLevel, 134 Extents baseSize, 135 const Format &format, 136 InitState initState); 137 void setImageDescChainMultisample(Extents baseSize, 138 const Format &format, 139 GLsizei samples, 140 bool fixedSampleLocations, 141 InitState initState); 142 143 void clearImageDesc(GLenum target, size_t level); 144 void clearImageDescs(); 145 146 const GLenum mTarget; 147 148 SwizzleState mSwizzleState; 149 150 SamplerState mSamplerState; 151 152 GLuint mBaseLevel; 153 GLuint mMaxLevel; 154 155 GLenum mDepthStencilTextureMode; 156 157 bool mImmutableFormat; 158 GLuint mImmutableLevels; 159 160 // From GL_ANGLE_texture_usage 161 GLenum mUsage; 162 163 std::vector<ImageDesc> mImageDescs; 164 InitState mInitState; 165 }; 166 167 bool operator==(const TextureState &a, const TextureState &b); 168 bool operator!=(const TextureState &a, const TextureState &b); 169 170 class Texture final : public egl::ImageSibling, 171 public LabeledObject 172 { 173 public: 174 Texture(rx::GLImplFactory *factory, GLuint id, GLenum target); 175 ~Texture() override; 176 177 Error onDestroy(const Context *context) override; 178 179 void setLabel(const std::string &label) override; 180 const std::string &getLabel() const override; 181 182 GLenum getTarget() const; 183 184 void setSwizzleRed(GLenum swizzleRed); 185 GLenum getSwizzleRed() const; 186 187 void setSwizzleGreen(GLenum swizzleGreen); 188 GLenum getSwizzleGreen() const; 189 190 void setSwizzleBlue(GLenum swizzleBlue); 191 GLenum getSwizzleBlue() const; 192 193 void setSwizzleAlpha(GLenum swizzleAlpha); 194 GLenum getSwizzleAlpha() const; 195 196 void setMinFilter(GLenum minFilter); 197 GLenum getMinFilter() const; 198 199 void setMagFilter(GLenum magFilter); 200 GLenum getMagFilter() const; 201 202 void setWrapS(GLenum wrapS); 203 GLenum getWrapS() const; 204 205 void setWrapT(GLenum wrapT); 206 GLenum getWrapT() const; 207 208 void setWrapR(GLenum wrapR); 209 GLenum getWrapR() const; 210 211 void setMaxAnisotropy(float maxAnisotropy); 212 float getMaxAnisotropy() const; 213 214 void setMinLod(GLfloat minLod); 215 GLfloat getMinLod() const; 216 217 void setMaxLod(GLfloat maxLod); 218 GLfloat getMaxLod() const; 219 220 void setCompareMode(GLenum compareMode); 221 GLenum getCompareMode() const; 222 223 void setCompareFunc(GLenum compareFunc); 224 GLenum getCompareFunc() const; 225 226 void setSRGBDecode(GLenum sRGBDecode); 227 GLenum getSRGBDecode() const; 228 229 const SamplerState &getSamplerState() const; 230 231 gl::Error setBaseLevel(const Context *context, GLuint baseLevel); 232 GLuint getBaseLevel() const; 233 234 void setMaxLevel(GLuint maxLevel); 235 GLuint getMaxLevel() const; 236 237 void setDepthStencilTextureMode(GLenum mode); 238 GLenum getDepthStencilTextureMode() const; 239 240 bool getImmutableFormat() const; 241 242 GLuint getImmutableLevels() const; 243 244 void setUsage(GLenum usage); 245 GLenum getUsage() const; 246 247 const TextureState &getTextureState() const; 248 249 size_t getWidth(GLenum target, size_t level) const; 250 size_t getHeight(GLenum target, size_t level) const; 251 size_t getDepth(GLenum target, size_t level) const; 252 GLsizei getSamples(GLenum target, size_t level) const; 253 bool getFixedSampleLocations(GLenum target, size_t level) const; 254 const Format &getFormat(GLenum target, size_t level) const; 255 256 // Returns the value called "q" in the GLES 3.0.4 spec section 3.8.10. 257 GLuint getMipmapMaxLevel() const; 258 259 bool isMipmapComplete() const; 260 261 Error setImage(const Context *context, 262 const PixelUnpackState &unpackState, 263 GLenum target, 264 size_t level, 265 GLenum internalFormat, 266 const Extents &size, 267 GLenum format, 268 GLenum type, 269 const uint8_t *pixels); 270 Error setSubImage(const Context *context, 271 const PixelUnpackState &unpackState, 272 GLenum target, 273 size_t level, 274 const Box &area, 275 GLenum format, 276 GLenum type, 277 const uint8_t *pixels); 278 279 Error setCompressedImage(const Context *context, 280 const PixelUnpackState &unpackState, 281 GLenum target, 282 size_t level, 283 GLenum internalFormat, 284 const Extents &size, 285 size_t imageSize, 286 const uint8_t *pixels); 287 Error setCompressedSubImage(const Context *context, 288 const PixelUnpackState &unpackState, 289 GLenum target, 290 size_t level, 291 const Box &area, 292 GLenum format, 293 size_t imageSize, 294 const uint8_t *pixels); 295 296 Error copyImage(const Context *context, 297 GLenum target, 298 size_t level, 299 const Rectangle &sourceArea, 300 GLenum internalFormat, 301 Framebuffer *source); 302 Error copySubImage(const Context *context, 303 GLenum target, 304 size_t level, 305 const Offset &destOffset, 306 const Rectangle &sourceArea, 307 Framebuffer *source); 308 309 Error copyTexture(const Context *context, 310 GLenum target, 311 size_t level, 312 GLenum internalFormat, 313 GLenum type, 314 size_t sourceLevel, 315 bool unpackFlipY, 316 bool unpackPremultiplyAlpha, 317 bool unpackUnmultiplyAlpha, 318 Texture *source); 319 Error copySubTexture(const Context *context, 320 GLenum target, 321 size_t level, 322 const Offset &destOffset, 323 size_t sourceLevel, 324 const Rectangle &sourceArea, 325 bool unpackFlipY, 326 bool unpackPremultiplyAlpha, 327 bool unpackUnmultiplyAlpha, 328 Texture *source); 329 Error copyCompressedTexture(const Context *context, const Texture *source); 330 331 Error setStorage(const Context *context, 332 GLenum target, 333 GLsizei levels, 334 GLenum internalFormat, 335 const Extents &size); 336 337 Error setStorageMultisample(const Context *context, 338 GLenum target, 339 GLsizei samples, 340 GLint internalformat, 341 const Extents &size, 342 bool fixedSampleLocations); 343 344 Error setEGLImageTarget(const Context *context, GLenum target, egl::Image *imageTarget); 345 346 Error generateMipmap(const Context *context); 347 348 egl::Surface *getBoundSurface() const; 349 egl::Stream *getBoundStream() const; 350 351 void signalDirty(InitState initState) const; 352 353 bool isSamplerComplete(const Context *context, const Sampler *optionalSampler); 354 getImplementation()355 rx::TextureImpl *getImplementation() const { return mTexture; } 356 357 // FramebufferAttachmentObject implementation 358 Extents getAttachmentSize(const ImageIndex &imageIndex) const override; 359 const Format &getAttachmentFormat(GLenum binding, const ImageIndex &imageIndex) const override; 360 GLsizei getAttachmentSamples(const ImageIndex &imageIndex) const override; 361 362 void onAttach(const Context *context) override; 363 void onDetach(const Context *context) override; 364 GLuint getId() const override; 365 366 // Needed for robust resource init. 367 Error ensureInitialized(const Context *context); 368 InitState initState(const ImageIndex &imageIndex) const override; 369 InitState initState() const; 370 void setInitState(const ImageIndex &imageIndex, InitState initState) override; 371 372 enum DirtyBitType 373 { 374 // Sampler state 375 DIRTY_BIT_MIN_FILTER, 376 DIRTY_BIT_MAG_FILTER, 377 DIRTY_BIT_WRAP_S, 378 DIRTY_BIT_WRAP_T, 379 DIRTY_BIT_WRAP_R, 380 DIRTY_BIT_MAX_ANISOTROPY, 381 DIRTY_BIT_MIN_LOD, 382 DIRTY_BIT_MAX_LOD, 383 DIRTY_BIT_COMPARE_MODE, 384 DIRTY_BIT_COMPARE_FUNC, 385 DIRTY_BIT_SRGB_DECODE, 386 387 // Texture state 388 DIRTY_BIT_SWIZZLE_RED, 389 DIRTY_BIT_SWIZZLE_GREEN, 390 DIRTY_BIT_SWIZZLE_BLUE, 391 DIRTY_BIT_SWIZZLE_ALPHA, 392 DIRTY_BIT_BASE_LEVEL, 393 DIRTY_BIT_MAX_LEVEL, 394 395 // Misc 396 DIRTY_BIT_LABEL, 397 DIRTY_BIT_USAGE, 398 399 DIRTY_BIT_COUNT, 400 }; 401 using DirtyBits = angle::BitSet<DIRTY_BIT_COUNT>; 402 403 void syncState(); hasAnyDirtyBit()404 bool hasAnyDirtyBit() const { return mDirtyBits.any(); } 405 406 private: 407 rx::FramebufferAttachmentObjectImpl *getAttachmentImpl() const override; 408 409 // ANGLE-only method, used internally 410 friend class egl::Surface; 411 Error bindTexImageFromSurface(const Context *context, egl::Surface *surface); 412 Error releaseTexImageFromSurface(const Context *context); 413 414 // ANGLE-only methods, used internally 415 friend class egl::Stream; 416 void bindStream(egl::Stream *stream); 417 void releaseStream(); 418 Error acquireImageFromStream(const Context *context, 419 const egl::Stream::GLTextureDescription &desc); 420 Error releaseImageFromStream(const Context *context); 421 422 void invalidateCompletenessCache() const; 423 Error releaseTexImageInternal(const Context *context); 424 425 Error ensureSubImageInitialized(const Context *context, 426 GLenum target, 427 size_t level, 428 const gl::Box &area); 429 430 TextureState mState; 431 DirtyBits mDirtyBits; 432 rx::TextureImpl *mTexture; 433 434 std::string mLabel; 435 436 egl::Surface *mBoundSurface; 437 egl::Stream *mBoundStream; 438 439 struct SamplerCompletenessCache 440 { 441 SamplerCompletenessCache(); 442 443 // Context used to generate this cache entry 444 ContextID context; 445 446 // All values that affect sampler completeness that are not stored within 447 // the texture itself 448 SamplerState samplerState; 449 450 // Result of the sampler completeness with the above parameters 451 bool samplerComplete; 452 }; 453 454 mutable SamplerCompletenessCache mCompletenessCache; 455 }; 456 457 inline bool operator==(const TextureState &a, const TextureState &b) 458 { 459 return a.mSwizzleState == b.mSwizzleState && a.mSamplerState == b.mSamplerState && 460 a.mBaseLevel == b.mBaseLevel && a.mMaxLevel == b.mMaxLevel && 461 a.mImmutableFormat == b.mImmutableFormat && a.mImmutableLevels == b.mImmutableLevels && 462 a.mUsage == b.mUsage; 463 } 464 465 inline bool operator!=(const TextureState &a, const TextureState &b) 466 { 467 return !(a == b); 468 } 469 } // namespace gl 470 471 #endif // LIBANGLE_TEXTURE_H_ 472