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