From 93613d884e600ec53a58cf6a457d20209e392fca Mon Sep 17 00:00:00 2001 From: Benau Date: Sun, 1 Jan 2023 10:26:38 +0800 Subject: [PATCH] Compile SPIR-V shaders with multiple threads --- .../src/ge_vulkan_shader_manager.cpp | 34 ++++++++++++++----- src/graphics/irr_driver.cpp | 4 ++- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/lib/graphics_engine/src/ge_vulkan_shader_manager.cpp b/lib/graphics_engine/src/ge_vulkan_shader_manager.cpp index a2a170a47..587b0ab38 100644 --- a/lib/graphics_engine/src/ge_vulkan_shader_manager.cpp +++ b/lib/graphics_engine/src/ge_vulkan_shader_manager.cpp @@ -1,6 +1,8 @@ #include "ge_vulkan_shader_manager.hpp" +#include "ge_vulkan_command_loader.hpp" #include "ge_main.hpp" +#include "ge_spin_lock.hpp" #include "ge_vulkan_driver.hpp" #include "ge_vulkan_features.hpp" @@ -9,6 +11,7 @@ #include #include #include +#include #include "IFileSystem.h" @@ -27,7 +30,7 @@ uint32_t g_mesh_texture_layer = 2; uint32_t g_sampler_size = 512; -std::map g_shaders; +std::map* > g_shaders; } // GEVulkanShaderManager // ============================================================================ @@ -75,7 +78,12 @@ void GEVulkanShaderManager::destroy() if (!g_vk) return; for (auto& p : g_shaders) - vkDestroyShaderModule(g_vk->getDevice(), p.second, NULL); + { + p.second->first.lock(); + p.second->first.unlock(); + vkDestroyShaderModule(g_vk->getDevice(), p.second->second, NULL); + delete p.second; + } g_shaders.clear(); } // destroy @@ -103,7 +111,15 @@ void GEVulkanShaderManager::loadAllShaders() kind = shaderc_tess_evaluation_shader; else continue; - g_shaders[filename] = loadShader(kind, filename); + auto pair = new std::pair(); + g_shaders[filename] = pair; + pair->first.lock(); + GEVulkanCommandLoader::addMultiThreadingCommand( + [pair, kind, filename]() + { + pair->second = loadShader(kind, filename); + pair->first.unlock(); + }); } files->drop(); } // loadAllShaders @@ -113,8 +129,7 @@ VkShaderModule GEVulkanShaderManager::loadShader(shaderc_shader_kind kind, const std::string& name) { std::string shader_fullpath = getShaderFolder() + name; - irr::io::IReadFile* r = - g_file_system->createAndOpenFile(shader_fullpath.c_str()); + irr::io::IReadFile* r = irr::io::createReadFile(shader_fullpath.c_str()); if (!r) { throw std::runtime_error(std::string("File ") + shader_fullpath + @@ -161,8 +176,8 @@ VkShaderModule GEVulkanShaderManager::loadShader(shaderc_shader_kind kind, includer->m_shader_fullpath.push_back(std::string()); std::string& shader_fullpath = includer->m_shader_fullpath.back(); shader_fullpath = path.substr(0, pos) + '/' + requested_source; - irr::io::IReadFile* r = GEVulkanShaderManager:: - g_file_system->createAndOpenFile(shader_fullpath.c_str()); + irr::io::IReadFile* r = + irr::io::createReadFile(shader_fullpath.c_str()); if (!r) { throw std::runtime_error(std::string("File ") + shader_fullpath @@ -240,7 +255,10 @@ unsigned GEVulkanShaderManager::getMeshTextureLayer() // ---------------------------------------------------------------------------- VkShaderModule GEVulkanShaderManager::getShader(const std::string& filename) { - return g_shaders.at(filename); + auto it = g_shaders.at(filename); + it->first.lock(); + it->first.unlock(); + return it->second; } // getShader } diff --git a/src/graphics/irr_driver.cpp b/src/graphics/irr_driver.cpp index 715fc6eea..7020af5f3 100644 --- a/src/graphics/irr_driver.cpp +++ b/src/graphics/irr_driver.cpp @@ -391,7 +391,9 @@ void IrrDriver::createListOfVideoModes() void IrrDriver::initDevice() { #if !defined(SERVER_ONLY) - GE::setShaderFolder(file_manager->getShadersDir()); + std::string abs_shader_dir = file_manager->getFileSystem() + ->getAbsolutePath(file_manager->getShadersDir().c_str()).c_str(); + GE::setShaderFolder(abs_shader_dir); #endif SIrrlichtCreationParameters params; core::stringw display_msg;