Browse Source

GLES2: Added support for 3D texture extension. Added shader patching to enable extensions.

bkaradzic 12 years ago
parent
commit
3cf263ec86
3 changed files with 151 additions and 64 deletions
  1. 4 0
      src/glimports.h
  2. 133 19
      src/renderer_gl.cpp
  3. 14 45
      src/renderer_gl.h

+ 4 - 0
src/glimports.h

@@ -181,6 +181,10 @@ GL_IMPORT____(true,  PFNGLFRAMETERMINATORGREMEDYPROC,            glFrameTerminat
 GL_IMPORT____(true,  PFNGLGETTRANSLATEDSHADERSOURCEANGLEPROC,    glGetTranslatedShaderSourceANGLE);
 GL_IMPORT____(true,  PFNGLGETPROGRAMBINARYOESPROC,               glGetProgramBinaryOES);
 GL_IMPORT____(true,  PFNGLPROGRAMBINARYOESPROC,                  glProgramBinaryOES);
+GL_IMPORT____(true,  PFNGLTEXIMAGE3DOESPROC,                     glTexImage3DOES);
+GL_IMPORT____(true,  PFNGLTEXSUBIMAGE3DOESPROC,                  glTexSubImage3DOES);
+GL_IMPORT____(true,  PFNGLCOMPRESSEDTEXIMAGE3DOESPROC,           glCompressedTexImage3DOES);
+GL_IMPORT____(true,  PFNGLCOMPRESSEDTEXSUBIMAGE3DOESPROC,        glCompressedTexSubImage3DOES);
 
 GL_IMPORT____(true,  PFNGLBINDVERTEXARRAYOESPROC,                glBindVertexArrayOES);
 GL_IMPORT____(true,  PFNGLDELETEVERTEXARRAYSOESPROC,             glDeleteVertexArraysOES);

+ 133 - 19
src/renderer_gl.cpp

@@ -279,6 +279,7 @@ namespace bgfx
 			OES_read_format,
 			OES_rgb8_rgba8,
 			OES_standard_derivatives,
+			OES_texture_3D,
 			OES_texture_float,
 			OES_texture_float_linear,
 			OES_texture_half_float,
@@ -352,6 +353,7 @@ namespace bgfx
 		{ "GL_OES_read_format",                    false,                             true  },
 		{ "GL_OES_rgb8_rgba8",                     false,                             true  },
 		{ "GL_OES_standard_derivatives",           false,                             true  },
+		{ "GL_OES_texture_3D",                     false,                             true  },
 		{ "GL_OES_texture_float",                  false,                             true  },
 		{ "GL_OES_texture_float_linear",           false,                             true  },
 		{ "GL_OES_texture_half_float",             false,                             true  },
@@ -396,13 +398,17 @@ namespace bgfx
 #endif // BGFX_CONFIG_DEBUG_GREMEDY
 
 #if BX_PLATFORM_IOS
-	PFNGLBINDVERTEXARRAYOESPROC         glBindVertexArrayOES    = NULL;
-	PFNGLDELETEVERTEXARRAYSOESPROC      glDeleteVertexArraysOES = NULL;
-	PFNGLGENVERTEXARRAYSOESPROC         glGenVertexArraysOES    = NULL;
-	PFNGLPROGRAMBINARYOESPROC           glProgramBinaryOES      = NULL;
-	PFNGLGETPROGRAMBINARYOESPROC        glGetProgramBinaryOES   = NULL;
-	PFLGLDRAWARRAYSINSTANCEDANGLEPROC   glDrawArraysInstanced   = NULL;
-	PFLGLDRAWELEMENTSINSTANCEDANGLEPROC glDrawElementsInstanced = NULL;
+	PFNGLBINDVERTEXARRAYOESPROC         glBindVertexArrayOES         = NULL;
+	PFNGLDELETEVERTEXARRAYSOESPROC      glDeleteVertexArraysOES      = NULL;
+	PFNGLGENVERTEXARRAYSOESPROC         glGenVertexArraysOES         = NULL;
+	PFNGLPROGRAMBINARYOESPROC           glProgramBinaryOES           = NULL;
+	PFNGLGETPROGRAMBINARYOESPROC        glGetProgramBinaryOES        = NULL;
+	PFNGLTEXIMAGE3DOESPROC              glTexImage3DOES              = NULL;
+	PFNGLTEXSUBIMAGE3DOESPROC           glTexSubImage3DOES           = NULL;
+	PFNGLCOMPRESSEDTEXIMAGE3DOESPROC    glCompressedTexImage3DOES    = NULL;
+	PFNGLCOMPRESSEDTEXSUBIMAGE3DOESPROC glCompressedTexSubImage3DOES = NULL;
+	PFLGLDRAWARRAYSINSTANCEDANGLEPROC   glDrawArraysInstanced        = NULL;
+	PFLGLDRAWELEMENTSINSTANCEDANGLEPROC glDrawElementsInstanced      = NULL;
 #endif // BX_PLATFORM_IOS
 
 	typedef void (*PostSwapBuffersFn)(uint32_t _width, uint32_t _height);
@@ -1276,13 +1282,11 @@ namespace bgfx
 		_internalFormat = _format; // GLES wants internal format to match format...
 #endif // !BGFX_CONFIG_RENDERER_OPENGL
 
-#if BGFX_CONFIG_RENDERER_OPENGL|BGFX_CONFIG_RENDERER_OPENGLES3
 		if (_target == GL_TEXTURE_3D)
 		{
 			GL_CHECK(glTexImage3D(_target, _level, _internalFormat, _width, _height, _depth, _border, _format, _type, _data) );
 		}
 		else
-#endif // BGFX_CONFIG_RENDERER_OPENGL|BGFX_CONFIG_RENDERER_OPENGLES3
 		{
 			BX_UNUSED(_depth);
 			GL_CHECK(glTexImage2D(_target, _level, _internalFormat, _width, _height, _border, _format, _type, _data) );
@@ -1291,13 +1295,11 @@ namespace bgfx
 
 	static void texSubImage(GLenum _target, GLint _level, GLint _xoffset, GLint _yoffset, GLint _zoffset, GLsizei _width, GLsizei _height, GLsizei _depth, GLenum _format, GLenum _type, const GLvoid* _data)
 	{
-#if BGFX_CONFIG_RENDERER_OPENGL|BGFX_CONFIG_RENDERER_OPENGLES3
 		if (_target == GL_TEXTURE_3D)
 		{
 			GL_CHECK(glTexSubImage3D(_target, _level, _xoffset, _yoffset, _zoffset, _width, _height, _depth, _format, _type, _data) );
 		}
 		else
-#endif // BGFX_CONFIG_RENDERER_OPENGL|BGFX_CONFIG_RENDERER_OPENGLES3
 		{
 			BX_UNUSED(_zoffset, _depth);
 			GL_CHECK(glTexSubImage2D(_target, _level, _xoffset, _yoffset, _width, _height, _format, _type, _data) );
@@ -1306,13 +1308,11 @@ namespace bgfx
 
 	static void compressedTexImage(GLenum _target, GLint _level, GLenum _internalformat, GLsizei _width, GLsizei _height, GLsizei _depth, GLint _border, GLsizei _imageSize, const GLvoid* _data)
 	{
-#if BGFX_CONFIG_RENDERER_OPENGL|BGFX_CONFIG_RENDERER_OPENGLES3
 		if (_target == GL_TEXTURE_3D)
 		{
 			GL_CHECK(glCompressedTexImage3D(_target, _level, _internalformat, _width, _height, _depth, _border, _imageSize, _data) );
 		}
 		else
-#endif // BGFX_CONFIG_RENDERER_OPENGL|BGFX_CONFIG_RENDERER_OPENGLES3
 		{
 			BX_UNUSED(_depth);
 			GL_CHECK(glCompressedTexImage2D(_target, _level, _internalformat, _width, _height, _border, _imageSize, _data) );
@@ -1321,13 +1321,11 @@ namespace bgfx
 
 	static void compressedTexSubImage(GLenum _target, GLint _level, GLint _xoffset, GLint _yoffset, GLint _zoffset, GLsizei _width, GLsizei _height, GLsizei _depth, GLenum _format, GLsizei _imageSize, const GLvoid* _data)
 	{
-#if BGFX_CONFIG_RENDERER_OPENGL|BGFX_CONFIG_RENDERER_OPENGLES3
 		if (_target == GL_TEXTURE_3D)
 		{
 			GL_CHECK(glCompressedTexSubImage3D(_target, _level, _xoffset, _yoffset, _zoffset, _width, _height, _depth, _format, _imageSize, _data) );
 		}
 		else
-#endif // BGFX_CONFIG_RENDERER_OPENGL|BGFX_CONFIG_RENDERER_OPENGLES3
 		{
 			BX_UNUSED(_zoffset, _depth);
 			GL_CHECK(glCompressedTexSubImage2D(_target, _level, _xoffset, _yoffset, _width, _height, _format, _imageSize, _data) );
@@ -1387,12 +1385,10 @@ namespace bgfx
 			{
 				target = GL_TEXTURE_CUBE_MAP;
 			}
-#if BGFX_CONFIG_RENDERER_OPENGL|BGFX_CONFIG_RENDERER_OPENGLES3
 			else if (imageContainer.m_depth > 1)
 			{
 				target = GL_TEXTURE_3D;
 			}
-#endif // BGFX_CONFIG_RENDERER_OPENGL|BGFX_CONFIG_RENDERER_OPENGLES3
 
 			init(target
 				, imageContainer.m_format
@@ -1717,12 +1713,12 @@ namespace bgfx
 
 #if BGFX_CONFIG_RENDERER_OPENGL|BGFX_CONFIG_RENDERER_OPENGLES3
 			GL_CHECK(glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, numMips-1) );
+#endif // BGFX_CONFIG_RENDERER_OPENGL|BGFX_CONFIG_RENDERER_OPENGLES3
 
 			if (target == GL_TEXTURE_3D)
 			{
 				GL_CHECK(glTexParameteri(target, GL_TEXTURE_WRAP_R, s_textureAddress[(flags&BGFX_TEXTURE_W_MASK)>>BGFX_TEXTURE_W_SHIFT]) );
 			}
-#endif // BGFX_CONFIG_RENDERER_OPENGL|BGFX_CONFIG_RENDERER_OPENGLES3
 
 			uint32_t mag = (flags&BGFX_TEXTURE_MAG_MASK)>>BGFX_TEXTURE_MAG_SHIFT;
 			uint32_t min = (flags&BGFX_TEXTURE_MIN_MASK)>>BGFX_TEXTURE_MIN_SHIFT;
@@ -1764,6 +1760,124 @@ namespace bgfx
 #endif // BGFX_CONFIG_RENDERER_*
 	}
 
+	void writeString(bx::WriterI* _writer, const char* _str)
+	{
+		bx::write(_writer, _str, strlen(_str) );
+	}
+
+	const char* findMatch(const char* _str, const char* _word)
+	{
+		size_t len = strlen(_word);
+		const char* ptr = strstr(_str, _word);
+		for (; NULL != ptr; ptr = strstr(ptr + len, _word) )
+		{
+			if (ptr != _str)
+			{
+				char ch = *(ptr - 1);
+				if (isalnum(ch) || '_' == ch)
+				{
+					continue;
+				}
+			}
+
+			char ch = ptr[len];
+			if (isalnum(ch) || '_' == ch)
+			{
+				continue;
+			}
+
+			return ptr;
+		}
+
+		return ptr;
+	}
+
+	void Shader::create(GLenum _type, Memory* _mem)
+	{
+		m_id = glCreateShader(_type);
+		m_type = _type;
+
+		bx::MemoryReader reader(_mem->data, _mem->size);
+		m_hash = bx::hashMurmur2A(_mem->data, _mem->size);
+
+		uint32_t magic;
+		bx::read(&reader, magic);
+
+		uint32_t iohash;
+		bx::read(&reader, iohash);
+
+		const char* code = (const char*)reader.getDataPtr();
+
+		if (0 != m_id)
+		{
+#if BGFX_CONFIG_RENDERER_OPENGLES2
+			bool usesDerivatives = s_extension[Extension::OES_standard_derivatives].m_supported &&
+							(  findMatch(code, "dFdx")
+							|| findMatch(code, "dFdy")
+							|| findMatch(code, "fwidth")
+							);
+
+			bool usesTexture3D = s_extension[Extension::OES_texture_3D].m_supported &&
+							(  findMatch(code, "texture3D")
+							|| findMatch(code, "texture3DProj")
+							|| findMatch(code, "texture3DLod")
+							|| findMatch(code, "texture3DProjLod")
+							);
+
+			if (usesDerivatives
+			||  usesTexture3D)
+			{
+				size_t codeLen = strlen(code);
+				size_t tempLen = codeLen + 1024;
+				char* temp = (char*)alloca(tempLen);
+				bx::StaticMemoryBlockWriter writer(temp, tempLen);
+
+				if (usesDerivatives)
+				{
+					writeString(&writer, "#extension GL_OES_standard_derivatives : enable\n");
+				}
+
+				if (usesTexture3D)
+				{
+					writeString(&writer, "#extension GL_OES_texture_3D : enable\n");
+				}
+
+				bx::write(&writer, code, codeLen);
+				bx::write(&writer, '\0');
+
+				code = temp;
+			}
+#endif // BGFX_CONFIG_RENDERER_OPENGLES2
+
+			GL_CHECK(glShaderSource(m_id, 1, (const GLchar**)&code, NULL) );
+			GL_CHECK(glCompileShader(m_id) );
+
+			GLint compiled = 0;
+			GL_CHECK(glGetShaderiv(m_id, GL_COMPILE_STATUS, &compiled) );
+
+			if (0 == compiled)
+			{
+				BX_TRACE("\n####\n%s\n####", code);
+
+				char log[1024];
+				GL_CHECK(glGetShaderInfoLog(m_id, sizeof(log), NULL, log) );
+				BX_TRACE("Failed to compile shader. %d: %s", compiled, log);
+
+				GL_CHECK(glDeleteShader(m_id) );
+				BGFX_FATAL(false, bgfx::Fatal::InvalidShader, "Failed to compile shader.");
+			}
+		}
+	}
+
+	void Shader::destroy()
+	{
+		if (0 != m_id)
+		{
+			GL_CHECK(glDeleteShader(m_id) );
+			m_id = 0;
+		}
+	}
+
 	void RenderTarget::create(uint16_t _width, uint16_t _height, uint32_t _flags, uint32_t _textureFlags)
 	{
 		BX_TRACE("Create render target %dx%d 0x%02x", _width, _height, _flags);
@@ -2413,7 +2527,7 @@ namespace bgfx
 							| ptc1Supported  ? BGFX_CAPS_TEXTURE_FORMAT_PTC12|BGFX_CAPS_TEXTURE_FORMAT_PTC14|BGFX_CAPS_TEXTURE_FORMAT_PTC14A|BGFX_CAPS_TEXTURE_FORMAT_PTC12A : 0
 							| ptc2Supported  ? BGFX_CAPS_TEXTURE_FORMAT_PTC22|BGFX_CAPS_TEXTURE_FORMAT_PTC24 : 0
 							);
-		g_caps.supported |= !!(BGFX_CONFIG_RENDERER_OPENGL|BGFX_CONFIG_RENDERER_OPENGLES3)
+		g_caps.supported |= !!(BGFX_CONFIG_RENDERER_OPENGL|BGFX_CONFIG_RENDERER_OPENGLES3)|s_extension[Extension::OES_texture_3D].m_supported
 						 ? BGFX_CAPS_TEXTURE_3D
 						 : 0
 						 ;

+ 14 - 45
src/renderer_gl.h

@@ -55,12 +55,18 @@ typedef void (GL_APIENTRYP PFNGLGENVERTEXARRAYSOESPROC) (GLsizei n, GLuint *arra
 typedef GLboolean (GL_APIENTRYP PFNGLISVERTEXARRAYOESPROC) (GLuint array);
 typedef void (GL_APIENTRYP PFNGLGETPROGRAMBINARYOESPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, GLvoid *binary);
 typedef void (GL_APIENTRYP PFNGLPROGRAMBINARYOESPROC) (GLuint program, GLenum binaryFormat, const GLvoid *binary, GLint length);
+typedef void (GL_APIENTRYP PFNGLTEXIMAGE3DOESPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels);
+typedef void (GL_APIENTRYP PFNGLTEXSUBIMAGE3DOESPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels);
+typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DOESPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data);
+typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DOESPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data);
 typedef void (GL_APIENTRYP PFLGLDRAWARRAYSINSTANCEDANGLEPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount);
 typedef void (GL_APIENTRYP PFLGLDRAWELEMENTSINSTANCEDANGLEPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount);
 typedef void (GL_APIENTRYP PFLGLVERTEXATTRIBDIVISORANGLEPROC) (GLuint index, GLuint divisor);
 //#define GL_UNSIGNED_INT_10_10_10_2_OES                          0x8DF6
 #define GL_UNSIGNED_INT_2_10_10_10_REV_EXT                      0x8368
+#define GL_TEXTURE_3D_OES                                       0x806F
 #define GL_SAMPLER_3D_OES                                       0x8B5F
+#define GL_TEXTURE_WRAP_R_OES                                   0x8072
 #define GL_PROGRAM_BINARY_LENGTH_OES                            0x8741
 #		else
 #			include <GLES2/gl2platform.h>
@@ -69,6 +75,10 @@ typedef void (GL_APIENTRYP PFLGLVERTEXATTRIBDIVISORANGLEPROC) (GLuint index, GLu
 #		endif // BX_PLATFORM_
 #		define glProgramBinary glProgramBinaryOES
 #		define glGetProgramBinary glGetProgramBinaryOES
+#		define glTexImage3D glTexImage3DOES
+#		define glTexSubImage3D glTexSubImage3DOES
+#		define glCompressedTexImage3D glCompressedTexImage3DOES
+#		define glCompressedTexSubImage3D glCompressedTexSubImage3DOES
 #		define glBindVertexArray glBindVertexArrayOES
 #		define glDeleteVertexArrays glDeleteVertexArraysOES
 #		define glGenVertexArrays glGenVertexArraysOES
@@ -79,7 +89,9 @@ typedef void (GL_APIENTRYP PFLGLVERTEXATTRIBDIVISORANGLEPROC) (GLuint index, GLu
 #		define GL_R16F GL_R16F_EXT
 #		define GL_R32F GL_R32F_EXT
 #		define GL_UNSIGNED_INT_2_10_10_10_REV GL_UNSIGNED_INT_2_10_10_10_REV_EXT
+#		define GL_TEXTURE_3D GL_TEXTURE_3D_OES
 #		define GL_SAMPLER_3D GL_SAMPLER_3D_OES
+#		define GL_TEXTURE_WRAP_R GL_TEXTURE_WRAP_R_OES
 #		define GL_MIN GL_MIN_EXT
 #		define GL_MAX GL_MAX_EXT
 #	elif BGFX_CONFIG_RENDERER_OPENGLES3
@@ -571,51 +583,8 @@ namespace bgfx
 		{
 		}
 
-		void create(GLenum _type, Memory* _mem)
-		{
-			m_id = glCreateShader(_type);
-			m_type = _type;
-
-			bx::MemoryReader reader(_mem->data, _mem->size);
-			m_hash = bx::hashMurmur2A(_mem->data, _mem->size);
-
-			uint32_t magic;
-			bx::read(&reader, magic);
-
-			uint32_t iohash;
-			bx::read(&reader, iohash);
-
-			const uint8_t* code = reader.getDataPtr();
-
-			if (0 != m_id)
-			{
-				GL_CHECK(glShaderSource(m_id, 1, (const GLchar**)&code, NULL) );
-				GL_CHECK(glCompileShader(m_id) );
-
-				GLint compiled = 0;
-				GL_CHECK(glGetShaderiv(m_id, GL_COMPILE_STATUS, &compiled) );
-
-				if (0 == compiled)
-				{
-					char log[1024];
-					GL_CHECK(glGetShaderInfoLog(m_id, sizeof(log), NULL, log) );
-					BX_TRACE("Failed to compile shader. %d: %s", compiled, log);
-					BX_TRACE("\n####\n%s\n####", code);
-
-					GL_CHECK(glDeleteShader(m_id) );
-					BGFX_FATAL(false, bgfx::Fatal::InvalidShader, "Failed to compile shader.");
-				}
-			}
-		}
-
-		void destroy()
-		{
-			if (0 != m_id)
-			{
-				GL_CHECK(glDeleteShader(m_id) );
-				m_id = 0;
-			}
-		}
+		void create(GLenum _type, Memory* _mem);
+		void destroy();
 
 		GLuint m_id;
 		GLenum m_type;