mirror of https://github.com/xemu-project/xemu.git
112 lines
4.2 KiB
C++
112 lines
4.2 KiB
C++
// Copyright (c) 2025 The Khronos Group Inc.
|
|
//
|
|
// 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 "TestFixture.h"
|
|
|
|
#include "glslang/MachineIndependent/LiveTraverser.h"
|
|
|
|
namespace glslangtest {
|
|
namespace {
|
|
|
|
struct LiveTraverserTestParams {
|
|
std::string fileName;
|
|
std::vector<std::string> liveVars;
|
|
};
|
|
|
|
using LiveTraverserTest = GlslangTest<::testing::TestWithParam<LiveTraverserTestParams>>;
|
|
|
|
TEST_P(LiveTraverserTest, FromFile)
|
|
{
|
|
const auto& fileName = GetParam().fileName;
|
|
const auto& expectedLiveVars = GetParam().liveVars;
|
|
const EShMessages controls = DeriveOptions(Source::GLSL, Semantics::Vulkan, Target::AST);
|
|
GlslangResult result;
|
|
result.validationResult = true;
|
|
|
|
std::string contents;
|
|
tryLoadFile(GlobalTestSettings.testRoot + "/" + fileName, "input", &contents);
|
|
std::unique_ptr<glslang::TShader> shader = std::make_unique<glslang::TShader>(GetShaderStage(GetSuffix(fileName)));
|
|
|
|
bool success = compile(shader.get(), contents, "", controls);
|
|
result.shaderResults.push_back({fileName, shader->getInfoLog(), shader->getInfoDebugLog()});
|
|
|
|
std::ostringstream stream;
|
|
outputResultToStream(&stream, result, controls);
|
|
|
|
class TLiveSymbolTraverser : public glslang::TLiveTraverser {
|
|
public:
|
|
TLiveSymbolTraverser(const glslang::TIntermediate& i, std::vector<std::string>& liveVars)
|
|
: glslang::TLiveTraverser(i), liveVars(liveVars)
|
|
{
|
|
}
|
|
|
|
virtual void visitSymbol(glslang::TIntermSymbol* symbol)
|
|
{
|
|
if (symbol->getAsSymbolNode()->getAccessName().compare(0, 3, "gl_") == 0)
|
|
return;
|
|
|
|
if (symbol->getQualifier().storage == glslang::TStorageQualifier::EvqVaryingIn ||
|
|
symbol->getQualifier().storage == glslang::TStorageQualifier::EvqVaryingOut ||
|
|
symbol->getQualifier().storage == glslang::TStorageQualifier::EvqUniform ||
|
|
symbol->getQualifier().storage == glslang::TStorageQualifier::EvqBuffer) {
|
|
liveVars.push_back(symbol->getAccessName().c_str());
|
|
}
|
|
}
|
|
|
|
private:
|
|
std::vector<std::string>& liveVars;
|
|
};
|
|
|
|
if (success) {
|
|
std::vector<std::string> actualLiveVars;
|
|
TLiveSymbolTraverser liveTraverser(*shader->getIntermediate(), actualLiveVars);
|
|
liveTraverser.pushFunction(shader->getIntermediate()->getEntryPointMangledName().c_str());
|
|
while (!liveTraverser.destinations.empty()) {
|
|
TIntermNode* destination = liveTraverser.destinations.back();
|
|
liveTraverser.destinations.pop_back();
|
|
destination->traverse(&liveTraverser);
|
|
}
|
|
|
|
for (const auto& expectedVar : expectedLiveVars) {
|
|
auto it = std::find(actualLiveVars.begin(), actualLiveVars.end(), expectedVar);
|
|
EXPECT_NE(it, actualLiveVars.end());
|
|
if (it != actualLiveVars.end())
|
|
actualLiveVars.erase(it);
|
|
}
|
|
EXPECT_TRUE(actualLiveVars.empty());
|
|
}
|
|
|
|
// Check with expected results.
|
|
const std::string expectedOutputFname = GlobalTestSettings.testRoot + "/baseResults/" + fileName + ".out";
|
|
std::string expectedOutput;
|
|
tryLoadFile(expectedOutputFname, "expected output", &expectedOutput);
|
|
|
|
checkEqAndUpdateIfRequested(expectedOutput, stream.str(), expectedOutputFname, result.spirvWarningsErrors);
|
|
}
|
|
|
|
// clang-format off
|
|
INSTANTIATE_TEST_SUITE_P(
|
|
Glsl, LiveTraverserTest,
|
|
::testing::ValuesIn(std::vector<LiveTraverserTestParams>({
|
|
{"liveTraverser.switch.vert", {"a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9", "a10"}},
|
|
// TODO: implement test for if statements
|
|
}))
|
|
);
|
|
// clang-format on
|
|
|
|
} // anonymous namespace
|
|
} // namespace glslangtest
|