소스 검색

Added support for the extension OES_EGL_image_external(_essl3) for GLES2/3 (#2021)

Co-authored-by: Gabriel <[email protected]>
G 5 년 전
부모
커밋
f07a0f5179
5개의 변경된 파일259개의 추가작업 그리고 15개의 파일을 삭제
  1. 3 1
      3rdparty/glsl-optimizer/src/glsl/ir_print_glsl_visitor.cpp
  2. 8 0
      src/bgfx_shader.sh
  3. 133 11
      src/renderer_gl.cpp
  4. 104 3
      src/renderer_gl.h
  5. 11 0
      tools/shaderc/shaderc.cpp

+ 3 - 1
3rdparty/glsl-optimizer/src/glsl/ir_print_glsl_visitor.cpp

@@ -50,7 +50,7 @@ static inline const char* get_precision_string (glsl_precision p)
 static const int tex_sampler_type_count = 7;
 // [glsl_sampler_dim]
 static const char* tex_sampler_dim_name[tex_sampler_type_count] = {
-	"1D", "2D", "3D", "Cube", "Rect", "Buf", "External",
+	"1D", "2D", "3D", "Cube", "Rect", "Buf", "2D",
 };
 static int tex_sampler_dim_size[tex_sampler_type_count] = {
 	1, 2, 3, 3, 2, 2, 2,
@@ -256,6 +256,8 @@ _mesa_print_ir_glsl(exec_list *instructions,
 			str.asprintf_append("#extension GL_ARB_shader_bit_encoding : enable\n");
 		if (state->EXT_texture_array_enable)
 			str.asprintf_append ("#extension GL_EXT_texture_array : enable\n");
+		if (state->OES_EGL_image_external_enable)
+			str.asprintf_append ("#extension GL_OES_EGL_image_external : enable\n");
 	}
 	
 	// remove unused struct declarations

+ 8 - 0
src/bgfx_shader.sh

@@ -495,6 +495,8 @@ float bgfxShadow2DProj(sampler2DShadow _sampler, vec4 _coord)
 
 #	endif // BGFX_SHADER_LANGUAGE_HLSL > 3
 
+#	define SAMPLEREXTERNAL(_name, _reg) SAMPLER2D(_name, _reg)
+
 vec3 instMul(vec3 _vec, mat3 _mtx) { return mul(_mtx, _vec); }
 vec3 instMul(mat3 _mtx, vec3 _vec) { return mul(_vec, _mtx); }
 vec4 instMul(vec4 _vec, mat4 _mtx) { return mul(_mtx, _vec); }
@@ -555,6 +557,12 @@ vec4  mod(vec4  _a, vec4  _b) { return _a - _b * floor(_a / _b); }
 #	define ISAMPLER3D(_name, _reg) uniform isampler3D _name
 #	define USAMPLER3D(_name, _reg) uniform usampler3D _name
 
+#	if BGFX_SHADER_LANGUAGE_GLSL == 1
+#		define SAMPLEREXTERNAL(_name, _reg) uniform samplerExternalOES _name
+#	else
+#		define SAMPLEREXTERNAL(_name, _reg) SAMPLER2D(_name, _req)
+#	endif
+
 #	define texture2DBias(_sampler, _coord, _bias)      texture2D(_sampler, _coord, _bias)
 #	define textureCubeBias(_sampler, _coord, _bias)    textureCube(_sampler, _coord, _bias)
 

+ 133 - 11
src/renderer_gl.cpp

@@ -635,6 +635,8 @@ namespace bgfx { namespace gl
 			OES_depth24,
 			OES_depth32,
 			OES_depth_texture,
+			OES_EGL_image_external,
+			OES_EGL_image_external_essl3,
 			OES_element_index_uint,
 			OES_fragment_precision_high,
 			OES_get_program_binary,
@@ -846,6 +848,8 @@ namespace bgfx { namespace gl
 		{ "OES_depth24",                              false,                             true  },
 		{ "OES_depth32",                              false,                             true  },
 		{ "OES_depth_texture",                        false,                             true  },
+		{ "OES_EGL_image_external",                   false,                             true  }, // GLES2 extension.
+		{ "OES_EGL_image_external_essl3",             false,                             true  }, // GLES3 extension.
 		{ "OES_element_index_uint",                   false,                             true  },
 		{ "OES_fragment_precision_high",              false,                             true  },
 		{ "OES_get_program_binary",                   false,                             true  },
@@ -927,6 +931,12 @@ namespace bgfx { namespace gl
 		NULL
 	};
 
+	static const char* s_OES_EGL_image_external[] =
+	{
+		"samplerExternalOES",
+		NULL
+	};
+
 	static const char* s_uisamplers[] =
 	{
 		"isampler2D",
@@ -3433,7 +3443,7 @@ namespace bgfx { namespace gl
 
 			ProgramGL& program = m_program[_blitter.m_program.idx];
 			GL_CHECK(glUseProgram(program.m_id) );
-			GL_CHECK(glUniform1i(program.m_sampler[0], 0) );
+			GL_CHECK(glUniform1i(program.m_sampler[0].loc, 0) );
 
 			float proj[16];
 			bx::mtxOrtho(proj, 0.0f, (float)width, (float)height, 0.0f, 0.0f, 1000.0f, 0.0f, g_caps.homogeneousDepth);
@@ -4393,6 +4403,8 @@ namespace bgfx { namespace gl
 			GLSL_TYPE(GL_IMAGE_CUBE);
 			GLSL_TYPE(GL_INT_IMAGE_CUBE);
 			GLSL_TYPE(GL_UNSIGNED_INT_IMAGE_CUBE);
+			GLSL_TYPE(GL_SAMPLER_EXTERNAL_OES);
+
 		}
 
 #undef GLSL_TYPE
@@ -4491,6 +4503,8 @@ namespace bgfx { namespace gl
 		case GL_IMAGE_CUBE:
 		case GL_INT_IMAGE_CUBE:
 		case GL_UNSIGNED_INT_IMAGE_CUBE:
+
+		case GL_SAMPLER_EXTERNAL_OES:
 			return UniformType::Sampler;
 		};
 
@@ -4498,6 +4512,88 @@ namespace bgfx { namespace gl
 		return UniformType::End;
 	}
 
+	GLenum glSamplerTarget(GLenum _sampler){
+		switch (_sampler)
+		{
+			case GL_SAMPLER_1D:
+			case GL_INT_SAMPLER_1D:
+			case GL_UNSIGNED_INT_SAMPLER_1D:
+			case GL_SAMPLER_1D_SHADOW:
+				return GL_TEXTURE_1D;
+
+			case GL_SAMPLER_1D_ARRAY:
+			case GL_INT_SAMPLER_1D_ARRAY:
+			case GL_UNSIGNED_INT_SAMPLER_1D_ARRAY:
+			case GL_SAMPLER_1D_ARRAY_SHADOW:
+				return GL_TEXTURE_1D_ARRAY;
+
+			case GL_SAMPLER_2D:
+			case GL_INT_SAMPLER_2D:
+			case GL_UNSIGNED_INT_SAMPLER_2D:
+			case GL_SAMPLER_2D_SHADOW:
+				return GL_TEXTURE_2D;
+
+			case GL_SAMPLER_2D_ARRAY:
+			case GL_INT_SAMPLER_2D_ARRAY:
+			case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
+			case GL_SAMPLER_2D_ARRAY_SHADOW:
+				return GL_TEXTURE_2D_ARRAY;
+
+			case GL_SAMPLER_2D_MULTISAMPLE:
+				return GL_TEXTURE_2D_MULTISAMPLE;
+
+			case GL_SAMPLER_2D_MULTISAMPLE_ARRAY:
+				return GL_TEXTURE_2D_MULTISAMPLE_ARRAY;
+
+			case GL_SAMPLER_CUBE:
+			case GL_SAMPLER_CUBE_SHADOW:
+			case GL_INT_SAMPLER_CUBE:
+			case GL_UNSIGNED_INT_SAMPLER_CUBE:
+				return GL_TEXTURE_CUBE_MAP;
+
+			case GL_SAMPLER_CUBE_MAP_ARRAY:
+			case GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW:
+			case GL_INT_SAMPLER_CUBE_MAP_ARRAY:
+			case GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY:
+				return GL_TEXTURE_CUBE_MAP_ARRAY;
+
+			case GL_SAMPLER_3D:
+			case GL_INT_SAMPLER_3D:
+			case GL_UNSIGNED_INT_SAMPLER_3D:
+				return GL_TEXTURE_3D;
+
+			case GL_SAMPLER_EXTERNAL_OES:
+				return GL_TEXTURE_EXTERNAL_OES;
+
+			case GL_SAMPLER_2D_RECT:
+			case GL_INT_SAMPLER_2D_RECT:
+			case GL_UNSIGNED_INT_SAMPLER_2D_RECT:
+			case GL_SAMPLER_2D_RECT_SHADOW:
+				return GL_TEXTURE_RECTANGLE;
+
+			case GL_IMAGE_1D:
+
+			case GL_INT_IMAGE_1D:
+			case GL_UNSIGNED_INT_IMAGE_1D:
+
+			case GL_IMAGE_2D:
+			case GL_INT_IMAGE_2D:
+			case GL_UNSIGNED_INT_IMAGE_2D:
+
+			case GL_IMAGE_3D:
+			case GL_INT_IMAGE_3D:
+			case GL_UNSIGNED_INT_IMAGE_3D:
+
+			case GL_IMAGE_CUBE:
+			case GL_INT_IMAGE_CUBE:
+			case GL_UNSIGNED_INT_IMAGE_CUBE:
+				return 0;
+		}
+
+		BX_CHECK(false, "Unrecognized GL sampler type 0x%04x.", _sampler);
+		return 0;
+	}
+
 	void ProgramGL::create(const ShaderGL& _vsh, const ShaderGL& _fsh)
 	{
 		m_id = glCreateProgram();
@@ -4646,6 +4742,7 @@ namespace bgfx { namespace gl
 
 		m_numPredefined = 0;
 		m_numSamplers = 0;
+		bx::memSet(m_sampler, 0, sizeof(m_sampler) );
 
 		BX_TRACE("Uniforms (%d):", activeUniforms);
 		for (int32_t ii = 0; ii < activeUniforms; ++ii)
@@ -4745,10 +4842,12 @@ namespace bgfx { namespace gl
 			case GL_IMAGE_CUBE:
 			case GL_INT_IMAGE_CUBE:
 			case GL_UNSIGNED_INT_IMAGE_CUBE:
+
+			case GL_SAMPLER_EXTERNAL_OES:
 				if (m_numSamplers < BX_COUNTOF(m_sampler) )
 				{
 					BX_TRACE("Sampler #%d at location %d.", m_numSamplers, loc);
-					m_sampler[m_numSamplers] = loc;
+					m_sampler[m_numSamplers] = {loc, glSamplerTarget(gltype)};
 					m_numSamplers++;
 				}
 				else
@@ -5595,16 +5694,17 @@ namespace bgfx { namespace gl
 		}
 	}
 
-	void TextureGL::commit(uint32_t _stage, uint32_t _flags, const float _palette[][4])
+	void TextureGL::commit(uint32_t _stage, uint32_t _flags, const float _palette[][4], GLenum _target)
 	{
 		const uint32_t flags = 0 == (BGFX_SAMPLER_INTERNAL_DEFAULT & _flags)
 			? _flags
 			: uint32_t(m_flags)
 			;
 		const uint32_t index = (flags & BGFX_SAMPLER_BORDER_COLOR_MASK) >> BGFX_SAMPLER_BORDER_COLOR_SHIFT;
+		const GLenum target = 0 == _target ? m_target : _target;
 
 		GL_CHECK(glActiveTexture(GL_TEXTURE0+_stage) );
-		GL_CHECK(glBindTexture(m_target, m_id) );
+		GL_CHECK(glBindTexture(target, m_id) );
 
 		if (BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGLES)
 		&&  BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGLES < 30) )
@@ -5750,6 +5850,10 @@ namespace bgfx { namespace gl
 						&& !bx::findIdentifierMatch(code, s_OES_standard_derivatives).isEmpty()
 						;
 
+					const bool  usesSamplerExternal = s_extension[Extension::OES_EGL_image_external].m_supported
+						&& !bx::findIdentifierMatch(code, s_OES_EGL_image_external).isEmpty()
+						;
+
 					const bool usesFragData         = !bx::findIdentifierMatch(code, "gl_FragData").isEmpty();
 					const bool usesFragDepth        = !bx::findIdentifierMatch(code, "gl_FragDepth").isEmpty();
 					const bool usesShadowSamplers   = !bx::findIdentifierMatch(code, s_EXT_shadow_samplers).isEmpty();
@@ -5766,6 +5870,11 @@ namespace bgfx { namespace gl
 						bx::write(&writer, "#extension GL_OES_standard_derivatives : enable\n");
 					}
 
+					if (usesSamplerExternal)
+					{
+						bx::write(&writer, "#extension GL_OES_EGL_image_external : enable\n");
+					}
+
 					if (usesFragData)
 					{
 						BX_WARN(s_extension[Extension::EXT_draw_buffers  ].m_supported
@@ -6118,11 +6227,7 @@ namespace bgfx { namespace gl
 				{
 					if (BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGLES >= 30) )
 					{
-						bx::write(&writer, &err
-							, "#version 300 es\n"
-							  "precision %s float;\n"
-							, m_type == GL_FRAGMENT_SHADER ? "mediump" : "highp"
-							);
+						bx::write(&writer, "#version 300 es\n");
 					}
 					else
 					{
@@ -6191,6 +6296,23 @@ namespace bgfx { namespace gl
 							bx::write(&writer, "#extension GL_ARB_texture_multisample : enable\n");
 						}
 
+						const bool  usesSamplerExternal = s_extension[Extension::OES_EGL_image_external_essl3].m_supported
+							&& !bx::findIdentifierMatch(code, s_OES_EGL_image_external).isEmpty()
+							;
+
+						if(usesSamplerExternal)
+						{
+							bx::write(&writer, "#extension GL_OES_EGL_image_external_essl3 : enable\n");
+						}
+
+						if (BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGLES >= 30) )
+						{
+							bx::write(&writer, &err
+								, "precision %s float;\n"
+								, m_type == GL_FRAGMENT_SHADER ? "mediump" : "highp"
+								);
+						}
+
 						if (0 != fragData)
 						{
 							bx::write(&writer, &err, "out vec4 bgfx_FragData[%d];\n", fragData);
@@ -7046,7 +7168,7 @@ namespace bgfx { namespace gl
 								case Binding::Texture:
 									{
 										TextureGL& texture = m_textures[bind.m_idx];
-										texture.commit(ii, bind.m_samplerFlags, _render->m_colorPalette);
+										texture.commit(ii, bind.m_samplerFlags, _render->m_colorPalette, program.m_sampler[ii].target);
 									}
 									break;
 
@@ -7566,7 +7688,7 @@ namespace bgfx { namespace gl
 									case Binding::Texture:
 										{
 											TextureGL& texture = m_textures[bind.m_idx];
-											texture.commit(stage, bind.m_samplerFlags, _render->m_colorPalette);
+											texture.commit(stage, bind.m_samplerFlags, _render->m_colorPalette, program.m_sampler[stage].target);
 										}
 										break;
 

+ 104 - 3
src/renderer_gl.h

@@ -724,6 +724,90 @@ typedef uint64_t GLuint64;
 #	define GL_COMPARE_REF_TO_TEXTURE 0x884E
 #endif // GL_COMPARE_REF_TO_TEXTURE
 
+#ifndef GL_SAMPLER_1D
+#    define GL_SAMPLER_1D 0x8B5D
+#endif // GL_SAMPLER_1D
+
+#ifndef GL_INT_SAMPLER_1D
+#    define GL_INT_SAMPLER_1D 0x8DC9
+#endif // GL_INT_SAMPLER_1D
+
+#ifndef GL_UNSIGNED_INT_SAMPLER_1D
+#    define GL_UNSIGNED_INT_SAMPLER_1D 0x8DD1
+#endif // GL_UNSIGNED_INT_SAMPLER_1D
+
+#ifndef GL_SAMPLER_1D_SHADOW
+#    define GL_SAMPLER_1D_SHADOW 0x8B61
+#endif // GL_SAMPLER_1D_SHADOW
+
+#ifndef GL_TEXTURE_1D
+#    define GL_TEXTURE_1D 0x0DE0
+#endif // GL_TEXTURE_1D
+
+#ifndef GL_SAMPLER_1D_ARRAY
+#    define GL_SAMPLER_1D_ARRAY 0x8DC0
+#endif // GL_SAMPLER_1D_ARRAY
+
+#ifndef GL_INT_SAMPLER_1D_ARRAY
+#    define GL_INT_SAMPLER_1D_ARRAY 0x8DCE
+#endif // GL_INT_SAMPLER_1D_ARRAY
+
+#ifndef GL_UNSIGNED_INT_SAMPLER_1D_ARRAY
+#    define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY 0x8DD6
+#endif // GL_UNSIGNED_INT_SAMPLER_1D_ARRAY
+
+#ifndef GL_SAMPLER_1D_ARRAY_SHADOW
+#    define GL_SAMPLER_1D_ARRAY_SHADOW 0x8DC3
+#endif // GL_SAMPLER_1D_ARRAY_SHADOW
+
+#ifndef GL_TEXTURE_1D_ARRAY
+#    define GL_TEXTURE_1D_ARRAY 0x8C18
+#endif // GL_TEXTURE_1D_ARRAY
+
+#ifndef GL_SAMPLER_2D_MULTISAMPLE_ARRAY
+#    define GL_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910B
+#endif // GL_SAMPLER_2D_MULTISAMPLE_ARRAY
+
+#ifndef GL_SAMPLER_CUBE_MAP_ARRAY
+#    define GL_SAMPLER_CUBE_MAP_ARRAY 0x900C
+#endif // GL_SAMPLER_CUBE_MAP_ARRAY
+
+#ifndef GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW
+#    define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW 0x900D
+#endif // GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW
+
+#ifndef GL_INT_SAMPLER_CUBE_MAP_ARRAY
+#    define GL_INT_SAMPLER_CUBE_MAP_ARRAY 0x900E
+#endif // GL_INT_SAMPLER_CUBE_MAP_ARRAY
+
+#ifndef GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY
+#    define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY 0x900F
+#endif // GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY
+
+#ifndef GL_SAMPLER_2D_RECT
+#    define GL_SAMPLER_2D_RECT 0x8B63
+#endif // GL_SAMPLER_2D_RECT
+
+#ifndef GL_INT_SAMPLER_2D_RECT
+#    define GL_INT_SAMPLER_2D_RECT 0x8DCD
+#endif // GL_INT_SAMPLER_2D_RECT
+
+#ifndef GL_UNSIGNED_INT_SAMPLER_2D_RECT
+#    define GL_UNSIGNED_INT_SAMPLER_2D_RECT 0x8DD5
+#endif // GL_UNSIGNED_INT_SAMPLER_2D_RECT
+
+#ifndef GL_SAMPLER_2D_RECT_SHADOW
+#    define GL_SAMPLER_2D_RECT_SHADOW 0x8B64
+#endif // GL_SAMPLER_2D_RECT_SHADOW
+
+#ifndef GL_TEXTURE_RECTANGLE
+#    define GL_TEXTURE_RECTANGLE 0x84F5
+#endif // GL_TEXTURE_RECTANGLE
+
+#ifndef GL_SAMPLER_CUBE_SHADOW
+#    define GL_SAMPLER_CUBE_SHADOW 0x8DC5
+#endif // GL_SAMPLER_CUBE_SHADOW
+
 #ifndef GL_INT_SAMPLER_2D
 #	define GL_INT_SAMPLER_2D 0x8DCA
 #endif // GL_INT_SAMPLER_2D
@@ -750,7 +834,7 @@ typedef uint64_t GLuint64;
 
 #ifndef GL_INT_SAMPLER_CUBE
 #	define GL_INT_SAMPLER_CUBE 0x8DCC
-#endif // GL_INT_SAMPLER_CUBEER_3D
+#endif // GL_INT_SAMPLER_CUBE
 
 #ifndef GL_UNSIGNED_INT_SAMPLER_CUBE
 #	define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4
@@ -780,6 +864,18 @@ typedef uint64_t GLuint64;
 #	define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4
 #endif // GL_SAMPLER_2D_ARRAY_SHADOW
 
+#ifndef GL_SAMPLER_EXTERNAL_OES
+#    define GL_SAMPLER_EXTERNAL_OES 0x8D66
+#endif // GL_SAMPLER_EXTERNAL_OES
+
+#ifndef GL_TEXTURE_EXTERNAL_OES
+#    define GL_TEXTURE_EXTERNAL_OES 0x8D65
+#endif // GL_TEXTURE_EXTERNAL_OES
+
+#ifndef GL_TEXTURE_BINDING_EXTERNAL_OES
+#    define GL_TEXTURE_BINDING_EXTERNAL_OES 0x8D67
+#endif // GL_TEXTURE_BINDING_EXTERNAL_OES
+
 #ifndef GL_TEXTURE_MAX_LEVEL
 #	define GL_TEXTURE_MAX_LEVEL 0x813D
 #endif // GL_TEXTURE_MAX_LEVEL
@@ -1295,7 +1391,7 @@ namespace bgfx { namespace gl
 		void overrideInternal(uintptr_t _ptr);
 		void update(uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, uint16_t _pitch, const Memory* _mem);
 		void setSamplerState(uint32_t _flags, const float _rgba[4]);
-		void commit(uint32_t _stage, uint32_t _flags, const float _palette[][4]);
+		void commit(uint32_t _stage, uint32_t _flags, const float _palette[][4], GLenum _target);
 		void resolve(uint8_t _resolve) const;
 
 		bool isCubeMap() const
@@ -1369,6 +1465,11 @@ namespace bgfx { namespace gl
 		Attachment m_attachment[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS];
 	};
 
+	struct SamplerGL {
+		GLint loc;
+		GLenum target;
+	};
+
 	struct ProgramGL
 	{
 		ProgramGL()
@@ -1414,7 +1515,7 @@ namespace bgfx { namespace gl
 		GLint m_attributes[Attrib::Count]; // Sparse.
 		GLint m_instanceData[BGFX_CONFIG_MAX_INSTANCE_DATA_COUNT+1];
 
-		GLint m_sampler[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS];
+		SamplerGL m_sampler[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS];
 		uint8_t m_numSamplers;
 
 		UniformBuffer* m_constantBuffer;

+ 11 - 0
tools/shaderc/shaderc.cpp

@@ -83,6 +83,12 @@ namespace bgfx
 		NULL
 	};
 
+	static const char* s_OES_EGL_image_external[] =
+	{
+		"samplerExternalOES",
+		NULL
+	};
+
 	static const char* s_EXT_gpu_shader4[] =
 	{
 		"gl_VertexID",
@@ -2181,6 +2187,11 @@ namespace bgfx
 										bx::stringPrintf(code, "#extension GL_OES_texture_3D : enable\n");
 									}
 
+									if (!bx::findIdentifierMatch(input, s_OES_EGL_image_external).isEmpty() )
+									{
+										bx::stringPrintf(code, "#extension GL_OES_EGL_image_external : enable\n");
+									}
+
 									if (!bx::findIdentifierMatch(input, s_EXT_shadow_samplers).isEmpty() )
 									{
 										bx::stringPrintf(code