From d37a3b8c7e70d0665ca7fe0a4b8d1d68f230342e Mon Sep 17 00:00:00 2001 From: Benau Date: Tue, 26 Jul 2022 13:21:07 +0800 Subject: [PATCH] Sort materials if needed --- .../src/ge_vulkan_draw_call.cpp | 33 ++++++++++++++++--- .../src/ge_vulkan_draw_call.hpp | 2 +- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/lib/graphics_engine/src/ge_vulkan_draw_call.cpp b/lib/graphics_engine/src/ge_vulkan_draw_call.cpp index 8e4922d09..b799ccb6f 100644 --- a/lib/graphics_engine/src/ge_vulkan_draw_call.cpp +++ b/lib/graphics_engine/src/ge_vulkan_draw_call.cpp @@ -150,7 +150,8 @@ void GEVulkanDrawCall::generate() }}; const irr::video::ITexture** list = &textures[0]; const int material_id = m_texture_descriptor->getTextureID(list); - m_materials.push_back(material_id); + if (!GEVulkanFeatures::supportsBindMeshTexturesAtOnce()) + m_materials[p.first->getVBOOffset()] = material_id; unsigned visible_count = p.second.size(); if (visible_count != 0) { @@ -177,6 +178,18 @@ void GEVulkanDrawCall::generate() m_cmds.emplace_back(cmd, skinning ? "solid_skinning" : "solid"); } } + if (!GEVulkanFeatures::supportsBindMeshTexturesAtOnce()) + { + std::stable_sort(m_cmds.begin(), m_cmds.end(), + [this]( + const std::pair& a, + const std::pair& b) + { + return m_materials[a.first.vertexOffset] < + m_materials[b.first.vertexOffset]; + }); + } + std::stable_sort(m_cmds.begin(), m_cmds.end(), [](const std::pair& a, const std::pair& b) @@ -694,16 +707,27 @@ void GEVulkanDrawCall::render(GEVulkanDriver* vk, GEVulkanCameraSceneNode* cam, } else { + int cur_mid = m_materials[m_cmds[0].first.vertexOffset]; vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, m_graphics_pipelines[cur_pipeline].first); + if (!GEVulkanFeatures::supportsBindMeshTexturesAtOnce()) + { + vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, + m_pipeline_layout, 0, 1, + &m_texture_descriptor->getDescriptorSet()[cur_mid], 0, NULL); + } for (unsigned i = 0; i < m_cmds.size(); i++) { - if (!GEVulkanFeatures::supportsBindMeshTexturesAtOnce()) + const VkDrawIndexedIndirectCommand& cur_cmd = m_cmds[i].first; + int mid = m_materials[cur_cmd.vertexOffset]; + if (!GEVulkanFeatures::supportsBindMeshTexturesAtOnce() && + cur_mid != mid) { + cur_mid = mid; vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline_layout, 0, 1, - &m_texture_descriptor->getDescriptorSet()[m_materials[i]], - 0, NULL); + &m_texture_descriptor->getDescriptorSet()[cur_mid], 0, + NULL); } if (m_cmds[i].second != cur_pipeline) { @@ -711,7 +735,6 @@ void GEVulkanDrawCall::render(GEVulkanDriver* vk, GEVulkanCameraSceneNode* cam, vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, m_graphics_pipelines[cur_pipeline].first); } - const VkDrawIndexedIndirectCommand& cur_cmd = m_cmds[i].first; vkCmdDrawIndexed(cmd, cur_cmd.indexCount, cur_cmd.instanceCount, cur_cmd.firstIndex, cur_cmd.vertexOffset, cur_cmd.firstInstance); } diff --git a/lib/graphics_engine/src/ge_vulkan_draw_call.hpp b/lib/graphics_engine/src/ge_vulkan_draw_call.hpp index 1e8ef6471..3dc62ef89 100644 --- a/lib/graphics_engine/src/ge_vulkan_draw_call.hpp +++ b/lib/graphics_engine/src/ge_vulkan_draw_call.hpp @@ -76,7 +76,7 @@ private: std::unordered_map > m_graphics_pipelines; - std::vector m_materials; + std::unordered_map m_materials; GEVulkanTextureDescriptor* m_texture_descriptor;