From a9c2e316b6f856be8473ad9d0f9a8382ae9dd94d Mon Sep 17 00:00:00 2001 From: Robert Beckebans Date: Thu, 31 Oct 2019 15:22:28 +0100 Subject: [PATCH] Added Experiment to compile GLSL to SPIR-V using shaderc --- neo/CMakeLists.txt | 53 ++++++++++++------ neo/cmake-vs2017-64bit-windows10-vulkan.bat | 2 +- neo/renderer/Vulkan/RenderProgs_VK.cpp | 59 ++++++++++++++++++++- 3 files changed, 94 insertions(+), 20 deletions(-) diff --git a/neo/CMakeLists.txt b/neo/CMakeLists.txt index 5ae298c2..928a24ee 100644 --- a/neo/CMakeLists.txt +++ b/neo/CMakeLists.txt @@ -27,6 +27,9 @@ option(BINKDEC option(USE_VULKAN "Use Vulkan instead of OpenGL" OFF) +option(SPIRV_SHADERC + "Compile SPIR-V shader byte code using shaderc instead of using Glslang directly" OFF) + option(ONATIVE "Optimize for the host CPU" OFF) @@ -293,22 +296,34 @@ if(USE_VULKAN) endif() add_definitions(-DUSE_VULKAN) - include_directories($ENV{VK_SDK_PATH}/Include) + include_directories($ENV{VULKAN_SDK}/Include) - # override Glslang build options - SET_OPTION(ENABLE_SPVREMAPPER OFF) - SET_OPTION(ENABLE_GLSLANG_BINARIES OFF) - SET_OPTION(ENABLE_HLSL OFF) - #SET_OPTION(ENABLE_OPT OFF) + if(SPIRV_SHADERC) + add_definitions(-DSPIRV_SHADERC) + + if(CMAKE_CL_64) + link_directories($ENV{VULKAN_SDK}/Lib) + else() + link_directories($ENV{VULKAN_SDK}/Lib32) + endif() + + else() + # override Glslang build options + SET_OPTION(ENABLE_SPVREMAPPER OFF) + SET_OPTION(ENABLE_GLSLANG_BINARIES OFF) + SET_OPTION(ENABLE_HLSL OFF) + SET_OPTION(ENABLE_OPT ON) + SET_OPTION(SPIRV_SKIP_EXECUTABLES ON) - #option(ENABLE_AMD_EXTENSIONS "Enables support of AMD-specific extensions" ON) - #option(ENABLE_NV_EXTENSIONS "Enables support of Nvidia-specific extensions" ON) - #option(ENABLE_OPT "Enables spirv-opt capability if present" ON) + #option(ENABLE_AMD_EXTENSIONS "Enables support of AMD-specific extensions" ON) + #option(ENABLE_NV_EXTENSIONS "Enables support of Nvidia-specific extensions" ON) + #option(ENABLE_OPT "Enables spirv-opt capability if present" ON) - set(GLSLANG_DIR ${CMAKE_CURRENT_SOURCE_DIR}/libs/glslang) - add_subdirectory(${GLSLANG_DIR}) + set(GLSLANG_DIR ${CMAKE_CURRENT_SOURCE_DIR}/libs/glslang) + add_subdirectory(${GLSLANG_DIR}) - include_directories(${GLSLANG_DIR}/glslang) + include_directories(${GLSLANG_DIR}/glslang) + endif() else() @@ -1309,12 +1324,16 @@ if(MSVC) set(Vulkan_LIBRARIES ${Vulkan_LIBRARY} - glslang - SPIRV ) - - if(ENABLE_GLSLANG_BINARIES) - list(APPEND Vulkan_LIBRARIES glslang-default-resource-limits) + + if(SPIRV_SHADERC) + list(APPEND Vulkan_LIBRARIES shaderc_combined) + else() + list(APPEND Vulkan_LIBRARIES glslang SPIRV) + + if(ENABLE_GLSLANG_BINARIES) + list(APPEND Vulkan_LIBRARIES glslang-default-resource-limits) + endif() endif() else() diff --git a/neo/cmake-vs2017-64bit-windows10-vulkan.bat b/neo/cmake-vs2017-64bit-windows10-vulkan.bat index d67e1a7d..b5d41809 100644 --- a/neo/cmake-vs2017-64bit-windows10-vulkan.bat +++ b/neo/cmake-vs2017-64bit-windows10-vulkan.bat @@ -2,5 +2,5 @@ cd .. del /s /q build mkdir build cd build -cmake -G "Visual Studio 15 Win64" -DWINDOWS10=ON -DUSE_VULKAN=ON -DUSE_FFMPEG=ON ../neo +cmake -G "Visual Studio 15 Win64" -DWINDOWS10=ON -DUSE_VULKAN=ON -DSPIRV_SHADERC=OFF -DFFMPEG=OFF ../neo pause \ No newline at end of file diff --git a/neo/renderer/Vulkan/RenderProgs_VK.cpp b/neo/renderer/Vulkan/RenderProgs_VK.cpp index a528ac3d..f2c96f9c 100644 --- a/neo/renderer/Vulkan/RenderProgs_VK.cpp +++ b/neo/renderer/Vulkan/RenderProgs_VK.cpp @@ -337,9 +337,64 @@ void idRenderProgManager::LoadShader( int index, rpStage_t stage ) CompileGLSLtoSPIRV ================================================================================================ */ -#define USE_GLSLANG 1 -#if defined(USE_GLSLANG) + +#if defined(SPIRV_SHADERC) + +#include + +static int CompileGLSLtoSPIRV( const char* filename, const idStr& dataGLSL, const rpStage_t stage, uint32** spirvBuffer ) +{ + shaderc::Compiler compiler; + shaderc::CompileOptions options; + + // Like -DMY_DEFINE=1 + //options.AddMacroDefinition("MY_DEFINE", "1"); + + //if (optimize) + { + options.SetOptimizationLevel( shaderc_optimization_level_size ); + } + + shaderc_shader_kind shaderKind; + if( stage == SHADER_STAGE_VERTEX ) + { + shaderKind = shaderc_glsl_vertex_shader; + } + else if( stage == SHADER_STAGE_COMPUTE ) + { + shaderKind = shaderc_glsl_compute_shader; + } + else + { + shaderKind = shaderc_glsl_fragment_shader; + } + + std::string source = dataGLSL.c_str(); + + shaderc::SpvCompilationResult module = compiler.CompileGlslToSpv( source, shaderKind, filename, options ); + + if( module.GetCompilationStatus() != shaderc_compilation_status_success ) + { + idLib::Printf( "Comping GLSL to SPIR-V using shaderc failed for: %s\n", filename ); + idLib::Printf( "%s\n", module.GetErrorMessage().c_str() ); + return 0; + } + + std::vector spirV = { module.cbegin(), module.cend() }; + + // copy to spirvBuffer + int32 spirvLen = spirV.size() * sizeof( uint32_t ); + + void* buffer = Mem_Alloc( spirvLen, TAG_RENDERPROG ); + memcpy( buffer, spirV.data(), spirvLen ); + + *spirvBuffer = ( uint32_t* ) buffer; + return spirvLen; + + +} +#else #include #include