From a5a9c913fb0758ebf6b040f8220fdaf1368f773a Mon Sep 17 00:00:00 2001 From: Eliza Velasquez Date: Mon, 23 Oct 2023 13:52:59 -0700 Subject: [PATCH] Miscellaneous feature level 0 fixes Fix edge case where an empty struct could be generated in an ESSL 1.0 shader. Include _maskThreshold and _doubleSided in ESSL 1.0 shaders. Add GL_OES_standard_derivatives extension to ESSL 1.0 shaders. According to gpuinfo.org, this has 96% device coverage and supports both Mali-400 and Adreno (TM) 304. Remove 3D sampler support from ESSL 1.0 shaders. This extension is only supported by 62% of devices. Change filagui material to a FL0 material. --- NEW_RELEASE_NOTES.md | 3 +++ .../include/private/filament/BufferInterfaceBlock.h | 2 ++ libs/filabridge/src/BufferInterfaceBlock.cpp | 9 ++++++++- libs/filagui/src/materials/uiBlit.mat | 5 +++-- libs/filamat/src/MaterialBuilder.cpp | 4 ++-- libs/filamat/src/shaders/CodeGenerator.cpp | 12 +++++++----- 6 files changed, 25 insertions(+), 10 deletions(-) diff --git a/NEW_RELEASE_NOTES.md b/NEW_RELEASE_NOTES.md index f0b7719bd31c..824aabcd3d75 100644 --- a/NEW_RELEASE_NOTES.md +++ b/NEW_RELEASE_NOTES.md @@ -15,3 +15,6 @@ appropriate header in [RELEASE_NOTES.md](./RELEASE_NOTES.md). - matinfo: Add support for viewing ESSL 1.0 shaders - engine: Add `Renderer::getClearOptions()` [b/243846268] - engine: Fix stable shadows (again) when an IBL rotation is used +- matc: Enable `GL_OES_standard_derivatives` extension in ESSL 1.0 shaders +- matc: Fix code generation of double sided and masked materials in ESSL 1.0 shaders +- filagui: Add support for feature level 0 diff --git a/libs/filabridge/include/private/filament/BufferInterfaceBlock.h b/libs/filabridge/include/private/filament/BufferInterfaceBlock.h index 2d7c8963de30..c47193208fd0 100644 --- a/libs/filabridge/include/private/filament/BufferInterfaceBlock.h +++ b/libs/filabridge/include/private/filament/BufferInterfaceBlock.h @@ -160,6 +160,8 @@ class BufferInterfaceBlock { bool isEmpty() const noexcept { return mFieldInfoList.empty(); } + bool isEmptyForFeatureLevel(backend::FeatureLevel featureLevel) const noexcept; + Alignment getAlignment() const noexcept { return mAlignment; } Target getTarget() const noexcept { return mTarget; } diff --git a/libs/filabridge/src/BufferInterfaceBlock.cpp b/libs/filabridge/src/BufferInterfaceBlock.cpp index 96e725f95fe6..6c6cf9efc5c9 100644 --- a/libs/filabridge/src/BufferInterfaceBlock.cpp +++ b/libs/filabridge/src/BufferInterfaceBlock.cpp @@ -171,6 +171,14 @@ BufferInterfaceBlock::FieldInfo const* BufferInterfaceBlock::getFieldInfo( return &mFieldInfoList[pos->second]; } +bool BufferInterfaceBlock::isEmptyForFeatureLevel( + backend::FeatureLevel featureLevel) const noexcept { + return std::all_of(mFieldInfoList.begin(), mFieldInfoList.end(), + [featureLevel](auto const &info) { + return featureLevel < info.minFeatureLevel; + }); +} + uint8_t UTILS_NOINLINE BufferInterfaceBlock::baseAlignmentForType(BufferInterfaceBlock::Type type) noexcept { switch (type) { case Type::BOOL: @@ -230,4 +238,3 @@ uint8_t UTILS_NOINLINE BufferInterfaceBlock::strideForType(BufferInterfaceBlock: } } // namespace filament - diff --git a/libs/filagui/src/materials/uiBlit.mat b/libs/filagui/src/materials/uiBlit.mat index 46b66338a91a..08b2161b13ec 100644 --- a/libs/filagui/src/materials/uiBlit.mat +++ b/libs/filagui/src/materials/uiBlit.mat @@ -13,7 +13,8 @@ material { shadingModel : unlit, culling : none, depthCulling: false, - blending : transparent + blending : transparent, + featureLevel : 0 } fragment { @@ -21,7 +22,7 @@ fragment { prepareMaterial(material); vec2 uv = getUV0(); uv.y = 1.0 - uv.y; - vec4 albedo = texture(materialParams_albedo, uv); + vec4 albedo = texture2D(materialParams_albedo, uv); material.baseColor = getColor() * albedo; material.baseColor.rgb *= material.baseColor.a; } diff --git a/libs/filamat/src/MaterialBuilder.cpp b/libs/filamat/src/MaterialBuilder.cpp index 01e645c68779..b6d52e3396d4 100644 --- a/libs/filamat/src/MaterialBuilder.cpp +++ b/libs/filamat/src/MaterialBuilder.cpp @@ -587,11 +587,11 @@ void MaterialBuilder::prepareToBuild(MaterialInfo& info) noexcept { } if (mBlendingMode == BlendingMode::MASKED) { - ibb.add({{ "_maskThreshold", 0, UniformType::FLOAT }}); + ibb.add({{ "_maskThreshold", 0, UniformType::FLOAT, Precision::DEFAULT, FeatureLevel::FEATURE_LEVEL_0 }}); } if (mDoubleSidedCapability) { - ibb.add({{ "_doubleSided", 0, UniformType::BOOL }}); + ibb.add({{ "_doubleSided", 0, UniformType::BOOL, Precision::DEFAULT, FeatureLevel::FEATURE_LEVEL_0 }}); } mRequiredAttributes.set(VertexAttribute::POSITION); diff --git a/libs/filamat/src/shaders/CodeGenerator.cpp b/libs/filamat/src/shaders/CodeGenerator.cpp index dc9d2150341f..28ba2a4fa7ea 100644 --- a/libs/filamat/src/shaders/CodeGenerator.cpp +++ b/libs/filamat/src/shaders/CodeGenerator.cpp @@ -63,9 +63,6 @@ utils::io::sstream& CodeGenerator::generateProlog(utils::io::sstream& out, Shade out << "#extension GL_OES_EGL_image_external : require\n\n"; } } - if (material.has3dSamplers && mFeatureLevel == FeatureLevel::FEATURE_LEVEL_0) { - out << "#extension GL_OES_texture_3D : require\n\n"; - } if (v.hasInstancedStereo() && stage == ShaderStage::VERTEX) { // If we're not processing the shader through glslang (in the case of unoptimized // OpenGL shaders), then we need to add the #extension string ourselves. @@ -89,6 +86,10 @@ utils::io::sstream& CodeGenerator::generateProlog(utils::io::sstream& out, Shade break; } + if (mFeatureLevel == FeatureLevel::FEATURE_LEVEL_0) { + out << "#extension GL_OES_standard_derivatives : require\n\n"; + } + // This allows our includer system to use the #line directive to denote the source file for // #included code. This way, glslang reports errors more accurately. out << "#extension GL_GOOGLE_cpp_style_line_directive : enable\n\n"; @@ -554,11 +555,12 @@ io::sstream& CodeGenerator::generateUboAsPlainUniforms(io::sstream& out, ShaderS io::sstream& CodeGenerator::generateBufferInterfaceBlock(io::sstream& out, ShaderStage stage, uint32_t binding, const BufferInterfaceBlock& uib) const { - auto const& infos = uib.getFieldInfoList(); - if (infos.empty()) { + if (uib.isEmptyForFeatureLevel(mFeatureLevel)) { return out; } + auto const& infos = uib.getFieldInfoList(); + if (mTargetLanguage == TargetLanguage::GLSL && mFeatureLevel == FeatureLevel::FEATURE_LEVEL_0) { // we need to generate a structure instead