• 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 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