Allow using custom command buffer for draw call

This commit is contained in:
Benau 2022-07-24 08:54:47 +08:00
parent 9f25652455
commit 99d565f961
4 changed files with 42 additions and 35 deletions

View File

@ -419,11 +419,15 @@ void GEVulkanDrawCall::createVulkanData()
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void GEVulkanDrawCall::uploadDynamicData(GEVulkanDriver* vk, void GEVulkanDrawCall::uploadDynamicData(GEVulkanDriver* vk,
GEVulkanCameraSceneNode* cam) GEVulkanCameraSceneNode* cam,
VkCommandBuffer custom_cmd)
{ {
if (!m_dynamic_data) if (!m_dynamic_data)
return; return;
VkCommandBuffer cmd =
custom_cmd ? custom_cmd : vk->getCurrentCommandBuffer();
const VkPhysicalDeviceLimits& limit = const VkPhysicalDeviceLimits& limit =
vk->getPhysicalDeviceProperties().limits; vk->getPhysicalDeviceProperties().limits;
const size_t object_data_size = const size_t object_data_size =
@ -452,7 +456,7 @@ void GEVulkanDrawCall::uploadDynamicData(GEVulkanDriver* vk,
sizeof(VkDrawIndexedIndirectCommand) * m_cmds.size()); sizeof(VkDrawIndexedIndirectCommand) * m_cmds.size());
dst_stage |= VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT; dst_stage |= VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT;
} }
m_dynamic_data->setCurrentData(data); m_dynamic_data->setCurrentData(data, cmd);
VkBufferMemoryBarrier barrier = {}; VkBufferMemoryBarrier barrier = {};
barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER; barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
@ -463,17 +467,19 @@ void GEVulkanDrawCall::uploadDynamicData(GEVulkanDriver* vk,
barrier.buffer = m_dynamic_data->getCurrentBuffer(); barrier.buffer = m_dynamic_data->getCurrentBuffer();
barrier.size = m_dynamic_data->getRealSize(); barrier.size = m_dynamic_data->getRealSize();
vkCmdPipelineBarrier(vk->getCurrentCommandBuffer(), vkCmdPipelineBarrier(cmd, VK_PIPELINE_STAGE_TRANSFER_BIT, dst_stage, 0, 0,
VK_PIPELINE_STAGE_TRANSFER_BIT, dst_stage, 0, 0, NULL, 1, &barrier, 0, NULL, 1, &barrier, 0, NULL);
NULL);
} // uploadDynamicData } // uploadDynamicData
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void GEVulkanDrawCall::render(GEVulkanDriver* vk, GEVulkanCameraSceneNode* cam) void GEVulkanDrawCall::render(GEVulkanDriver* vk, GEVulkanCameraSceneNode* cam,
VkCommandBuffer custom_cmd)
{ {
if (m_data_layout == VK_NULL_HANDLE || m_cmds.empty()) if (m_data_layout == VK_NULL_HANDLE || m_cmds.empty())
return; return;
VkCommandBuffer cmd =
custom_cmd ? custom_cmd : vk->getCurrentCommandBuffer();
const unsigned cur_frame = vk->getCurrentFrame(); const unsigned cur_frame = vk->getCurrentFrame();
VkDescriptorBufferInfo ubo_info; VkDescriptorBufferInfo ubo_info;
@ -508,28 +514,26 @@ void GEVulkanDrawCall::render(GEVulkanDriver* vk, GEVulkanCameraSceneNode* cam)
m_texture_descriptor->updateDescriptor(); m_texture_descriptor->updateDescriptor();
vkCmdBindPipeline(vk->getCurrentCommandBuffer(), vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
VK_PIPELINE_BIND_POINT_GRAPHICS, m_graphics_pipeline); m_graphics_pipeline);
if (GEVulkanFeatures::supportsBindMeshTexturesAtOnce()) if (GEVulkanFeatures::supportsBindMeshTexturesAtOnce())
{ {
vkCmdBindDescriptorSets(vk->getCurrentCommandBuffer(), vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline_layout, 0, 1, m_pipeline_layout, 0, 1, m_texture_descriptor->getDescriptorSet(),
m_texture_descriptor->getDescriptorSet(), 0, NULL); 0, NULL);
} }
vkCmdBindDescriptorSets(vk->getCurrentCommandBuffer(), vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline_layout, 1, 1, m_pipeline_layout, 1, 1, &m_data_descriptor_sets[cur_frame], 0, NULL);
&m_data_descriptor_sets[cur_frame], 0, NULL);
VkDeviceSize offsets[] = {0}; VkDeviceSize offsets[] = {0};
GEVulkanMeshCache* mc = vk->getVulkanMeshCache(); GEVulkanMeshCache* mc = vk->getVulkanMeshCache();
VkBuffer vertex_buffer = mc->getBuffer(); VkBuffer vertex_buffer = mc->getBuffer();
vkCmdBindVertexBuffers(vk->getCurrentCommandBuffer(), 0, 1, &vertex_buffer, vkCmdBindVertexBuffers(cmd, 0, 1, &vertex_buffer, offsets);
offsets);
vkCmdBindIndexBuffer(vk->getCurrentCommandBuffer(), mc->getBuffer(), vkCmdBindIndexBuffer(cmd, mc->getBuffer(), mc->getIBOOffset(),
mc->getIBOOffset(), VK_INDEX_TYPE_UINT16); VK_INDEX_TYPE_UINT16);
VkViewport vp; VkViewport vp;
vp.x = cam->getViewPort().UpperLeftCorner.X; vp.x = cam->getViewPort().UpperLeftCorner.X;
@ -539,21 +543,20 @@ void GEVulkanDrawCall::render(GEVulkanDriver* vk, GEVulkanCameraSceneNode* cam)
vp.minDepth = 0; vp.minDepth = 0;
vp.maxDepth = 1.0f; vp.maxDepth = 1.0f;
vk->getRotatedViewport(&vp); vk->getRotatedViewport(&vp);
vkCmdSetViewport(vk->getCurrentCommandBuffer(), 0, 1, &vp); vkCmdSetViewport(cmd, 0, 1, &vp);
VkRect2D scissor; VkRect2D scissor;
scissor.offset.x = vp.x; scissor.offset.x = vp.x;
scissor.offset.y = vp.y; scissor.offset.y = vp.y;
scissor.extent.width = vp.width; scissor.extent.width = vp.width;
scissor.extent.height = vp.height; scissor.extent.height = vp.height;
vkCmdSetScissor(vk->getCurrentCommandBuffer(), 0, 1, &scissor); vkCmdSetScissor(cmd, 0, 1, &scissor);
const bool use_multidraw = GEVulkanFeatures::supportsMultiDrawIndirect() && const bool use_multidraw = GEVulkanFeatures::supportsMultiDrawIndirect() &&
GEVulkanFeatures::supportsBindMeshTexturesAtOnce(); GEVulkanFeatures::supportsBindMeshTexturesAtOnce();
if (use_multidraw) if (use_multidraw)
{ {
vkCmdDrawIndexedIndirect(vk->getCurrentCommandBuffer(), vkCmdDrawIndexedIndirect(cmd, m_dynamic_data->getCurrentBuffer(),
m_dynamic_data->getCurrentBuffer(),
m_object_data_padded_size + sizeof(GEVulkanCameraUBO), m_object_data_padded_size + sizeof(GEVulkanCameraUBO),
m_cmds.size(), sizeof(VkDrawIndexedIndirectCommand)); m_cmds.size(), sizeof(VkDrawIndexedIndirectCommand));
} }
@ -563,15 +566,14 @@ void GEVulkanDrawCall::render(GEVulkanDriver* vk, GEVulkanCameraSceneNode* cam)
{ {
if (!GEVulkanFeatures::supportsBindMeshTexturesAtOnce()) if (!GEVulkanFeatures::supportsBindMeshTexturesAtOnce())
{ {
vkCmdBindDescriptorSets(vk->getCurrentCommandBuffer(), vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline_layout, 0, 1, m_pipeline_layout, 0, 1,
&m_texture_descriptor->getDescriptorSet()[m_materials[i]], &m_texture_descriptor->getDescriptorSet()[m_materials[i]],
0, NULL); 0, NULL);
} }
const VkDrawIndexedIndirectCommand& cmd = m_cmds[i]; const VkDrawIndexedIndirectCommand& cur_cmd = m_cmds[i];
vkCmdDrawIndexed(vk->getCurrentCommandBuffer(), cmd.indexCount, vkCmdDrawIndexed(cmd, cur_cmd.indexCount, cur_cmd.instanceCount,
cmd.instanceCount, cmd.firstIndex, cmd.vertexOffset, cur_cmd.firstIndex, cur_cmd.vertexOffset, cur_cmd.firstInstance);
cmd.firstInstance);
} }
} }
} // render } // render

View File

@ -79,9 +79,11 @@ public:
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
void generate(); void generate();
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
void uploadDynamicData(GEVulkanDriver* vk, GEVulkanCameraSceneNode* cam); void uploadDynamicData(GEVulkanDriver* vk, GEVulkanCameraSceneNode* cam,
VkCommandBuffer custom_cmd = VK_NULL_HANDLE);
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
void render(GEVulkanDriver* vk, GEVulkanCameraSceneNode* cam); void render(GEVulkanDriver* vk, GEVulkanCameraSceneNode* cam,
VkCommandBuffer custom_cmd = VK_NULL_HANDLE);
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
unsigned getPolyCount() const unsigned getPolyCount() const
{ {

View File

@ -155,7 +155,8 @@ void GEVulkanDynamicBuffer::destroy()
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void GEVulkanDynamicBuffer::setCurrentData(const std::vector< void GEVulkanDynamicBuffer::setCurrentData(const std::vector<
std::pair<void*, size_t> >& data) std::pair<void*, size_t> >& data,
VkCommandBuffer custom_cmd)
{ {
GEVulkanDriver* vk = getVKDriver(); GEVulkanDriver* vk = getVKDriver();
const unsigned cur_frame = vk->getCurrentFrame(); const unsigned cur_frame = vk->getCurrentFrame();
@ -187,7 +188,7 @@ void GEVulkanDynamicBuffer::setCurrentData(const std::vector<
{ {
VkBufferCopy copy_region = {}; VkBufferCopy copy_region = {};
copy_region.size = size; copy_region.size = size;
vkCmdCopyBuffer(vk->getCurrentCommandBuffer(), vkCmdCopyBuffer(custom_cmd ? custom_cmd : vk->getCurrentCommandBuffer(),
m_staging_buffer[cur_frame], m_buffer[cur_frame], 1, &copy_region); m_staging_buffer[cur_frame], m_buffer[cur_frame], 1, &copy_region);
} }
} // setCurrentData } // setCurrentData

View File

@ -49,10 +49,12 @@ public:
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
~GEVulkanDynamicBuffer(); ~GEVulkanDynamicBuffer();
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
void setCurrentData(const std::vector<std::pair<void*, size_t> >& data); void setCurrentData(const std::vector<std::pair<void*, size_t> >& data,
VkCommandBuffer custom_cmd = VK_NULL_HANDLE);
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
void setCurrentData(void* data, size_t size) void setCurrentData(void* data, size_t size,
{ setCurrentData({{ data, size }}); } VkCommandBuffer custom_cmd = VK_NULL_HANDLE)
{ setCurrentData({{ data, size }}, custom_cmd); }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
VkBuffer getCurrentBuffer() const; VkBuffer getCurrentBuffer() const;
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------