Adds a SPIR-V cache that skips frontend compilation for shaders that are already compiled in a previous run of Blender. Initially this was postponed to 4.4 but it was observed that the vulkan backend didn't perform well on Windows in debug builds. The reason is that the compiler would also be a debug build which makes compiling a shader really slow. Starting Blender on a debug build could take minutes. So the decision was made to give this task a higher priority so the vulkan backend would become more usable to developers as well. The cache is stored in the application cache dir. The SPIR-V binaries can be used by different Blender versions so there is no version specific cache folder. **Sidecar**: SPIR-V files are a stream of bytes. There is no header information that allow us to validate the stream. To add basic validations we could add our custom header or a sidecar. It was chosen to use a sidecar as having the SPIR-V files unmodified allows us to load them directly in debug tools for analyzing. **Retention**: Shaders that are not used are automatically removed with a retention period of 30 days. **Shader builder**: Shader builder cannot use the SPIR-V cache as it uses stubs that returns invalid cache directories. This would load/save the cache to the location where you started the build. Pull Request: https://projects.blender.org/blender/blender/pulls/128741
84 lines
2.1 KiB
C++
84 lines
2.1 KiB
C++
/* SPDX-FileCopyrightText: 2024 Blender Authors
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
|
|
/** \file
|
|
* \ingroup gpu
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include "gpu_shader_private.hh"
|
|
|
|
#include "vk_common.hh"
|
|
|
|
#include "shaderc/shaderc.hpp"
|
|
|
|
namespace blender::gpu {
|
|
class VKShader;
|
|
|
|
/**
|
|
* Shader module.
|
|
*
|
|
* A shader module contains shader code and can be used as a vertex/geometry/fragment/compute stage
|
|
* of a shader. The shader code in this sense doesn't need to be GLSL, but can also be SPIR-V
|
|
* binary.
|
|
*
|
|
* For now this is just a data container so code can be reused when working with multiple shader
|
|
* stages.
|
|
*
|
|
* Later we could load the SPIR-V binary directly from disk to skip front end compilation
|
|
* phase completely or skip shader module at all when the cache is already aware of this shader by
|
|
* using VK_EXT_shader_module_identifier.
|
|
*/
|
|
class VKShaderModule {
|
|
public:
|
|
/**
|
|
* Single string containing GLSL source code.
|
|
*
|
|
* Is cleared after compilation phase has completed. (VKShader::finalize_post).
|
|
*/
|
|
std::string combined_sources;
|
|
|
|
/**
|
|
* Hash of the combined sources. Used to generate the name inside spirv cache.
|
|
*/
|
|
std::string sources_hash;
|
|
|
|
/**
|
|
* Vulkan handler of the shader module.
|
|
*/
|
|
VkShaderModule vk_shader_module = VK_NULL_HANDLE;
|
|
|
|
/**
|
|
* Compilation result when compiling the shader module.
|
|
*
|
|
* Is cleared after compilation phase has completed. (VKShader::finalize_post).
|
|
*/
|
|
shaderc::SpvCompilationResult compilation_result;
|
|
Vector<uint32_t> spirv_binary;
|
|
|
|
/**
|
|
* Is compilation needed and is the compilation step done.
|
|
*
|
|
* Is set to false when GLSL sources are loaded and will be set to true again after the
|
|
* compilation step. It will also be true when compilation has failed.
|
|
*/
|
|
bool is_ready = true;
|
|
|
|
~VKShaderModule();
|
|
|
|
/**
|
|
* Finalize the shader module.
|
|
*
|
|
* When compilation succeeded the VkShaderModule will be created and stored in
|
|
* `vk_shader_module`.
|
|
*/
|
|
void finalize(StringRefNull name);
|
|
|
|
/** Build the sources hash from the combined_sources. */
|
|
void build_sources_hash();
|
|
};
|
|
|
|
} // namespace blender::gpu
|