Browse Source

ShaderTools: ability to control optimizations and debug level.

So the -O and -g options in magnum-sceneconverter can be implemented in
a generic way.
pull/481/head
Vladimír Vondruš 6 years ago
parent
commit
b9ef6b4a02
  1. 28
      src/Magnum/ShaderTools/AbstractConverter.cpp
  2. 66
      src/Magnum/ShaderTools/AbstractConverter.h
  3. 132
      src/Magnum/ShaderTools/Test/AbstractConverterTest.cpp

28
src/Magnum/ShaderTools/AbstractConverter.cpp

@ -79,7 +79,7 @@ AbstractConverter::AbstractConverter(PluginManager::AbstractManager& manager, co
ConverterFeatures AbstractConverter::features() const { ConverterFeatures AbstractConverter::features() const {
const ConverterFeatures features = doFeatures(); const ConverterFeatures features = doFeatures();
CORRADE_ASSERT(features & ~(ConverterFeature::InputFileCallback|ConverterFeature::Preprocess), CORRADE_ASSERT(features & ~(ConverterFeature::InputFileCallback|ConverterFeature::Preprocess|ConverterFeature::Optimize|ConverterFeature::DebugInfo),
"ShaderTools::AbstractConverter::features(): implementation reported no features", {}); "ShaderTools::AbstractConverter::features(): implementation reported no features", {});
return features; return features;
} }
@ -139,6 +139,26 @@ void AbstractConverter::doSetDefinitions(Containers::ArrayView<const std::pair<C
CORRADE_ASSERT_UNREACHABLE("ShaderTools::AbstractConverter::setDefinitions(): feature advertised but not implemented", ); CORRADE_ASSERT_UNREACHABLE("ShaderTools::AbstractConverter::setDefinitions(): feature advertised but not implemented", );
} }
void AbstractConverter::setOptimizationLevel(const Containers::StringView level) {
CORRADE_ASSERT(features() & ConverterFeature::Optimize,
"ShaderTools::AbstractConverter::setOptimizationLevel(): feature not supported", );
doSetOptimizationLevel(level);
}
void AbstractConverter::doSetOptimizationLevel(Containers::StringView) {
CORRADE_ASSERT_UNREACHABLE("ShaderTools::AbstractConverter::setOptimizationLevel(): feature advertised but not implemented", );
}
void AbstractConverter::setDebugInfoLevel(const Containers::StringView level) {
CORRADE_ASSERT(features() & ConverterFeature::DebugInfo,
"ShaderTools::AbstractConverter::setDebugInfoLevel(): feature not supported", );
doSetDebugInfoLevel(level);
}
void AbstractConverter::doSetDebugInfoLevel(Containers::StringView) {
CORRADE_ASSERT_UNREACHABLE("ShaderTools::AbstractConverter::setDebugInfoLevel(): feature advertised but not implemented", );
}
std::pair<bool, Containers::String> AbstractConverter::validateData(const Stage stage, const Containers::ArrayView<const void> data) { std::pair<bool, Containers::String> AbstractConverter::validateData(const Stage stage, const Containers::ArrayView<const void> data) {
CORRADE_ASSERT(features() & ConverterFeature::ValidateData, CORRADE_ASSERT(features() & ConverterFeature::ValidateData,
"ShaderTools::AbstractConverter::validateData(): feature not supported", {}); "ShaderTools::AbstractConverter::validateData(): feature not supported", {});
@ -643,6 +663,8 @@ Debug& operator<<(Debug& debug, const ConverterFeature value) {
_c(LinkFile) _c(LinkFile)
_c(InputFileCallback) _c(InputFileCallback)
_c(Preprocess) _c(Preprocess)
_c(Optimize)
_c(DebugInfo)
#undef _c #undef _c
/* LCOV_EXCL_STOP */ /* LCOV_EXCL_STOP */
} }
@ -662,7 +684,9 @@ Debug& operator<<(Debug& debug, const ConverterFeatures value) {
/* Implied by LinkData, has to be after */ /* Implied by LinkData, has to be after */
ConverterFeature::LinkFile, ConverterFeature::LinkFile,
ConverterFeature::InputFileCallback, ConverterFeature::InputFileCallback,
ConverterFeature::Preprocess ConverterFeature::Preprocess,
ConverterFeature::Optimize,
ConverterFeature::DebugInfo
}); });
} }

66
src/Magnum/ShaderTools/AbstractConverter.h

@ -100,7 +100,19 @@ enum class ConverterFeature: UnsignedInt {
* Set preprocess definitions using @ref AbstractConverter::setDefinitions() * Set preprocess definitions using @ref AbstractConverter::setDefinitions()
* and the @ref ConverterFlag::PreprocessOnly flag. * and the @ref ConverterFlag::PreprocessOnly flag.
*/ */
Preprocess = 1 << 7 Preprocess = 1 << 7,
/**
* Control code optimization using
* @ref AbstractConverter::setOptimizationLevel()
*/
Optimize = 1 << 8,
/**
* Control amount of debug info present in the output using
* @ref AbstractConverter::setDebugInfoLevel()
*/
DebugInfo = 1 << 9
}; };
/** /**
@ -608,6 +620,32 @@ class MAGNUM_SHADERTOOLS_EXPORT AbstractConverter: public PluginManager::Abstrac
/** @overload */ /** @overload */
void setDefinitions(std::initializer_list<std::pair<Containers::StringView, Containers::StringView>> definitions); void setDefinitions(std::initializer_list<std::pair<Containers::StringView, Containers::StringView>> definitions);
/**
* @brief Set optimization level
*
* Available only if @ref ConverterFeature::Optimize is supported.
* Interpreted in a plugin-specific way, if it's not recognized the
* following @ref convertDataToData(), @ref convertDataToFile(),
* @ref convertFileToFile(), @ref convertFileToData(),
* @ref linkDataToData(), @ref linkDataToFile(), @ref linkFilesToFile()
* or @ref linkFilesToData() call will fail.
* @see @ref setDebugInfoLevel()
*/
void setOptimizationLevel(Containers::StringView level);
/**
* @brief Set debug info level
*
* Available only if @ref ConverterFeature::DebugInfo is supported.
* Interpreted in a plugin-specific way, if it's not recognized the
* following @ref convertDataToData(), @ref convertDataToFile(),
* @ref convertFileToFile(), @ref convertFileToData(),
* @ref linkDataToData(), @ref linkDataToFile(), @ref linkFilesToFile()
* or @ref linkFilesToData() call will fail.
* @see @ref setOptimizationLevel()
*/
void setDebugInfoLevel(Containers::StringView level);
/** /**
* @brief Validate a shader * @brief Validate a shader
* *
@ -912,6 +950,32 @@ class MAGNUM_SHADERTOOLS_EXPORT AbstractConverter: public PluginManager::Abstrac
*/ */
virtual void doSetDefinitions(Containers::ArrayView<const std::pair<Containers::StringView, Containers::StringView>> definitions); virtual void doSetDefinitions(Containers::ArrayView<const std::pair<Containers::StringView, Containers::StringView>> definitions);
/**
* @brief Implementation for @ref setOptimizationLevel()
*
* Has to be implemented if @ref ConverterFeature::Optimize is
* supported. To simplify error handling on user side, this function
* isn't expected to fail --- if the level isn't recognized, the
* following @ref convertDataToData(), @ref convertDataToFile(),
* @ref convertFileToFile(), @ref convertFileToData(),
* @ref linkDataToData(), @ref linkDataToFile(), @ref linkFilesToFile()
* or @ref linkFilesToData() should fail instead.
*/
virtual void doSetOptimizationLevel(Containers::StringView level);
/**
* @brief Implementation for @ref setDebugInfoLevel()
*
* Has to be implemented if @ref ConverterFeature::DebugInfo is
* supported. To simplify error handling on user side, this function
* isn't expected to fail --- if the level isn't recognized, the
* following @ref convertDataToData(), @ref convertDataToFile(),
* @ref convertFileToFile(), @ref convertFileToData(),
* @ref linkDataToData(), @ref linkDataToFile(), @ref linkFilesToFile()
* or @ref linkFilesToData() should fail instead.
*/
virtual void doSetDebugInfoLevel(Containers::StringView level);
/** /**
* @brief Implementation for @ref validateData() * @brief Implementation for @ref validateData()
* *

132
src/Magnum/ShaderTools/Test/AbstractConverterTest.cpp

@ -58,6 +58,14 @@ struct AbstractConverterTest: TestSuite::Tester {
void setDefinitionsNotSupported(); void setDefinitionsNotSupported();
void setDefinitionsNotImplemented(); void setDefinitionsNotImplemented();
void setOptimizationLevel();
void setOptimizationLevelNotSupported();
void setOptimizationLevelNotImplemented();
void setDebugInfoLevel();
void setDebugInfoLevelNotSupported();
void setDebugInfoLevelNotImplemented();
void validateData(); void validateData();
void validateDataNotSupported(); void validateDataNotSupported();
void validateDataNotImplemented(); void validateDataNotImplemented();
@ -184,6 +192,14 @@ AbstractConverterTest::AbstractConverterTest() {
&AbstractConverterTest::setDefinitionsNotSupported, &AbstractConverterTest::setDefinitionsNotSupported,
&AbstractConverterTest::setDefinitionsNotImplemented, &AbstractConverterTest::setDefinitionsNotImplemented,
&AbstractConverterTest::setOptimizationLevel,
&AbstractConverterTest::setOptimizationLevelNotSupported,
&AbstractConverterTest::setOptimizationLevelNotImplemented,
&AbstractConverterTest::setDebugInfoLevel,
&AbstractConverterTest::setDebugInfoLevelNotSupported,
&AbstractConverterTest::setDebugInfoLevelNotImplemented,
&AbstractConverterTest::validateData, &AbstractConverterTest::validateData,
&AbstractConverterTest::validateDataNotSupported, &AbstractConverterTest::validateDataNotSupported,
&AbstractConverterTest::validateDataNotImplemented, &AbstractConverterTest::validateDataNotImplemented,
@ -306,7 +322,7 @@ void AbstractConverterTest::featuresNone() {
struct: AbstractConverter { struct: AbstractConverter {
ConverterFeatures doFeatures() const override { ConverterFeatures doFeatures() const override {
/* These aren't real features, so it should still complain */ /* These aren't real features, so it should still complain */
return ConverterFeature::InputFileCallback|ConverterFeature::Preprocess; return ConverterFeature::InputFileCallback|ConverterFeature::Preprocess|ConverterFeature::Optimize|ConverterFeature::DebugInfo;
} }
void doSetInputFormat(Format, Containers::StringView) override {} void doSetInputFormat(Format, Containers::StringView) override {}
void doSetOutputFormat(Format, Containers::StringView) override {} void doSetOutputFormat(Format, Containers::StringView) override {}
@ -518,6 +534,120 @@ void AbstractConverterTest::setDefinitionsNotImplemented() {
CORRADE_COMPARE(out.str(), "ShaderTools::AbstractConverter::setDefinitions(): feature advertised but not implemented\n"); CORRADE_COMPARE(out.str(), "ShaderTools::AbstractConverter::setDefinitions(): feature advertised but not implemented\n");
} }
void AbstractConverterTest::setOptimizationLevel() {
struct: AbstractConverter {
ConverterFeatures doFeatures() const override {
return ConverterFeature::Optimize|ConverterFeature::ValidateData;
}
void doSetInputFormat(Format, Containers::StringView) override {}
void doSetOutputFormat(Format, Containers::StringView) override {}
void doSetOptimizationLevel(Containers::StringView level) override {
optimization = level;
}
Containers::StringView optimization;
} converter;
converter.setOptimizationLevel("2");
CORRADE_COMPARE(converter.optimization, "2");
}
void AbstractConverterTest::setOptimizationLevelNotSupported() {
#ifdef CORRADE_NO_ASSERT
CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions");
#endif
struct: AbstractConverter {
ConverterFeatures doFeatures() const override {
return ConverterFeature::ValidateData;
}
void doSetInputFormat(Format, Containers::StringView) override {}
void doSetOutputFormat(Format, Containers::StringView) override {}
} converter;
std::ostringstream out;
Error redirectError{&out};
converter.setOptimizationLevel({});
CORRADE_COMPARE(out.str(), "ShaderTools::AbstractConverter::setOptimizationLevel(): feature not supported\n");
}
void AbstractConverterTest::setOptimizationLevelNotImplemented() {
#ifdef CORRADE_NO_ASSERT
CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions");
#endif
struct: AbstractConverter {
ConverterFeatures doFeatures() const override {
return ConverterFeature::Optimize|ConverterFeature::ValidateData;
}
void doSetInputFormat(Format, Containers::StringView) override {}
void doSetOutputFormat(Format, Containers::StringView) override {}
} converter;
std::ostringstream out;
Error redirectError{&out};
converter.setOptimizationLevel({});
CORRADE_COMPARE(out.str(), "ShaderTools::AbstractConverter::setOptimizationLevel(): feature advertised but not implemented\n");
}
void AbstractConverterTest::setDebugInfoLevel() {
struct: AbstractConverter {
ConverterFeatures doFeatures() const override {
return ConverterFeature::DebugInfo|ConverterFeature::ValidateData;
}
void doSetInputFormat(Format, Containers::StringView) override {}
void doSetOutputFormat(Format, Containers::StringView) override {}
void doSetDebugInfoLevel(Containers::StringView level) override {
debugInfo = level;
}
Containers::StringView debugInfo;
} converter;
converter.setDebugInfoLevel("0");
CORRADE_COMPARE(converter.debugInfo, "0");
}
void AbstractConverterTest::setDebugInfoLevelNotSupported() {
#ifdef CORRADE_NO_ASSERT
CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions");
#endif
struct: AbstractConverter {
ConverterFeatures doFeatures() const override {
return ConverterFeature::ValidateData;
}
void doSetInputFormat(Format, Containers::StringView) override {}
void doSetOutputFormat(Format, Containers::StringView) override {}
} converter;
std::ostringstream out;
Error redirectError{&out};
converter.setDebugInfoLevel({});
CORRADE_COMPARE(out.str(), "ShaderTools::AbstractConverter::setDebugInfoLevel(): feature not supported\n");
}
void AbstractConverterTest::setDebugInfoLevelNotImplemented() {
#ifdef CORRADE_NO_ASSERT
CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions");
#endif
struct: AbstractConverter {
ConverterFeatures doFeatures() const override {
return ConverterFeature::DebugInfo|ConverterFeature::ValidateData;
}
void doSetInputFormat(Format, Containers::StringView) override {}
void doSetOutputFormat(Format, Containers::StringView) override {}
} converter;
std::ostringstream out;
Error redirectError{&out};
converter.setDebugInfoLevel({});
CORRADE_COMPARE(out.str(), "ShaderTools::AbstractConverter::setDebugInfoLevel(): feature advertised but not implemented\n");
}
void AbstractConverterTest::validateData() { void AbstractConverterTest::validateData() {
struct: AbstractConverter { struct: AbstractConverter {
ConverterFeatures doFeatures() const override { ConverterFeatures doFeatures() const override {

Loading…
Cancel
Save