1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // Texture.h: Defines the abstract Texture class and its concrete derived 16 // classes Texture2D and TextureCubeMap. Implements GL texture objects and 17 // related functionality. [OpenGL ES 2.0.24] section 3.7 page 63. 18 19 #ifndef LIBGLESV2_TEXTURE_H_ 20 #define LIBGLESV2_TEXTURE_H_ 21 22 #include "Renderbuffer.h" 23 #include "common/Object.hpp" 24 #include "utilities.h" 25 #include "libEGL/Texture.hpp" 26 #include "common/debug.h" 27 28 #include <GLES2/gl2.h> 29 30 #include <vector> 31 32 namespace gl { class Surface; } 33 34 namespace es2 35 { 36 class Sampler; 37 38 enum 39 { 40 IMPLEMENTATION_MAX_TEXTURE_LEVELS = sw::MIPMAP_LEVELS, 41 IMPLEMENTATION_MAX_TEXTURE_SIZE = 1 << (IMPLEMENTATION_MAX_TEXTURE_LEVELS - 1), 42 IMPLEMENTATION_MAX_3D_TEXTURE_SIZE = IMPLEMENTATION_MAX_TEXTURE_SIZE, 43 IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE = IMPLEMENTATION_MAX_TEXTURE_SIZE, 44 IMPLEMENTATION_MAX_ARRAY_TEXTURE_LAYERS = IMPLEMENTATION_MAX_TEXTURE_SIZE, 45 IMPLEMENTATION_MAX_RENDERBUFFER_SIZE = sw::OUTLINE_RESOLUTION, 46 }; 47 48 class ImageLevels 49 { 50 public: 51 inline const egl::Image* operator[](size_t index) const 52 { 53 return (index < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? image[index] : nullptr; 54 } 55 56 inline egl::Image*& operator[](size_t index) 57 { 58 if(index < IMPLEMENTATION_MAX_TEXTURE_LEVELS) 59 { 60 return image[index]; 61 } 62 63 return getNullImage(); 64 } 65 release()66 inline void release() 67 { 68 for(int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) 69 { 70 if(image[i]) 71 { 72 image[i]->release(); 73 image[i] = nullptr; 74 } 75 } 76 } 77 unbind(const egl::Texture * texture)78 inline void unbind(const egl::Texture* texture) 79 { 80 for(int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) 81 { 82 if(image[i]) 83 { 84 image[i]->unbind(texture); 85 image[i] = nullptr; 86 } 87 } 88 } 89 90 private: 91 egl::Image *image[IMPLEMENTATION_MAX_TEXTURE_LEVELS] = {}; 92 static egl::Image*& getNullImage(); 93 }; 94 95 class Texture : public egl::Texture 96 { 97 public: 98 explicit Texture(GLuint name); 99 100 sw::Resource *getResource() const override; 101 102 virtual void addProxyRef(const Renderbuffer *proxy) = 0; 103 virtual void releaseProxy(const Renderbuffer *proxy) = 0; 104 105 virtual GLenum getTarget() const = 0; 106 107 bool setMinFilter(GLenum filter); 108 bool setMagFilter(GLenum filter); 109 bool setWrapS(GLenum wrap); 110 bool setWrapT(GLenum wrap); 111 bool setWrapR(GLenum wrap); 112 bool setMaxAnisotropy(GLfloat textureMaxAnisotropy); 113 bool setBaseLevel(GLint baseLevel); 114 bool setCompareFunc(GLenum compareFunc); 115 bool setCompareMode(GLenum compareMode); 116 void makeImmutable(GLsizei levels); 117 bool setMaxLevel(GLint maxLevel); 118 bool setMaxLOD(GLfloat maxLOD); 119 bool setMinLOD(GLfloat minLOD); 120 bool setSwizzleR(GLenum swizzleR); 121 bool setSwizzleG(GLenum swizzleG); 122 bool setSwizzleB(GLenum swizzleB); 123 bool setSwizzleA(GLenum swizzleA); 124 getMinFilter()125 GLenum getMinFilter() const { return mMinFilter; } getMagFilter()126 GLenum getMagFilter() const { return mMagFilter; } getWrapS()127 GLenum getWrapS() const { return mWrapS; } getWrapT()128 GLenum getWrapT() const { return mWrapT; } getWrapR()129 GLenum getWrapR() const { return mWrapR; } getMaxAnisotropy()130 GLfloat getMaxAnisotropy() const { return mMaxAnisotropy; } getBaseLevel()131 GLint getBaseLevel() const { return mBaseLevel; } getCompareFunc()132 GLenum getCompareFunc() const { return mCompareFunc; } getCompareMode()133 GLenum getCompareMode() const { return mCompareMode; } getImmutableFormat()134 GLboolean getImmutableFormat() const { return mImmutableFormat; } getImmutableLevels()135 GLsizei getImmutableLevels() const { return mImmutableLevels; } getMaxLevel()136 GLint getMaxLevel() const { return mMaxLevel; } getMaxLOD()137 GLfloat getMaxLOD() const { return mMaxLOD; } getMinLOD()138 GLfloat getMinLOD() const { return mMinLOD; } getSwizzleR()139 GLenum getSwizzleR() const { return mSwizzleR; } getSwizzleG()140 GLenum getSwizzleG() const { return mSwizzleG; } getSwizzleB()141 GLenum getSwizzleB() const { return mSwizzleB; } getSwizzleA()142 GLenum getSwizzleA() const { return mSwizzleA; } 143 144 virtual GLsizei getWidth(GLenum target, GLint level) const = 0; 145 virtual GLsizei getHeight(GLenum target, GLint level) const = 0; 146 virtual GLsizei getDepth(GLenum target, GLint level) const; 147 virtual GLint getFormat(GLenum target, GLint level) const = 0; 148 virtual int getTopLevel() const = 0; 149 virtual bool requiresSync() const = 0; 150 151 virtual bool isSamplerComplete(Sampler *sampler) const = 0; 152 virtual bool isCompressed(GLenum target, GLint level) const = 0; 153 virtual bool isDepth(GLenum target, GLint level) const = 0; 154 155 virtual Renderbuffer *getRenderbuffer(GLenum target, GLint level) = 0; 156 virtual egl::Image *getRenderTarget(GLenum target, unsigned int level) = 0; 157 egl::Image *createSharedImage(GLenum target, unsigned int level); 158 virtual bool isShared(GLenum target, unsigned int level) const = 0; 159 160 virtual void generateMipmaps() = 0; 161 virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source) = 0; 162 163 protected: 164 ~Texture() override; 165 166 void setImage(GLenum format, GLenum type, const gl::PixelStorageModes &unpackParameters, const void *pixels, egl::Image *image); 167 void subImage(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelStorageModes &unpackParameters, const void *pixels, egl::Image *image); 168 void setCompressedImage(GLsizei imageSize, const void *pixels, egl::Image *image); 169 void subImageCompressed(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels, egl::Image *image); 170 171 bool copy(egl::Image *source, const sw::SliceRect &sourceRect, GLint xoffset, GLint yoffset, GLint zoffset, egl::Image *dest); 172 173 bool isMipmapFiltered(Sampler *sampler) const; 174 175 GLenum mMinFilter; 176 GLenum mMagFilter; 177 GLenum mWrapS; 178 GLenum mWrapT; 179 GLenum mWrapR; 180 GLfloat mMaxAnisotropy; 181 GLint mBaseLevel; 182 GLenum mCompareFunc; 183 GLenum mCompareMode; 184 GLboolean mImmutableFormat; 185 GLsizei mImmutableLevels; 186 GLint mMaxLevel; 187 GLfloat mMaxLOD; 188 GLfloat mMinLOD; 189 GLenum mSwizzleR; 190 GLenum mSwizzleG; 191 GLenum mSwizzleB; 192 GLenum mSwizzleA; 193 194 sw::Resource *resource; 195 }; 196 197 class Texture2D : public Texture 198 { 199 public: 200 explicit Texture2D(GLuint name); 201 202 void addProxyRef(const Renderbuffer *proxy) override; 203 void releaseProxy(const Renderbuffer *proxy) override; 204 void sweep() override; 205 206 GLenum getTarget() const override; 207 208 GLsizei getWidth(GLenum target, GLint level) const override; 209 GLsizei getHeight(GLenum target, GLint level) const override; 210 GLint getFormat(GLenum target, GLint level) const override; 211 int getTopLevel() const override; 212 bool requiresSync() const override; 213 214 void setImage(GLint level, GLsizei width, GLsizei height, GLint internalformat, GLenum format, GLenum type, const gl::PixelStorageModes &unpackParameters, const void *pixels); 215 void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels); 216 void subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const gl::PixelStorageModes &unpackParameters, const void *pixels); 217 void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels); 218 void copyImage(GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source); 219 void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source) override; 220 221 void setSharedImage(egl::Image *image); 222 223 bool isSamplerComplete(Sampler *sampler) const override; 224 bool isCompressed(GLenum target, GLint level) const override; 225 bool isDepth(GLenum target, GLint level) const override; 226 void bindTexImage(gl::Surface *surface); 227 void releaseTexImage() override; 228 229 void generateMipmaps() override; 230 231 Renderbuffer *getRenderbuffer(GLenum target, GLint level) override; 232 egl::Image *getRenderTarget(GLenum target, unsigned int level) override; 233 bool isShared(GLenum target, unsigned int level) const override; 234 235 egl::Image *getImage(unsigned int level); 236 237 protected: 238 ~Texture2D() override; 239 240 bool isMipmapComplete() const; 241 242 ImageLevels image; 243 244 gl::Surface *mSurface; 245 246 // A specific internal reference count is kept for colorbuffer proxy references, 247 // because, as the renderbuffer acting as proxy will maintain a binding pointer 248 // back to this texture, there would be a circular reference if we used a binding 249 // pointer here. This reference count will cause the pointer to be set to null if 250 // the count drops to zero, but will not cause deletion of the Renderbuffer. 251 Renderbuffer *mColorbufferProxy; 252 unsigned int mProxyRefs; 253 }; 254 255 class Texture2DRect : public Texture2D 256 { 257 public: 258 explicit Texture2DRect(GLuint name); 259 260 GLenum getTarget() const override; 261 262 Renderbuffer *getRenderbuffer(GLenum target, GLint level) override; 263 }; 264 265 class TextureCubeMap : public Texture 266 { 267 public: 268 explicit TextureCubeMap(GLuint name); 269 270 void addProxyRef(const Renderbuffer *proxy) override; 271 void releaseProxy(const Renderbuffer *proxy) override; 272 void sweep() override; 273 274 GLenum getTarget() const override; 275 276 GLsizei getWidth(GLenum target, GLint level) const override; 277 GLsizei getHeight(GLenum target, GLint level) const override; 278 GLint getFormat(GLenum target, GLint level) const override; 279 int getTopLevel() const override; 280 bool requiresSync() const override; 281 282 void setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLint internalformat, GLenum format, GLenum type, const gl::PixelStorageModes &unpackParameters, const void *pixels); 283 void setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels); 284 285 void subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const gl::PixelStorageModes &unpackParameters, const void *pixels); 286 void subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels); 287 void copyImage(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source); 288 void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source) override; 289 290 bool isSamplerComplete(Sampler *sampler) const override; 291 bool isCompressed(GLenum target, GLint level) const override; 292 bool isDepth(GLenum target, GLint level) const override; 293 void releaseTexImage() override; 294 295 void generateMipmaps() override; 296 void updateBorders(int level); 297 298 Renderbuffer *getRenderbuffer(GLenum target, GLint level) override; 299 egl::Image *getRenderTarget(GLenum target, unsigned int level) override; 300 bool isShared(GLenum target, unsigned int level) const override; 301 302 egl::Image *getImage(int face, unsigned int level); 303 304 bool isCubeComplete() const; 305 306 protected: 307 ~TextureCubeMap() override; 308 309 private: 310 bool isMipmapCubeComplete() const; 311 312 // face is one of the GL_TEXTURE_CUBE_MAP_* enumerants. Returns nullptr on failure. 313 egl::Image *getImage(GLenum face, unsigned int level); 314 315 ImageLevels image[6]; 316 317 // A specific internal reference count is kept for colorbuffer proxy references, 318 // because, as the renderbuffer acting as proxy will maintain a binding pointer 319 // back to this texture, there would be a circular reference if we used a binding 320 // pointer here. This reference count will cause the pointer to be set to null if 321 // the count drops to zero, but will not cause deletion of the Renderbuffer. 322 Renderbuffer *mFaceProxies[6]; 323 unsigned int mFaceProxyRefs[6]; 324 }; 325 326 class Texture3D : public Texture 327 { 328 public: 329 explicit Texture3D(GLuint name); 330 331 void addProxyRef(const Renderbuffer *proxy) override; 332 void releaseProxy(const Renderbuffer *proxy) override; 333 void sweep() override; 334 335 GLenum getTarget() const override; 336 337 GLsizei getWidth(GLenum target, GLint level) const override; 338 GLsizei getHeight(GLenum target, GLint level) const override; 339 GLsizei getDepth(GLenum target, GLint level) const override; 340 GLint getFormat(GLenum target, GLint level) const override; 341 int getTopLevel() const override; 342 bool requiresSync() const override; 343 344 void setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLint internalformat, GLenum format, GLenum type, const gl::PixelStorageModes &unpackParameters, const void *pixels); 345 void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels); 346 void subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const gl::PixelStorageModes &unpackParameters, const void *pixels); 347 void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels); 348 void copyImage(GLint level, GLenum internalformat, GLint x, GLint y, GLint z, GLsizei width, GLsizei height, GLsizei depth, Renderbuffer *source); 349 void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source) override; 350 351 void setSharedImage(egl::Image *image); 352 353 bool isSamplerComplete(Sampler *sampler) const override; 354 bool isCompressed(GLenum target, GLint level) const override; 355 bool isDepth(GLenum target, GLint level) const override; 356 void releaseTexImage() override; 357 358 void generateMipmaps() override; 359 360 Renderbuffer *getRenderbuffer(GLenum target, GLint level) override; 361 egl::Image *getRenderTarget(GLenum target, unsigned int level) override; 362 bool isShared(GLenum target, unsigned int level) const override; 363 364 egl::Image *getImage(unsigned int level); 365 366 protected: 367 ~Texture3D() override; 368 369 bool isMipmapComplete() const; 370 371 ImageLevels image; 372 373 gl::Surface *mSurface; 374 375 // A specific internal reference count is kept for colorbuffer proxy references, 376 // because, as the renderbuffer acting as proxy will maintain a binding pointer 377 // back to this texture, there would be a circular reference if we used a binding 378 // pointer here. This reference count will cause the pointer to be set to null if 379 // the count drops to zero, but will not cause deletion of the Renderbuffer. 380 Renderbuffer *mColorbufferProxy; 381 unsigned int mProxyRefs; 382 }; 383 384 class Texture2DArray : public Texture3D 385 { 386 public: 387 explicit Texture2DArray(GLuint name); 388 389 GLenum getTarget() const override; 390 void generateMipmaps() override; 391 392 protected: 393 ~Texture2DArray() override; 394 }; 395 396 class TextureExternal : public Texture2D 397 { 398 public: 399 explicit TextureExternal(GLuint name); 400 401 GLenum getTarget() const override; 402 403 protected: 404 ~TextureExternal() override; 405 }; 406 } 407 408 #endif // LIBGLESV2_TEXTURE_H_ 409