get rid of filmat-lite, which was poorly maintained

This commit is contained in:
Mathias Agopian
2023-09-26 13:38:44 -07:00
committed by Mathias Agopian
parent df50f4c25d
commit 39d555d115
14 changed files with 9 additions and 669 deletions

View File

@@ -6,9 +6,6 @@ option(FILAMENT_ENABLE_MATDBG "Enables Material debugger" OFF)
set(FILAMENT_DIR ${FILAMENT_DIST_DIR})
set(FILAMAT_FLAVOR "filamat")
if(FILAMAT_LITE)
set(FILAMAT_FLAVOR "filamat_lite")
endif()
if (FILAMENT_SUPPORTS_VULKAN)
message("Library filamat ignores Vulkan settings")

View File

@@ -1,29 +1,8 @@
android {
namespace 'com.google.android.filament.filamat'
flavorDimensions "functionality"
productFlavors {
full {
dimension "functionality"
}
lite {
dimension "functionality"
externalNativeBuild {
cmake {
arguments.add("-DFILAMAT_LITE=ON")
}
}
}
}
publishing {
singleVariant("fullRelease") {
withSourcesJar()
withJavadocJar()
}
singleVariant("liteRelease") {
singleVariant("release") {
withSourcesJar()
withJavadocJar()
}
@@ -39,14 +18,9 @@ apply from: rootProject.file('gradle/gradle-mvn-push.gradle')
afterEvaluate { project ->
publishing {
publications {
fullRelease(MavenPublication) {
release(MavenPublication) {
artifactId = POM_ARTIFACT_ID_FULL
from components.fullRelease
}
liteRelease(MavenPublication) {
artifactId = POM_ARTIFACT_ID_LITE
from components.liteRelease
from components.release
}
}
}

View File

@@ -12,9 +12,6 @@ android {
}
}
defaultConfig {
missingDimensionStrategy 'functionality', 'full'
}
packagingOptions {
// No need to package up the following shared libs, which arise as a side effect of our
// externalNativeBuild dependencies. When clients pick and choose from project-level gradle

View File

@@ -1,12 +1,6 @@
android {
namespace 'com.google.android.filament.gltfio'
flavorDimensions "functionality"
productFlavors {
full {
dimension "functionality"
}
}
packagingOptions {
// No need to package up the following shared libs, which arise as a side effect of our
// externalNativeBuild dependencies. When clients pick and choose from project-level gradle
@@ -18,7 +12,7 @@ android {
}
publishing {
singleVariant("fullRelease") {
singleVariant("release") {
withSourcesJar()
withJavadocJar()
}
@@ -36,9 +30,9 @@ apply from: rootProject.file('gradle/gradle-mvn-push.gradle')
afterEvaluate { project ->
publishing {
publications {
fullRelease(MavenPublication) {
release(MavenPublication) {
artifactId = POM_ARTIFACT_ID_FULL
from components.fullRelease
from components.release
}
}
}

View File

@@ -32,7 +32,6 @@ android {
applicationId "com.google.android.filament.gltf"
minSdkVersion 19
targetSdkVersion versions.targetSdk
missingDimensionStrategy 'functionality', 'full'
}
// NOTE: This is a workaround required because the AGP task collectReleaseDependencies

View File

@@ -32,13 +32,6 @@ android {
targetSdkVersion versions.targetSdk
}
// The filamat library has two variants: full and lite. Here we default to the "full" variant.
// Replace "full" with "lite" to use the filamat-lite variant, which has a smaller binary size
// but comes with certain restrictions. See "Filamat Lite" in libs/filamat/README.md.
defaultConfig {
missingDimensionStrategy 'functionality', 'full'
}
// NOTE: This is a workaround required because the AGP task collectReleaseDependencies
// is not configuration-cache friendly yet; this is only useful for Play publication
dependenciesInfo {

View File

@@ -33,7 +33,6 @@ android {
applicationId "com.google.android.filament.textured"
minSdkVersion versions.minSdk
targetSdkVersion versions.targetSdk
missingDimensionStrategy 'functionality', 'full'
}
// NOTE: This is a workaround required because the AGP task collectReleaseDependencies

View File

@@ -544,7 +544,6 @@ function build_android {
if [[ "${INSTALL_COMMAND}" ]]; then
echo "Installing out/filamat-android-release.aar..."
cp filamat-android/build/outputs/aar/filamat-android-lite-release.aar ../out/
cp filamat-android/build/outputs/aar/filamat-android-full-release.aar ../out/filamat-android-release.aar
echo "Installing out/filament-android-release.aar..."

View File

@@ -4,11 +4,6 @@ project(filamat)
set(TARGET filamat)
set(PUBLIC_HDR_DIR include)
# filamat is split into two targets: filamat, and filamat_lite.
# filamat_lite forgoes SPIRV-V / MSL output, static analysis, and optimization in favor of a smaller
# binary size.
# Both libraries use the same public header files.
# ==================================================================================================
# Sources and headers
# ==================================================================================================
@@ -76,16 +71,6 @@ set(SRCS
src/ShaderMinifier.cpp
src/SpirvFixup.cpp)
# Sources and headers for filamat lite
set(LITE_PRIVATE_HDRS
${COMMON_PRIVATE_HDRS}
src/sca/GLSLToolsLite.h)
set(LITE_SRCS
${COMMON_SRCS}
src/sca/GLSLToolsLite.cpp)
# ==================================================================================================
# Include and target definitions
# ==================================================================================================
@@ -98,12 +83,6 @@ target_include_directories(${TARGET} PUBLIC ${PUBLIC_HDR_DIR})
set_target_properties(${TARGET} PROPERTIES FOLDER Libs)
target_link_libraries(${TARGET} shaders filabridge utils smol-v)
# Filamat Lite
add_library(filamat_lite STATIC ${HDRS} ${LITE_PRIVATE_HDRS} ${LITE_SRCS})
target_include_directories(filamat_lite PUBLIC ${PUBLIC_HDR_DIR})
set_target_properties(filamat_lite PROPERTIES FOLDER Libs)
target_link_libraries(filamat_lite shaders filabridge utils)
# We are being naughty and accessing private headers here
# For spirv-tools, we're just following glslang's example
target_include_directories(${TARGET} PRIVATE ${spirv-tools_SOURCE_DIR}/include)
@@ -124,8 +103,6 @@ endif()
# this must match options enabled in glslang's CMakeLists.txt
target_compile_options(${TARGET} PRIVATE -DAMD_EXTENSIONS -DNV_EXTENSIONS )
target_compile_definitions(filamat_lite PRIVATE FILAMAT_LITE)
if (MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W0 /Zc:__cplusplus")
endif()
@@ -162,8 +139,6 @@ set(FILAMAT_LIB_NAME ${CMAKE_STATIC_LIBRARY_PREFIX}filamat${CMAKE_STATIC_LIBRARY
install(FILES "${FILAMAT_COMBINED_OUTPUT}" DESTINATION lib/${DIST_DIR} RENAME ${FILAMAT_LIB_NAME})
install(DIRECTORY ${PUBLIC_HDR_DIR}/filamat DESTINATION include)
install(TARGETS filamat_lite ARCHIVE DESTINATION lib/${DIST_DIR})
# ==================================================================================================
# Tests
# ==================================================================================================
@@ -183,14 +158,3 @@ target_link_libraries(${TARGET} filamat gtest)
set_target_properties(${TARGET} PROPERTIES FOLDER Tests)
set(TARGET test_filamat_lite)
set(SRCS
tests/test_filamat_lite.cpp)
add_executable(${TARGET} ${SRCS})
target_include_directories(${TARGET} PRIVATE src)
target_link_libraries(${TARGET} filamat_lite gtest)
set_target_properties(${TARGET} PROPERTIES FOLDER Tests)

View File

@@ -23,12 +23,8 @@
#include "shaders/SibGenerator.h"
#include "shaders/UibGenerator.h"
#ifndef FILAMAT_LITE
# include "GLSLPostProcessor.h"
# include "sca/GLSLTools.h"
#else
# include "sca/GLSLToolsLite.h"
#endif
#include "GLSLPostProcessor.h"
#include "sca/GLSLTools.h"
#include "shaders/MaterialInfo.h"
#include "shaders/ShaderGenerator.h"
@@ -182,16 +178,12 @@ MaterialBuilder::~MaterialBuilder() = default;
void MaterialBuilderBase::init() {
materialBuilderClients++;
#ifndef FILAMAT_LITE
GLSLTools::init();
#endif
}
void MaterialBuilderBase::shutdown() {
materialBuilderClients--;
#ifndef FILAMAT_LITE
GLSLTools::shutdown();
#endif
}
MaterialBuilder& MaterialBuilder::name(const char* name) noexcept {
@@ -642,7 +634,6 @@ void MaterialBuilder::prepareToBuild(MaterialInfo& info) noexcept {
bool MaterialBuilder::findProperties(backend::ShaderStage type,
MaterialBuilder::PropertyList& allProperties,
CodeGenParams const& semanticCodeGenParams) noexcept {
#ifndef FILAMAT_LITE
GLSLTools glslTools;
std::string shaderCodeAllProperties = peek(type, semanticCodeGenParams, allProperties);
// Populate mProperties with the properties set in the shader.
@@ -656,9 +647,6 @@ bool MaterialBuilder::findProperties(backend::ShaderStage type,
return false;
}
return true;
#else
return false;
#endif
}
bool MaterialBuilder::findAllProperties(CodeGenParams const& semanticCodeGenParams) noexcept {
@@ -668,7 +656,6 @@ bool MaterialBuilder::findAllProperties(CodeGenParams const& semanticCodeGenPara
using namespace backend;
#ifndef FILAMAT_LITE
// Some fields in MaterialInputs only exist if the property is set (e.g: normal, subsurface
// for cloth shading model). Give our shader all properties. This will enable us to parse and
// static code analyse the AST.
@@ -681,19 +668,10 @@ bool MaterialBuilder::findAllProperties(CodeGenParams const& semanticCodeGenPara
return false;
}
return true;
#else
GLSLToolsLite glslTools;
if (glslTools.findProperties(ShaderStage::FRAGMENT, mMaterialFragmentCode.getResolved(), mProperties)) {
return glslTools.findProperties(
ShaderStage::VERTEX, mMaterialVertexCode.getResolved(), mProperties);
}
return false;
#endif
}
bool MaterialBuilder::runSemanticAnalysis(MaterialInfo* inOutInfo,
CodeGenParams const& semanticCodeGenParams) noexcept {
#ifndef FILAMAT_LITE
using namespace backend;
TargetApi targetApi = semanticCodeGenParams.targetApi;
@@ -730,28 +708,6 @@ bool MaterialBuilder::runSemanticAnalysis(MaterialInfo* inOutInfo,
slog.e << shaderCode << io::endl;
}
return success;
#else
return true;
#endif
}
bool MaterialBuilder::checkLiteRequirements() noexcept {
#ifdef FILAMAT_LITE
if (mTargetApi != TargetApi::OPENGL) {
slog.e
<< "Filamat lite only supports building materials for the OpenGL backend."
<< io::endl;
return false;
}
if (mOptimization != Optimization::NONE) {
slog.e
<< "Filamat lite does not support material optimization." << io::endl
<< "Ensure optimization is set to NONE." << io::endl;
return false;
}
#endif
return true;
}
bool MaterialBuilder::ShaderCode::resolveIncludes(IncludeCallback callback,
@@ -827,12 +783,11 @@ static void showErrorMessage(const char* materialName, filament::Variant variant
bool MaterialBuilder::generateShaders(JobSystem& jobSystem, const std::vector<Variant>& variants,
ChunkContainer& container, const MaterialInfo& info) const noexcept {
// Create a postprocessor to optimize / compile to Spir-V if necessary.
#ifndef FILAMAT_LITE
uint32_t flags = 0;
flags |= mPrintShaders ? GLSLPostProcessor::PRINT_SHADERS : 0;
flags |= mGenerateDebugInfo ? GLSLPostProcessor::GENERATE_DEBUG_INFO : 0;
GLSLPostProcessor postProcessor(mOptimization, flags);
#endif
// Start: must be protected by lock
Mutex entriesLock;
@@ -841,9 +796,7 @@ bool MaterialBuilder::generateShaders(JobSystem& jobSystem, const std::vector<Va
std::vector<SpirvEntry> spirvEntries;
std::vector<TextEntry> metalEntries;
LineDictionary textDictionary;
#ifndef FILAMAT_LITE
BlobDictionary spirvDictionary;
#endif
// End: must be protected by lock
ShaderGenerator sg(mProperties, mVariables, mOutputs, mDefines, mConstants,
@@ -920,17 +873,11 @@ bool MaterialBuilder::generateShaders(JobSystem& jobSystem, const std::vector<Va
shaderModel, targetApi, targetLanguage, featureLevel, info);
}
#ifdef FILAMAT_LITE
GLSLToolsLite glslTools;
glslTools.removeGoogleLineDirectives(shader);
#endif
std::string* pGlsl = nullptr;
if (targetApiNeedsGlsl) {
pGlsl = &shader;
}
#ifndef FILAMAT_LITE
GLSLPostProcessor::Config config{
.variant = v.variant,
.targetApi = targetApi,
@@ -950,9 +897,6 @@ bool MaterialBuilder::generateShaders(JobSystem& jobSystem, const std::vector<Va
}
bool const ok = postProcessor.process(shader, config, pGlsl, pSpirv, pMsl);
#else
bool ok = true;
#endif
if (!ok) {
showErrorMessage(mMaterialName.c_str_safe(), v.variant, targetApi, v.stage,
featureLevel, shader);
@@ -991,21 +935,17 @@ bool MaterialBuilder::generateShaders(JobSystem& jobSystem, const std::vector<Va
}
break;
case TargetApi::VULKAN:
#ifndef FILAMAT_LITE
assert(!spirv.empty());
spirvEntry.stage = v.stage;
spirvEntry.spirv = std::move(spirv);
spirvEntries.push_back(spirvEntry);
#endif
break;
case TargetApi::METAL:
#ifndef FILAMAT_LITE
assert(!spirv.empty());
assert(msl.length() > 0);
metalEntry.stage = v.stage;
metalEntry.shader = msl;
metalEntries.push_back(metalEntry);
#endif
break;
}
});
@@ -1048,12 +988,10 @@ bool MaterialBuilder::generateShaders(JobSystem& jobSystem, const std::vector<Va
for (const auto& s : essl1Entries) {
textDictionary.addText(s.shader);
}
#ifndef FILAMAT_LITE
for (auto& s : spirvEntries) {
std::vector<uint32_t> spirv = std::move(s.spirv);
s.dictionaryIndex = spirvDictionary.addBlob(spirv);
}
#endif
for (const auto& s : metalEntries) {
textDictionary.addText(s.shader);
}
@@ -1075,7 +1013,6 @@ bool MaterialBuilder::generateShaders(JobSystem& jobSystem, const std::vector<Va
}
// Emit SPIRV chunks (SpirvDictionaryReader and MaterialSpirvChunk).
#ifndef FILAMAT_LITE
if (!spirvEntries.empty()) {
const bool stripInfo = !mGenerateDebugInfo;
container.push<filamat::DictionarySpirvChunk>(std::move(spirvDictionary), stripInfo);
@@ -1087,7 +1024,6 @@ bool MaterialBuilder::generateShaders(JobSystem& jobSystem, const std::vector<Va
container.push<MaterialTextChunk>(std::move(metalEntries),
dictionaryChunk.getDictionary(), ChunkType::MaterialMetal);
}
#endif
return true;
}
@@ -1191,12 +1127,6 @@ error:
// The call to findProperties populates mProperties and must come before runSemanticAnalysis.
// Return an empty package to signal a failure to build the material.
#ifdef FILAMAT_LITE
if (!checkLiteRequirements()) {
goto error;
}
#endif
// For finding properties and running semantic analysis, we always use the same code gen
// permutation. This is the first permutation generated with default arguments passed to matc.
CodeGenParams const semanticCodeGenParams = {

View File

@@ -40,10 +40,8 @@ struct SpirvEntry {
filament::backend::ShaderStage stage;
size_t dictionaryIndex;
#ifndef FILAMAT_LITE
// temporarily holds this entry's spirv until added to the dictionary
std::vector<uint32_t> spirv;
#endif
};
} // namespace filamat

View File

@@ -1,169 +0,0 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "GLSLToolsLite.h"
#include <filamat/Enums.h>
#include <stdlib.h>
using namespace filament::backend;
namespace filamat {
static bool isVariableCharacter(char c) {
return (c >= 'A' && c <= 'Z') ||
(c >= 'a' && c <= 'z') ||
(c >= '0' && c <= '9') ||
(c == '_');
}
static bool isWhitespace(char c) {
return (c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v');
}
static std::string stripComments(const std::string& code) {
char* temp = (char*) malloc(code.size() + 1);
size_t r = 0;
bool insideSlashSlashComment = false, insideMultilineComment = false;
for (size_t loc = 0; loc < code.size(); loc++) {
char c = code[loc];
char lookahead = (loc + 1) < code.size() ? code[loc + 1] : 0;
// Handle slash slash comments.
if (!insideSlashSlashComment && c == '/' && lookahead == '/') {
insideSlashSlashComment = true;
}
if (insideSlashSlashComment && c == '\n') {
insideSlashSlashComment = false;
}
// Handle multiline comments.
if (!insideMultilineComment && c == '/' && lookahead == '*') {
insideMultilineComment = true;
}
if (insideMultilineComment && c == '*' && lookahead == '/') {
insideMultilineComment = false;
}
if (insideSlashSlashComment || insideMultilineComment) {
continue;
}
temp[r++] = c;
}
temp[r] = 0;
std::string result(temp);
free(temp);
return result;
}
bool GLSLToolsLite::findProperties(
filament::backend::ShaderStage type,
const utils::CString& material,
MaterialBuilder::PropertyList& properties) const noexcept {
if (material.empty()) {
return true;
}
const std::string shaderCode = stripComments(material.c_str());
size_t start = 0, end = 0;
const auto p = Enums::map<Property>();
// Find all occurrences of "material.someProperty" in the shader string.
// TODO: We should find the name of the structure and search for <theName>.someProperty
size_t loc;
while ((loc = shaderCode.find("material", start)) != std::string::npos) {
// Set start to the index of the first character after "material"
start = loc + 8;
// Eat up any whitespace after "material"
while (start != shaderCode.length() && isWhitespace(shaderCode[start])) {
start++;
}
// If the next character isn't a '.', then this isn't a property set.
if (start == shaderCode.length() || shaderCode[start] != '.') {
continue;
}
start++;
// Eat up any whitespace after the '.'.
while (start != shaderCode.length() && isWhitespace(shaderCode[start])) {
start++;
}
// Increment end until we reach a non-variable character.
end = start;
while (end != shaderCode.length() && isVariableCharacter(shaderCode[end])) {
end++;
}
std::string foundProperty = shaderCode.substr(start, end - start);
// Check to see if this property matches any in the property list.
for (const auto& i : p) {
const std::string& propertySymbol = i.first;
Property prop = i.second;
if (foundProperty == propertySymbol) {
properties[size_t(prop)] = true;
}
}
}
return true;
}
void GLSLToolsLite::removeGoogleLineDirectives(std::string& text) const noexcept {
size_t found;
size_t start = std::string::npos;
while ((found = text.rfind("#line", start)) != std::string::npos) {
// Eat up anything until a newline character.
// If we find a quote character, then this is a Google-style line directive.
size_t c = found + 5;
size_t len = 5;
bool googleStyleDirective = false;
while (c < text.length()) {
if (text[c] == '"') {
googleStyleDirective = true;
}
if (text[c] == '\n') {
len++;
break;
}
len++;
c++;
}
if (googleStyleDirective) {
text.replace(found, len, "");
}
if (found == 0) {
break;
}
start = found - 1;
}
}
} // namespace filamat

View File

@@ -1,57 +0,0 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef TNT_GLSLTOOLSLITE_H
#define TNT_GLSLTOOLSLITE_H
#include <backend/DriverEnums.h>
#include <filamat/MaterialBuilder.h>
#include <string>
namespace filamat {
class GLSLToolsLite {
public:
// Public for unit tests.
using Property = MaterialBuilder::Property;
/* Guess the properties that the material is using based on a naive text-based search.
*
* In order for this method to detect the usage of a property:
* 1. The MaterialInputs argument to the user-defined material function must be named "material".
* 2. The properties on "material" should be set directly, i.e., not passed via an inout qualifier
* to another function which sets properties (this only works if the argument to the
* function is also named "material").
*/
bool findProperties(
filament::backend::ShaderStage type,
const utils::CString& material,
MaterialBuilder::PropertyList& properties) const noexcept;
/* Remove Google-style #line directives from the source string.
*
* Google-style #line directives use quotes to specify file names. For example:
* #line 100 "foobar.h"
*/
void removeGoogleLineDirectives(std::string& text) const noexcept;
};
} // namespace filamat
#endif // TNT_GLSLTOOLSLITE_H

View File

@@ -1,278 +0,0 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <gtest/gtest.h>
#include "sca/GLSLToolsLite.h"
#include <filamat/MaterialBuilder.h>
#include <filamat/Enums.h>
using namespace filamat;
using namespace filament::backend;
static ::testing::AssertionResult PropertyListsMatch(const MaterialBuilder::PropertyList& expected,
const MaterialBuilder::PropertyList& actual) {
for (size_t i = 0; i < MaterialBuilder::MATERIAL_PROPERTIES_COUNT; i++) {
if (expected[i] != actual[i]) {
const auto& propString = Enums::toString<Property>(Property(i));
return ::testing::AssertionFailure()
<< "actual[" << propString << "] (" << actual[i]
<< ") != expected[" << propString << "] (" << expected[i] << ")";
}
}
return ::testing::AssertionSuccess();
}
class FilamatLite : public ::testing::Test {
protected:
FilamatLite() = default;
~FilamatLite() override = default;
void SetUp() override {
MaterialBuilder::init();
}
};
TEST_F(FilamatLite, StaticCodeAnalyzerNothingDetected) {
utils::CString shaderCode(R"(
void material(inout MaterialInputs material) {
prepareMaterial(material);
}
)");
GLSLToolsLite glslTools;
MaterialBuilder::PropertyList properties {false};
glslTools.findProperties(ShaderStage::FRAGMENT, shaderCode, properties);
MaterialBuilder::PropertyList expected {false};
EXPECT_TRUE(PropertyListsMatch(expected, properties));
}
TEST_F(FilamatLite, StaticCodeAnalyzerNothingDetectedinVertex) {
utils::CString shaderCode(R"(
void materialVertex(inout MaterialVertexInputs material) {
}
)");
GLSLToolsLite glslTools;
MaterialBuilder::PropertyList properties {false};
glslTools.findProperties(ShaderStage::VERTEX, shaderCode, properties);
MaterialBuilder::PropertyList expected {false};
EXPECT_TRUE(PropertyListsMatch(expected, properties));
}
TEST_F(FilamatLite, StaticCodeAnalyzerDirectAssign) {
utils::CString shaderCode(R"(
void material(inout MaterialInputs material) {
prepareMaterial(material);
material.baseColor = vec4(0.8);
}
)");
GLSLToolsLite glslTools;
MaterialBuilder::PropertyList properties {false};
glslTools.findProperties(ShaderStage::FRAGMENT, shaderCode, properties);
MaterialBuilder::PropertyList expected {false};
expected[size_t(MaterialBuilder::Property::BASE_COLOR)] = true;
EXPECT_TRUE(PropertyListsMatch(expected, properties));
}
TEST_F(FilamatLite, StaticCodeAnalyzerDirectAssignVertex) {
utils::CString shaderCode(R"(
void materialVertex(inout MaterialVertexInputs material) {
material.clipSpaceTransform = mat4(2.0);
}
)");
GLSLToolsLite glslTools;
MaterialBuilder::PropertyList properties {false};
glslTools.findProperties(ShaderStage::VERTEX, shaderCode, properties);
MaterialBuilder::PropertyList expected {false};
expected[size_t(MaterialBuilder::Property::CLIP_SPACE_TRANSFORM)] = true;
EXPECT_TRUE(PropertyListsMatch(expected, properties));
}
TEST_F(FilamatLite, StaticCodeAnalyzerAssignMultiple) {
utils::CString shaderCode(R"(
void material(inout MaterialInputs material) {
material.clearCoat = 1.0;
prepareMaterial(material);
material.baseColor = vec4(0.8);
material.metallic = 1.0;
}
)");
GLSLToolsLite glslTools;
MaterialBuilder::PropertyList properties {false};
glslTools.findProperties(ShaderStage::FRAGMENT, shaderCode, properties);
MaterialBuilder::PropertyList expected {false};
expected[size_t(MaterialBuilder::Property::CLEAR_COAT)] = true;
expected[size_t(MaterialBuilder::Property::BASE_COLOR)] = true;
expected[size_t(MaterialBuilder::Property::METALLIC)] = true;
EXPECT_TRUE(PropertyListsMatch(expected, properties));
}
TEST_F(FilamatLite, StaticCodeAnalyzerDirectAssignWithSwizzling) {
utils::CString shaderCode(R"(
void material(inout MaterialInputs material) {
prepareMaterial(material);
material.subsurfaceColor.rgb = vec3(1.0, 0.4, 0.8);
}
)");
GLSLToolsLite glslTools;
MaterialBuilder::PropertyList properties {false};
glslTools.findProperties(ShaderStage::FRAGMENT, shaderCode, properties);
MaterialBuilder::PropertyList expected {false};
expected[size_t(MaterialBuilder::Property::SUBSURFACE_COLOR)] = true;
EXPECT_TRUE(PropertyListsMatch(expected, properties));
}
TEST_F(FilamatLite, StaticCodeAnalyzerNoSpace) {
utils::CString shaderCode(R"(
void material(inout MaterialInputs material) {
prepareMaterial(material);
material.ambientOcclusion=vec3(1.0);
}
)");
GLSLToolsLite glslTools;
MaterialBuilder::PropertyList properties {false};
glslTools.findProperties(ShaderStage::FRAGMENT, shaderCode, properties);
MaterialBuilder::PropertyList expected {false};
expected[size_t(MaterialBuilder::Property::AMBIENT_OCCLUSION)] = true;
EXPECT_TRUE(PropertyListsMatch(expected, properties));
}
TEST_F(FilamatLite, StaticCodeAnalyzerWhitespace) {
utils::CString shaderCode(R"(
void material(inout MaterialInputs material) {
prepareMaterial(material);
material .subsurfaceColor = vec3(1.0);
material . ambientOcclusion = vec3(1.0);
material
. baseColor = vec3(1.0);
}
)");
GLSLToolsLite glslTools;
MaterialBuilder::PropertyList properties {false};
glslTools.findProperties(ShaderStage::FRAGMENT, shaderCode, properties);
MaterialBuilder::PropertyList expected {false};
expected[size_t(MaterialBuilder::Property::SUBSURFACE_COLOR)] = true;
expected[size_t(MaterialBuilder::Property::AMBIENT_OCCLUSION)] = true;
expected[size_t(MaterialBuilder::Property::BASE_COLOR)] = true;
EXPECT_TRUE(PropertyListsMatch(expected, properties));
}
TEST_F(FilamatLite, StaticCodeAnalyzerEndOfShader) {
utils::CString shaderCode(R"(
void material(inout MaterialInputs material) {
material.)");
GLSLToolsLite glslTools;
MaterialBuilder::PropertyList properties {false};
glslTools.findProperties(ShaderStage::FRAGMENT, shaderCode, properties);
MaterialBuilder::PropertyList expected {false};
EXPECT_TRUE(PropertyListsMatch(expected, properties));
}
TEST_F(FilamatLite, StaticCodeAnalyzerSlashComments) {
utils::CString shaderCode(R"(
void material(inout MaterialInputs material) {
prepareMaterial(material);
material.metallic = 1.0;
// material.baseColor = vec4(1.0); // material.baseColor = vec4(1.0);
// material.ambientOcclusion = vec3(1.0);
material.clearCoat = 0.5;
material.anisotropy = -1.0;
}
)");
GLSLToolsLite glslTools;
MaterialBuilder::PropertyList properties {false};
glslTools.findProperties(ShaderStage::FRAGMENT, shaderCode, properties);
MaterialBuilder::PropertyList expected {false};
expected[size_t(MaterialBuilder::Property::METALLIC)] = true;
expected[size_t(MaterialBuilder::Property::CLEAR_COAT)] = true;
expected[size_t(MaterialBuilder::Property::ANISOTROPY)] = true;
EXPECT_TRUE(PropertyListsMatch(expected, properties));
}
TEST_F(FilamatLite, StaticCodeAnalyzerMultilineComments) {
utils::CString shaderCode(R"(
void material(inout MaterialInputs material) {
prepareMaterial(material);
material.metallic = 1.0;
/*
material.baseColor = vec4(1.0); // material.baseColor = vec4(1.0);
material.ambientOcclusion = vec3(1.0);
*/
material.clearCoat = 0.5;
}
)");
GLSLToolsLite glslTools;
MaterialBuilder::PropertyList properties {false};
glslTools.findProperties(ShaderStage::FRAGMENT, shaderCode, properties);
MaterialBuilder::PropertyList expected {false};
expected[size_t(MaterialBuilder::Property::METALLIC)] = true;
expected[size_t(MaterialBuilder::Property::CLEAR_COAT)] = true;
EXPECT_TRUE(PropertyListsMatch(expected, properties));
}
TEST_F(FilamatLite, RemoveLineDirectivesOneLine) {
{
std::string shaderCode("#line 10 \"foobar\"");
GLSLToolsLite glslTools;
glslTools.removeGoogleLineDirectives(shaderCode);
EXPECT_STREQ("", shaderCode.c_str());
}
{
// Ignore non-Google extension line directives
std::string shaderCode("#line 100");
GLSLToolsLite glslTools;
glslTools.removeGoogleLineDirectives(shaderCode);
EXPECT_STREQ("#line 100", shaderCode.c_str());
}
}
TEST_F(FilamatLite, RemoveLineDirectives) {
std::string shaderCode(R"(
aaa
#line 10 "foobar"
bbb
ccc
#line 100
)");
std::string expected(R"(
aaa
bbb
ccc
#line 100
)");
GLSLToolsLite glslTools;
glslTools.removeGoogleLineDirectives(shaderCode);
EXPECT_STREQ(expected.c_str(), shaderCode.c_str());
}
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}