Fix queue family transfer operations between graphics <-> compute queues, generalize getQueueFamilyIndex() to support VkQueueFlags vs. VkQueueFlagBits, computecloth deltaT now based on frameTimer
This commit is contained in:
parent
17aaa7305b
commit
b2f501dc98
7 changed files with 306 additions and 80 deletions
|
|
@ -149,6 +149,32 @@ public:
|
|||
|
||||
VK_CHECK_RESULT(vkBeginCommandBuffer(drawCmdBuffers[i], &cmdBufInfo));
|
||||
|
||||
// Acquire barrier
|
||||
if (vulkanDevice->queueFamilyIndices.graphics != vulkanDevice->queueFamilyIndices.compute)
|
||||
{
|
||||
VkBufferMemoryBarrier buffer_barrier =
|
||||
{
|
||||
VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
|
||||
nullptr,
|
||||
0,
|
||||
VK_ACCESS_INDIRECT_COMMAND_READ_BIT,
|
||||
vulkanDevice->queueFamilyIndices.compute,
|
||||
vulkanDevice->queueFamilyIndices.graphics,
|
||||
indirectCommandsBuffer.buffer,
|
||||
0,
|
||||
indirectCommandsBuffer.descriptor.range
|
||||
};
|
||||
|
||||
vkCmdPipelineBarrier(
|
||||
drawCmdBuffers[i],
|
||||
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
|
||||
VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT,
|
||||
0,
|
||||
0, nullptr,
|
||||
1, &buffer_barrier,
|
||||
0, nullptr);
|
||||
}
|
||||
|
||||
vkCmdBeginRenderPass(drawCmdBuffers[i], &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
|
||||
|
||||
VkViewport viewport = vks::initializers::viewport((float)width, (float)height, 0.0f, 1.0f);
|
||||
|
|
@ -169,7 +195,7 @@ public:
|
|||
|
||||
if (vulkanDevice->features.multiDrawIndirect)
|
||||
{
|
||||
vkCmdDrawIndexedIndirect(drawCmdBuffers[i], indirectCommandsBuffer.buffer, 0, indirectCommands.size(), sizeof(VkDrawIndexedIndirectCommand));
|
||||
vkCmdDrawIndexedIndirect(drawCmdBuffers[i], indirectCommandsBuffer.buffer, 0, static_cast<uint32_t>(indirectCommands.size()), sizeof(VkDrawIndexedIndirectCommand));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -184,6 +210,32 @@ public:
|
|||
|
||||
vkCmdEndRenderPass(drawCmdBuffers[i]);
|
||||
|
||||
// Release barrier
|
||||
if (vulkanDevice->queueFamilyIndices.graphics != vulkanDevice->queueFamilyIndices.compute)
|
||||
{
|
||||
VkBufferMemoryBarrier buffer_barrier =
|
||||
{
|
||||
VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
|
||||
nullptr,
|
||||
VK_ACCESS_INDIRECT_COMMAND_READ_BIT,
|
||||
0,
|
||||
vulkanDevice->queueFamilyIndices.graphics,
|
||||
vulkanDevice->queueFamilyIndices.compute,
|
||||
indirectCommandsBuffer.buffer,
|
||||
0,
|
||||
indirectCommandsBuffer.descriptor.range
|
||||
};
|
||||
|
||||
vkCmdPipelineBarrier(
|
||||
drawCmdBuffers[i],
|
||||
VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT,
|
||||
VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
|
||||
0,
|
||||
0, nullptr,
|
||||
1, &buffer_barrier,
|
||||
0, nullptr);
|
||||
}
|
||||
|
||||
VK_CHECK_RESULT(vkEndCommandBuffer(drawCmdBuffers[i]));
|
||||
}
|
||||
}
|
||||
|
|
@ -200,23 +252,32 @@ public:
|
|||
|
||||
VK_CHECK_RESULT(vkBeginCommandBuffer(compute.commandBuffer, &cmdBufInfo));
|
||||
|
||||
// Acquire barrier
|
||||
// Add memory barrier to ensure that the indirect commands have been consumed before the compute shader updates them
|
||||
VkBufferMemoryBarrier bufferBarrier = vks::initializers::bufferMemoryBarrier();
|
||||
bufferBarrier.buffer = indirectCommandsBuffer.buffer;
|
||||
bufferBarrier.size = indirectCommandsBuffer.descriptor.range;
|
||||
bufferBarrier.srcAccessMask = VK_ACCESS_INDIRECT_COMMAND_READ_BIT;
|
||||
bufferBarrier.dstAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
|
||||
bufferBarrier.srcQueueFamilyIndex = vulkanDevice->queueFamilyIndices.graphics;
|
||||
bufferBarrier.dstQueueFamilyIndex = vulkanDevice->queueFamilyIndices.compute;
|
||||
if (vulkanDevice->queueFamilyIndices.graphics != vulkanDevice->queueFamilyIndices.compute)
|
||||
{
|
||||
VkBufferMemoryBarrier buffer_barrier =
|
||||
{
|
||||
VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
|
||||
nullptr,
|
||||
0,
|
||||
VK_ACCESS_SHADER_WRITE_BIT,
|
||||
vulkanDevice->queueFamilyIndices.graphics,
|
||||
vulkanDevice->queueFamilyIndices.compute,
|
||||
indirectCommandsBuffer.buffer,
|
||||
0,
|
||||
indirectCommandsBuffer.descriptor.range
|
||||
};
|
||||
|
||||
vkCmdPipelineBarrier(
|
||||
compute.commandBuffer,
|
||||
VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT,
|
||||
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||
VK_FLAGS_NONE,
|
||||
0, nullptr,
|
||||
1, &bufferBarrier,
|
||||
0, nullptr);
|
||||
vkCmdPipelineBarrier(
|
||||
compute.commandBuffer,
|
||||
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
|
||||
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||
VK_FLAGS_NONE,
|
||||
0, nullptr,
|
||||
1, &buffer_barrier,
|
||||
0, nullptr);
|
||||
}
|
||||
|
||||
vkCmdBindPipeline(compute.commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, compute.pipeline);
|
||||
vkCmdBindDescriptorSets(compute.commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, compute.pipelineLayout, 0, 1, &compute.descriptorSet, 0, 0);
|
||||
|
|
@ -226,22 +287,32 @@ public:
|
|||
// It also determines the lod to use depending on distance to the viewer.
|
||||
vkCmdDispatch(compute.commandBuffer, objectCount / 16, 1, 1);
|
||||
|
||||
// Release barrier
|
||||
// Add memory barrier to ensure that the compute shader has finished writing the indirect command buffer before it's consumed
|
||||
bufferBarrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
|
||||
bufferBarrier.dstAccessMask = VK_ACCESS_INDIRECT_COMMAND_READ_BIT;
|
||||
bufferBarrier.buffer = indirectCommandsBuffer.buffer;
|
||||
bufferBarrier.size = indirectCommandsBuffer.descriptor.range;
|
||||
bufferBarrier.srcQueueFamilyIndex = vulkanDevice->queueFamilyIndices.compute;
|
||||
bufferBarrier.dstQueueFamilyIndex = vulkanDevice->queueFamilyIndices.graphics;
|
||||
if (vulkanDevice->queueFamilyIndices.graphics != vulkanDevice->queueFamilyIndices.compute)
|
||||
{
|
||||
VkBufferMemoryBarrier buffer_barrier =
|
||||
{
|
||||
VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
|
||||
nullptr,
|
||||
VK_ACCESS_SHADER_WRITE_BIT,
|
||||
0,
|
||||
vulkanDevice->queueFamilyIndices.compute,
|
||||
vulkanDevice->queueFamilyIndices.graphics,
|
||||
indirectCommandsBuffer.buffer,
|
||||
0,
|
||||
indirectCommandsBuffer.descriptor.range
|
||||
};
|
||||
|
||||
vkCmdPipelineBarrier(
|
||||
compute.commandBuffer,
|
||||
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||
VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT,
|
||||
VK_FLAGS_NONE,
|
||||
0, nullptr,
|
||||
1, &bufferBarrier,
|
||||
0, nullptr);
|
||||
vkCmdPipelineBarrier(
|
||||
compute.commandBuffer,
|
||||
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||
VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
|
||||
VK_FLAGS_NONE,
|
||||
0, nullptr,
|
||||
1, &buffer_barrier,
|
||||
0, nullptr);
|
||||
}
|
||||
|
||||
// todo: barrier for indirect stats buffer?
|
||||
|
||||
|
|
@ -424,7 +495,38 @@ public:
|
|||
&instanceBuffer,
|
||||
stagingBuffer.size));
|
||||
|
||||
vulkanDevice->copyBuffer(&stagingBuffer, &instanceBuffer, queue);
|
||||
// Copy from staging buffer to instance buffer
|
||||
VkCommandBuffer copyCmd = vulkanDevice->createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, true);
|
||||
VkBufferCopy copyRegion = {};
|
||||
copyRegion.size = stagingBuffer.size;
|
||||
vkCmdCopyBuffer(copyCmd, stagingBuffer.buffer, instanceBuffer.buffer, 1, ©Region);
|
||||
// Add an initial release barrier to the graphics queue,
|
||||
// so that when the compute command buffer executes for the first time
|
||||
// it doesn't complain about a lack of a corresponding "release" to its "acquire"
|
||||
if (vulkanDevice->queueFamilyIndices.graphics != vulkanDevice->queueFamilyIndices.compute)
|
||||
{ VkBufferMemoryBarrier buffer_barrier =
|
||||
{
|
||||
VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
|
||||
nullptr,
|
||||
VK_ACCESS_INDIRECT_COMMAND_READ_BIT,
|
||||
0,
|
||||
vulkanDevice->queueFamilyIndices.graphics,
|
||||
vulkanDevice->queueFamilyIndices.compute,
|
||||
indirectCommandsBuffer.buffer,
|
||||
0,
|
||||
indirectCommandsBuffer.descriptor.range
|
||||
};
|
||||
|
||||
vkCmdPipelineBarrier(
|
||||
copyCmd,
|
||||
VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT,
|
||||
VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
|
||||
0,
|
||||
0, nullptr,
|
||||
1, &buffer_barrier,
|
||||
0, nullptr);
|
||||
}
|
||||
vulkanDevice->flushCommandBuffer(copyCmd, queue, true);
|
||||
|
||||
stagingBuffer.destroy();
|
||||
|
||||
|
|
@ -710,6 +812,11 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
virtual void viewChanged()
|
||||
{
|
||||
updateUniformBuffer(true);
|
||||
}
|
||||
|
||||
virtual void OnUpdateUIOverlay(vks::UIOverlay *overlay)
|
||||
{
|
||||
if (overlay->header("Settings")) {
|
||||
|
|
@ -726,4 +833,4 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
VULKAN_EXAMPLE_MAIN()
|
||||
VULKAN_EXAMPLE_MAIN()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue