From 57a80c209a12a5a54b5632053ba6e1a443fda143 Mon Sep 17 00:00:00 2001 From: Benau Date: Thu, 23 May 2024 08:43:52 +0000 Subject: [PATCH] Fix possibly missed dynamic spm buffer rendering --- .../src/ge_vulkan_draw_call.cpp | 95 +++++++++++++------ .../src/ge_vulkan_draw_call.hpp | 16 +++- 2 files changed, 82 insertions(+), 29 deletions(-) diff --git a/lib/graphics_engine/src/ge_vulkan_draw_call.cpp b/lib/graphics_engine/src/ge_vulkan_draw_call.cpp index 0e2b90d1e..3eb376167 100644 --- a/lib/graphics_engine/src/ge_vulkan_draw_call.cpp +++ b/lib/graphics_engine/src/ge_vulkan_draw_call.cpp @@ -252,7 +252,8 @@ void GEVulkanDrawCall::addNode(irr::scene::ISceneNode* node) { GEVulkanDynamicSPMBuffer* dbuffer = static_cast< GEVulkanDynamicSPMBuffer*>(buffer); - m_dynamic_spm_buffers[shader].emplace_back(dbuffer, node); + m_dynamic_spm_buffers[getDynamicBufferKey(shader)] + .emplace_back(dbuffer, node); continue; } m_visible_nodes[buffer][shader].emplace_back(node, i); @@ -1378,19 +1379,20 @@ void GEVulkanDrawCall::render(GEVulkanDriver* vk, GEVulkanCameraSceneNode* cam, const size_t dynamic_spm_size = sizeof(ObjectData) + getPadding( sizeof(ObjectData), sbo_alignment); size_t dynamic_spm_offset = 0; + + int cur_mid = -1; + std::vector dynamic_offsets = + { + 0u, + 0u, + 0u, + 0u, + }; if (bind_mesh_textures) { vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline_layout, 0, 1, m_texture_descriptor->getDescriptorSet(), 0, NULL); - - std::array dynamic_offsets = - {{ - 0u, - 0u, - 0u, - 0u, - }}; size_t indirect_offset = sizeof(GEVulkanCameraUBO); const size_t indirect_size = sizeof(VkDrawIndexedIndirectCommand); unsigned draw_count = 0; @@ -1404,12 +1406,13 @@ void GEVulkanDrawCall::render(GEVulkanDriver* vk, GEVulkanCameraSceneNode* cam, if (m_cmds[i].m_shader != cur_pipeline) { bindPipeline(cmd, cur_pipeline); - auto it = m_dynamic_spm_buffers.find(cur_pipeline); - if (it != m_dynamic_spm_buffers.end() && !it->second.empty()) + auto it = m_dynamic_spm_buffers.find( + getDynamicBufferKey(cur_pipeline)); + if (it != m_dynamic_spm_buffers.end()) { - rebind_base_vertex = true; for (auto& buf : it->second) { + rebind_base_vertex = true; dynamic_offsets[1] = dynamic_spm_offset; vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline_layout, @@ -1419,6 +1422,7 @@ void GEVulkanDrawCall::render(GEVulkanDriver* vk, GEVulkanCameraSceneNode* cam, current_buffer_idx); dynamic_spm_offset += dynamic_spm_size; } + m_dynamic_spm_buffers.erase(it); } if (rebind_base_vertex) { @@ -1451,12 +1455,13 @@ void GEVulkanDrawCall::render(GEVulkanDriver* vk, GEVulkanCameraSceneNode* cam, draw_count++; } bindPipeline(cmd, m_cmds.back().m_shader); - auto it = m_dynamic_spm_buffers.find(m_cmds.back().m_shader); - if (it != m_dynamic_spm_buffers.end() && !it->second.empty()) + auto it = m_dynamic_spm_buffers.find( + getDynamicBufferKey(m_cmds.back().m_shader)); + if (it != m_dynamic_spm_buffers.end()) { - rebind_base_vertex = true; for (auto& buf : it->second) { + rebind_base_vertex = true; dynamic_offsets[1] = dynamic_spm_offset; vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline_layout, 1, 1, @@ -1466,6 +1471,7 @@ void GEVulkanDrawCall::render(GEVulkanDriver* vk, GEVulkanCameraSceneNode* cam, current_buffer_idx); dynamic_spm_offset += dynamic_spm_size; } + m_dynamic_spm_buffers.erase(it); } if (rebind_base_vertex) bindBaseVertex(vk, cmd); @@ -1480,21 +1486,16 @@ void GEVulkanDrawCall::render(GEVulkanDriver* vk, GEVulkanCameraSceneNode* cam, } else { - std::array dynamic_offsets = - {{ - 0u, - 0u, - 0u, - }}; + dynamic_offsets.resize(3); bool rebind_base_vertex = true; - int cur_mid = -1; bindPipeline(cmd, cur_pipeline); - auto it = m_dynamic_spm_buffers.find(cur_pipeline); - if (it != m_dynamic_spm_buffers.end() && !it->second.empty()) + auto it = m_dynamic_spm_buffers.find( + getDynamicBufferKey(cur_pipeline)); + if (it != m_dynamic_spm_buffers.end()) { - rebind_base_vertex = true; for (auto& buf : it->second) { + rebind_base_vertex = true; dynamic_offsets[1] = dynamic_spm_offset; vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline_layout, @@ -1514,6 +1515,7 @@ void GEVulkanDrawCall::render(GEVulkanDriver* vk, GEVulkanCameraSceneNode* cam, current_buffer_idx); dynamic_spm_offset += dynamic_spm_size; } + m_dynamic_spm_buffers.erase(it); } if (cur_mid != m_materials[m_cmds[0].m_mb]) { @@ -1541,12 +1543,13 @@ void GEVulkanDrawCall::render(GEVulkanDriver* vk, GEVulkanCameraSceneNode* cam, { cur_pipeline = m_cmds[i].m_shader; bindPipeline(cmd, cur_pipeline); - auto it = m_dynamic_spm_buffers.find(cur_pipeline); - if (it != m_dynamic_spm_buffers.end() && !it->second.empty()) + auto it = m_dynamic_spm_buffers.find( + getDynamicBufferKey(cur_pipeline)); + if (it != m_dynamic_spm_buffers.end()) { - rebind_base_vertex = true; for (auto& buf : it->second) { + rebind_base_vertex = true; dynamic_offsets[1] = dynamic_spm_offset; vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline_layout, @@ -1566,6 +1569,7 @@ void GEVulkanDrawCall::render(GEVulkanDriver* vk, GEVulkanCameraSceneNode* cam, current_buffer_idx); dynamic_spm_offset += dynamic_spm_size; } + m_dynamic_spm_buffers.erase(it); } } int mid = m_materials[m_cmds[i].m_mb]; @@ -1604,6 +1608,41 @@ void GEVulkanDrawCall::render(GEVulkanDriver* vk, GEVulkanCameraSceneNode* cam, } if (!drawn_skybox) GEVulkanSkyBoxRenderer::render(cmd, cam); + for (auto& p : m_dynamic_spm_buffers) + { + bindPipeline(cmd, getShaderFromKey(p.first)); + for (auto& buf : p.second) + { + dynamic_offsets[1] = dynamic_spm_offset; + vkCmdBindDescriptorSets(cmd, + VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline_layout, + 1, 1, &m_data_descriptor_sets[current_buffer_idx], + dynamic_offsets.size(), dynamic_offsets.data()); + if (bind_mesh_textures) + { + if (!drawn_skybox) + { + vkCmdBindDescriptorSets(cmd, + VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline_layout, 0, + 1, m_texture_descriptor->getDescriptorSet(), 0, NULL); + } + } + else + { + int dy_mat = m_materials[buf.first]; + if (dy_mat != cur_mid) + { + cur_mid = dy_mat; + vkCmdBindDescriptorSets(cmd, + VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline_layout, 0, + 1, &m_texture_descriptor->getDescriptorSet()[cur_mid], + 0, NULL); + } + } + buf.first->drawDynamicVertexIndexBuffer(cmd, current_buffer_idx); + dynamic_spm_offset += dynamic_spm_size; + } + } } // render // ---------------------------------------------------------------------------- diff --git a/lib/graphics_engine/src/ge_vulkan_draw_call.hpp b/lib/graphics_engine/src/ge_vulkan_draw_call.hpp index fba35fdb9..f6be7ba0c 100644 --- a/lib/graphics_engine/src/ge_vulkan_draw_call.hpp +++ b/lib/graphics_engine/src/ge_vulkan_draw_call.hpp @@ -115,7 +115,7 @@ private: std::unordered_map m_mb_map; - std::unordered_map > > m_dynamic_spm_buffers; @@ -199,6 +199,20 @@ private: void updateDataDescriptorSets(GEVulkanDriver* vk); // ------------------------------------------------------------------------ void bindBaseVertex(GEVulkanDriver* vk, VkCommandBuffer cmd); + // ------------------------------------------------------------------------ + std::string getDynamicBufferKey(const std::string& shader) const + { + static PipelineSettings default_settings = {}; + const PipelineSettings* settings = &default_settings; + auto it = m_graphics_pipelines.find(shader); + if (it != m_graphics_pipelines.end()) + settings = &it->second.second; + return std::string(1, settings->isTransparent() ? (char)1 : (char)0) + + std::string(1, settings->m_drawing_priority) + shader; + } + // ------------------------------------------------------------------------ + std::string getShaderFromKey(const std::string& key) const + { return key.substr(2); } public: // ------------------------------------------------------------------------ GEVulkanDrawCall();