Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorr.kuznetsov <r.kuznetsov@corp.mail.ru>2018-12-25 11:18:32 +0300
committerDaria Volvenkova <d.volvenkova@corp.mail.ru>2019-03-01 10:45:24 +0300
commitc146c9957475237031e18fb121ecac8017549e45 (patch)
treeac06741bb6b897bce6fe9708bedfef32163499a3 /shaders/vulkan_program_pool.cpp
parent8706e531ffa40cec080192ec378b3b9365ba575e (diff)
[Vulkan] Added shader subsystem
Diffstat (limited to 'shaders/vulkan_program_pool.cpp')
-rw-r--r--shaders/vulkan_program_pool.cpp162
1 files changed, 162 insertions, 0 deletions
diff --git a/shaders/vulkan_program_pool.cpp b/shaders/vulkan_program_pool.cpp
new file mode 100644
index 0000000000..a215b816c2
--- /dev/null
+++ b/shaders/vulkan_program_pool.cpp
@@ -0,0 +1,162 @@
+#include "shaders/vulkan_program_pool.hpp"
+#include "shaders/program_params.hpp"
+
+#include "drape/vulkan/vulkan_utils.hpp"
+
+#include "platform/platform.hpp"
+
+#include "coding/file_name_utils.hpp"
+#include "coding/reader.hpp"
+#include "coding/serdes_json.hpp"
+
+#include "base/logging.hpp"
+
+#include <cstdint>
+#include <map>
+#include <string>
+#include <vector>
+
+namespace gpu
+{
+namespace vulkan
+{
+namespace
+{
+std::string const kShadersDir = "vulkan_shaders/";
+std::string const kShadersReflecton = kShadersDir + "reflection.json";
+
+std::vector<uint32_t> ReadShaderFile(std::string const & filename)
+{
+ std::vector<uint32_t> result;
+ try
+ {
+ ReaderPtr<Reader> reader(GetPlatform().GetReader(filename));
+ auto const size = static_cast<size_t>(reader.Size());
+ CHECK(size % sizeof(uint32_t) == 0,
+ ("Incorrect SPIR_V file alignment. Name =", filename, "Size =", size));
+ result.resize(size / sizeof(uint32_t));
+ reader.Read(0, result.data(), size);
+ }
+ catch (RootException const & e)
+ {
+ LOG(LERROR, ("Error reading shader file ", filename, " : ", e.what()));
+ return {};
+ }
+
+ return result;
+}
+
+struct ReflectionData
+{
+ int32_t m_programIndex = -1;
+ dp::vulkan::VulkanGpuProgram::ReflectionInfo m_info;
+ DECLARE_VISITOR(visitor(m_programIndex, "prg"),
+ visitor(m_info, "info"))
+};
+
+struct ReflectionFile
+{
+ std::vector<ReflectionData> m_reflectionData;
+ DECLARE_VISITOR(visitor(m_reflectionData))
+};
+
+std::map<uint8_t, dp::vulkan::VulkanGpuProgram::ReflectionInfo> ReadReflectionFile(
+ std::string const & filename)
+{
+ std::map<uint8_t, dp::vulkan::VulkanGpuProgram::ReflectionInfo> result;
+ std::string jsonStr;
+ try
+ {
+ ReaderPtr<Reader>(GetPlatform().GetReader(filename)).ReadAsString(jsonStr);
+ }
+ catch (RootException const & e)
+ {
+ LOG(LERROR, ("Error reading file ", filename, ":", e.what()));
+ return {};
+ }
+
+ ReflectionFile reflectionFile;
+ try
+ {
+ coding::DeserializerJson des(jsonStr);
+ des(reflectionFile);
+ }
+ catch (base::Json::Exception const & e)
+ {
+ LOG(LERROR, ("Error deserialization reflection file :", e.what()));
+ return {};
+ }
+
+ for (auto & d : reflectionFile.m_reflectionData)
+ result.insert(std::make_pair(d.m_programIndex, std::move(d.m_info)));
+
+ return result;
+}
+
+VkShaderModule LoadShaderModule(VkDevice device, std::string const & filename)
+{
+ VkShaderModule shaderModule;
+
+ auto src = ReadShaderFile(filename);
+ if (src.empty())
+ return {};
+
+ auto const sizeInBytes = src.size() * sizeof(uint32_t);
+
+ VkShaderModuleCreateInfo moduleCreateInfo = {};
+ moduleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
+ moduleCreateInfo.pNext = nullptr;
+ moduleCreateInfo.codeSize = sizeInBytes;
+ moduleCreateInfo.pCode = src.data();
+ moduleCreateInfo.flags = 0;
+
+ CHECK_VK_CALL(vkCreateShaderModule(device, &moduleCreateInfo, nullptr, &shaderModule));
+ return shaderModule;
+}
+} // namespace
+
+VulkanProgramPool::VulkanProgramPool(VkDevice device)
+ : m_device(device)
+{
+ auto reflection = ReadReflectionFile(kShadersReflecton);
+ CHECK_EQUAL(reflection.size(), static_cast<size_t>(Program::ProgramsCount), ());
+ for (size_t i = 0; i < static_cast<size_t>(Program::ProgramsCount); ++i)
+ {
+ auto const programName = DebugPrint(static_cast<Program>(i));
+ auto const shaderPath = kShadersDir + programName;
+
+ m_programs[i] = make_unique_dp<dp::vulkan::VulkanGpuProgram>(
+ programName,
+ std::move(reflection[i]),
+ LoadShaderModule(device, shaderPath + ".vert.spv"),
+ LoadShaderModule(device, shaderPath + ".frag.spv"));
+ }
+
+ ProgramParams::Init();
+}
+
+VulkanProgramPool::~VulkanProgramPool()
+{
+ ProgramParams::Destroy();
+
+ for (auto & p : m_programs)
+ {
+ if (p != nullptr)
+ {
+ vkDestroyShaderModule(m_device, p->GetVertexShader(), nullptr);
+ vkDestroyShaderModule(m_device, p->GetFragmentShader(), nullptr);
+ }
+ }
+}
+
+drape_ptr<dp::GpuProgram> VulkanProgramPool::Get(Program program)
+{
+ auto & p = m_programs[static_cast<size_t>(program)];
+ CHECK(p != nullptr, ());
+ return make_unique_dp<dp::vulkan::VulkanGpuProgram>(p->GetName(),
+ p->GetReflectionInfo(),
+ p->GetVertexShader(),
+ p->GetFragmentShader());
+}
+} // namespace vulkan
+} // namespace gpu