mirror of https://github.com/mosra/magnum.git
Browse Source
Currently there's just a plugin interface for shader converters. More stuff (probably something like SPIR-V reflection) will come later.pull/481/head
24 changed files with 3122 additions and 7 deletions
@ -0,0 +1,95 @@ |
|||||||
|
/*
|
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, |
||||||
|
2020 Vladimír Vondruš <mosra@centrum.cz> |
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a |
||||||
|
copy of this software and associated documentation files (the "Software"), |
||||||
|
to deal in the Software without restriction, including without limitation |
||||||
|
the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||||
|
and/or sell copies of the Software, and to permit persons to whom the |
||||||
|
Software is furnished to do so, subject to the following conditions: |
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included |
||||||
|
in all copies or substantial portions of the Software. |
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||||
|
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||||
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||||
|
DEALINGS IN THE SOFTWARE. |
||||||
|
*/ |
||||||
|
|
||||||
|
#include <unordered_map> |
||||||
|
#include <Corrade/Containers/Array.h> |
||||||
|
#include <Corrade/Containers/Optional.h> |
||||||
|
#include <Corrade/Containers/String.h> |
||||||
|
#include <Corrade/Utility/Resource.h> |
||||||
|
|
||||||
|
#include "Magnum/FileCallback.h" |
||||||
|
#include "Magnum/ShaderTools/AbstractConverter.h" |
||||||
|
|
||||||
|
#define DOXYGEN_IGNORE(...) __VA_ARGS__ |
||||||
|
|
||||||
|
using namespace Magnum; |
||||||
|
|
||||||
|
int main() { |
||||||
|
{ |
||||||
|
Containers::Pointer<ShaderTools::AbstractConverter> converter; |
||||||
|
Containers::Array<const char> extract(const std::string&, const std::string&); |
||||||
|
/* [AbstractConverter-usage-callbacks] */ |
||||||
|
struct Data { |
||||||
|
std::unordered_map<std::string, |
||||||
|
Containers::Array<const char>> files; |
||||||
|
} data; |
||||||
|
|
||||||
|
converter->setInputFileCallback([](const std::string& filename, |
||||||
|
InputFileCallbackPolicy policy, Data& data) |
||||||
|
-> Containers::Optional<Containers::ArrayView<const char>> |
||||||
|
{ |
||||||
|
auto found = data.files.find(filename); |
||||||
|
|
||||||
|
/* Discard the loaded file, if not needed anymore */ |
||||||
|
if(policy == InputFileCallbackPolicy::Close) { |
||||||
|
if(found != data.files.end()) data.files.erase(found); |
||||||
|
return {}; |
||||||
|
} |
||||||
|
|
||||||
|
/* Extract from an archive if not there yet */ |
||||||
|
if(found == data.files.end()) found = data.files.emplace( |
||||||
|
filename, extract("shaders.zip", filename)).first; |
||||||
|
|
||||||
|
return Containers::arrayView(found->second); |
||||||
|
}, data); |
||||||
|
|
||||||
|
/* extracted from a ZIP */ |
||||||
|
auto result = converter->validateFile(ShaderTools::Stage::Fragment, "ssao.frag"); |
||||||
|
/* [AbstractConverter-usage-callbacks] */ |
||||||
|
} |
||||||
|
|
||||||
|
{ |
||||||
|
Containers::Pointer<ShaderTools::AbstractConverter> converter; |
||||||
|
/* [AbstractConverter-setInputFileCallback] */ |
||||||
|
converter->setInputFileCallback([](const std::string& filename, |
||||||
|
InputFileCallbackPolicy, void*) { |
||||||
|
Utility::Resource rs("data"); |
||||||
|
return Containers::optional(rs.getRaw(filename)); |
||||||
|
}); |
||||||
|
/* [AbstractConverter-setInputFileCallback] */ |
||||||
|
} |
||||||
|
|
||||||
|
{ |
||||||
|
Containers::Pointer<ShaderTools::AbstractConverter> converter; |
||||||
|
/* [AbstractConverter-setInputFileCallback-template] */ |
||||||
|
const Utility::Resource rs{"data"}; |
||||||
|
converter->setInputFileCallback([](const std::string& filename, |
||||||
|
InputFileCallbackPolicy, const Utility::Resource& rs) { |
||||||
|
return Containers::optional(rs.getRaw(filename)); |
||||||
|
}, rs); |
||||||
|
/* [AbstractConverter-setInputFileCallback-template] */ |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
@ -0,0 +1,429 @@ |
|||||||
|
/*
|
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, |
||||||
|
2020 Vladimír Vondruš <mosra@centrum.cz> |
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a |
||||||
|
copy of this software and associated documentation files (the "Software"), |
||||||
|
to deal in the Software without restriction, including without limitation |
||||||
|
the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||||
|
and/or sell copies of the Software, and to permit persons to whom the |
||||||
|
Software is furnished to do so, subject to the following conditions: |
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included |
||||||
|
in all copies or substantial portions of the Software. |
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||||
|
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||||
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||||
|
DEALINGS IN THE SOFTWARE. |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "AbstractConverter.h" |
||||||
|
|
||||||
|
#include <Corrade/Containers/Array.h> |
||||||
|
#include <Corrade/Containers/EnumSet.hpp> |
||||||
|
#include <Corrade/Containers/Optional.h> |
||||||
|
#include <Corrade/Containers/String.h> |
||||||
|
#include <Corrade/Containers/StringStl.h> |
||||||
|
#include <Corrade/Utility/DebugStl.h> |
||||||
|
#include <Corrade/Utility/Directory.h> |
||||||
|
|
||||||
|
#include "Magnum/FileCallback.h" |
||||||
|
|
||||||
|
#ifndef CORRADE_PLUGINMANAGER_NO_DYNAMIC_PLUGIN_SUPPORT |
||||||
|
#include "Magnum/ShaderTools/configure.h" |
||||||
|
#endif |
||||||
|
|
||||||
|
namespace Magnum { namespace ShaderTools { |
||||||
|
|
||||||
|
std::string AbstractConverter::pluginInterface() { |
||||||
|
return |
||||||
|
/* [interface] */ |
||||||
|
"cz.mosra.magnum.ShaderTools.AbstractConverter/0.1" |
||||||
|
/* [interface] */ |
||||||
|
; |
||||||
|
} |
||||||
|
|
||||||
|
#ifndef CORRADE_PLUGINMANAGER_NO_DYNAMIC_PLUGIN_SUPPORT |
||||||
|
std::vector<std::string> AbstractConverter::pluginSearchPaths() { |
||||||
|
return PluginManager::implicitPluginSearchPaths( |
||||||
|
#ifndef MAGNUM_BUILD_STATIC |
||||||
|
Utility::Directory::libraryLocation(&pluginInterface), |
||||||
|
#else |
||||||
|
{}, |
||||||
|
#endif |
||||||
|
#ifdef CORRADE_IS_DEBUG_BUILD |
||||||
|
MAGNUM_PLUGINS_SHADERCONVERTER_DEBUG_DIR, |
||||||
|
#else |
||||||
|
MAGNUM_PLUGINS_SHADERCONVERTER_DIR, |
||||||
|
#endif |
||||||
|
#ifdef CORRADE_IS_DEBUG_BUILD |
||||||
|
"magnum-d/" |
||||||
|
#else |
||||||
|
"magnum/" |
||||||
|
#endif |
||||||
|
"shaderconverters"); |
||||||
|
} |
||||||
|
#endif |
||||||
|
|
||||||
|
AbstractConverter::AbstractConverter() = default; |
||||||
|
|
||||||
|
AbstractConverter::AbstractConverter(PluginManager::Manager<AbstractConverter>& manager): PluginManager::AbstractManagingPlugin<AbstractConverter>{manager} {} |
||||||
|
|
||||||
|
AbstractConverter::AbstractConverter(PluginManager::AbstractManager& manager, const std::string& plugin): PluginManager::AbstractManagingPlugin<AbstractConverter>{manager, plugin} {} |
||||||
|
|
||||||
|
ConverterFeatures AbstractConverter::features() const { |
||||||
|
const ConverterFeatures features = doFeatures(); |
||||||
|
CORRADE_ASSERT(features & ~ConverterFeature::InputFileCallback, "ShaderTools::AbstractConverter::features(): implementation reported no features", {}); |
||||||
|
return features; |
||||||
|
} |
||||||
|
|
||||||
|
void AbstractConverter::setFlags(const ConverterFlags flags) { |
||||||
|
_flags = flags; |
||||||
|
doSetFlags(flags); |
||||||
|
} |
||||||
|
|
||||||
|
void AbstractConverter::doSetFlags(ConverterFlags) {} |
||||||
|
|
||||||
|
void AbstractConverter::setInputFileCallback(Containers::Optional<Containers::ArrayView<const char>>(*callback)(const std::string&, InputFileCallbackPolicy, void*), void* const userData) { |
||||||
|
/* Clearing the *File bits as those are present in *Data as well and thus
|
||||||
|
this would pass even if only file conversion/validation is supported, |
||||||
|
which is wrong */ |
||||||
|
CORRADE_ASSERT(features() & (ConverterFeature::InputFileCallback|ConverterFeature::ValidateData|ConverterFeature::ConvertData) & ~(ConverterFeature::ValidateFile|ConverterFeature::ConvertFile), |
||||||
|
"ShaderTools::AbstractConverter::setInputFileCallback(): converter supports neither loading from data nor via callbacks, callbacks can't be used", ); |
||||||
|
|
||||||
|
_inputFileCallback = callback; |
||||||
|
_inputFileCallbackUserData = userData; |
||||||
|
doSetInputFileCallback(callback, userData); |
||||||
|
} |
||||||
|
|
||||||
|
void AbstractConverter::doSetInputFileCallback(Containers::Optional<Containers::ArrayView<const char>>(*)(const std::string&, InputFileCallbackPolicy, void*), void*) {} |
||||||
|
|
||||||
|
std::pair<bool, Containers::String> AbstractConverter::validateData(const Stage stage, const Containers::ArrayView<const void> data) { |
||||||
|
CORRADE_ASSERT(features() & ConverterFeature::ValidateData, |
||||||
|
"ShaderTools::AbstractConverter::validateData(): feature not supported", {}); |
||||||
|
|
||||||
|
/* Cast to a non-void type for more convenience */ |
||||||
|
std::pair<bool, Containers::String> out = doValidateData(stage, Containers::arrayCast<const char>(data)); |
||||||
|
CORRADE_ASSERT(out.second.isSmall() || !out.second.deleter(), |
||||||
|
"ShaderTools::AbstractConverter::validateData(): implementation is not allowed to use a custom String deleter", {}); |
||||||
|
return out; |
||||||
|
} |
||||||
|
|
||||||
|
std::pair<bool, Containers::String> AbstractConverter::doValidateData(Stage, Containers::ArrayView<const char>) { |
||||||
|
CORRADE_ASSERT_UNREACHABLE("ShaderTools::AbstractConverter::validateData(): feature advertised but not implemented", {}); |
||||||
|
} |
||||||
|
|
||||||
|
std::pair<bool, Containers::String> AbstractConverter::validateFile(const Stage stage, const Containers::StringView filename) { |
||||||
|
CORRADE_ASSERT(features() & (ConverterFeature::ValidateFile|ConverterFeature::ValidateData), |
||||||
|
"ShaderTools::AbstractConverter::validateFile(): feature not supported", {}); |
||||||
|
|
||||||
|
std::pair<bool, Containers::String> out; |
||||||
|
|
||||||
|
/* If input file callbacks are not set or the converter supports handling
|
||||||
|
them directly, call into the implementation */ |
||||||
|
if(!_inputFileCallback || (doFeatures() & ConverterFeature::InputFileCallback)) { |
||||||
|
out = doValidateFile(stage, filename); |
||||||
|
|
||||||
|
/* Otherwise, if validating data is supported, use the callback and pass
|
||||||
|
the data through to validateData(). Mark the file as ready to be closed |
||||||
|
once validating is finished. */ |
||||||
|
} else if(doFeatures() & ConverterFeature::ValidateData) { |
||||||
|
/* This needs to be duplicated here and in the doValidateFile()
|
||||||
|
implementation in order to support both following cases: |
||||||
|
- plugins that don't support InputFileCallback but have their own |
||||||
|
doValidateFile() implementation (callback needs to be used here, |
||||||
|
because the base doValidateFile() implementation might never get |
||||||
|
called) |
||||||
|
- plugins that support InputFileCallback but want to delegate the |
||||||
|
actual file loading to the default implementation (callback used |
||||||
|
in the base doValidateFile() implementation, because this branch |
||||||
|
is never taken in that case) */ |
||||||
|
const Containers::Optional<Containers::ArrayView<const char>> data = _inputFileCallback(filename, InputFileCallbackPolicy::LoadTemporary, _inputFileCallbackUserData); |
||||||
|
if(!data) { |
||||||
|
Error{} << "ShaderTools::AbstractConverter::validateFile(): cannot open file" << filename; |
||||||
|
return {}; |
||||||
|
} |
||||||
|
out = doValidateData(stage, *data); |
||||||
|
_inputFileCallback(filename, InputFileCallbackPolicy::Close, _inputFileCallbackUserData); |
||||||
|
|
||||||
|
/* Shouldn't get here, the assert is fired already in setFileCallback() */ |
||||||
|
} else CORRADE_INTERNAL_ASSERT_UNREACHABLE(); /* LCOV_EXCL_LINE */ |
||||||
|
|
||||||
|
CORRADE_ASSERT(out.second.isSmall() || !out.second.deleter(), |
||||||
|
"ShaderTools::AbstractConverter::validateFile(): implementation is not allowed to use a custom String deleter", {}); |
||||||
|
return out; |
||||||
|
} |
||||||
|
|
||||||
|
std::pair<bool, Containers::String> AbstractConverter::doValidateFile(const Stage stage, const Containers::StringView filename) { |
||||||
|
CORRADE_ASSERT(features() >= ConverterFeature::ValidateData, "ShaderTools::AbstractConverter::validateFile(): feature advertised but not implemented", {}); |
||||||
|
|
||||||
|
/* If callbacks are set, use them. This is the same implementation as in
|
||||||
|
validateFile(), see the comment there for details. */ |
||||||
|
if(_inputFileCallback) { |
||||||
|
const Containers::Optional<Containers::ArrayView<const char>> data = _inputFileCallback(filename, InputFileCallbackPolicy::LoadTemporary, _inputFileCallbackUserData); |
||||||
|
if(!data) { |
||||||
|
Error{} << "ShaderTools::AbstractConverter::validateFile(): cannot open file" << filename; |
||||||
|
return {}; |
||||||
|
} |
||||||
|
std::pair<bool, Containers::String> out = doValidateData(stage, *data); |
||||||
|
_inputFileCallback(filename, InputFileCallbackPolicy::Close, _inputFileCallbackUserData); |
||||||
|
return out; |
||||||
|
|
||||||
|
/* Otherwise open the file directly */ |
||||||
|
} else { |
||||||
|
if(!Utility::Directory::exists(filename)) { |
||||||
|
Error() << "ShaderTools::AbstractConverter::validateFile(): cannot open file" << filename; |
||||||
|
return {}; |
||||||
|
} |
||||||
|
|
||||||
|
return doValidateData(stage, Utility::Directory::read(filename)); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
Containers::Array<char> AbstractConverter::convertDataToData(const Stage stage, const Containers::ArrayView<const void> data) { |
||||||
|
CORRADE_ASSERT(features() >= ConverterFeature::ConvertData, |
||||||
|
"ShaderTools::AbstractConverter::convertDataToData(): feature not supported", {}); |
||||||
|
|
||||||
|
/* Cast to a non-void type for more convenience */ |
||||||
|
Containers::Array<char> out = doConvertDataToData(stage, Containers::arrayCast<const char>(data)); |
||||||
|
CORRADE_ASSERT(!out.deleter(), |
||||||
|
"ShaderTools::AbstractConverter::convertDataToData(): implementation is not allowed to use a custom Array deleter", {}); |
||||||
|
return out; |
||||||
|
} |
||||||
|
|
||||||
|
Containers::Array<char> AbstractConverter::doConvertDataToData(Stage, Containers::ArrayView<const char>) { |
||||||
|
CORRADE_ASSERT_UNREACHABLE("ShaderTools::AbstractConverter::convertDataToData(): feature advertised but not implemented", {}); |
||||||
|
} |
||||||
|
|
||||||
|
bool AbstractConverter::convertDataToFile(const Stage stage, const Containers::ArrayView<const void> data, const Containers::StringView to) { |
||||||
|
CORRADE_ASSERT(features() >= ConverterFeature::ConvertData, |
||||||
|
"ShaderTools::AbstractConverter::convertDataToFile(): feature not supported", {}); |
||||||
|
|
||||||
|
/** @todo this needs expansion once output callbacks are supported as well */ |
||||||
|
|
||||||
|
/* Cast to a non-void type for more convenience */ |
||||||
|
Containers::Array<char> out = doConvertDataToData(stage, Containers::arrayCast<const char>(data)); |
||||||
|
if(!out) return false; |
||||||
|
|
||||||
|
if(!Utility::Directory::write(to, out)) { |
||||||
|
Error{} << "ShaderTools::AbstractConverter::convertDataToFile(): cannot write to file" << to; |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
Containers::Array<char> AbstractConverter::convertDataToDataUsingInputFileCallbacks(const char* const prefix, const Stage stage, const Containers::StringView from) { |
||||||
|
const Containers::Optional<Containers::ArrayView<const char>> data = _inputFileCallback(from, InputFileCallbackPolicy::LoadTemporary, _inputFileCallbackUserData); |
||||||
|
if(!data) { |
||||||
|
Error{} << prefix << "cannot open file" << from; |
||||||
|
return {}; |
||||||
|
} |
||||||
|
Containers::Array<char> out = doConvertDataToData(stage, *data); |
||||||
|
_inputFileCallback(from, InputFileCallbackPolicy::Close, _inputFileCallbackUserData); |
||||||
|
return out; |
||||||
|
} |
||||||
|
|
||||||
|
bool AbstractConverter::convertFileToFile(const Stage stage, const Containers::StringView from, const Containers::StringView to) { |
||||||
|
CORRADE_ASSERT(features() & (ConverterFeature::ConvertFile|ConverterFeature::ConvertData), |
||||||
|
"ShaderTools::AbstractConverter::convertFileToFile(): feature not supported", {}); |
||||||
|
|
||||||
|
/** @todo this needs expansion once output callbacks are supported as well */ |
||||||
|
|
||||||
|
/* If input file callbacks are not set or the converter supports handling
|
||||||
|
them directly, call into the implementation */ |
||||||
|
if(!_inputFileCallback || (doFeatures() & ConverterFeature::InputFileCallback)) { |
||||||
|
return doConvertFileToFile(stage, from, to); |
||||||
|
|
||||||
|
/* Otherwise, if converting data is supported, use the callback and pass
|
||||||
|
the data through to convertDataToData(). Mark the file as ready to be |
||||||
|
closed once conversion is finished. */ |
||||||
|
} else if(doFeatures() & ConverterFeature::ConvertData) { |
||||||
|
/* This needs to be duplicated here and in the doConvertFileToFile()
|
||||||
|
implementation in order to support both following cases: |
||||||
|
- plugins that don't support InputFileCallback but have their own |
||||||
|
doConvertFileToFile() implementation (callback needs to be used |
||||||
|
here, because the base doConvertFileToFile() implementation might |
||||||
|
never get called) |
||||||
|
- plugins that support InputFileCallback but want to delegate the |
||||||
|
actual file loading to the default implementation (callback used |
||||||
|
in the base doConvertFileToFile() implementation, because this |
||||||
|
branch is never taken in that case) */ |
||||||
|
Containers::Array<char> out = convertDataToDataUsingInputFileCallbacks("ShaderTools::AbstractConverter::convertFileToFile():", stage, from); |
||||||
|
if(!out) return false; |
||||||
|
|
||||||
|
if(!Utility::Directory::write(to, out)) { |
||||||
|
Error{} << "ShaderTools::AbstractConverter::convertFileToFile(): cannot write to file" << to; |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
return true; |
||||||
|
|
||||||
|
/* Shouldn't get here, the assert is fired already in setFileCallback() */ |
||||||
|
} else CORRADE_INTERNAL_ASSERT_UNREACHABLE(); /* LCOV_EXCL_LINE */ |
||||||
|
} |
||||||
|
|
||||||
|
bool AbstractConverter::doConvertFileToFile(const Stage stage, const Containers::StringView from, const Containers::StringView to) { |
||||||
|
CORRADE_ASSERT(features() >= ConverterFeature::ConvertData, "ShaderTools::AbstractConverter::convertFileToFile(): feature advertised but not implemented", {}); |
||||||
|
|
||||||
|
/** @todo this needs expansion once output callbacks are supported as well */ |
||||||
|
Containers::Array<char> out; |
||||||
|
|
||||||
|
/* If callbacks are set, use them. This is the same implementation as in
|
||||||
|
convertFileToFile(), see the comment there for details. */ |
||||||
|
if(_inputFileCallback) { |
||||||
|
out = convertDataToDataUsingInputFileCallbacks("ShaderTools::AbstractConverter::convertFileToFile():", stage, from); |
||||||
|
|
||||||
|
/* Otherwise open the file directly */ |
||||||
|
} else { |
||||||
|
if(!Utility::Directory::exists(from)) { |
||||||
|
Error() << "ShaderTools::AbstractConverter::convertFileToFile(): cannot open file" << from; |
||||||
|
return {}; |
||||||
|
} |
||||||
|
|
||||||
|
out = doConvertDataToData(stage, Utility::Directory::read(from)); |
||||||
|
} |
||||||
|
|
||||||
|
if(!out) return false; |
||||||
|
|
||||||
|
if(!Utility::Directory::write(to, out)) { |
||||||
|
Error{} << "ShaderTools::AbstractConverter::convertFileToFile(): cannot write to file" << to; |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
Containers::Array<char> AbstractConverter::convertFileToData(const Stage stage, const Containers::StringView from) { |
||||||
|
CORRADE_ASSERT(features() >= ConverterFeature::ConvertData, |
||||||
|
"ShaderTools::AbstractConverter::convertFileToData(): feature not supported", {}); |
||||||
|
|
||||||
|
Containers::Array<char> out; |
||||||
|
|
||||||
|
/* If input file callbacks are not set or the converter supports handling
|
||||||
|
them directly, call into the implementation */ |
||||||
|
if(!_inputFileCallback || (doFeatures() & ConverterFeature::InputFileCallback)) { |
||||||
|
out = doConvertFileToData(stage, from); |
||||||
|
|
||||||
|
/* Otherwise use the callback and pass the data through to
|
||||||
|
convertDataToData(). Mark the file as ready to be closed once conversion |
||||||
|
is finished. */ |
||||||
|
} else { |
||||||
|
/* This needs to be duplicated here and in the doConvertFileToData()
|
||||||
|
implementation in order to support both following cases: |
||||||
|
- plugins that don't support InputFileCallback but have their own |
||||||
|
doConvertFileToData() implementation (callback needs to be used |
||||||
|
here, because the base doConvertFileToData() implementation might |
||||||
|
never get called) |
||||||
|
- plugins that support InputFileCallback but want to delegate the |
||||||
|
actual file loading to the default implementation (callback used |
||||||
|
in the base doConvertFileToData() implementation, because this |
||||||
|
branch is never taken in that case) */ |
||||||
|
out = convertDataToDataUsingInputFileCallbacks("ShaderTools::AbstractConverter::convertFileToData():", stage, from); |
||||||
|
} |
||||||
|
|
||||||
|
CORRADE_ASSERT(!out.deleter(), |
||||||
|
"ShaderTools::AbstractConverter::convertFileToData(): implementation is not allowed to use a custom Array deleter", {}); |
||||||
|
return out; |
||||||
|
} |
||||||
|
|
||||||
|
Containers::Array<char> AbstractConverter::doConvertFileToData(const Stage stage, const Containers::StringView from) { |
||||||
|
/* If callbacks are set, use them. This is the same implementation as in
|
||||||
|
convertFileToFile(), see the comment there for details. */ |
||||||
|
if(_inputFileCallback) { |
||||||
|
return convertDataToDataUsingInputFileCallbacks("ShaderTools::AbstractConverter::convertFileToData():", stage, from); |
||||||
|
|
||||||
|
/* Otherwise open the file directly */ |
||||||
|
} else { |
||||||
|
if(!Utility::Directory::exists(from)) { |
||||||
|
Error() << "ShaderTools::AbstractConverter::convertFileToData(): cannot open file" << from; |
||||||
|
return {}; |
||||||
|
} |
||||||
|
|
||||||
|
return doConvertDataToData(stage, Utility::Directory::read(from)); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
Debug& operator<<(Debug& debug, const ConverterFeature value) { |
||||||
|
debug << "ShaderTools::ConverterFeature" << Debug::nospace; |
||||||
|
|
||||||
|
switch(value) { |
||||||
|
/* LCOV_EXCL_START */ |
||||||
|
#define _c(v) case ConverterFeature::v: return debug << "::" #v; |
||||||
|
_c(ValidateData) |
||||||
|
_c(ValidateFile) |
||||||
|
_c(ConvertData) |
||||||
|
_c(ConvertFile) |
||||||
|
_c(InputFileCallback) |
||||||
|
#undef _c |
||||||
|
/* LCOV_EXCL_STOP */ |
||||||
|
} |
||||||
|
|
||||||
|
return debug << "(" << Debug::nospace << reinterpret_cast<void*>(UnsignedByte(value)) << Debug::nospace << ")"; |
||||||
|
} |
||||||
|
|
||||||
|
Debug& operator<<(Debug& debug, const ConverterFeatures value) { |
||||||
|
return Containers::enumSetDebugOutput(debug, value, "ShaderTools::ConverterFeatures{}", { |
||||||
|
ConverterFeature::ValidateData, |
||||||
|
/* Implied by ValidateData, has to be after */ |
||||||
|
ConverterFeature::ValidateFile, |
||||||
|
ConverterFeature::ConvertData, |
||||||
|
/* Implied by ConvertData, has to be after */ |
||||||
|
ConverterFeature::ConvertFile, |
||||||
|
ConverterFeature::InputFileCallback}); |
||||||
|
} |
||||||
|
|
||||||
|
Debug& operator<<(Debug& debug, const ConverterFlag value) { |
||||||
|
debug << "ShaderTools::ConverterFlag" << Debug::nospace; |
||||||
|
|
||||||
|
switch(value) { |
||||||
|
/* LCOV_EXCL_START */ |
||||||
|
#define _c(v) case ConverterFlag::v: return debug << "::" #v; |
||||||
|
_c(Verbose) |
||||||
|
#undef _c |
||||||
|
/* LCOV_EXCL_STOP */ |
||||||
|
} |
||||||
|
|
||||||
|
return debug << "(" << Debug::nospace << reinterpret_cast<void*>(UnsignedByte(value)) << Debug::nospace << ")"; |
||||||
|
} |
||||||
|
|
||||||
|
Debug& operator<<(Debug& debug, const ConverterFlags value) { |
||||||
|
return Containers::enumSetDebugOutput(debug, value, "ShaderTools::ConverterFlags{}", { |
||||||
|
ConverterFlag::Verbose}); |
||||||
|
} |
||||||
|
|
||||||
|
Debug& operator<<(Debug& debug, const Stage value) { |
||||||
|
debug << "ShaderTools::Stage" << Debug::nospace; |
||||||
|
|
||||||
|
switch(value) { |
||||||
|
/* LCOV_EXCL_START */ |
||||||
|
#define _c(v) case Stage::v: return debug << "::" #v; |
||||||
|
_c(Unspecified) |
||||||
|
_c(Vertex) |
||||||
|
_c(Fragment) |
||||||
|
_c(Geometry) |
||||||
|
_c(TessellationControl) |
||||||
|
_c(TessellationEvaluation) |
||||||
|
_c(Compute) |
||||||
|
_c(RayGeneration) |
||||||
|
_c(RayAnyHit) |
||||||
|
_c(RayClosestHit) |
||||||
|
_c(RayMiss) |
||||||
|
_c(RayIntersection) |
||||||
|
_c(RayCallable) |
||||||
|
_c(MeshTask) |
||||||
|
_c(Mesh) |
||||||
|
#undef _c |
||||||
|
/* LCOV_EXCL_STOP */ |
||||||
|
} |
||||||
|
|
||||||
|
return debug << "(" << Debug::nospace << reinterpret_cast<void*>(UnsignedByte(value)) << Debug::nospace << ")"; |
||||||
|
} |
||||||
|
|
||||||
|
}} |
||||||
@ -0,0 +1,651 @@ |
|||||||
|
#ifndef Magnum_ShaderTools_AbstractConverter_h |
||||||
|
#define Magnum_ShaderTools_AbstractConverter_h |
||||||
|
/*
|
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, |
||||||
|
2020 Vladimír Vondruš <mosra@centrum.cz> |
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a |
||||||
|
copy of this software and associated documentation files (the "Software"), |
||||||
|
to deal in the Software without restriction, including without limitation |
||||||
|
the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||||
|
and/or sell copies of the Software, and to permit persons to whom the |
||||||
|
Software is furnished to do so, subject to the following conditions: |
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included |
||||||
|
in all copies or substantial portions of the Software. |
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||||
|
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||||
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||||
|
DEALINGS IN THE SOFTWARE. |
||||||
|
*/ |
||||||
|
|
||||||
|
/** @file
|
||||||
|
* @brief Class @ref Magnum::ShaderTools::AbstractConverter, enum @ref Magnum::ShaderTools::ConverterFeature, @ref Magnum::ShaderTools::ConverterFlag, @ref Magnum::ShaderTools::Stage, enum set @ref Magnum::ShaderTools::ConverterFeatures, @ref Magnum::ShaderTools::ConverterFlags |
||||||
|
* @m_since_latest |
||||||
|
*/ |
||||||
|
|
||||||
|
#include <Corrade/Containers/EnumSet.h> |
||||||
|
#include <Corrade/PluginManager/AbstractManagingPlugin.h> |
||||||
|
|
||||||
|
#include "Magnum/Magnum.h" |
||||||
|
#include "Magnum/ShaderTools/visibility.h" |
||||||
|
|
||||||
|
namespace Magnum { namespace ShaderTools { |
||||||
|
|
||||||
|
/**
|
||||||
|
@brief Features supported by a shader converter |
||||||
|
@m_since_latest |
||||||
|
|
||||||
|
@see @ref ConverterFeatures, @ref AbstractConverter::features() |
||||||
|
*/ |
||||||
|
enum class ConverterFeature: UnsignedInt { |
||||||
|
/**
|
||||||
|
* Validate shader file with @ref AbstractConverter::validateFile() |
||||||
|
*/ |
||||||
|
ValidateFile = 1 << 0, |
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate shader data with @ref AbstractConverter::validateData(). |
||||||
|
* Implies @ref ConverterFeature::ValidateData. |
||||||
|
*/ |
||||||
|
ValidateData = ValidateFile|(1 << 1), |
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert shader file to a file with @ref AbstractConverter::convertFileToFile() |
||||||
|
*/ |
||||||
|
ConvertFile = 1 << 2, |
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert shader data to data with |
||||||
|
* @ref AbstractConverter::convertDataToData() or any of the other |
||||||
|
* @ref AbstractConverter::convertDataToFile(), |
||||||
|
* @ref AbstractConverter::convertFileToData() combinations. Implies |
||||||
|
* @ref ConverterFeature::ConvertFile. |
||||||
|
*/ |
||||||
|
ConvertData = ConvertFile|(1 << 3), |
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifying input file callbacks for additional files referenced from the |
||||||
|
* main file using @ref AbstractConverter::setInputFileCallback(). If the |
||||||
|
* converter doesn't expose this feature, the format is either single-file |
||||||
|
* or input file callbacks are not supported. |
||||||
|
* |
||||||
|
* See @ref ShaderTools-AbstractConverter-usage-callbacks and particular |
||||||
|
* converter documentation for more information. |
||||||
|
*/ |
||||||
|
InputFileCallback = 1 << 4 |
||||||
|
}; |
||||||
|
|
||||||
|
/**
|
||||||
|
@brief Features supported by a shader converter |
||||||
|
@m_since_latest |
||||||
|
|
||||||
|
@see @ref AbstractConverter::features() |
||||||
|
*/ |
||||||
|
typedef Containers::EnumSet<ConverterFeature> ConverterFeatures; |
||||||
|
|
||||||
|
CORRADE_ENUMSET_OPERATORS(ConverterFeatures) |
||||||
|
|
||||||
|
/**
|
||||||
|
@debugoperatorenum{ConverterFeature} |
||||||
|
@m_since_latest |
||||||
|
*/ |
||||||
|
MAGNUM_SHADERTOOLS_EXPORT Debug& operator<<(Debug& debug, ConverterFeature value); |
||||||
|
|
||||||
|
/**
|
||||||
|
@debugoperatorenum{ConverterFeatures} |
||||||
|
@m_since_latest |
||||||
|
*/ |
||||||
|
MAGNUM_SHADERTOOLS_EXPORT Debug& operator<<(Debug& debug, ConverterFeatures value); |
||||||
|
|
||||||
|
/**
|
||||||
|
@brief Shader converter flag |
||||||
|
@m_since_latest |
||||||
|
|
||||||
|
@see @ref ConverterFlags, @ref AbstractConverter::setFlags() |
||||||
|
*/ |
||||||
|
enum class ConverterFlag: UnsignedInt { |
||||||
|
/**
|
||||||
|
* Print verbose diagnostic. By default the converter only prints warnings |
||||||
|
* and errors. |
||||||
|
*/ |
||||||
|
Verbose = 1 << 0 |
||||||
|
}; |
||||||
|
|
||||||
|
/**
|
||||||
|
@brief Shader converter flags |
||||||
|
@m_since_latest |
||||||
|
|
||||||
|
@see @ref AbstractConverter::setFlags() |
||||||
|
*/ |
||||||
|
typedef Containers::EnumSet<ConverterFlag> ConverterFlags; |
||||||
|
|
||||||
|
CORRADE_ENUMSET_OPERATORS(ConverterFlags) |
||||||
|
|
||||||
|
/**
|
||||||
|
@debugoperatorenum{ConverterFlag} |
||||||
|
@m_since_latest |
||||||
|
*/ |
||||||
|
MAGNUM_SHADERTOOLS_EXPORT Debug& operator<<(Debug& debug, ConverterFlag value); |
||||||
|
|
||||||
|
/**
|
||||||
|
@debugoperatorenum{ConverterFlags} |
||||||
|
@m_since_latest |
||||||
|
*/ |
||||||
|
MAGNUM_SHADERTOOLS_EXPORT Debug& operator<<(Debug& debug, ConverterFlags value); |
||||||
|
|
||||||
|
/**
|
||||||
|
@brief Shader stage |
||||||
|
@m_since_latest |
||||||
|
|
||||||
|
@see @ref AbstractConverter |
||||||
|
*/ |
||||||
|
enum class Stage: UnsignedInt { |
||||||
|
/**
|
||||||
|
* Unspecified stage. When used in the |
||||||
|
* @ref AbstractConverter::validateFile(), |
||||||
|
* @ref AbstractConverter::convertFileToFile() "convertFileToFile()", |
||||||
|
* @ref AbstractConverter::convertFileToData() "convertFileToData()" APIs, |
||||||
|
* particular plugins may attempt to detect the stage from filename, the |
||||||
|
* shader stage might also be encoded directly in certain formats. Leaving |
||||||
|
* the stage unspecified might limit validation and conversion |
||||||
|
* capabilities, see documentation of a particular converter for concrete |
||||||
|
* behavior. |
||||||
|
* |
||||||
|
* This value is guaranteed to be @cpp 0 @ce, which means you're encouraged |
||||||
|
* to simply use @cpp {} @ce in function calls and elsewhere. |
||||||
|
*/ |
||||||
|
Unspecified = 0, |
||||||
|
|
||||||
|
Vertex, /**< Vertex stage */ |
||||||
|
Fragment, /**< Fragment stage */ |
||||||
|
Geometry, /**< Geometry stage */ |
||||||
|
TessellationControl, /**< Tessellation control stage */ |
||||||
|
TessellationEvaluation, /**< Tessellation evaluation stage */ |
||||||
|
Compute, /**< Compute stage */ |
||||||
|
|
||||||
|
RayGeneration, /**< Ray generation stage */ |
||||||
|
RayAnyHit, /**< Ray any hit stage */ |
||||||
|
RayClosestHit, /**< Ray closest hit stage */ |
||||||
|
RayMiss, /**< Ray miss stage */ |
||||||
|
RayIntersection, /**< Ray intersection stage */ |
||||||
|
RayCallable, /**< Ray callable stage */ |
||||||
|
|
||||||
|
MeshTask, /**< Mesh task stage */ |
||||||
|
Mesh /**< Mesh stage */ |
||||||
|
}; |
||||||
|
|
||||||
|
/**
|
||||||
|
@debugoperatorenum{Stage} |
||||||
|
@m_since_latest |
||||||
|
*/ |
||||||
|
MAGNUM_SHADERTOOLS_EXPORT Debug& operator<<(Debug& debug, Stage value); |
||||||
|
|
||||||
|
/**
|
||||||
|
@brief Base for shader converter plugins |
||||||
|
@m_since_latest |
||||||
|
|
||||||
|
Provides functionality for validating and converting shader code between |
||||||
|
different representations or performing optimizations and other operations on |
||||||
|
them. See @ref plugins for more information and `*ShaderConverter` classes in |
||||||
|
the @ref ShaderTools namespace for available scene converter plugins. |
||||||
|
|
||||||
|
@section ShaderTools-AbstractConverter-usage Usage |
||||||
|
|
||||||
|
Shader converters are most commonly implemented as plugins. Depending on |
||||||
|
exposed @ref features(), a plugin can support shader validation, conversion or |
||||||
|
linking. |
||||||
|
|
||||||
|
@subsection ShaderTools-AbstractConverter-usage-validation Shader validation |
||||||
|
|
||||||
|
@subsection ShaderTools-AbstractConverter-usage-conversion Shader conversion |
||||||
|
|
||||||
|
@subsection ShaderTools-AbstractConverter-usage-callbacks Loading shaders from memory, using file callbacks |
||||||
|
|
||||||
|
Besides loading shaders directly from the filesystem using @ref validateFile() |
||||||
|
/ @ref convertFileToFile() like shown above, it's possible to use |
||||||
|
@ref validateData(), @ref convertDataToData() and variants to load data from |
||||||
|
memory. Note that the particular converter implementation has to support |
||||||
|
@ref ConverterFeature::ValidateData / @ref ConverterFeature::ConvertData for |
||||||
|
this method to work. |
||||||
|
|
||||||
|
Textual shader sources sometimes @cpp #include @ce other sources and in that |
||||||
|
case you may want to intercept those references and load them in a custom way |
||||||
|
as well. For converters that advertise support for this with |
||||||
|
@ref ConverterFeature::InputFileCallback this is done by specifying an input |
||||||
|
file callback using @ref setInputFileCallback(). The callback gets a filename, |
||||||
|
@ref InputFileCallbackPolicy and an user pointer as parameters; returns a |
||||||
|
non-owning view on the loaded data or a |
||||||
|
@ref Corrade::Containers::NullOpt "Containers::NullOpt" to indicate the file |
||||||
|
loading failed. For example, validating a shader from compiled-in resources |
||||||
|
could look like below. Note that the input file callback affects |
||||||
|
@ref validateFile() / @ref convertFileToFile() / @ref convertFileToData() as |
||||||
|
well --- you don't have to load the top-level file manually and pass it to |
||||||
|
@ref validateData() / @ref convertDataToData(), any converter supporting the |
||||||
|
callback feature handles that correctly. |
||||||
|
|
||||||
|
@snippet MagnumShaderTools.cpp AbstractConverter-usage-callbacks |
||||||
|
|
||||||
|
For converters that don't support @ref ConverterFeature::InputFileCallback |
||||||
|
directly, the base @ref validateFile() / @ref convertFileToFile() / |
||||||
|
@ref convertFileToData() implementations will use the file callback to pass |
||||||
|
the loaded data through to @ref validateData() / @ref convertDataToData(), in |
||||||
|
case the converter supports at least @ref ConverterFeature::ValidateData |
||||||
|
/ @ref ConverterFeature::ConvertData. If the converter supports none of |
||||||
|
@ref ConverterFeature::InputFileCallback, @ref ConverterFeature::ValidateData |
||||||
|
or @ref ConverterFeature::ConvertData, @ref setInputFileCallback() doesn't |
||||||
|
allow the callbacks to be set. |
||||||
|
|
||||||
|
The input file callback signature is the same for |
||||||
|
@ref ShaderTools::AbstractConverter, @ref Trade::AbstractImporter and |
||||||
|
@ref Text::AbstractFont to allow code reuse. |
||||||
|
|
||||||
|
@section ShaderTools-AbstractConverter-data-dependency Data dependency |
||||||
|
|
||||||
|
The instances returned from various functions *by design* have no dependency on |
||||||
|
the importer instance and neither on the dynamic plugin module. In other words, |
||||||
|
you don't need to keep the importer instance (or the plugin manager instance) |
||||||
|
around in order to have the returned data valid --- all returned |
||||||
|
@ref Corrade::Containers::String and @ref Corrade::Containers::Array instances |
||||||
|
are only allowed to have default deleters and this is to avoid potential |
||||||
|
dangling function pointer calls when destructing such instances after the |
||||||
|
plugin module has been unloaded. |
||||||
|
|
||||||
|
@section ShaderTools-AbstractConverter-subclassing Subclassing |
||||||
|
|
||||||
|
The plugin needs to implement the @ref doFeatures() function and one or more of |
||||||
|
@ref doValidateData(), @ref doValidateFile(), @ref doConvertDataToData(), |
||||||
|
@ref doConvertFileToData(), or @ref doConvertFileToFile() functions based on |
||||||
|
what features are supported. |
||||||
|
|
||||||
|
You don't need to do most of the redundant sanity checks, these things are |
||||||
|
checked by the implementation: |
||||||
|
|
||||||
|
- The function @ref doValidateData() is called only if |
||||||
|
@ref ConverterFeature::ValidateData is supported. |
||||||
|
- The function @ref doValidateFile() is called only if |
||||||
|
@ref ConverterFeature::ValidateFile is supported. |
||||||
|
- Functions @ref doConvertDataToData() and @ref doConvertFileToData() are |
||||||
|
called only if @ref ConverterFeature::ConvertData is supported. |
||||||
|
- The function @ref doConvertFileToFile() is called only if |
||||||
|
@ref ConverterFeature::ConvertFile is supported. |
||||||
|
|
||||||
|
@m_class{m-block m-warning} |
||||||
|
|
||||||
|
@par Dangling function pointers on plugin unload |
||||||
|
As @ref ShaderTools-AbstractConverter-data-dependency "mentioned above", |
||||||
|
@ref Corrade::Containers::String and @ref Corrade::Containers::Array |
||||||
|
instances returned from plugin implementations are not allowed to use |
||||||
|
anything else than the default deleter, otherwise this could cause dangling |
||||||
|
function pointer call on array destruction if the plugin gets unloaded |
||||||
|
before the array is destroyed. This is asserted by the base implementation |
||||||
|
on return. |
||||||
|
*/ |
||||||
|
class MAGNUM_SHADERTOOLS_EXPORT AbstractConverter: public PluginManager::AbstractManagingPlugin<AbstractConverter> { |
||||||
|
public: |
||||||
|
/**
|
||||||
|
* @brief Plugin interface |
||||||
|
* |
||||||
|
* @snippet Magnum/ShaderTools/AbstractConverter.cpp interface |
||||||
|
*/ |
||||||
|
static std::string pluginInterface(); |
||||||
|
|
||||||
|
#ifndef CORRADE_PLUGINMANAGER_NO_DYNAMIC_PLUGIN_SUPPORT |
||||||
|
/**
|
||||||
|
* @brief Plugin search paths |
||||||
|
* |
||||||
|
* Looks into `magnum/shaderconverters/` or `magnum-d/shaderconverters/` |
||||||
|
* next to the dynamic @ref ShaderTools library, next to the executable |
||||||
|
* and elsewhere according to the rules documented in |
||||||
|
* @ref Corrade::PluginManager::implicitPluginSearchPaths(). The search |
||||||
|
* directory can be also hardcoded using the `MAGNUM_PLUGINS_DIR` CMake |
||||||
|
* variables, see @ref building for more information. |
||||||
|
* |
||||||
|
* Not defined on platforms without |
||||||
|
* @ref CORRADE_PLUGINMANAGER_NO_DYNAMIC_PLUGIN_SUPPORT "dynamic plugin support". |
||||||
|
*/ |
||||||
|
static std::vector<std::string> pluginSearchPaths(); |
||||||
|
#endif |
||||||
|
|
||||||
|
/** @brief Default constructor */ |
||||||
|
explicit AbstractConverter(); |
||||||
|
|
||||||
|
/** @brief Constructor with access to plugin manager */ |
||||||
|
explicit AbstractConverter(PluginManager::Manager<AbstractConverter>& manager); |
||||||
|
|
||||||
|
/** @brief Plugin manager constructor */ |
||||||
|
explicit AbstractConverter(PluginManager::AbstractManager& manager, const std::string& plugin); |
||||||
|
|
||||||
|
/** @brief Features supported by this converter */ |
||||||
|
ConverterFeatures features() const; |
||||||
|
|
||||||
|
/** @brief Converter flags */ |
||||||
|
ConverterFlags flags() const { return _flags; } |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set converter flags |
||||||
|
* |
||||||
|
* Some flags can be set only if the converter supports particular |
||||||
|
* features, see documentation of each @ref ConverterFlag for more |
||||||
|
* information. By default no flags are set. |
||||||
|
*/ |
||||||
|
void setFlags(ConverterFlags flags); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Input file callback function |
||||||
|
* |
||||||
|
* @see @ref ShaderTools-AbstractConverter-usage-callbacks |
||||||
|
*/ |
||||||
|
auto inputFileCallback() const -> Containers::Optional<Containers::ArrayView<const char>>(*)(const std::string&, InputFileCallbackPolicy, void*) { return _inputFileCallback; } |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Input file callback user data |
||||||
|
* |
||||||
|
* @see @ref ShaderTools-AbstractConverter-usage-callbacks |
||||||
|
*/ |
||||||
|
void* inputFileCallbackUserData() const { return _inputFileCallbackUserData; } |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set input file callback |
||||||
|
* |
||||||
|
* In case the converter supports @ref ConverterFeature::InputFileCallback, |
||||||
|
* files opened through @ref validateFile(), @ref convertFileToData() |
||||||
|
* and @ref convertFileToFile() will be loaded through the provided |
||||||
|
* callback. Besides that, all external files referenced by the |
||||||
|
* top-level file will be loaded through the callback function as well, |
||||||
|
* usually on demand. The callback function gets a filename, |
||||||
|
* @ref InputFileCallbackPolicy and the @p userData pointer as input |
||||||
|
* and returns a non-owning view on the loaded data as output or a |
||||||
|
* @ref Corrade::Containers::NullOpt if loading failed --- because |
||||||
|
* empty files might also be valid in some circumstances, |
||||||
|
* @cpp nullptr @ce can't be used to indicate a failure. |
||||||
|
* |
||||||
|
* In case the converter doesn't support |
||||||
|
* @ref ConverterFeature::InputFileCallback but supports at least |
||||||
|
* @ref ConverterFeature::ValidateData / |
||||||
|
* @ref ConverterFeature::ConvertData, a file opened through |
||||||
|
* @ref validateFile(), @ref convertFileToData() or |
||||||
|
* @ref convertFileToFile() will be internally loaded through the |
||||||
|
* provided callback and then passed to @ref validateData() or |
||||||
|
* @ref convertDataToData(). First the file is loaded with |
||||||
|
* @ref InputFileCallbackPolicy::LoadTemporary passed to the callback, |
||||||
|
* then the returned memory view is passed to @ref validateData() / |
||||||
|
* @ref convertDataToData() (sidestepping the potential |
||||||
|
* @ref validateFile() / @ref convertFileToFile() implementation of |
||||||
|
* that particular converter) and after that the callback is called |
||||||
|
* again with @ref InputFileCallbackPolicy::Close. In case you need a |
||||||
|
* different behavior, use @ref validateData() / |
||||||
|
* @ref convertDataToData() directly. |
||||||
|
* |
||||||
|
* In case @p callback is @cpp nullptr @ce, the current callback (if |
||||||
|
* any) is reset. This function expects that the converter supports |
||||||
|
* either @ref ConverterFeature::InputFileCallback or at least one of |
||||||
|
* @ref ConverterFeature::ValidateData, |
||||||
|
* @ref ConverterFeature::ConvertData. If a converter supports neither, |
||||||
|
* callbacks can't be used. |
||||||
|
* |
||||||
|
* Following is an example of setting up an input file callback for |
||||||
|
* fetching compiled-in resources from @ref Corrade::Utility::Resource. |
||||||
|
* See the overload below for a more convenient type-safe way to pass |
||||||
|
* the user data pointer. |
||||||
|
* |
||||||
|
* @snippet MagnumShaderTools.cpp AbstractConverter-setInputFileCallback |
||||||
|
* |
||||||
|
* @see @ref ShaderTools-AbstractConverter-usage-callbacks |
||||||
|
*/ |
||||||
|
void setInputFileCallback(Containers::Optional<Containers::ArrayView<const char>>(*callback)(const std::string&, InputFileCallbackPolicy, void*), void* userData = nullptr); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set file opening callback |
||||||
|
* |
||||||
|
* Equivalent to calling the above with a lambda wrapper that casts |
||||||
|
* @cpp void* @ce back to @cpp T* @ce and dereferences it in order to |
||||||
|
* pass it to @p callback. Example usage --- this reuses an existing |
||||||
|
* @ref Corrade::Utility::Resource instance to avoid a potentially slow |
||||||
|
* resource group lookup every time: |
||||||
|
* |
||||||
|
* @snippet MagnumShaderTools.cpp AbstractConverter-setInputFileCallback-template |
||||||
|
* |
||||||
|
* @see @ref ShaderTools-AbstractConverter-usage-callbacks |
||||||
|
*/ |
||||||
|
#ifdef DOXYGEN_GENERATING_OUTPUT |
||||||
|
template<class T> void setInputFileCallback(Containers::Optional<Containers::ArrayView<const char>>(*callback)(const std::string&, InputFileCallbackPolicy, T&), T& userData); |
||||||
|
#else |
||||||
|
/* Otherwise the user would be forced to use the + operator to convert
|
||||||
|
a lambda to a function pointer and (besides being weird and |
||||||
|
annoying) it's also not portable because it doesn't work on MSVC |
||||||
|
2015 and older versions of MSVC 2017. */ |
||||||
|
template<class Callback, class T> void setInputFileCallback(Callback callback, T& userData); |
||||||
|
#endif |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Validate a shader |
||||||
|
* |
||||||
|
* Available only if @ref ConverterFeature::ValidateData is |
||||||
|
* supported. Returns |
||||||
|
* |
||||||
|
* - @cpp true @ce and an empty string if validation passes without |
||||||
|
* warnings, |
||||||
|
* - @cpp true @ce and a non-empty string if validation passes with |
||||||
|
* warnings, and |
||||||
|
* - @cpp false @ce if validation doesn't pass. If an external error |
||||||
|
* occurs (for example a referenced file not being found), it may |
||||||
|
* also happen that the returned string is empty and a message is |
||||||
|
* printed to error output instead. |
||||||
|
* |
||||||
|
* @see @ref features(), @ref validateFile() |
||||||
|
*/ |
||||||
|
std::pair<bool, Containers::String> validateData(Stage stage, Containers::ArrayView<const void> data); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Validate a shader |
||||||
|
* |
||||||
|
* Available only if @ref ConverterFeature::ValidateFile or |
||||||
|
* @ref ConverterFeature::ValidateData is supported. Returns |
||||||
|
* |
||||||
|
* - @cpp true @ce and an empty string if validation passes without |
||||||
|
* warnings, |
||||||
|
* - @cpp true @ce and a non-empty string if validation passes with |
||||||
|
* warnings, and |
||||||
|
* - @cpp false @ce if validation doesn't pass. If an external error |
||||||
|
* occurs (for example when a file cannot be read), it may also |
||||||
|
* happen that the returned string is empty and a message is |
||||||
|
* printed to error output instead. |
||||||
|
* |
||||||
|
* @see @ref features(), @ref validateData() |
||||||
|
*/ |
||||||
|
std::pair<bool, Containers::String> validateFile(Stage stage, Containers::StringView filename); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Convert shader data to a data |
||||||
|
* |
||||||
|
* Available only if @ref ConverterFeature::ConvertData is supported. |
||||||
|
* On failure the function prints an error message and returns |
||||||
|
* @cpp nullptr @ce. |
||||||
|
* @see @ref features(), @ref convertDataToFile(), |
||||||
|
* @ref convertFileToData(), @ref convertFileToFile() |
||||||
|
*/ |
||||||
|
Containers::Array<char> convertDataToData(Stage stage, Containers::ArrayView<const void> data); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Convert shader data to a file |
||||||
|
* |
||||||
|
* Available only if @ref ConverterFeature::ConvertData is supported. |
||||||
|
* Returns @cpp true @ce on success, prints an error message and |
||||||
|
* returns @cpp false @ce otherwise. |
||||||
|
* @see @ref features(), @ref convertDataToData(), |
||||||
|
* @ref convertFileToData(), @ref convertFileToFile() |
||||||
|
*/ |
||||||
|
bool convertDataToFile(Stage stage, Containers::ArrayView<const void> data, Containers::StringView to); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Convert shader file to a file |
||||||
|
* |
||||||
|
* Available only if @ref ConverterFeature::ConvertFile or |
||||||
|
* @ref ConverterFeature::ConvertData is supported. Returns |
||||||
|
* @cpp true @ce on success, prints an error message and returns |
||||||
|
* @cpp false @ce otherwise. |
||||||
|
* @see @ref features(), @ref convertFileToData(), |
||||||
|
* @ref convertDataToData(), @ref convertDataToFile() |
||||||
|
*/ |
||||||
|
bool convertFileToFile(Stage stage, Containers::StringView from, Containers::StringView to); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Convert shader data to a file |
||||||
|
* |
||||||
|
* Available only if @ref ConverterFeature::ConvertData is supported. |
||||||
|
* On failure the function prints an error message and returns |
||||||
|
* @cpp nullptr @ce. |
||||||
|
* @see @ref features(), @ref convertFileToFile(), |
||||||
|
* @ref convertDataToFile(), @ref convertDataToData() |
||||||
|
*/ |
||||||
|
Containers::Array<char> convertFileToData(Stage stage, const Containers::StringView from); |
||||||
|
|
||||||
|
protected: |
||||||
|
/**
|
||||||
|
* @brief Implementation for @ref validateFile() |
||||||
|
* |
||||||
|
* If @ref ConverterFeature::ValidateData is supported, default |
||||||
|
* implementation opens the file and calls @ref doValidateData() with |
||||||
|
* its contents. It is allowed to call this function from your |
||||||
|
* @ref doValidateFile() implementation --- in particular, this |
||||||
|
* implementation will also correctly handle callbacks set through |
||||||
|
* @ref setInputFileCallback(). |
||||||
|
* |
||||||
|
* This function is not called when file callbacks are set through |
||||||
|
* @ref setInputFileCallback() and @ref ConverterFeature::InputFileCallback |
||||||
|
* is not supported --- instead, file is loaded though the callback and |
||||||
|
* data passed through to @ref doValidateData(). |
||||||
|
*/ |
||||||
|
virtual std::pair<bool, Containers::String> doValidateFile(Stage stage, Containers::StringView filename); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Implementation for @ref convertFileToFile() |
||||||
|
* |
||||||
|
* If @ref ConverterFeature::ConvertData is supported, default |
||||||
|
* implementation opens the file and calls @ref doConvertDataToData() |
||||||
|
* with its contents, then saving the output to a file. It is allowed |
||||||
|
* to call this function from your @ref doConvertFileToFile() |
||||||
|
* implementation --- in particular, this implementation will also |
||||||
|
* correctly handle callbacks set through @ref setInputFileCallback(). |
||||||
|
* |
||||||
|
* This function is not called when file callbacks are set through |
||||||
|
* @ref setInputFileCallback() and @ref ConverterFeature::InputFileCallback |
||||||
|
* is not supported --- instead, file is loaded though the callback and |
||||||
|
* data passed through to @ref doConvertDataToData(). |
||||||
|
*/ |
||||||
|
virtual bool doConvertFileToFile(Stage stage, Containers::StringView from, Containers::StringView to); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Implementation for @ref convertFileToData() |
||||||
|
* |
||||||
|
* Default implementation opens the file and calls |
||||||
|
* @ref doConvertDataToData() with its contents --- you only need to |
||||||
|
* implement this if you need to do extra work with file inputs. It is |
||||||
|
* allowed to call this function from your @ref doConvertFileToData() |
||||||
|
* implementation --- in particular, this implementation will also |
||||||
|
* correctly handle callbacks set through @ref setInputFileCallback(). |
||||||
|
* |
||||||
|
* This function is not called when file callbacks are set through |
||||||
|
* @ref setInputFileCallback() and @ref ConverterFeature::InputFileCallback |
||||||
|
* is not supported --- instead, file is loaded though the callback and |
||||||
|
* data passed through to @ref doConvertDataToData(). |
||||||
|
*/ |
||||||
|
virtual Containers::Array<char> doConvertFileToData(Stage stage, Containers::StringView from); |
||||||
|
|
||||||
|
private: |
||||||
|
/**
|
||||||
|
* @brief Implementation for @ref features() |
||||||
|
* |
||||||
|
* Has to be implemented always, the implementation is expected to |
||||||
|
* support at least one feature. |
||||||
|
*/ |
||||||
|
virtual ConverterFeatures doFeatures() const = 0; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Implementation for @ref setFlags() |
||||||
|
* |
||||||
|
* Useful when the converter needs to modify some internal state on |
||||||
|
* flag setup. Default implementation does nothing and this |
||||||
|
* function doesn't need to be implemented --- the flags are available |
||||||
|
* through @ref flags(). |
||||||
|
* |
||||||
|
* To reduce the amount of error checking on user side, this function |
||||||
|
* isn't expected to fail --- if a flag combination is invalid / |
||||||
|
* unsuported, error reporting should be delayed to various conversion |
||||||
|
* functions, where the user is expected to do error handling anyway. |
||||||
|
*/ |
||||||
|
virtual void doSetFlags(ConverterFlags flags); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Implementation for @ref setInputFileCallback() |
||||||
|
* |
||||||
|
* Useful when the converter needs to modify some internal state on |
||||||
|
* callback setup. Default implementation does nothing and this |
||||||
|
* function doesn't need to be implemented --- the callback function |
||||||
|
* and user data pointer are available through @ref inputFileCallback() |
||||||
|
* and @ref inputFileCallbackUserData(). |
||||||
|
*/ |
||||||
|
virtual void doSetInputFileCallback(Containers::Optional<Containers::ArrayView<const char>>(*callback)(const std::string&, InputFileCallbackPolicy, void*), void* userData); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Implementation for @ref validateData() |
||||||
|
* |
||||||
|
* Has to be implemented if @ref ConverterFeature::ValidateData |
||||||
|
* is supported. While @ref validateData() uses a @cpp void @ce view in |
||||||
|
* order to accept any type, this function gets it cast to |
||||||
|
* @cpp char @ce for more convenience. |
||||||
|
*/ |
||||||
|
virtual std::pair<bool, Containers::String> doValidateData(Stage stage, Containers::ArrayView<const char> data); |
||||||
|
|
||||||
|
/* Used by convertFileToFile(), doConvertFileToFile(),
|
||||||
|
convertFileToData() and doConvertFileToData() */ |
||||||
|
MAGNUM_SHADERTOOLS_LOCAL Containers::Array<char> convertDataToDataUsingInputFileCallbacks(const char* prefix, const Stage stage, Containers::StringView from); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Implementation for @ref convertDataToData() |
||||||
|
* |
||||||
|
* Has to be implemented if @ref ConverterFeature::ConvertData is |
||||||
|
* supported. While @ref convertDataToData() uses a @cpp void @ce view |
||||||
|
* in order to accept any type, this function gets it cast to |
||||||
|
* @cpp char @ce for more convenience. |
||||||
|
*/ |
||||||
|
virtual Containers::Array<char> doConvertDataToData(Stage stage, Containers::ArrayView<const char> data); |
||||||
|
|
||||||
|
ConverterFlags _flags; |
||||||
|
|
||||||
|
Containers::Optional<Containers::ArrayView<const char>>(*_inputFileCallback)(const std::string&, InputFileCallbackPolicy, void*){}; |
||||||
|
void* _inputFileCallbackUserData{}; |
||||||
|
|
||||||
|
/* Used by the templated version only */ |
||||||
|
struct FileCallbackTemplate { |
||||||
|
void(*callback)(); |
||||||
|
const void* userData; |
||||||
|
/* GCC 4.8 complains loudly about missing initializers otherwise */ |
||||||
|
} _inputFileCallbackTemplate{nullptr, nullptr}; |
||||||
|
}; |
||||||
|
|
||||||
|
#ifndef DOXYGEN_GENERATING_OUTPUT |
||||||
|
template<class Callback, class T> void AbstractConverter::setInputFileCallback(Callback callback, T& userData) { |
||||||
|
/* Don't try to wrap a null function pointer. Need to cast first because
|
||||||
|
MSVC (even 2017) can't apply ! to a lambda. Ugh. */ |
||||||
|
const auto callbackPtr = static_cast<Containers::Optional<Containers::ArrayView<const char>>(*)(const std::string&, InputFileCallbackPolicy, T&)>(callback); |
||||||
|
if(!callbackPtr) return setInputFileCallback(nullptr); |
||||||
|
|
||||||
|
_inputFileCallbackTemplate = { reinterpret_cast<void(*)()>(callbackPtr), static_cast<const void*>(&userData) }; |
||||||
|
setInputFileCallback([](const std::string& filename, const InputFileCallbackPolicy flags, void* const userData) { |
||||||
|
auto& s = *reinterpret_cast<FileCallbackTemplate*>(userData); |
||||||
|
return reinterpret_cast<Containers::Optional<Containers::ArrayView<const char>>(*)(const std::string&, InputFileCallbackPolicy, T&)>(s.callback)(filename, flags, *static_cast<T*>(const_cast<void*>(s.userData))); |
||||||
|
}, &_inputFileCallbackTemplate); |
||||||
|
} |
||||||
|
#endif |
||||||
|
|
||||||
|
}} |
||||||
|
|
||||||
|
#endif |
||||||
@ -0,0 +1,102 @@ |
|||||||
|
# |
||||||
|
# This file is part of Magnum. |
||||||
|
# |
||||||
|
# Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, |
||||||
|
# 2020 Vladimír Vondruš <mosra@centrum.cz> |
||||||
|
# |
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a |
||||||
|
# copy of this software and associated documentation files (the "Software"), |
||||||
|
# to deal in the Software without restriction, including without limitation |
||||||
|
# the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||||
|
# and/or sell copies of the Software, and to permit persons to whom the |
||||||
|
# Software is furnished to do so, subject to the following conditions: |
||||||
|
# |
||||||
|
# The above copyright notice and this permission notice shall be included |
||||||
|
# in all copies or substantial portions of the Software. |
||||||
|
# |
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||||
|
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||||
|
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||||
|
# DEALINGS IN THE SOFTWARE. |
||||||
|
# |
||||||
|
|
||||||
|
find_package(Corrade REQUIRED PluginManager) |
||||||
|
|
||||||
|
# Files shared between main library and unit test library |
||||||
|
set(MagnumShaderTools_SRCS ) |
||||||
|
|
||||||
|
# Files compiled with different flags for main library and unit test library |
||||||
|
set(MagnumShaderTools_GracefulAssert_SRCS |
||||||
|
AbstractConverter.cpp) |
||||||
|
|
||||||
|
set(MagnumShaderTools_HEADERS |
||||||
|
AbstractConverter.h |
||||||
|
ShaderTools.h |
||||||
|
|
||||||
|
visibility.h) |
||||||
|
|
||||||
|
if(NOT CORRADE_PLUGINMANAGER_NO_DYNAMIC_PLUGIN_SUPPORT) |
||||||
|
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/configure.h.cmake |
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/configure.h) |
||||||
|
endif() |
||||||
|
|
||||||
|
# # Objects shared between main and test library |
||||||
|
# add_library(MagnumShaderToolsObjects OBJECT |
||||||
|
# ${MagnumShaderTools_SRCS} |
||||||
|
# ${MagnumShaderTools_HEADERS}) |
||||||
|
# target_include_directories(MagnumShaderToolsObjects PUBLIC $<TARGET_PROPERTY:Magnum,INTERFACE_INCLUDE_DIRECTORIES>) |
||||||
|
# if(NOT BUILD_STATIC) |
||||||
|
# target_compile_definitions(MagnumShaderToolsObjects PRIVATE "MagnumShaderToolsObjects_EXPORTS") |
||||||
|
# endif() |
||||||
|
# if(NOT BUILD_STATIC OR BUILD_STATIC_PIC) |
||||||
|
# set_target_properties(MagnumShaderToolsObjects PROPERTIES POSITION_INDEPENDENT_CODE ON) |
||||||
|
# endif() |
||||||
|
# set_target_properties(MagnumShaderToolsObjects PROPERTIES FOLDER "Magnum/ShaderTools") |
||||||
|
|
||||||
|
# Main ShaderTools library |
||||||
|
add_library(MagnumShaderTools ${SHARED_OR_STATIC} |
||||||
|
# $<TARGET_OBJECTS:MagnumShaderToolsObjects> |
||||||
|
${MagnumShaderTools_GracefulAssert_SRCS}) |
||||||
|
set_target_properties(MagnumShaderTools PROPERTIES |
||||||
|
DEBUG_POSTFIX "-d" |
||||||
|
FOLDER "Magnum/ShaderTools") |
||||||
|
if(NOT BUILD_STATIC) |
||||||
|
set_target_properties(MagnumShaderTools PROPERTIES VERSION ${MAGNUM_LIBRARY_VERSION} SOVERSION ${MAGNUM_LIBRARY_SOVERSION}) |
||||||
|
elseif(BUILD_STATIC_PIC) |
||||||
|
set_target_properties(MagnumShaderTools PROPERTIES POSITION_INDEPENDENT_CODE ON) |
||||||
|
endif() |
||||||
|
target_link_libraries(MagnumShaderTools PUBLIC |
||||||
|
Magnum |
||||||
|
Corrade::PluginManager) |
||||||
|
|
||||||
|
install(TARGETS MagnumShaderTools |
||||||
|
RUNTIME DESTINATION ${MAGNUM_BINARY_INSTALL_DIR} |
||||||
|
LIBRARY DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR} |
||||||
|
ARCHIVE DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR}) |
||||||
|
install(FILES ${MagnumShaderTools_HEADERS} DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/ShaderTools) |
||||||
|
|
||||||
|
if(BUILD_TESTS) |
||||||
|
# Library with graceful assert for testing |
||||||
|
add_library(MagnumShaderToolsTestLib ${SHARED_OR_STATIC} |
||||||
|
# $<TARGET_OBJECTS:MagnumShaderToolsObjects> |
||||||
|
${MagnumShaderTools_GracefulAssert_SRCS}) |
||||||
|
set_target_properties(MagnumShaderToolsTestLib PROPERTIES |
||||||
|
DEBUG_POSTFIX "-d" |
||||||
|
FOLDER "Magnum/ShaderTools") |
||||||
|
target_compile_definitions(MagnumShaderToolsTestLib PRIVATE |
||||||
|
"CORRADE_GRACEFUL_ASSERT" "MagnumShaderTools_EXPORTS") |
||||||
|
if(BUILD_STATIC_PIC) |
||||||
|
set_target_properties(MagnumShaderToolsTestLib PROPERTIES POSITION_INDEPENDENT_CODE ON) |
||||||
|
endif() |
||||||
|
target_link_libraries(MagnumShaderToolsTestLib PUBLIC |
||||||
|
Magnum |
||||||
|
Corrade::PluginManager) |
||||||
|
|
||||||
|
add_subdirectory(Test) |
||||||
|
endif() |
||||||
|
|
||||||
|
# Magnum ShaderTools target alias for superprojects |
||||||
|
add_library(Magnum::ShaderTools ALIAS MagnumShaderTools) |
||||||
@ -0,0 +1,40 @@ |
|||||||
|
#ifndef Magnum_Trade_ShaderTools_h |
||||||
|
#define Magnum_Trade_ShaderTools_h |
||||||
|
/*
|
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, |
||||||
|
2020 Vladimír Vondruš <mosra@centrum.cz> |
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a |
||||||
|
copy of this software and associated documentation files (the "Software"), |
||||||
|
to deal in the Software without restriction, including without limitation |
||||||
|
the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||||
|
and/or sell copies of the Software, and to permit persons to whom the |
||||||
|
Software is furnished to do so, subject to the following conditions: |
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included |
||||||
|
in all copies or substantial portions of the Software. |
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||||
|
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||||
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||||
|
DEALINGS IN THE SOFTWARE. |
||||||
|
*/ |
||||||
|
|
||||||
|
/** @file
|
||||||
|
* @brief Forward declarations for the @ref Magnum::ShaderTools namespace |
||||||
|
*/ |
||||||
|
|
||||||
|
namespace Magnum { namespace Trade { |
||||||
|
|
||||||
|
#ifndef DOXYGEN_GENERATING_OUTPUT |
||||||
|
class AbstractConverter; |
||||||
|
#endif |
||||||
|
|
||||||
|
}} |
||||||
|
|
||||||
|
#endif |
||||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,41 @@ |
|||||||
|
# |
||||||
|
# This file is part of Magnum. |
||||||
|
# |
||||||
|
# Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, |
||||||
|
# 2020 Vladimír Vondruš <mosra@centrum.cz> |
||||||
|
# |
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a |
||||||
|
# copy of this software and associated documentation files (the "Software"), |
||||||
|
# to deal in the Software without restriction, including without limitation |
||||||
|
# the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||||
|
# and/or sell copies of the Software, and to permit persons to whom the |
||||||
|
# Software is furnished to do so, subject to the following conditions: |
||||||
|
# |
||||||
|
# The above copyright notice and this permission notice shall be included |
||||||
|
# in all copies or substantial portions of the Software. |
||||||
|
# |
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||||
|
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||||
|
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||||
|
# DEALINGS IN THE SOFTWARE. |
||||||
|
# |
||||||
|
|
||||||
|
if(CORRADE_TARGET_EMSCRIPTEN OR CORRADE_TARGET_ANDROID) |
||||||
|
set(SHADERTOOLS_TEST_DIR ".") |
||||||
|
set(SHADERTOOLS_TEST_OUTPUT_DIR "./write") |
||||||
|
else() |
||||||
|
set(SHADERTOOLS_TEST_DIR ${CMAKE_CURRENT_SOURCE_DIR}) |
||||||
|
set(SHADERTOOLS_TEST_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}) |
||||||
|
endif() |
||||||
|
|
||||||
|
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/configure.h.cmake |
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/configure.h) |
||||||
|
|
||||||
|
corrade_add_test(ShaderToolsAbstractConverterTest AbstractConverterTest.cpp |
||||||
|
LIBRARIES MagnumShaderToolsTestLib |
||||||
|
FILES file.dat) |
||||||
|
|
||||||
|
target_include_directories(ShaderToolsAbstractConverterTest PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) |
||||||
@ -0,0 +1,27 @@ |
|||||||
|
/* |
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, |
||||||
|
2020 Vladimír Vondruš <mosra@centrum.cz> |
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a |
||||||
|
copy of this software and associated documentation files (the "Software"), |
||||||
|
to deal in the Software without restriction, including without limitation |
||||||
|
the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||||
|
and/or sell copies of the Software, and to permit persons to whom the |
||||||
|
Software is furnished to do so, subject to the following conditions: |
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included |
||||||
|
in all copies or substantial portions of the Software. |
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||||
|
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||||
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||||
|
DEALINGS IN THE SOFTWARE. |
||||||
|
*/ |
||||||
|
|
||||||
|
#define SHADERTOOLS_TEST_DIR "${SHADERTOOLS_TEST_DIR}" |
||||||
|
#define SHADERTOOLS_TEST_OUTPUT_DIR "${SHADERTOOLS_TEST_OUTPUT_DIR}" |
||||||
@ -0,0 +1,27 @@ |
|||||||
|
/* |
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, |
||||||
|
2020 Vladimír Vondruš <mosra@centrum.cz> |
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a |
||||||
|
copy of this software and associated documentation files (the "Software"), |
||||||
|
to deal in the Software without restriction, including without limitation |
||||||
|
the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||||
|
and/or sell copies of the Software, and to permit persons to whom the |
||||||
|
Software is furnished to do so, subject to the following conditions: |
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included |
||||||
|
in all copies or substantial portions of the Software. |
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||||
|
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||||
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||||
|
DEALINGS IN THE SOFTWARE. |
||||||
|
*/ |
||||||
|
|
||||||
|
#define MAGNUM_PLUGINS_SHADERCONVERTER_DIR "${MAGNUM_PLUGINS_SHADERCONVERTER_DIR}" |
||||||
|
#define MAGNUM_PLUGINS_SHADERCONVERTER_DEBUG_DIR "${MAGNUM_PLUGINS_SHADERCONVERTER_DEBUG_DIR}" |
||||||
@ -0,0 +1,48 @@ |
|||||||
|
#ifndef Magnum_ShaderTools_visibility_h |
||||||
|
#define Magnum_ShaderTools_visibility_h |
||||||
|
/*
|
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, |
||||||
|
2020 Vladimír Vondruš <mosra@centrum.cz> |
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a |
||||||
|
copy of this software and associated documentation files (the "Software"), |
||||||
|
to deal in the Software without restriction, including without limitation |
||||||
|
the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||||
|
and/or sell copies of the Software, and to permit persons to whom the |
||||||
|
Software is furnished to do so, subject to the following conditions: |
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included |
||||||
|
in all copies or substantial portions of the Software. |
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||||
|
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||||
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||||
|
DEALINGS IN THE SOFTWARE. |
||||||
|
*/ |
||||||
|
|
||||||
|
#include <Corrade/Utility/VisibilityMacros.h> |
||||||
|
|
||||||
|
#include "Magnum/configure.h" |
||||||
|
|
||||||
|
#ifndef DOXYGEN_GENERATING_OUTPUT |
||||||
|
#ifndef MAGNUM_BUILD_STATIC |
||||||
|
#if defined(MagnumShaderTools_EXPORTS) || defined(MagnumShaderToolsObjects_EXPORTS) |
||||||
|
#define MAGNUM_SHADERTOOLS_EXPORT CORRADE_VISIBILITY_EXPORT |
||||||
|
#else |
||||||
|
#define MAGNUM_SHADERTOOLS_EXPORT CORRADE_VISIBILITY_IMPORT |
||||||
|
#endif |
||||||
|
#else |
||||||
|
#define MAGNUM_SHADERTOOLS_EXPORT CORRADE_VISIBILITY_STATIC |
||||||
|
#endif |
||||||
|
#define MAGNUM_SHADERTOOLS_LOCAL CORRADE_VISIBILITY_LOCAL |
||||||
|
#else |
||||||
|
#define MAGNUM_SHADERTOOLS_EXPORT |
||||||
|
#define MAGNUM_SHADERTOOLS_LOCAL |
||||||
|
#endif |
||||||
|
|
||||||
|
#endif |
||||||
Loading…
Reference in new issue