mirror of https://github.com/auygun/kaliber.git
Vulkan: Spirv cache.
This commit is contained in:
parent
580ff678ec
commit
f332246ea9
|
@ -397,20 +397,30 @@ void RendererVulkan::CreateShader(std::shared_ptr<void> impl_data,
|
||||||
Primitive primitive) {
|
Primitive primitive) {
|
||||||
auto shader = reinterpret_cast<ShaderVulkan*>(impl_data.get());
|
auto shader = reinterpret_cast<ShaderVulkan*>(impl_data.get());
|
||||||
|
|
||||||
VkShaderModule vert_shader_module;
|
auto it = spirv_cache_.find(source->name());
|
||||||
{
|
if (it == spirv_cache_.end()) {
|
||||||
// TODO: Reuse compiled spirv on context-lost.
|
std::array<std::vector<uint8_t>, 2> spirv;
|
||||||
std::string error;
|
std::string error;
|
||||||
shader->spirv_vertex =
|
spirv[0] = CompileGlsl(EShLangVertex, source->GetVertexSource(), &error);
|
||||||
CompileGlsl(EShLangVertex, source->GetVertexSource(), &error);
|
|
||||||
if (!error.empty())
|
if (!error.empty())
|
||||||
DLOG << source->name() << " vertex shader compile error: " << error;
|
DLOG << source->name() << " vertex shader compile error: " << error;
|
||||||
|
spirv[1] =
|
||||||
|
CompileGlsl(EShLangFragment, source->GetFragmentSource(), &error);
|
||||||
|
if (!error.empty())
|
||||||
|
DLOG << source->name() << " fragment shader compile error: " << error;
|
||||||
|
it = spirv_cache_.insert({source->name(), spirv}).first;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& spirv_vertex = it->second[0];
|
||||||
|
auto& spirv_fragment = it->second[1];
|
||||||
|
|
||||||
|
VkShaderModule vert_shader_module;
|
||||||
|
{
|
||||||
VkShaderModuleCreateInfo shader_module_info{};
|
VkShaderModuleCreateInfo shader_module_info{};
|
||||||
shader_module_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
|
shader_module_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
|
||||||
shader_module_info.codeSize = shader->spirv_vertex.size();
|
shader_module_info.codeSize = spirv_vertex.size();
|
||||||
shader_module_info.pCode =
|
shader_module_info.pCode =
|
||||||
reinterpret_cast<const uint32_t*>(shader->spirv_vertex.data());
|
reinterpret_cast<const uint32_t*>(spirv_vertex.data());
|
||||||
|
|
||||||
if (vkCreateShaderModule(device_, &shader_module_info, nullptr,
|
if (vkCreateShaderModule(device_, &shader_module_info, nullptr,
|
||||||
&vert_shader_module) != VK_SUCCESS) {
|
&vert_shader_module) != VK_SUCCESS) {
|
||||||
|
@ -421,18 +431,11 @@ void RendererVulkan::CreateShader(std::shared_ptr<void> impl_data,
|
||||||
|
|
||||||
VkShaderModule frag_shader_module;
|
VkShaderModule frag_shader_module;
|
||||||
{
|
{
|
||||||
// TODO: Reuse compiled spirv on context-lost.
|
|
||||||
std::string error;
|
|
||||||
shader->spirv_fragment =
|
|
||||||
CompileGlsl(EShLangFragment, source->GetFragmentSource(), &error);
|
|
||||||
if (!error.empty())
|
|
||||||
DLOG << source->name() << " fragment shader compile error: " << error;
|
|
||||||
|
|
||||||
VkShaderModuleCreateInfo shader_module_info{};
|
VkShaderModuleCreateInfo shader_module_info{};
|
||||||
shader_module_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
|
shader_module_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
|
||||||
shader_module_info.codeSize = shader->spirv_fragment.size();
|
shader_module_info.codeSize = spirv_fragment.size();
|
||||||
shader_module_info.pCode =
|
shader_module_info.pCode =
|
||||||
reinterpret_cast<const uint32_t*>(shader->spirv_fragment.data());
|
reinterpret_cast<const uint32_t*>(spirv_fragment.data());
|
||||||
|
|
||||||
if (vkCreateShaderModule(device_, &shader_module_info, nullptr,
|
if (vkCreateShaderModule(device_, &shader_module_info, nullptr,
|
||||||
&frag_shader_module) != VK_SUCCESS) {
|
&frag_shader_module) != VK_SUCCESS) {
|
||||||
|
@ -441,7 +444,7 @@ void RendererVulkan::CreateShader(std::shared_ptr<void> impl_data,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!CreatePipelineLayout(shader))
|
if (!CreatePipelineLayout(shader, spirv_vertex, spirv_fragment))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
VkPipelineShaderStageCreateInfo vert_shader_stage_info{};
|
VkPipelineShaderStageCreateInfo vert_shader_stage_info{};
|
||||||
|
@ -1505,19 +1508,21 @@ void RendererVulkan::ImageMemoryBarrier(VkImage image,
|
||||||
nullptr, 1, &image_mem_barrier);
|
nullptr, 1, &image_mem_barrier);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RendererVulkan::CreatePipelineLayout(ShaderVulkan* shader) {
|
bool RendererVulkan::CreatePipelineLayout(
|
||||||
|
ShaderVulkan* shader,
|
||||||
|
const std::vector<uint8_t>& spirv_vertex,
|
||||||
|
const std::vector<uint8_t>& spirv_fragment) {
|
||||||
SpvReflectShaderModule module_vertex;
|
SpvReflectShaderModule module_vertex;
|
||||||
SpvReflectResult result = spvReflectCreateShaderModule(
|
SpvReflectResult result = spvReflectCreateShaderModule(
|
||||||
shader->spirv_vertex.size(), shader->spirv_vertex.data(), &module_vertex);
|
spirv_vertex.size(), spirv_vertex.data(), &module_vertex);
|
||||||
if (result != SPV_REFLECT_RESULT_SUCCESS) {
|
if (result != SPV_REFLECT_RESULT_SUCCESS) {
|
||||||
DLOG << "SPIR-V reflection failed to parse vertex shader.";
|
DLOG << "SPIR-V reflection failed to parse vertex shader.";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
SpvReflectShaderModule module_fragment;
|
SpvReflectShaderModule module_fragment;
|
||||||
result = spvReflectCreateShaderModule(shader->spirv_fragment.size(),
|
result = spvReflectCreateShaderModule(
|
||||||
shader->spirv_fragment.data(),
|
spirv_fragment.size(), spirv_fragment.data(), &module_fragment);
|
||||||
&module_fragment);
|
|
||||||
if (result != SPV_REFLECT_RESULT_SUCCESS) {
|
if (result != SPV_REFLECT_RESULT_SUCCESS) {
|
||||||
DLOG << "SPIR-V reflection failed to parse fragment shader.";
|
DLOG << "SPIR-V reflection failed to parse fragment shader.";
|
||||||
spvReflectDestroyShaderModule(&module_vertex);
|
spvReflectDestroyShaderModule(&module_vertex);
|
||||||
|
|
|
@ -101,6 +101,9 @@ class RendererVulkan : public Renderer {
|
||||||
using PipelineDeathRow =
|
using PipelineDeathRow =
|
||||||
std::vector<std::tuple<VkPipeline, VkPipelineLayout>>;
|
std::vector<std::tuple<VkPipeline, VkPipelineLayout>>;
|
||||||
|
|
||||||
|
std::unordered_map<std::string, std::array<std::vector<uint8_t>, 2>>
|
||||||
|
spirv_cache_;
|
||||||
|
|
||||||
struct GeometryVulkan {
|
struct GeometryVulkan {
|
||||||
Buffer<VkBuffer> buffer;
|
Buffer<VkBuffer> buffer;
|
||||||
uint32_t num_vertices = 0;
|
uint32_t num_vertices = 0;
|
||||||
|
@ -115,8 +118,6 @@ class RendererVulkan : public Renderer {
|
||||||
size_t push_constants_size = 0;
|
size_t push_constants_size = 0;
|
||||||
std::vector<std::string> sampler_uniform_names;
|
std::vector<std::string> sampler_uniform_names;
|
||||||
int desc_set_count = 0;
|
int desc_set_count = 0;
|
||||||
std::vector<uint8_t> spirv_vertex;
|
|
||||||
std::vector<uint8_t> spirv_fragment;
|
|
||||||
VkPipelineLayout pipeline_layout = VK_NULL_HANDLE;
|
VkPipelineLayout pipeline_layout = VK_NULL_HANDLE;
|
||||||
VkPipeline pipeline = VK_NULL_HANDLE;
|
VkPipeline pipeline = VK_NULL_HANDLE;
|
||||||
};
|
};
|
||||||
|
@ -248,7 +249,9 @@ class RendererVulkan : public Renderer {
|
||||||
VkImageLayout old_layout,
|
VkImageLayout old_layout,
|
||||||
VkImageLayout new_layout);
|
VkImageLayout new_layout);
|
||||||
|
|
||||||
bool CreatePipelineLayout(ShaderVulkan* shader);
|
bool CreatePipelineLayout(ShaderVulkan* shader,
|
||||||
|
const std::vector<uint8_t>& spirv_vertex,
|
||||||
|
const std::vector<uint8_t>& spirv_fragment);
|
||||||
|
|
||||||
void DrawListBegin();
|
void DrawListBegin();
|
||||||
void DrawListEnd();
|
void DrawListEnd();
|
||||||
|
|
Loading…
Reference in New Issue