• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
getMinFilter()74 	GLenum getMinFilter() const { return mMinFilter; }
getMagFilter()75 	GLenum getMagFilter() const { return mMagFilter; }
getWrapS()76 	GLenum getWrapS() const { return mWrapS; }
getWrapT()77 	GLenum getWrapT() const { return mWrapT; }
getWrapR()78 	GLenum getWrapR() const { return mWrapR; }
getMaxAnisotropy()79 	GLfloat getMaxAnisotropy() const { return mMaxAnisotropy; }
getBaseLevel()80 	GLint getBaseLevel() const { return mBaseLevel; }
getCompareFunc()81 	GLenum getCompareFunc() const { return mCompareFunc; }
getCompareMode()82 	GLenum getCompareMode() const { return mCompareMode; }
getImmutableFormat()83 	GLboolean getImmutableFormat() const { return mImmutableFormat; }
getImmutableLevels()84 	GLsizei getImmutableLevels() const { return mImmutableLevels; }
getMaxLevel()85 	GLint getMaxLevel() const { return mMaxLevel; }
getMaxLOD()86 	GLfloat getMaxLOD() const { return mMaxLOD; }
getMinLOD()87 	GLfloat getMinLOD() const { return mMinLOD; }
getSwizzleR()88 	GLenum getSwizzleR() const { return mSwizzleR; }
getSwizzleG()89 	GLenum getSwizzleG() const { return mSwizzleG; }
getSwizzleB()90 	GLenum getSwizzleB() const { return mSwizzleB; }
getSwizzleA()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