diff options
| author | Egor Yusov <egor.yusov@gmail.com> | 2018-10-31 03:02:11 +0000 |
|---|---|---|
| committer | Egor Yusov <egor.yusov@gmail.com> | 2018-10-31 03:02:11 +0000 |
| commit | 749d440dbf43181e8106c482ee621e60bc3605f7 (patch) | |
| tree | f29391e59474db28ddcc0e6dc270c98e1ad39cf1 /Graphics/GraphicsEngineVulkan | |
| parent | Implemented HLSL vertex shader inputs mapping in Vulkan backend using SPV_GOO... (diff) | |
| download | DiligentCore-749d440dbf43181e8106c482ee621e60bc3605f7.tar.gz DiligentCore-749d440dbf43181e8106c482ee621e60bc3605f7.zip | |
Stripping reflection information from SPIRV binaries before creating Vulkan shader modules to fix validation error
Diffstat (limited to 'Graphics/GraphicsEngineVulkan')
| -rw-r--r-- | Graphics/GraphicsEngineVulkan/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp | 36 |
2 files changed, 35 insertions, 2 deletions
diff --git a/Graphics/GraphicsEngineVulkan/CMakeLists.txt b/Graphics/GraphicsEngineVulkan/CMakeLists.txt index e7ab3e44..e96ba9a5 100644 --- a/Graphics/GraphicsEngineVulkan/CMakeLists.txt +++ b/Graphics/GraphicsEngineVulkan/CMakeLists.txt @@ -176,6 +176,7 @@ set(PRIVATE_DEPENDENCIES TargetPlatform GraphicsEngineNextGenBase GLSLTools + SPIRV-Tools-opt ) if(PLATFORM_WIN32) diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp index a5cd7342..cc80fa02 100644 --- a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp @@ -31,6 +31,7 @@ #include "ShaderResourceBindingVkImpl.h" #include "EngineMemory.h" #include "StringTools.h" +#include "spirv-tools/optimizer.hpp" namespace Diligent { @@ -126,6 +127,22 @@ VkRenderPassCreateInfo PipelineStateVkImpl::GetRenderPassCreateInfo( return RenderPassCI; } +static std::vector<uint32_t> StripReflection(const std::vector<uint32_t>& OriginalSPIRV) +{ + std::vector<uint32_t> StrippedSPIRV; + spvtools::Optimizer SpirvOptimizer(SPV_ENV_VULKAN_1_0); + // Decorations defined in SPV_GOOGLE_hlsl_functionality1 are the only instructions + // removed by strip-reflect-info pass. SPIRV offsets become INVALID after this operation. + SpirvOptimizer.RegisterPass(spvtools::CreateStripReflectInfoPass()); + auto res = SpirvOptimizer.Run(OriginalSPIRV.data(), OriginalSPIRV.size(), &StrippedSPIRV); + if (!res) + { + // Optimized SPIRV may be invalid + StrippedSPIRV.clear(); + } + return StrippedSPIRV; +} + PipelineStateVkImpl :: PipelineStateVkImpl(IReferenceCounters* pRefCounters, RenderDeviceVkImpl* pDeviceVk, const PipelineStateDesc& PipelineDesc) : @@ -195,8 +212,23 @@ PipelineStateVkImpl :: PipelineStateVkImpl(IReferenceCounters* pRefCounters ShaderModuleCI.pNext = nullptr; ShaderModuleCI.flags = 0; const auto& SPIRV = ShaderSPIRVs[s]; - ShaderModuleCI.codeSize = SPIRV.size() * sizeof(uint32_t); - ShaderModuleCI.pCode = SPIRV.data(); + + // We have to strip reflection instructions to fix the follownig validation error: + // SPIR-V module not valid: DecorateStringGOOGLE requires one of the following extensions: SPV_GOOGLE_decorate_string + // Optimizer also performs validation and may catch problems with the byte code. + auto StrippedSPIRV = StripReflection(SPIRV); + if (!StrippedSPIRV.empty()) + { + ShaderModuleCI.codeSize = StrippedSPIRV.size() * sizeof(uint32_t); + ShaderModuleCI.pCode = StrippedSPIRV.data(); + } + else + { + LOG_ERROR("Failed to strip reflection information from shader '", pShaderVk->GetDesc().Name, "'. This may indicate a problem with the byte code."); + ShaderModuleCI.codeSize = SPIRV.size() * sizeof(uint32_t); + ShaderModuleCI.pCode = SPIRV.data(); + } + m_ShaderModules[s] = LogicalDevice.CreateShaderModule(ShaderModuleCI, m_Desc.Name); StageCI.module = m_ShaderModules[s]; |
