Fix possibly missed dynamic spm buffer rendering

This commit is contained in:
Benau 2024-05-23 08:43:52 +00:00
parent af18315c73
commit 57a80c209a
2 changed files with 82 additions and 29 deletions

View File

@ -252,7 +252,8 @@ void GEVulkanDrawCall::addNode(irr::scene::ISceneNode* node)
{ {
GEVulkanDynamicSPMBuffer* dbuffer = static_cast< GEVulkanDynamicSPMBuffer* dbuffer = static_cast<
GEVulkanDynamicSPMBuffer*>(buffer); GEVulkanDynamicSPMBuffer*>(buffer);
m_dynamic_spm_buffers[shader].emplace_back(dbuffer, node); m_dynamic_spm_buffers[getDynamicBufferKey(shader)]
.emplace_back(dbuffer, node);
continue; continue;
} }
m_visible_nodes[buffer][shader].emplace_back(node, i); 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( const size_t dynamic_spm_size = sizeof(ObjectData) + getPadding(
sizeof(ObjectData), sbo_alignment); sizeof(ObjectData), sbo_alignment);
size_t dynamic_spm_offset = 0; size_t dynamic_spm_offset = 0;
int cur_mid = -1;
std::vector<uint32_t> dynamic_offsets =
{
0u,
0u,
0u,
0u,
};
if (bind_mesh_textures) if (bind_mesh_textures)
{ {
vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
m_pipeline_layout, 0, 1, m_texture_descriptor->getDescriptorSet(), m_pipeline_layout, 0, 1, m_texture_descriptor->getDescriptorSet(),
0, NULL); 0, NULL);
std::array<uint32_t, 4> dynamic_offsets =
{{
0u,
0u,
0u,
0u,
}};
size_t indirect_offset = sizeof(GEVulkanCameraUBO); size_t indirect_offset = sizeof(GEVulkanCameraUBO);
const size_t indirect_size = sizeof(VkDrawIndexedIndirectCommand); const size_t indirect_size = sizeof(VkDrawIndexedIndirectCommand);
unsigned draw_count = 0; unsigned draw_count = 0;
@ -1404,12 +1406,13 @@ void GEVulkanDrawCall::render(GEVulkanDriver* vk, GEVulkanCameraSceneNode* cam,
if (m_cmds[i].m_shader != cur_pipeline) if (m_cmds[i].m_shader != cur_pipeline)
{ {
bindPipeline(cmd, cur_pipeline); bindPipeline(cmd, cur_pipeline);
auto it = m_dynamic_spm_buffers.find(cur_pipeline); auto it = m_dynamic_spm_buffers.find(
if (it != m_dynamic_spm_buffers.end() && !it->second.empty()) getDynamicBufferKey(cur_pipeline));
if (it != m_dynamic_spm_buffers.end())
{ {
rebind_base_vertex = true;
for (auto& buf : it->second) for (auto& buf : it->second)
{ {
rebind_base_vertex = true;
dynamic_offsets[1] = dynamic_spm_offset; dynamic_offsets[1] = dynamic_spm_offset;
vkCmdBindDescriptorSets(cmd, vkCmdBindDescriptorSets(cmd,
VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline_layout, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline_layout,
@ -1419,6 +1422,7 @@ void GEVulkanDrawCall::render(GEVulkanDriver* vk, GEVulkanCameraSceneNode* cam,
current_buffer_idx); current_buffer_idx);
dynamic_spm_offset += dynamic_spm_size; dynamic_spm_offset += dynamic_spm_size;
} }
m_dynamic_spm_buffers.erase(it);
} }
if (rebind_base_vertex) if (rebind_base_vertex)
{ {
@ -1451,12 +1455,13 @@ void GEVulkanDrawCall::render(GEVulkanDriver* vk, GEVulkanCameraSceneNode* cam,
draw_count++; draw_count++;
} }
bindPipeline(cmd, m_cmds.back().m_shader); bindPipeline(cmd, m_cmds.back().m_shader);
auto it = m_dynamic_spm_buffers.find(m_cmds.back().m_shader); auto it = m_dynamic_spm_buffers.find(
if (it != m_dynamic_spm_buffers.end() && !it->second.empty()) getDynamicBufferKey(m_cmds.back().m_shader));
if (it != m_dynamic_spm_buffers.end())
{ {
rebind_base_vertex = true;
for (auto& buf : it->second) for (auto& buf : it->second)
{ {
rebind_base_vertex = true;
dynamic_offsets[1] = dynamic_spm_offset; dynamic_offsets[1] = dynamic_spm_offset;
vkCmdBindDescriptorSets(cmd, vkCmdBindDescriptorSets(cmd,
VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline_layout, 1, 1, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline_layout, 1, 1,
@ -1466,6 +1471,7 @@ void GEVulkanDrawCall::render(GEVulkanDriver* vk, GEVulkanCameraSceneNode* cam,
current_buffer_idx); current_buffer_idx);
dynamic_spm_offset += dynamic_spm_size; dynamic_spm_offset += dynamic_spm_size;
} }
m_dynamic_spm_buffers.erase(it);
} }
if (rebind_base_vertex) if (rebind_base_vertex)
bindBaseVertex(vk, cmd); bindBaseVertex(vk, cmd);
@ -1480,21 +1486,16 @@ void GEVulkanDrawCall::render(GEVulkanDriver* vk, GEVulkanCameraSceneNode* cam,
} }
else else
{ {
std::array<uint32_t, 3> dynamic_offsets = dynamic_offsets.resize(3);
{{
0u,
0u,
0u,
}};
bool rebind_base_vertex = true; bool rebind_base_vertex = true;
int cur_mid = -1;
bindPipeline(cmd, cur_pipeline); bindPipeline(cmd, cur_pipeline);
auto it = m_dynamic_spm_buffers.find(cur_pipeline); auto it = m_dynamic_spm_buffers.find(
if (it != m_dynamic_spm_buffers.end() && !it->second.empty()) getDynamicBufferKey(cur_pipeline));
if (it != m_dynamic_spm_buffers.end())
{ {
rebind_base_vertex = true;
for (auto& buf : it->second) for (auto& buf : it->second)
{ {
rebind_base_vertex = true;
dynamic_offsets[1] = dynamic_spm_offset; dynamic_offsets[1] = dynamic_spm_offset;
vkCmdBindDescriptorSets(cmd, vkCmdBindDescriptorSets(cmd,
VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline_layout, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline_layout,
@ -1514,6 +1515,7 @@ void GEVulkanDrawCall::render(GEVulkanDriver* vk, GEVulkanCameraSceneNode* cam,
current_buffer_idx); current_buffer_idx);
dynamic_spm_offset += dynamic_spm_size; dynamic_spm_offset += dynamic_spm_size;
} }
m_dynamic_spm_buffers.erase(it);
} }
if (cur_mid != m_materials[m_cmds[0].m_mb]) 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; cur_pipeline = m_cmds[i].m_shader;
bindPipeline(cmd, cur_pipeline); bindPipeline(cmd, cur_pipeline);
auto it = m_dynamic_spm_buffers.find(cur_pipeline); auto it = m_dynamic_spm_buffers.find(
if (it != m_dynamic_spm_buffers.end() && !it->second.empty()) getDynamicBufferKey(cur_pipeline));
if (it != m_dynamic_spm_buffers.end())
{ {
rebind_base_vertex = true;
for (auto& buf : it->second) for (auto& buf : it->second)
{ {
rebind_base_vertex = true;
dynamic_offsets[1] = dynamic_spm_offset; dynamic_offsets[1] = dynamic_spm_offset;
vkCmdBindDescriptorSets(cmd, vkCmdBindDescriptorSets(cmd,
VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline_layout, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline_layout,
@ -1566,6 +1569,7 @@ void GEVulkanDrawCall::render(GEVulkanDriver* vk, GEVulkanCameraSceneNode* cam,
current_buffer_idx); current_buffer_idx);
dynamic_spm_offset += dynamic_spm_size; dynamic_spm_offset += dynamic_spm_size;
} }
m_dynamic_spm_buffers.erase(it);
} }
} }
int mid = m_materials[m_cmds[i].m_mb]; int mid = m_materials[m_cmds[i].m_mb];
@ -1604,6 +1608,41 @@ void GEVulkanDrawCall::render(GEVulkanDriver* vk, GEVulkanCameraSceneNode* cam,
} }
if (!drawn_skybox) if (!drawn_skybox)
GEVulkanSkyBoxRenderer::render(cmd, cam); 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 } // render
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@ -115,7 +115,7 @@ private:
std::unordered_map<GESPMBuffer*, irr::scene::IMesh*> m_mb_map; std::unordered_map<GESPMBuffer*, irr::scene::IMesh*> m_mb_map;
std::unordered_map<std::string, std::vector< std::map<std::string, std::vector<
std::pair<GEVulkanDynamicSPMBuffer*, irr::scene::ISceneNode*> > > std::pair<GEVulkanDynamicSPMBuffer*, irr::scene::ISceneNode*> > >
m_dynamic_spm_buffers; m_dynamic_spm_buffers;
@ -199,6 +199,20 @@ private:
void updateDataDescriptorSets(GEVulkanDriver* vk); void updateDataDescriptorSets(GEVulkanDriver* vk);
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
void bindBaseVertex(GEVulkanDriver* vk, VkCommandBuffer cmd); 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: public:
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
GEVulkanDrawCall(); GEVulkanDrawCall();