From dcbd860f9bca8e6370e6a4a1f5ae8d66284ae78a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Wed, 7 Oct 2020 19:30:31 +0200 Subject: [PATCH] shaderconverter: new tool. --- CMakeLists.txt | 3 +- doc/Doxyfile | 1 + doc/building.dox | 3 + doc/changelog.dox | 3 +- doc/cmake.dox | 2 + doc/utilities.dox | 1 + modules/FindMagnum.cmake | 5 +- package/archlinux/PKGBUILD | 1 + package/archlinux/PKGBUILD-clang | 1 + .../archlinux/PKGBUILD-clang-addressanitizer | 1 + package/archlinux/PKGBUILD-clang-analyzer | 1 + package/archlinux/PKGBUILD-clang-libc++ | 1 + package/archlinux/PKGBUILD-coverage | 1 + package/archlinux/PKGBUILD-es2 | 1 + package/archlinux/PKGBUILD-es2desktop | 1 + package/archlinux/PKGBUILD-es3 | 1 + package/archlinux/PKGBUILD-es3desktop | 1 + package/archlinux/PKGBUILD-gcc48 | 1 + package/archlinux/PKGBUILD-mingw-w64 | 2 + package/archlinux/PKGBUILD-release | 2 + package/archlinux/magnum-git/PKGBUILD | 1 + package/archlinux/magnum/PKGBUILD | 1 + package/ci/appveyor-desktop-gles.bat | 1 + package/ci/appveyor-desktop-mingw.bat | 1 + package/ci/appveyor-desktop.bat | 1 + package/ci/travis-desktop-gles.sh | 1 + package/ci/travis-desktop-vulkan.sh | 1 + package/ci/travis-desktop.sh | 1 + package/debian/rules | 1 + .../gentoo/dev-libs/magnum/magnum-9999.ebuild | 1 + package/homebrew/magnum.rb | 1 + package/msys/PKGBUILD | 1 + package/msys/magnum/PKGBUILD | 1 + src/Magnum/ShaderTools/CMakeLists.txt | 13 + src/Magnum/ShaderTools/shaderconverter.cpp | 439 ++++++++++++++++++ 35 files changed, 494 insertions(+), 4 deletions(-) create mode 100644 src/Magnum/ShaderTools/shaderconverter.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index a33a45e6b..72749a4a6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -72,6 +72,7 @@ endif() # API-independent utilities option(WITH_IMAGECONVERTER "Build magnum-imageconverter utility" OFF) option(WITH_SCENECONVERTER "Build magnum-sceneconverter utility" OFF) +option(WITH_SHADERCONVERTER "Build magnum-shaderconverter utility" OFF) # Magnum AL Info option(WITH_AL_INFO "Build magnum-al-info utility" OFF) @@ -96,7 +97,7 @@ option(WITH_DEBUGTOOLS "Build DebugTools library" ON) cmake_dependent_option(WITH_MESHTOOLS "Build MeshTools library" ON "NOT WITH_OBJIMPORTER;NOT WITH_SCENECONVERTER" ON) option(WITH_SCENEGRAPH "Build SceneGraph library" ON) option(WITH_SHADERS "Build Shaders library" ON) -option(WITH_SHADERTOOLS "Build ShaderTools library" ON) +cmake_dependent_option(WITH_SHADERTOOLS "Build ShaderTools library" ON "NOT WITH_SHADERCONVERTER" ON) cmake_dependent_option(WITH_TEXT "Build Text library" ON "NOT WITH_FONTCONVERTER;NOT WITH_MAGNUMFONT;NOT WITH_MAGNUMFONTCONVERTER" ON) cmake_dependent_option(WITH_TEXTURETOOLS "Build TextureTools library" ON "NOT WITH_TEXT;NOT WITH_DISTANCEFIELDCONVERTER" ON) cmake_dependent_option(WITH_TRADE "Build Trade library" ON "NOT WITH_MESHTOOLS;NOT WITH_PRIMITIVES;NOT WITH_IMAGECONVERTER;NOT WITH_ANYIMAGEIMPORTER;NOT WITH_ANYIMAGECONVERTER;NOT WITH_ANYSCENEIMPORTER;NOT WITH_OBJIMPORTER;NOT WITH_TGAIMAGECONVERTER;NOT WITH_TGAIMPORTER" ON) diff --git a/doc/Doxyfile b/doc/Doxyfile index a63e47ceb..cbdf75f6c 100644 --- a/doc/Doxyfile +++ b/doc/Doxyfile @@ -921,6 +921,7 @@ INPUT = ../src/Magnum \ ../src/Magnum/Audio/al-info.cpp \ ../src/Magnum/MeshTools/sceneconverter.cpp \ ../src/Magnum/Platform/gl-info.cpp \ + ../src/Magnum/ShaderTools/shaderconverter.cpp \ ../src/Magnum/Text/fontconverter.cpp \ ../src/Magnum/TextureTools/distancefieldconverter.cpp \ ../src/Magnum/Trade/imageconverter.cpp \ diff --git a/doc/building.dox b/doc/building.dox index e35fd8703..87d7830d3 100644 --- a/doc/building.dox +++ b/doc/building.dox @@ -628,6 +628,9 @@ There are also a few command-line utilities, also all disabled by default: - `WITH_SCENECONVERTER` --- Build the @ref magnum-sceneconverter "magnum-sceneconverter" executable for converting scenes of different formats. Enables also building of the @ref MeshTools library. +- `WITH_SHADERCONVERTER` --- Build the @ref magnum-shaderconverter "magnum-shaderconverter" + executable for converting scenes of different formats. Enables also + building of the @ref ShaderTools library. Options controlling the build: diff --git a/doc/changelog.dox b/doc/changelog.dox index 605291fad..5088eb71e 100644 --- a/doc/changelog.dox +++ b/doc/changelog.dox @@ -92,7 +92,8 @@ See also: - New @ref ShaderTools library that provides a @ref ShaderTools::AbstractConverter plugin interface for shader validation, conversion, compilation and optimization; together with a - @ref ShaderTools::AnyConverter "AnyShaderConverter" plugin + @ref ShaderTools::AnyConverter "AnyShaderConverter" plugin and a + @ref magnum-shaderconverter "magnum-shaderconverter" utility @subsubsection changelog-latest-new-scenegraph SceneGraph library diff --git a/doc/cmake.dox b/doc/cmake.dox index 6b194970d..464d54ac9 100644 --- a/doc/cmake.dox +++ b/doc/cmake.dox @@ -272,6 +272,8 @@ Lastly, a few utility executables are available: executable - `sceneconverter` --- @ref magnum-sceneconverter "magnum-imageconverter" executable +- `shaderconverter` --- @ref magnum-shaderconverter "magnum-shaderconverter" + executable - `gl-info` --- @ref magnum-gl-info "magnum-gl-info" executable - `al-info` --- @ref magnum-al-info "magnum-al-info" executable diff --git a/doc/utilities.dox b/doc/utilities.dox index 499daec6b..a58df6fa1 100644 --- a/doc/utilities.dox +++ b/doc/utilities.dox @@ -55,6 +55,7 @@ namespace Magnum { - @subpage magnum-fontconverter --- @copybrief magnum-fontconverter - @subpage magnum-imageconverter --- @copybrief magnum-imageconverter - @subpage magnum-sceneconverter --- @copybrief magnum-sceneconverter +- @subpage magnum-shaderconverter --- @copybrief magnum-shaderconverter */ } diff --git a/modules/FindMagnum.cmake b/modules/FindMagnum.cmake index ce743858e..9bfda176c 100644 --- a/modules/FindMagnum.cmake +++ b/modules/FindMagnum.cmake @@ -96,6 +96,7 @@ # fontconverter - magnum-fontconverter executable # imageconverter - magnum-imageconverter executable # sceneconverterter - magnum-sceneconverter executable +# shaderconverterter - magnum-shaderconverter executable # gl-info - magnum-gl-info executable # al-info - magnum-al-info executable # @@ -373,8 +374,8 @@ set(_MAGNUM_PLUGIN_COMPONENT_LIST AnySceneImporter MagnumFont MagnumFontConverter ObjImporter TgaImageConverter TgaImporter WavAudioImporter) set(_MAGNUM_EXECUTABLE_COMPONENT_LIST - distancefieldconverter fontconverter imageconverter sceneconverter gl-info - al-info) + distancefieldconverter fontconverter imageconverter sceneconverter + shaderconverter gl-info al-info) # Inter-component dependencies set(_MAGNUM_Audio_DEPENDENCIES ) diff --git a/package/archlinux/PKGBUILD b/package/archlinux/PKGBUILD index 6baa2ea50..b0559874a 100644 --- a/package/archlinux/PKGBUILD +++ b/package/archlinux/PKGBUILD @@ -51,6 +51,7 @@ build() { -DWITH_FONTCONVERTER=ON \ -DWITH_IMAGECONVERTER=ON \ -DWITH_SCENECONVERTER=ON \ + -DWITH_SHADERCONVERTER=ON \ -DWITH_GL_INFO=ON \ -DWITH_AL_INFO=ON \ -DBUILD_TESTS=ON \ diff --git a/package/archlinux/PKGBUILD-clang b/package/archlinux/PKGBUILD-clang index 79fc97550..adaa31ff6 100644 --- a/package/archlinux/PKGBUILD-clang +++ b/package/archlinux/PKGBUILD-clang @@ -54,6 +54,7 @@ build() { -DWITH_FONTCONVERTER=ON \ -DWITH_IMAGECONVERTER=ON \ -DWITH_SCENECONVERTER=ON \ + -DWITH_SHADERCONVERTER=ON \ -DWITH_GL_INFO=ON \ -DWITH_AL_INFO=ON \ -DBUILD_TESTS=ON \ diff --git a/package/archlinux/PKGBUILD-clang-addressanitizer b/package/archlinux/PKGBUILD-clang-addressanitizer index b4ce8fe47..150b72d5e 100644 --- a/package/archlinux/PKGBUILD-clang-addressanitizer +++ b/package/archlinux/PKGBUILD-clang-addressanitizer @@ -55,6 +55,7 @@ build() { -DWITH_FONTCONVERTER=ON \ -DWITH_IMAGECONVERTER=ON \ -DWITH_SCENECONVERTER=ON \ + -DWITH_SHADERCONVERTER=ON \ -DWITH_GL_INFO=ON \ -DWITH_AL_INFO=ON \ -DBUILD_TESTS=ON \ diff --git a/package/archlinux/PKGBUILD-clang-analyzer b/package/archlinux/PKGBUILD-clang-analyzer index ff151b778..c71ae35c0 100644 --- a/package/archlinux/PKGBUILD-clang-analyzer +++ b/package/archlinux/PKGBUILD-clang-analyzer @@ -46,6 +46,7 @@ build() { -DWITH_FONTCONVERTER=ON \ -DWITH_IMAGECONVERTER=ON \ -DWITH_SCENECONVERTER=ON \ + -DWITH_SHADERCONVERTER=ON \ -DWITH_GL_INFO=ON \ -DWITH_AL_INFO=ON \ -DBUILD_TESTS=ON \ diff --git a/package/archlinux/PKGBUILD-clang-libc++ b/package/archlinux/PKGBUILD-clang-libc++ index b9ff95a8c..66543f52d 100644 --- a/package/archlinux/PKGBUILD-clang-libc++ +++ b/package/archlinux/PKGBUILD-clang-libc++ @@ -57,6 +57,7 @@ build() { -DWITH_FONTCONVERTER=ON \ -DWITH_IMAGECONVERTER=ON \ -DWITH_SCENECONVERTER=ON \ + -DWITH_SHADERCONVERTER=ON \ -DWITH_GL_INFO=ON \ -DWITH_AL_INFO=ON \ -DBUILD_TESTS=ON \ diff --git a/package/archlinux/PKGBUILD-coverage b/package/archlinux/PKGBUILD-coverage index 5bde289ed..761130657 100644 --- a/package/archlinux/PKGBUILD-coverage +++ b/package/archlinux/PKGBUILD-coverage @@ -52,6 +52,7 @@ build() { -DWITH_FONTCONVERTER=ON \ -DWITH_IMAGECONVERTER=ON \ -DWITH_SCENECONVERTER=ON \ + -DWITH_SHADERCONVERTER=ON \ -DWITH_GL_INFO=ON \ -DWITH_AL_INFO=ON \ -DBUILD_TESTS=ON \ diff --git a/package/archlinux/PKGBUILD-es2 b/package/archlinux/PKGBUILD-es2 index 916b2b170..8ce8e50ec 100644 --- a/package/archlinux/PKGBUILD-es2 +++ b/package/archlinux/PKGBUILD-es2 @@ -41,6 +41,7 @@ build() { -DWITH_WAVAUDIOIMPORTER=ON \ -DWITH_IMAGECONVERTER=ON \ -DWITH_SCENECONVERTER=ON \ + -DWITH_SHADERCONVERTER=ON \ -DWITH_GL_INFO=ON \ -DWITH_AL_INFO=ON \ -DBUILD_TESTS=ON \ diff --git a/package/archlinux/PKGBUILD-es2desktop b/package/archlinux/PKGBUILD-es2desktop index d083add96..a756ba744 100644 --- a/package/archlinux/PKGBUILD-es2desktop +++ b/package/archlinux/PKGBUILD-es2desktop @@ -45,6 +45,7 @@ build() { -DWITH_WAVAUDIOIMPORTER=ON \ -DWITH_IMAGECONVERTER=ON \ -DWITH_SCENECONVERTER=ON \ + -DWITH_SHADERCONVERTER=ON \ -DWITH_GL_INFO=ON \ -DWITH_AL_INFO=ON \ -DBUILD_TESTS=ON \ diff --git a/package/archlinux/PKGBUILD-es3 b/package/archlinux/PKGBUILD-es3 index 598ea4c58..71c276d26 100644 --- a/package/archlinux/PKGBUILD-es3 +++ b/package/archlinux/PKGBUILD-es3 @@ -41,6 +41,7 @@ build() { -DWITH_WAVAUDIOIMPORTER=ON \ -DWITH_IMAGECONVERTER=ON \ -DWITH_SCENECONVERTER=ON \ + -DWITH_SHADERCONVERTER=ON \ -DWITH_GL_INFO=ON \ -DWITH_AL_INFO=ON \ -DBUILD_TESTS=ON \ diff --git a/package/archlinux/PKGBUILD-es3desktop b/package/archlinux/PKGBUILD-es3desktop index 61a43d312..3f0b1ebb5 100644 --- a/package/archlinux/PKGBUILD-es3desktop +++ b/package/archlinux/PKGBUILD-es3desktop @@ -45,6 +45,7 @@ build() { -DWITH_WAVAUDIOIMPORTER=ON \ -DWITH_IMAGECONVERTER=ON \ -DWITH_SCENECONVERTER=ON \ + -DWITH_SHADERCONVERTER=ON \ -DWITH_GL_INFO=ON \ -DWITH_AL_INFO=ON \ -DBUILD_TESTS=ON \ diff --git a/package/archlinux/PKGBUILD-gcc48 b/package/archlinux/PKGBUILD-gcc48 index eb74b6da0..8af824485 100644 --- a/package/archlinux/PKGBUILD-gcc48 +++ b/package/archlinux/PKGBUILD-gcc48 @@ -57,6 +57,7 @@ build() { -DWITH_FONTCONVERTER=ON \ -DWITH_IMAGECONVERTER=ON \ -DWITH_SCENECONVERTER=ON \ + -DWITH_SHADERCONVERTER=ON \ -DWITH_GL_INFO=ON \ -DWITH_AL_INFO=ON \ -DBUILD_TESTS=ON \ diff --git a/package/archlinux/PKGBUILD-mingw-w64 b/package/archlinux/PKGBUILD-mingw-w64 index ea7936989..2078372a6 100644 --- a/package/archlinux/PKGBUILD-mingw-w64 +++ b/package/archlinux/PKGBUILD-mingw-w64 @@ -41,6 +41,7 @@ build() { -DWITH_FONTCONVERTER=ON \ -DWITH_IMAGECONVERTER=ON \ -DWITH_SCENECONVERTER=ON \ + -DWITH_SHADERCONVERTER=ON \ -DWITH_GL_INFO=ON \ -DWITH_AL_INFO=ON \ -DBUILD_TESTS=ON \ @@ -76,6 +77,7 @@ build() { -DWITH_FONTCONVERTER=ON \ -DWITH_IMAGECONVERTER=ON \ -DWITH_SCENECONVERTER=ON \ + -DWITH_SHADERCONVERTER=ON \ -DWITH_GL_INFO=ON \ -DWITH_AL_INFO=ON \ -DBUILD_TESTS=ON \ diff --git a/package/archlinux/PKGBUILD-release b/package/archlinux/PKGBUILD-release index 555522f51..33748f856 100644 --- a/package/archlinux/PKGBUILD-release +++ b/package/archlinux/PKGBUILD-release @@ -46,6 +46,7 @@ build() { -DWITH_FONTCONVERTER=ON \ -DWITH_IMAGECONVERTER=ON \ -DWITH_SCENECONVERTER=ON \ + -DWITH_SHADERCONVERTER=ON \ -DWITH_GL_INFO=ON \ -DWITH_AL_INFO=ON \ -DBUILD_TESTS=ON \ @@ -85,6 +86,7 @@ build() { -DWITH_FONTCONVERTER=ON \ -DWITH_IMAGECONVERTER=ON \ -DWITH_SCENECONVERTER=ON \ + -DWITH_SHADERCONVERTER=ON \ -DWITH_GL_INFO=ON \ -DWITH_AL_INFO=ON \ -DBUILD_TESTS=ON \ diff --git a/package/archlinux/magnum-git/PKGBUILD b/package/archlinux/magnum-git/PKGBUILD index d011d7d35..72e6b8b36 100644 --- a/package/archlinux/magnum-git/PKGBUILD +++ b/package/archlinux/magnum-git/PKGBUILD @@ -48,6 +48,7 @@ build() { -DWITH_FONTCONVERTER=ON \ -DWITH_IMAGECONVERTER=ON \ -DWITH_SCENECONVERTER=ON \ + -DWITH_SHADERCONVERTER=ON \ -DWITH_GL_INFO=ON \ -DWITH_AL_INFO=ON \ -G Ninja diff --git a/package/archlinux/magnum/PKGBUILD b/package/archlinux/magnum/PKGBUILD index ddad5e0d9..f99222415 100644 --- a/package/archlinux/magnum/PKGBUILD +++ b/package/archlinux/magnum/PKGBUILD @@ -36,6 +36,7 @@ build() { -DWITH_GLXCONTEXT=ON \ -DWITH_IMAGECONVERTER=ON \ -DWITH_SCENECONVERTER=ON \ + -DWITH_SHADERCONVERTER=ON \ -DWITH_MAGNUMFONT=ON \ -DWITH_MAGNUMFONTCONVERTER=ON \ -DWITH_OBJIMPORTER=ON \ diff --git a/package/ci/appveyor-desktop-gles.bat b/package/ci/appveyor-desktop-gles.bat index 40eda8464..904df3606 100644 --- a/package/ci/appveyor-desktop-gles.bat +++ b/package/ci/appveyor-desktop-gles.bat @@ -48,6 +48,7 @@ cmake .. ^ -DWITH_FONTCONVERTER=OFF ^ -DWITH_IMAGECONVERTER=OFF ^ -DWITH_SCENECONVERTER=OFF ^ + -DWITH_SHADERCONVERTER=OFF ^ -DWITH_GL_INFO=ON ^ -DWITH_AL_INFO=OFF ^ -DBUILD_TESTS=ON ^ diff --git a/package/ci/appveyor-desktop-mingw.bat b/package/ci/appveyor-desktop-mingw.bat index 2a03512ff..0823e3464 100644 --- a/package/ci/appveyor-desktop-mingw.bat +++ b/package/ci/appveyor-desktop-mingw.bat @@ -47,6 +47,7 @@ cmake .. ^ -DWITH_FONTCONVERTER=ON ^ -DWITH_IMAGECONVERTER=ON ^ -DWITH_SCENECONVERTER=ON ^ + -DWITH_SHADERCONVERTER=ON ^ -DWITH_GL_INFO=ON ^ -DWITH_AL_INFO=ON ^ -DBUILD_TESTS=ON ^ diff --git a/package/ci/appveyor-desktop.bat b/package/ci/appveyor-desktop.bat index eacfb2c74..d1f59f643 100644 --- a/package/ci/appveyor-desktop.bat +++ b/package/ci/appveyor-desktop.bat @@ -54,6 +54,7 @@ cmake .. ^ -DWITH_FONTCONVERTER=ON ^ -DWITH_IMAGECONVERTER=ON ^ -DWITH_SCENECONVERTER=ON ^ + -DWITH_SHADERCONVERTER=ON ^ -DWITH_GL_INFO=ON ^ -DWITH_AL_INFO=ON ^ -DBUILD_TESTS=ON ^ diff --git a/package/ci/travis-desktop-gles.sh b/package/ci/travis-desktop-gles.sh index 48e83c0e0..c5ca7f8b2 100755 --- a/package/ci/travis-desktop-gles.sh +++ b/package/ci/travis-desktop-gles.sh @@ -49,6 +49,7 @@ cmake .. \ -DWITH_FONTCONVERTER=OFF \ -DWITH_IMAGECONVERTER=OFF \ -DWITH_SCENECONVERTER=OFF \ + -DWITH_SHADERCONVERTER=OFF \ -DWITH_GL_INFO=ON \ -DWITH_AL_INFO=OFF \ -DBUILD_TESTS=ON \ diff --git a/package/ci/travis-desktop-vulkan.sh b/package/ci/travis-desktop-vulkan.sh index ad57b64c4..405c124da 100755 --- a/package/ci/travis-desktop-vulkan.sh +++ b/package/ci/travis-desktop-vulkan.sh @@ -60,6 +60,7 @@ cmake .. \ -DWITH_FONTCONVERTER=OFF \ -DWITH_IMAGECONVERTER=OFF \ -DWITH_SCENECONVERTER=OFF \ + -DWITH_SHADERCONVERTER=OFF \ -DWITH_SDL2APPLICATION=ON \ -DWITH_GLFWAPPLICATION=ON \ -DBUILD_TESTS=ON \ diff --git a/package/ci/travis-desktop.sh b/package/ci/travis-desktop.sh index 201b2795e..389845f21 100755 --- a/package/ci/travis-desktop.sh +++ b/package/ci/travis-desktop.sh @@ -46,6 +46,7 @@ cmake .. \ -DWITH_FONTCONVERTER=ON \ -DWITH_IMAGECONVERTER=ON \ -DWITH_SCENECONVERTER=ON \ + -DWITH_SHADERCONVERTER=ON \ -DWITH_GL_INFO=ON \ -DWITH_AL_INFO=ON \ -DBUILD_TESTS=ON \ diff --git a/package/debian/rules b/package/debian/rules index 5381e6a2e..293f40e3b 100755 --- a/package/debian/rules +++ b/package/debian/rules @@ -38,6 +38,7 @@ override_dh_auto_configure: -DWITH_DISTANCEFIELDCONVERTER=ON \ -DWITH_IMAGECONVERTER=ON \ -DWITH_SCENECONVERTER=ON \ + -DWITH_SHADERCONVERTER=ON \ -DWITH_FONTCONVERTER=ON \ -DWITH_GL_INFO=ON \ -DWITH_AL_INFO=ON diff --git a/package/gentoo/dev-libs/magnum/magnum-9999.ebuild b/package/gentoo/dev-libs/magnum/magnum-9999.ebuild index c77d150d4..884f9c0cf 100644 --- a/package/gentoo/dev-libs/magnum/magnum-9999.ebuild +++ b/package/gentoo/dev-libs/magnum/magnum-9999.ebuild @@ -47,6 +47,7 @@ src_configure() { -DWITH_DISTANCEFIELDCONVERTER=ON -DWITH_IMAGECONVERTER=ON -DWITH_SCENECONVERTER=ON + -DWITH_SHADERCONVERTER=ON -DWITH_FONTCONVERTER=ON -DWITH_GL_INFO=ON -DWITH_AL_INFO=ON diff --git a/package/homebrew/magnum.rb b/package/homebrew/magnum.rb index 022ce2e83..ab95ad89f 100644 --- a/package/homebrew/magnum.rb +++ b/package/homebrew/magnum.rb @@ -40,6 +40,7 @@ class Magnum < Formula "-DWITH_FONTCONVERTER=ON", "-DWITH_IMAGECONVERTER=ON", "-DWITH_SCENECONVERTER=ON", + "-DWITH_SHADERCONVERTER=ON", "-DWITH_GL_INFO=ON", "-DWITH_AL_INFO=ON", ".." diff --git a/package/msys/PKGBUILD b/package/msys/PKGBUILD index 8228e4700..3a87e5053 100644 --- a/package/msys/PKGBUILD +++ b/package/msys/PKGBUILD @@ -53,6 +53,7 @@ build() { -DWITH_FONTCONVERTER=ON \ -DWITH_IMAGECONVERTER=ON \ -DWITH_SCENECONVERTER=ON \ + -DWITH_SHADERCONVERTER=ON \ -DWITH_GL_INFO=ON \ -DWITH_AL_INFO=ON ninja diff --git a/package/msys/magnum/PKGBUILD b/package/msys/magnum/PKGBUILD index 9a0dd8d20..00baa928c 100644 --- a/package/msys/magnum/PKGBUILD +++ b/package/msys/magnum/PKGBUILD @@ -59,6 +59,7 @@ build() { -DWITH_GLFWAPPLICATION=ON \ -DWITH_SCENECONVERTER=ON \ -DWITH_SDL2APPLICATION=ON \ + -DWITH_SHADERCONVERTER=ON \ -DWITH_TGAIMAGECONVERTER=ON \ -DWITH_TGAIMPORTER=ON \ -DWITH_VK=ON \ diff --git a/src/Magnum/ShaderTools/CMakeLists.txt b/src/Magnum/ShaderTools/CMakeLists.txt index 2553f8e4b..6065bab40 100644 --- a/src/Magnum/ShaderTools/CMakeLists.txt +++ b/src/Magnum/ShaderTools/CMakeLists.txt @@ -78,6 +78,19 @@ install(TARGETS MagnumShaderTools ARCHIVE DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR}) install(FILES ${MagnumShaderTools_HEADERS} DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/ShaderTools) +if(WITH_SHADERCONVERTER) + add_executable(magnum-shaderconverter shaderconverter.cpp) + target_link_libraries(magnum-shaderconverter PRIVATE + Magnum + MagnumShaderTools) + set_target_properties(magnum-shaderconverter PROPERTIES FOLDER "Magnum/ShaderTools") + + install(TARGETS magnum-shaderconverter DESTINATION ${MAGNUM_BINARY_INSTALL_DIR}) + + # Magnum shaderconverter target alias for superprojects + add_executable(Magnum::shaderconverter ALIAS magnum-shaderconverter) +endif() + if(BUILD_TESTS) # Library with graceful assert for testing add_library(MagnumShaderToolsTestLib ${SHARED_OR_STATIC} diff --git a/src/Magnum/ShaderTools/shaderconverter.cpp b/src/Magnum/ShaderTools/shaderconverter.cpp new file mode 100644 index 000000000..4785e32b3 --- /dev/null +++ b/src/Magnum/ShaderTools/shaderconverter.cpp @@ -0,0 +1,439 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, + 2020 Vladimír Vondruš + + 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 +#include +#include +#include +#include + +#include "Magnum/Implementation/converterUtilities.h" +#include "Magnum/Math/Functions.h" +#include "Magnum/ShaderTools/AbstractConverter.h" + +namespace Magnum { + +/** @page magnum-shaderconverter Shader conversion utility +@brief Converts, compiles, optimizes and links shaders of different formats +@m_since_latest + +@m_footernavigation +@m_keywords{magnum-shaderconverter shaderconverter} + +This utility is built if both `WITH_SHADERTOOLS` and `WITH_SHADERCONVERTER` is +enabled when building Magnum. To use this utility with CMake, you need to +request the `shaderconverter` component of the `Magnum` package and use the +`Magnum::shaderconverter` target for example in a custom command: + +@code{.cmake} +find_package(Magnum REQUIRED shaderconverter) + +add_custom_command(OUTPUT ... COMMAND Magnum::shaderconverter ...) +@endcode + +See @ref building, @ref cmake and the @ref ShaderTools namespace for more +information. + +@section magnum-shaderconverter-usage Usage + +@code{.sh} +magnum-shaderconverter [-h|--help] [--validate] [--link] + [-C|--converter NAME]... [--plugin-dir DIR] + [-c|--converter-options key=val,key2=val2,…]... [-q|--quiet] [-v|--verbose] + [--warning-as-error] [-E|--preprocess-only] [-D|--define name=value]... + [-U|--undefine name]... [-O|--optimize LEVEL] [-g|--debug-info LEVEL] + [--input-version VERSION]... [--output-version VERSION]... + [--] input... output +@endcode + +Arguments: + +- `input` --- input file(s) +- `output` --- output file, ignored if `--validate` is present +- `-h`, `--help` --- display this help message and exit +- `--validate` --- validate input +- `--link` --- link multiple input files together +- `-C`, `--converter CONVERTER` --- shader converter plugin(s) +- `--plugin-dir DIR` --- override base plugin dir +- `-c`, `--converter-options key=val,key2=val2,…` --- configuration options + to pass to the converter(s) +- `-q`, `--quiet` --- quiet output from converter plugin(s) +- `-v`, `--verbose` --- verbose output from converter plugin(s) +- `--warning-as-error` --- treat warnings as errors +- `-E`, `--preprocess-only` --- preprocess the input file and exit +- `-D`, `--define name=value` --- define a preprocessor macro +- `-U`, `--undefine name` --- undefine a preprocessor macro +- `-O`, `--optimize LEVEL` --- optimization level to use +- `-g`, `--debug-info LEVEL` --- debug info level to use +- `--input-version VERSION` --- input format version for each converter +- `--output-version VERSION` --- output format version for each converter + +If `--validate` is given, the utility will validate the `input` file using +passed `--converter` (or @ref ShaderTools::AnyConverter "AnyShaderConverter" if +none is specified), print the validation log on output and exit with a non-zero +code if the validation fails. If `--link` is given, the utility will link all +files together using passed `--converter` (or +@ref ShaderTools::AnyConverter "AnyShaderConverter" if none is specified) and +save it to `output`. If neither is specified, the utility will convert the +`input` file using (one or more) passed `--converter` (or +@ref ShaderTools::AnyConverter "AnyShaderConverter" if none is specified) and +save it to `output`. + +The `-c` / `--converter-options` argument accept a comma-separated list of +key/value pairs to set in the converter plugin configuration. If the `=` +character is omitted, it's equivalent to saying `key=true`; configuration +subgroups are delimited with `/`. It's possible to specify the `-C` / +`--converter` option (and correspondingly also `-c` / `--converter-options`, +`--input-version` and `--output-version`) multiple times in order to chain more +converters together. All converters in the chain have to support the +@ref ShaderTools::ConverterFeature::ConvertData feature, if there's just one +converter it's enough for it to support +@ref ShaderTools::ConverterFeature::ConvertFile. If no `-C` / `--converter` is +specified, @ref ShaderTools::AnyConverter "AnyShaderConverter" is used. + +The `-D` / `--define`, `-U` / `--undefine`, `-O` / `--optimize`, `-g` / +`--debug-info`, `-E` / `--preprocess-only` arguments apply only to the first +converter. Split the conversion to multiple passes if you need to pass those to +converters later in the chain. + +Values accepted by `-O` / `--optimize`, `-g` / `--debug-info`, `--input-version` +and `--output-version` are converter-specific, see documentation of a +particular converter for more information. + +@section magnum-shaderconverter-example Example usage + +Validate a SPIR-V file for a Vulkan 1.1 target, using +@ref ShaderTools::SpirvToolsConverter "SpirvToolsShaderConverter" picked by +@ref ShaderTools::AnyConverter "AnyShaderConverter": + +@code{.sh} +magnum-shaderconverter --validate --output-version vulkan1.1 shader.spv +@endcode + +Converting a GLSL 4.10 file to a SPIR-V, supplying various preprocessor +definitions, treating warnings as errors and targeting OpenGL instead of the +(default) Vulkan, using @ref ShaderTools::GlslangConverter "GlslangShaderConverter" +picked again by @ref ShaderTools::AnyConverter "AnyShaderConverter": + +@m_class{m-console-wrap} + +@code{.sh} +magnum-shaderconverter phong.frag -DDIFFUSE_TEXTURE -DNORMAL_TEXTURE --input-version "410 core" --output-version opengl4.5 --warning-as-error phong.frag.spv +@endcode +*/ + +} + +using namespace Magnum; + +int main(int argc, char** argv) { + Utility::Arguments args; + args.addArrayArgument("input").setHelp("input", "input file(s)") + .addArgument("output").setHelp("output", "output file, ignored if --validate is present") + .addBooleanOption("validate").setHelp("validate", "validate input") + .addBooleanOption("link").setHelp("link", "link multiple input files together") + .addArrayOption('C', "converter").setHelp("converter", "shader converter plugin(s)") + .addOption("plugin-dir").setHelp("plugin-dir", "override base plugin dir", "DIR") + .addArrayOption('c', "converter-options").setHelp("converter-options", "configuration options to pass to the converter(s)", "key=val,key2=val2,…") + .addBooleanOption('q', "quiet").setHelp("quiet", "quiet output from converter plugin(s)") + .addBooleanOption('v', "verbose").setHelp("verbose", "verbose output from converter plugin(s)") + .addBooleanOption("warning-as-error").setHelp("warning-as-error", "treat warnings as errors") + .addBooleanOption('E', "preprocess-only").setHelp("preprocess-only", "preprocess the input file and exit") + .addArrayOption('D', "define").setHelp("define", "define a preprocessor macro", "name=value") + .addArrayOption('U', "undefine").setHelp("undefine", "undefine a preprocessor macro", "name") + .addOption('O', "optimize").setHelp("optimize", "optimization level to use", "LEVEL") + .addOption('g', "debug-info").setHelp("debug-info", "debug info level to use", "LEVEL") + .addArrayOption("input-version").setHelp("input-version", "input format version for each converter", "VERSION") + .addArrayOption("output-version").setHelp("output-version", "output format version for each converter", "VERSION") + .setParseErrorCallback([](const Utility::Arguments& args, Utility::Arguments::ParseError error, const std::string& key) { + /* If --validate is passed, we don't need the output argument */ + if(error == Utility::Arguments::ParseError::MissingArgument && + key == "output" && args.isSet("validate")) return true; + + /* Handle all other errors as usual */ + return false; + }) + .setGlobalHelp(R"(Converts, compiles, optimizes and links shaders of different formats. + +If --validate is given, the utility will validate the input file using passed +--converter (or AnyShaderConverter if none is specified), print the validation +log on output and exit with a non-zero code if the validation fails. If --link +is given, the utility will link all files together using passed --converter (or +AnyShaderConverter if none is specified) and save it to output. If neither is +specified, the utility will convert the input file using (one or more) passed +--converter and save it to output. + +The -c / --converter-options argument accept a comma-separated list of +key/value pairs to set in the converter plugin configuration. If the = +character is omitted, it's equivalent to saying key=true; configuration +subgroups are delimited with /. It's possible to specify the -C / --converter +option (and correspondingly also -c / --converter-options, --input-version and +--output-version) multiple times in order to chain more converters together. +All converters in the chain have to support the ConvertData feature, if there's +just one converter it's enough for it to support ConvertFile. If no -C / +--converter is specified, AnyShaderConverter is used. + +The -D / --define, -U / --undefine, -O / --optimize, -g / --debug-info, -E / +--preprocess-only arguments apply only to the first converter. Split the +conversion to multiple passes if you need to pass those to converters later in +the chain. + +Values accepted by -O / --optimize, -g / --debug-info, --input-version and +--output-version are converter-specific, see documentation of a particular +converter for more information.)") + .parse(argc, argv); + + /* Generic checks */ + if(args.isSet("validate")) { + if(!args.value("output").empty()) { + Error{} << "Output file shouldn't be set for --validate"; + return 1; + } + } + if(!args.isSet("link")) { + if(args.arrayValueCount("input") != 1) { + Error{} << "Multiple input files are allowed only for --link"; + return 3; + } + if(args.isSet("preprocess-only")) { + Error{} << "The --preprocess-only option isn't allowed for --link"; + return 4; + } + } + if((args.isSet("validate") || args.isSet("link")) && args.arrayValueCount("converter") > 1) { + Error{} << "Cannot use multiple converters with --validate or --link"; + return 5; + } + if(args.isSet("quiet") && args.isSet("verbose")) { + Error{} << "Can't set both --quiet and --verbose"; + return 6; + } + if(args.isSet("quiet") && args.isSet("warning-as-error")) { + Error{} << "Can't set both --quiet and --warning-as-error"; + return 6; + } + + /* Set up a converter manager */ + PluginManager::Manager converterManager{ + args.value("plugin-dir").empty() ? std::string{} : + Utility::Directory::join(args.value("plugin-dir"), ShaderTools::AbstractConverter::pluginSearchPaths()[0])}; + + /* Data passed from one converter to another in case there's more than one */ + Containers::Array data; + + /* If there's no converters, it'll be just one AnyShaderConverter. */ + for(std::size_t i = 0, converterCount = args.arrayValueCount("converter"); i < Math::max(converterCount, std::size_t{1}); ++i) { + const std::string converterName = converterCount ? + args.arrayValue("converter", i) : "AnyShaderConverter"; + Containers::Pointer converter = converterManager.loadAndInstantiate(converterName); + if(!converter) { + Debug{} << "Available converter plugins:" << Utility::String::join(converterManager.aliasList(), ", "); + return 7; + } + + /* Set options and versions, if passed */ + if(i < args.arrayValueCount("converter-options")) + Implementation::setOptions(*converter, args.arrayValue("converter-options", i)); + if(i < args.arrayValueCount("input-version")) + converter->setInputFormat({}, args.arrayValue("input-version", i)); + if(i < args.arrayValueCount("output-version")) + converter->setOutputFormat({}, args.arrayValue("output-version", i)); + + ShaderTools::ConverterFlags flags; + + /* Global flags, applied for all converters */ + if(args.isSet("quiet")) flags |= ShaderTools::ConverterFlag::Quiet; + if(args.isSet("verbose")) flags |= ShaderTools::ConverterFlag::Verbose; + if(args.isSet("warning-as-error")) flags |= ShaderTools::ConverterFlag::WarningAsError; + + /* Options and flags applied just for the first converter; setting up + file list for linking */ + Containers::Array> linkInputs; + if(i == 0) { + if((args.isSet("preprocess-only") || args.arrayValueCount("define") || args.arrayValueCount("undefine"))) { + if(!(converter->features() & ShaderTools::ConverterFeature::Preprocess)) { + Error{} << "The -E / -D / -U options are set, but" << converterName << "doesn't support preprocessing"; + return 8; + } + + if(args.isSet("preprocess-only")) + flags |= ShaderTools::ConverterFlag::PreprocessOnly; + + Containers::Array> definitions; + arrayReserve(definitions, args.arrayValueCount("define") + args.arrayValueCount("undefine")); + for(std::size_t i = 0; i != args.arrayValueCount("define"); ++i) { + const Containers::Array3 define = + args.arrayValue("define", i).partition('='); + arrayAppend(definitions, Containers::InPlaceInit, + define[0], define[2]); + } + for(std::size_t i = 0; i != args.arrayValueCount("undefine"); ++i) { + arrayAppend(definitions, Containers::InPlaceInit, + args.arrayValue("undefine", i), nullptr); + } + + converter->setDefinitions(definitions); + } + + if(!args.value("optimize").empty()) { + if(!(converter->features() & ShaderTools::ConverterFeature::Optimize)) { + Error{} << "The -O option is set, but" << converterName << "doesn't support optimization"; + return 9; + } + + converter->setOptimizationLevel(args.value("optimize")); + } + + if(!args.value("debug-info").empty()) { + if(!(converter->features() & ShaderTools::ConverterFeature::DebugInfo)) { + Error{} << "The -g option is set, but" << converterName << "doesn't support debug info"; + return 10; + } + + converter->setDebugInfoLevel(args.value("debug-info")); + } + + if(args.isSet("link")) { + arrayReserve(linkInputs, args.arrayValueCount("input")); + for(std::size_t i = 0; i != args.arrayValueCount("input"); ++i) + arrayAppend(linkInputs, Containers::InPlaceInit, + ShaderTools::Stage::Unspecified, args.arrayValue("input", i)); + } + } + + converter->setFlags(flags); + + /* If validating, do it just with the first passed converter and then + exit */ + if(args.isSet("validate")) { + /* The validation exits right after, so this branch shouldn't get + re-entered again */ + CORRADE_INTERNAL_ASSERT(i == 0); + + if(!(converter->features() & ShaderTools::ConverterFeature::ValidateFile)) { + Error{} << converterName << "doesn't support file validation"; + return 11; + } + + std::pair out = converter->validateFile(ShaderTools::Stage::Unspecified, args.arrayValue("input", 0)); + if(!out.first) { + if(args.isSet("verbose")) + Error{} << "Validation failed:"; + if(!out.second.isEmpty()) Error{} << out.second; + } else if(!out.second.isEmpty()) { + if(args.isSet("verbose")) + Warning{} << "Validation succeeded with warnings:"; + if(!out.second.isEmpty()) Warning{} << out.second; + } else if(args.isSet("verbose")) + Debug{} << "Validation passed"; + return out.first ? 0 : 12; + } + + /** @todo ability to specify the stage (need a configurationvalue parser for this) */ + + /* This is the first *and* last --converter, go from a file to a file */ + if(i == 0 && converterCount <= 1) { + if(!(converter->features() & ShaderTools::ConverterFeature::ConvertFile)) { + Error{} << converterName << "doesn't support file conversion"; + return 13; + } + + /* No verbose output for just one converter */ + + /* Linking */ + if(args.isSet("link")) { + if(!converter->linkFilesToFile(linkInputs, args.value("output"))) { + Error{} << "Cannot link" << args.arrayValue("input", 0) << "and others to" << args.value("output"); + return 14; + } + + /* Converting */ + } else { + if(!converter->convertFileToFile(ShaderTools::Stage::Unspecified, args.arrayValue("input", 0), args.value("output"))) { + Error{} << "Cannot convert" << args.arrayValue("input", 0) << "to" << args.value("output"); + return 15; + } + } + + /* Otherwise we need to go through data */ + } else { + if(!(converter->features() & ShaderTools::ConverterFeature::ConvertData)) { + Error{} << converterName << "doesn't support data conversion"; + return 16; + } + + /* This is the first --converter and there are more, go from a file + to data */ + if(i == 0 && converterCount > 1) { + if(args.isSet("verbose")) + Debug{} << "Processing (" << Debug::nospace << (i+1) << Debug::nospace << "/" << Debug::nospace << converterCount << Debug::nospace << ") with" << converterName << Debug::nospace << "..."; + + /* Linking */ + if(args.isSet("link")) { + if(!(data = converter->linkFilesToData(linkInputs))) { + Error{} << "Cannot link" << args.arrayValue("input", 0) << "and others to" << args.value("output"); + return 17; + } + + /* Converting */ + } else { + if(!(data = converter->convertFileToData(ShaderTools::Stage::Unspecified, args.arrayValue("input", 0)))) { + Error{} << "Cannot convert" << args.arrayValue("input", 0); + return 18; + } + } + + /* This is neither first nor last --converter, go from data to + data */ + } else if(i > 0 && i + 1 < converterCount) { + if(args.isSet("verbose")) + Debug{} << "Processing (" << Debug::nospace << (i+1) << Debug::nospace << "/" << Debug::nospace << converterCount << Debug::nospace << ") with" << converterName << Debug::nospace << "..."; + + CORRADE_INTERNAL_ASSERT(data); + + /* Subsequent operations are always a conversion, not link */ + if(!(data = converter->convertDataToData(ShaderTools::Stage::Unspecified, data))) { + Error{} << "Cannot convert shader data"; + return 19; + } + + /* This is the last --converter, output to a file and exit the + loop */ + } else if(i + 1 >= converterCount) { + if(args.isSet("verbose")) + Debug{} << "Saving output with" << converterName << Debug::nospace << "..."; + + CORRADE_INTERNAL_ASSERT(data); + + /* Subsequent operations are always a conversion, not link */ + if(!converter->convertDataToFile(ShaderTools::Stage::Unspecified, data, args.value("output"))) { + Error{} << "Cannot save file" << args.value("output"); + return 20; + } + + } else CORRADE_INTERNAL_ASSERT_UNREACHABLE(); + } + } +}