From f80b238e2776b7c1fb60541b0d26b08ee488b735 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Thu, 29 Oct 2020 17:04:29 +0100 Subject: [PATCH] ShaderTools: intro docs for AbstractConverter. Now that we have AnyShaderConverter we can finally do that. --- doc/snippets/MagnumShaderTools.cpp | 58 ++++++++++++++++++++++ src/Magnum/ShaderTools/AbstractConverter.h | 39 +++++++++++++++ 2 files changed, 97 insertions(+) diff --git a/doc/snippets/MagnumShaderTools.cpp b/doc/snippets/MagnumShaderTools.cpp index 3052b89d2..12b91c6cb 100644 --- a/doc/snippets/MagnumShaderTools.cpp +++ b/doc/snippets/MagnumShaderTools.cpp @@ -37,6 +37,64 @@ using namespace Magnum; int main() { +{ +/* [AbstractConverter-usage-validation] */ +PluginManager::Manager manager; +Containers::Pointer converter = + manager.loadAndInstantiate("AnyShaderConverter"); + +bool valid; +Containers::String message; +if(converter) std::tie(valid, message) = + converter->validateFile(ShaderTools::Stage::Unspecified, "file.spv"); +if(!converter || !valid) + Error{} << "Validation failed:" << message; +else if(!message.isEmpty()) + Warning{} << "Validation succeeded with warnings:" << message; +else + Debug{} << "Validation passed"; +/* [AbstractConverter-usage-validation] */ +} + +{ +PluginManager::Manager manager; +/* [AbstractConverter-usage-compilation] */ +Containers::Pointer converter = + manager.loadAndInstantiate("GlslToSpirvShaderConverter"); + +/* Using CORRADE_LINE_STRING will make the compiler report line info that + matches the source */ +Containers::StringView glsl = "#line " CORRADE_LINE_STRING "\n" R"GLSL( +#version 450 core + +layout(binding=0) uniform Material { + vec4 color; +}; + +#ifdef TEXTURED +layout(binding=1) uniform sampler2D colorTexture; +layout(location=0) in vec2 textureCoordinates; +#endif + +layout(location=0) out vec4 fragmentColor; + +void main() { + fragmentColor = color + #ifdef TEXTURED + *texture(colorTexture, textureCoordinates) + #endif + ; +} +)GLSL"; + +converter->setDefinitions({ + {"TEXTURED", ""} +}); +Containers::Array spirv = converter->convertDataToData( + ShaderTools::Stage::Fragment, glsl); +/* [AbstractConverter-usage-compilation] */ +} + { Containers::Pointer converter; Containers::Array extract(const std::string&, const std::string&); diff --git a/src/Magnum/ShaderTools/AbstractConverter.h b/src/Magnum/ShaderTools/AbstractConverter.h index 783c81f2f..7be1d2000 100644 --- a/src/Magnum/ShaderTools/AbstractConverter.h +++ b/src/Magnum/ShaderTools/AbstractConverter.h @@ -322,10 +322,49 @@ Shader converters are most commonly implemented as plugins. Depending on exposed @ref features(), a plugin can support shader validation, conversion or linking. +@m_class{m-block m-warning} + +@par Multiple shader sources + Compared to the (very broad) OpenGL API, only one shader source can be + specified for a single stage. If you need to pass additional preprocessor + flags, it's possible to do it via @ref setDefinitions() for plugins that + support @ref ConverterFeature::Preprocess; if you have shader source + scattered across multiple files either concatenate them together before + processing or @cpp #include @ce the dependencies from the top-level file, + potentially together with setting up @ref ShaderTools-AbstractConverter-usage-callbacks "file callbacks" + (providing the particular converter implementation supports preprocessor + includes). + @subsection ShaderTools-AbstractConverter-usage-validation Shader validation +As is common with other plugin interfaces, the +@ref AnyConverter "AnyShaderConverter" will detect a shader format based on +file extension, load an appropriate validator plugin for given format and +validate it: + +@snippet MagnumShaderTools.cpp AbstractConverter-usage-validation + +In most cases, the validation result depends on the format version and target +environment used. Formats and versions set by @ref setInputFormat() / +@ref setOutputFormat() get propagated by @ref AnyConverter "AnyShaderConverter" +to the particular plugin, however the interpretation is plugin-specific, so be +sure to read their docs. + @subsection ShaderTools-AbstractConverter-usage-conversion Shader conversion and linking +The following example shows converting a GLSL shader to SPIR-V together with +setting preprocessor defines and treating any warnings as errors. This time +it's not using @ref AnyConverter "AnyShaderConverter" but instead asking for a +plugin using the `GlslToSpirvShaderConverter` alias (which maps for example to +@ref GlslangConverter "GlslangShaderConverter") --- since we're operating +directly on data, the plugin would have no chance to know the desired input / +output format otherwise. Same goes for the shader stage, which has to be +supplied explicitly: + +@snippet MagnumShaderTools.cpp AbstractConverter-usage-compilation + +@todoc document linking when SpirvToolsShaderConverter implements that + @subsection ShaderTools-AbstractConverter-usage-callbacks Loading shaders from memory, using file callbacks Besides loading shaders directly from the filesystem using @ref validateFile()