From f07a0f51792db2351f6a38e1625a704be159a6ee Mon Sep 17 00:00:00 2001 From: G <10632905+HerrKamrat@users.noreply.github.com> Date: Mon, 6 Apr 2020 17:20:49 +0200 Subject: [PATCH] Added support for the extension OES_EGL_image_external(_essl3) for GLES2/3 (#2021) Co-authored-by: Gabriel --- .../src/glsl/ir_print_glsl_visitor.cpp | 4 +- src/bgfx_shader.sh | 8 + src/renderer_gl.cpp | 144 ++++++++++++++++-- src/renderer_gl.h | 107 ++++++++++++- tools/shaderc/shaderc.cpp | 11 ++ 5 files changed, 259 insertions(+), 15 deletions(-) diff --git a/3rdparty/glsl-optimizer/src/glsl/ir_print_glsl_visitor.cpp b/3rdparty/glsl-optimizer/src/glsl/ir_print_glsl_visitor.cpp index 02bd86344..5e26cec81 100644 --- a/3rdparty/glsl-optimizer/src/glsl/ir_print_glsl_visitor.cpp +++ b/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 diff --git a/src/bgfx_shader.sh b/src/bgfx_shader.sh index 17e56a2eb..e36027057 100644 --- a/src/bgfx_shader.sh +++ b/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) diff --git a/src/renderer_gl.cpp b/src/renderer_gl.cpp index 3de91a1cc..65cd81dd3 100644 --- a/src/renderer_gl.cpp +++ b/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; diff --git a/src/renderer_gl.h b/src/renderer_gl.h index baa121593..37706d0c0 100644 --- a/src/renderer_gl.h +++ b/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; diff --git a/tools/shaderc/shaderc.cpp b/tools/shaderc/shaderc.cpp index 9ddd0e5ca..f1de75819 100644 --- a/tools/shaderc/shaderc.cpp +++ b/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