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 egl 33 { 34 class Surface; 35 class Config; 36 } 37 38 namespace es2 39 { 40 class Framebuffer; 41 42 enum 43 { 44 IMPLEMENTATION_MAX_TEXTURE_LEVELS = sw::MIPMAP_LEVELS, 45 IMPLEMENTATION_MAX_TEXTURE_SIZE = 1 << (IMPLEMENTATION_MAX_TEXTURE_LEVELS - 1), 46 IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE = 1 << (IMPLEMENTATION_MAX_TEXTURE_LEVELS - 1), 47 IMPLEMENTATION_MAX_RENDERBUFFER_SIZE = sw::OUTLINE_RESOLUTION, 48 }; 49 50 class Texture : public egl::Texture 51 { 52 public: 53 explicit Texture(GLuint name); 54 55 virtual sw::Resource *getResource() const; 56 57 virtual void addProxyRef(const Renderbuffer *proxy) = 0; 58 virtual void releaseProxy(const Renderbuffer *proxy) = 0; 59 60 virtual GLenum getTarget() const = 0; 61 62 bool setMinFilter(GLenum filter); 63 bool setMagFilter(GLenum filter); 64 bool setWrapS(GLenum wrap); 65 bool setWrapT(GLenum wrap); 66 bool setWrapR(GLenum wrap); 67 bool setMaxAnisotropy(GLfloat textureMaxAnisotropy); 68 bool setBaseLevel(GLint baseLevel); 69 bool setCompareFunc(GLenum compareFunc); 70 bool setCompareMode(GLenum compareMode); 71 void makeImmutable(GLsizei levels); 72 bool setMaxLevel(GLint maxLevel); 73 bool setMaxLOD(GLfloat maxLOD); 74 bool setMinLOD(GLfloat minLOD); 75 bool setSwizzleR(GLenum swizzleR); 76 bool setSwizzleG(GLenum swizzleG); 77 bool setSwizzleB(GLenum swizzleB); 78 bool setSwizzleA(GLenum swizzleA); 79 80 GLenum getMinFilter() const; 81 GLenum getMagFilter() const; 82 GLenum getWrapS() const; 83 GLenum getWrapT() const; 84 GLenum getWrapR() const; 85 GLfloat getMaxAnisotropy() const; 86 GLint getBaseLevel() const; 87 GLenum getCompareFunc() const; 88 GLenum getCompareMode() const; 89 GLboolean getImmutableFormat() const; 90 GLsizei getImmutableLevels() const; 91 GLint getMaxLevel() const; 92 GLfloat getMaxLOD() const; 93 GLfloat getMinLOD() const; 94 GLenum getSwizzleR() const; 95 GLenum getSwizzleG() const; 96 GLenum getSwizzleB() const; 97 GLenum getSwizzleA() const; 98 99 virtual GLsizei getWidth(GLenum target, GLint level) const = 0; 100 virtual GLsizei getHeight(GLenum target, GLint level) const = 0; 101 virtual GLsizei getDepth(GLenum target, GLint level) const; 102 virtual GLenum getFormat(GLenum target, GLint level) const = 0; 103 virtual GLenum getType(GLenum target, GLint level) const = 0; 104 virtual sw::Format getInternalFormat(GLenum target, GLint level) const = 0; 105 virtual int getLevelCount() const = 0; 106 107 virtual bool isSamplerComplete() const = 0; 108 virtual bool isCompressed(GLenum target, GLint level) const = 0; 109 virtual bool isDepth(GLenum target, GLint level) const = 0; 110 111 virtual Renderbuffer *getRenderbuffer(GLenum target, GLint level, GLint layer) = 0; 112 virtual egl::Image *getRenderTarget(GLenum target, unsigned int level) = 0; 113 virtual egl::Image *createSharedImage(GLenum target, unsigned int level); 114 virtual bool isShared(GLenum target, unsigned int level) const = 0; 115 116 virtual void generateMipmaps() = 0; 117 virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source) = 0; 118 119 protected: 120 virtual ~Texture(); 121 122 void setImage(GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels, egl::Image *image); 123 void subImage(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels, egl::Image *image); 124 void setCompressedImage(GLsizei imageSize, const void *pixels, egl::Image *image); 125 void subImageCompressed(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels, egl::Image *image); 126 127 bool copy(egl::Image *source, const sw::SliceRect &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, GLint zoffset, egl::Image *dest); 128 129 bool isMipmapFiltered() const; 130 131 GLenum mMinFilter; 132 GLenum mMagFilter; 133 GLenum mWrapS; 134 GLenum mWrapT; 135 GLenum mWrapR; 136 GLfloat mMaxAnisotropy; 137 GLint mBaseLevel; 138 GLenum mCompareFunc; 139 GLenum mCompareMode; 140 GLboolean mImmutableFormat; 141 GLsizei mImmutableLevels; 142 GLint mMaxLevel; 143 GLfloat mMaxLOD; 144 GLfloat mMinLOD; 145 GLenum mSwizzleR; 146 GLenum mSwizzleG; 147 GLenum mSwizzleB; 148 GLenum mSwizzleA; 149 150 sw::Resource *resource; 151 }; 152 153 class Texture2D : public Texture 154 { 155 public: 156 explicit Texture2D(GLuint name); 157 158 void addProxyRef(const Renderbuffer *proxy) override; 159 void releaseProxy(const Renderbuffer *proxy) override; 160 void sweep() override; 161 162 virtual GLenum getTarget() const; 163 164 virtual GLsizei getWidth(GLenum target, GLint level) const; 165 virtual GLsizei getHeight(GLenum target, GLint level) const; 166 virtual GLenum getFormat(GLenum target, GLint level) const; 167 virtual GLenum getType(GLenum target, GLint level) const; 168 virtual sw::Format getInternalFormat(GLenum target, GLint level) const; 169 virtual int getLevelCount() const; 170 171 void setImage(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels); 172 void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels); 173 void subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels); 174 void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels); 175 void copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source); 176 virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source); 177 178 void setImage(egl::Image *image); 179 180 virtual bool isSamplerComplete() const; 181 virtual bool isCompressed(GLenum target, GLint level) const; 182 virtual bool isDepth(GLenum target, GLint level) const; 183 virtual void bindTexImage(egl::Surface *surface); 184 virtual void releaseTexImage(); 185 186 virtual void generateMipmaps(); 187 188 virtual Renderbuffer *getRenderbuffer(GLenum target, GLint level, GLint layer); 189 virtual egl::Image *getRenderTarget(GLenum target, unsigned int level); 190 virtual bool isShared(GLenum target, unsigned int level) const; 191 192 egl::Image *getImage(unsigned int level); 193 194 protected: 195 virtual ~Texture2D(); 196 197 bool isMipmapComplete() const; 198 199 egl::Image *image[IMPLEMENTATION_MAX_TEXTURE_LEVELS]; 200 201 egl::Surface *mSurface; 202 203 // A specific internal reference count is kept for colorbuffer proxy references, 204 // because, as the renderbuffer acting as proxy will maintain a binding pointer 205 // back to this texture, there would be a circular reference if we used a binding 206 // pointer here. This reference count will cause the pointer to be set to null if 207 // the count drops to zero, but will not cause deletion of the Renderbuffer. 208 Renderbuffer *mColorbufferProxy; 209 unsigned int mProxyRefs; 210 }; 211 212 class TextureCubeMap : public Texture 213 { 214 public: 215 explicit TextureCubeMap(GLuint name); 216 217 void addProxyRef(const Renderbuffer *proxy) override; 218 void releaseProxy(const Renderbuffer *proxy) override; 219 void sweep() override; 220 221 virtual GLenum getTarget() const; 222 223 virtual GLsizei getWidth(GLenum target, GLint level) const; 224 virtual GLsizei getHeight(GLenum target, GLint level) const; 225 virtual GLenum getFormat(GLenum target, GLint level) const; 226 virtual GLenum getType(GLenum target, GLint level) const; 227 virtual sw::Format getInternalFormat(GLenum target, GLint level) const; 228 virtual int getLevelCount() const; 229 230 void setImage(GLenum target, GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels); 231 void setCompressedImage(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels); 232 233 void subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels); 234 void subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels); 235 void copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source); 236 virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source); 237 238 virtual bool isSamplerComplete() const; 239 virtual bool isCompressed(GLenum target, GLint level) const; 240 virtual bool isDepth(GLenum target, GLint level) const; 241 virtual void releaseTexImage(); 242 243 virtual void generateMipmaps(); 244 245 virtual Renderbuffer *getRenderbuffer(GLenum target, GLint level, GLint layer); 246 virtual egl::Image *getRenderTarget(GLenum target, unsigned int level); 247 virtual bool isShared(GLenum target, unsigned int level) const; 248 249 egl::Image *getImage(int face, unsigned int level); 250 251 protected: 252 virtual ~TextureCubeMap(); 253 254 private: 255 bool isCubeComplete() const; 256 bool isMipmapCubeComplete() const; 257 258 // face is one of the GL_TEXTURE_CUBE_MAP_* enumerants. Returns nullptr on failure. 259 egl::Image *getImage(GLenum face, unsigned int level); 260 261 egl::Image *image[6][IMPLEMENTATION_MAX_TEXTURE_LEVELS]; 262 263 // A specific internal reference count is kept for colorbuffer proxy references, 264 // because, as the renderbuffer acting as proxy will maintain a binding pointer 265 // back to this texture, there would be a circular reference if we used a binding 266 // pointer here. This reference count will cause the pointer to be set to null if 267 // the count drops to zero, but will not cause deletion of the Renderbuffer. 268 Renderbuffer *mFaceProxies[6]; 269 unsigned int mFaceProxyRefs[6]; 270 }; 271 272 class Texture3D : public Texture 273 { 274 public: 275 explicit Texture3D(GLuint name); 276 277 void addProxyRef(const Renderbuffer *proxy) override; 278 void releaseProxy(const Renderbuffer *proxy) override; 279 void sweep() override; 280 281 virtual GLenum getTarget() const; 282 283 virtual GLsizei getWidth(GLenum target, GLint level) const; 284 virtual GLsizei getHeight(GLenum target, GLint level) const; 285 virtual GLsizei getDepth(GLenum target, GLint level) const; 286 virtual GLenum getFormat(GLenum target, GLint level) const; 287 virtual GLenum getType(GLenum target, GLint level) const; 288 virtual sw::Format getInternalFormat(GLenum target, GLint level) const; 289 virtual int getLevelCount() const; 290 291 void setImage(GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels); 292 void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize, const void *pixels); 293 void subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels); 294 void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels); 295 void copyImage(GLint level, GLenum format, GLint x, GLint y, GLint z, GLsizei width, GLsizei height, GLsizei depth, Framebuffer *source); 296 void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source); 297 298 void setImage(egl::Image *image); 299 300 virtual bool isSamplerComplete() const; 301 virtual bool isCompressed(GLenum target, GLint level) const; 302 virtual bool isDepth(GLenum target, GLint level) const; 303 virtual void bindTexImage(egl::Surface *surface); 304 virtual void releaseTexImage(); 305 306 virtual void generateMipmaps(); 307 308 virtual Renderbuffer *getRenderbuffer(GLenum target, GLint level, GLint layer); 309 virtual egl::Image *getRenderTarget(GLenum target, unsigned int level); 310 virtual bool isShared(GLenum target, unsigned int level) const; 311 312 egl::Image *getImage(unsigned int level); 313 314 protected: 315 virtual ~Texture3D(); 316 317 bool isMipmapComplete() const; 318 319 egl::Image *image[IMPLEMENTATION_MAX_TEXTURE_LEVELS]; 320 321 egl::Surface *mSurface; 322 323 // A specific internal reference count is kept for colorbuffer proxy references, 324 // because, as the renderbuffer acting as proxy will maintain a binding pointer 325 // back to this texture, there would be a circular reference if we used a binding 326 // pointer here. This reference count will cause the pointer to be set to null if 327 // the count drops to zero, but will not cause deletion of the Renderbuffer. 328 Renderbuffer *mColorbufferProxy; 329 unsigned int mProxyRefs; 330 }; 331 332 class Texture2DArray : public Texture3D 333 { 334 public: 335 explicit Texture2DArray(GLuint name); 336 337 virtual GLenum getTarget() const; 338 virtual void generateMipmaps(); 339 340 protected: 341 virtual ~Texture2DArray(); 342 }; 343 344 class TextureExternal : public Texture2D 345 { 346 public: 347 explicit TextureExternal(GLuint name); 348 349 virtual GLenum getTarget() const; 350 351 protected: 352 virtual ~TextureExternal(); 353 }; 354 } 355 356 #endif // LIBGLESV2_TEXTURE_H_ 357