WIP: Vulkan: Reuse shader modules. #122044

Draft
Jeroen Bakker wants to merge 3 commits from Jeroen-Bakker/blender:vulkan/shader-modules into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
3 changed files with 15 additions and 98 deletions
Showing only changes of commit fb0f0fe421 - Show all commits

View File

@ -479,90 +479,6 @@ static std::string main_function_wrapper(std::string &pre_main, std::string &pos
return ss.str();
}
static const std::string to_stage_name(shaderc_shader_kind stage)
{
switch (stage) {
case shaderc_vertex_shader:
return std::string("vertex");
case shaderc_geometry_shader:
return std::string("geometry");
case shaderc_fragment_shader:
return std::string("fragment");
case shaderc_compute_shader:
return std::string("compute");
default:
BLI_assert_msg(false, "Do not know how to convert shaderc_shader_kind to stage name.");
break;
}
return std::string("unknown stage");
}
static std::string combine_sources(Span<const char *> sources)
{
char *sources_combined = BLI_string_join_arrayN((const char **)sources.data(), sources.size());
std::string result(sources_combined);
MEM_freeN(sources_combined);
return result;
}
Vector<uint32_t> VKShader::compile_glsl_to_spirv(Span<const char *> sources,
shaderc_shader_kind stage)
{
std::string combined_sources = combine_sources(sources);
VKBackend &backend = VKBackend::get();
shaderc::Compiler &compiler = backend.get_shaderc_compiler();
shaderc::CompileOptions options;
options.SetOptimizationLevel(shaderc_optimization_level_performance);
options.SetTargetEnvironment(shaderc_target_env_vulkan, shaderc_env_version_vulkan_1_2);
if (G.debug & G_DEBUG_GPU_RENDERDOC) {
options.SetOptimizationLevel(shaderc_optimization_level_zero);
options.SetGenerateDebugInfo();
}
shaderc::SpvCompilationResult module = compiler.CompileGlslToSpv(
combined_sources, stage, name, options);
if (module.GetNumErrors() != 0 || module.GetNumWarnings() != 0) {
std::string log = module.GetErrorMessage();
Vector<char> logcstr(log.c_str(), log.c_str() + log.size() + 1);
VKLogParser parser;
print_log(sources,
logcstr.data(),
to_stage_name(stage).c_str(),
module.GetCompilationStatus() != shaderc_compilation_status_success,
&parser);
}
if (module.GetCompilationStatus() != shaderc_compilation_status_success) {
compilation_failed_ = true;
return Vector<uint32_t>();
}
return Vector<uint32_t>(module.cbegin(), module.cend());
}
void VKShader::build_shader_module(Span<uint32_t> spirv_module, VkShaderModule *r_shader_module)
{
VK_ALLOCATION_CALLBACKS;
VkShaderModuleCreateInfo create_info = {};
create_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
create_info.codeSize = spirv_module.size() * sizeof(uint32_t);
create_info.pCode = spirv_module.data();
const VKDevice &device = VKBackend::get().device_get();
VkResult result = vkCreateShaderModule(
device.device_get(), &create_info, vk_allocation_callbacks, r_shader_module);
if (result == VK_SUCCESS) {
debug::object_label(*r_shader_module, name);
}
else {
compilation_failed_ = true;
*r_shader_module = VK_NULL_HANDLE;
}
}
VKShader::VKShader(const char *name) : Shader(name)
{
context_ = VKContext::get();

View File

@ -134,8 +134,6 @@ class VKShader : public Shader {
}
private:
Vector<uint32_t> compile_glsl_to_spirv(Span<const char *> sources, shaderc_shader_kind kind);
void build_shader_module(Span<uint32_t> spirv_module, VkShaderModule *r_shader_module);
void build_shader_module(MutableSpan<const char *> sources,
shaderc_shader_kind stage,
VkShaderModule *r_shader_module);

View File

@ -20,6 +20,7 @@
#include <sstream>
namespace blender::gpu {
bool VKShaderModules::construct(VKShader &shader,
const shader::ShaderCreateInfo & /*info*/,
Span<const char *> sources,
@ -40,6 +41,18 @@ bool VKShaderModules::construct(VKShader &shader,
return build_shader_module(shader, spirv_module, r_shader_module);
}
void VKShaderModules::destruct(VkShaderModule vk_shader_module)
{
VK_ALLOCATION_CALLBACKS
const VKDevice &device = VKBackend::get().device_get();
vkDestroyShaderModule(device.device_get(), vk_shader_module, vk_allocation_callbacks);
}
void VKShaderModules::free_data()
{
debug_print();
}
/* -------------------------------------------------------------------- */
/** \name Frontend compilation (GLSL -> SpirV)
*
@ -150,6 +163,7 @@ bool VKShaderModules::build_shader_module(const VKShader &shader,
/** \name Debugging and statistics
*
* \{ */
void VKShaderModules::debug_print() const
{
std::stringstream ss;
@ -157,18 +171,7 @@ void VKShaderModules::debug_print() const
<< ", spirv_shader_module_time" << stats_.spirv_to_shader_module_time << "s)\n";
std::cout << ss.str();
}
/** \} */
void VKShaderModules::destruct(VkShaderModule vk_shader_module)
{
VK_ALLOCATION_CALLBACKS
const VKDevice &device = VKBackend::get().device_get();
vkDestroyShaderModule(device.device_get(), vk_shader_module, vk_allocation_callbacks);
}
void VKShaderModules::free_data()
{
debug_print();
}
} // namespace blender::gpu