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
|
|
@ -94,6 +94,9 @@ public:
|
|||
|
||||
~VulkanExample()
|
||||
{
|
||||
// SRS - Ensure all operations on the device have finished before destroying resources
|
||||
vkDeviceWaitIdle(device);
|
||||
|
||||
// Graphics
|
||||
vkDestroyPipeline(device, graphics.pipeline, nullptr);
|
||||
vkDestroyPipelineLayout(device, graphics.pipelineLayout, nullptr);
|
||||
|
|
@ -223,16 +226,38 @@ public:
|
|||
imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
|
||||
imageMemoryBarrier.image = textureComputeTarget.image;
|
||||
imageMemoryBarrier.subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 };
|
||||
imageMemoryBarrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
|
||||
imageMemoryBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
|
||||
vkCmdPipelineBarrier(
|
||||
drawCmdBuffers[i],
|
||||
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
|
||||
VK_FLAGS_NONE,
|
||||
0, nullptr,
|
||||
0, nullptr,
|
||||
1, &imageMemoryBarrier);
|
||||
if (vulkanDevice->queueFamilyIndices.graphics != vulkanDevice->queueFamilyIndices.compute)
|
||||
{
|
||||
// Acquire barrier for graphics queue
|
||||
imageMemoryBarrier.srcAccessMask = 0;
|
||||
imageMemoryBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
|
||||
imageMemoryBarrier.srcQueueFamilyIndex = vulkanDevice->queueFamilyIndices.compute;
|
||||
imageMemoryBarrier.dstQueueFamilyIndex = vulkanDevice->queueFamilyIndices.graphics;
|
||||
vkCmdPipelineBarrier(
|
||||
drawCmdBuffers[i],
|
||||
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
|
||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
|
||||
VK_FLAGS_NONE,
|
||||
0, nullptr,
|
||||
0, nullptr,
|
||||
1, &imageMemoryBarrier);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Combined barrier on single queue family
|
||||
imageMemoryBarrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
|
||||
imageMemoryBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
|
||||
imageMemoryBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
imageMemoryBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
vkCmdPipelineBarrier(
|
||||
drawCmdBuffers[i],
|
||||
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
|
||||
VK_FLAGS_NONE,
|
||||
0, nullptr,
|
||||
0, nullptr,
|
||||
1, &imageMemoryBarrier);
|
||||
}
|
||||
|
||||
vkCmdBeginRenderPass(drawCmdBuffers[i], &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
|
||||
|
||||
|
|
@ -252,6 +277,23 @@ public:
|
|||
|
||||
vkCmdEndRenderPass(drawCmdBuffers[i]);
|
||||
|
||||
if (vulkanDevice->queueFamilyIndices.graphics != vulkanDevice->queueFamilyIndices.compute)
|
||||
{
|
||||
// Release barrier from graphics queue
|
||||
imageMemoryBarrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
|
||||
imageMemoryBarrier.dstAccessMask = 0;
|
||||
imageMemoryBarrier.srcQueueFamilyIndex = vulkanDevice->queueFamilyIndices.graphics;
|
||||
imageMemoryBarrier.dstQueueFamilyIndex = vulkanDevice->queueFamilyIndices.compute;
|
||||
vkCmdPipelineBarrier(
|
||||
drawCmdBuffers[i],
|
||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
|
||||
VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
|
||||
VK_FLAGS_NONE,
|
||||
0, nullptr,
|
||||
0, nullptr,
|
||||
1, &imageMemoryBarrier);
|
||||
}
|
||||
|
||||
VK_CHECK_RESULT(vkEndCommandBuffer(drawCmdBuffers[i]));
|
||||
}
|
||||
|
||||
|
|
@ -262,12 +304,52 @@ public:
|
|||
VkCommandBufferBeginInfo cmdBufInfo = vks::initializers::commandBufferBeginInfo();
|
||||
|
||||
VK_CHECK_RESULT(vkBeginCommandBuffer(compute.commandBuffer, &cmdBufInfo));
|
||||
|
||||
VkImageMemoryBarrier imageMemoryBarrier = {};
|
||||
imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
|
||||
imageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
|
||||
imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
|
||||
imageMemoryBarrier.image = textureComputeTarget.image;
|
||||
imageMemoryBarrier.subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 };
|
||||
if (vulkanDevice->queueFamilyIndices.graphics != vulkanDevice->queueFamilyIndices.compute)
|
||||
{
|
||||
// Acquire barrier for compute queue
|
||||
imageMemoryBarrier.srcAccessMask = 0;
|
||||
imageMemoryBarrier.dstAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
|
||||
imageMemoryBarrier.srcQueueFamilyIndex = vulkanDevice->queueFamilyIndices.graphics;
|
||||
imageMemoryBarrier.dstQueueFamilyIndex = vulkanDevice->queueFamilyIndices.compute;
|
||||
vkCmdPipelineBarrier(
|
||||
compute.commandBuffer,
|
||||
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
|
||||
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||
VK_FLAGS_NONE,
|
||||
0, nullptr,
|
||||
0, nullptr,
|
||||
1, &imageMemoryBarrier);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
vkCmdDispatch(compute.commandBuffer, textureComputeTarget.width / 16, textureComputeTarget.height / 16, 1);
|
||||
|
||||
if (vulkanDevice->queueFamilyIndices.graphics != vulkanDevice->queueFamilyIndices.compute)
|
||||
{
|
||||
// Release barrier from compute queue
|
||||
imageMemoryBarrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
|
||||
imageMemoryBarrier.dstAccessMask = 0;
|
||||
imageMemoryBarrier.srcQueueFamilyIndex = vulkanDevice->queueFamilyIndices.compute;
|
||||
imageMemoryBarrier.dstQueueFamilyIndex = vulkanDevice->queueFamilyIndices.graphics;
|
||||
vkCmdPipelineBarrier(
|
||||
compute.commandBuffer,
|
||||
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||
VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
|
||||
VK_FLAGS_NONE,
|
||||
0, nullptr,
|
||||
0, nullptr,
|
||||
1, &imageMemoryBarrier);
|
||||
}
|
||||
|
||||
vkEndCommandBuffer(compute.commandBuffer);
|
||||
}
|
||||
|
||||
|
|
@ -361,6 +443,30 @@ public:
|
|||
copyCmd = vulkanDevice->createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, true);
|
||||
copyRegion.size = storageBufferSize;
|
||||
vkCmdCopyBuffer(copyCmd, stagingBuffer.buffer, compute.storageBuffers.planes.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)
|
||||
{
|
||||
VkImageMemoryBarrier imageMemoryBarrier = {};
|
||||
imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
|
||||
imageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
|
||||
imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
|
||||
imageMemoryBarrier.image = textureComputeTarget.image;
|
||||
imageMemoryBarrier.subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 };
|
||||
imageMemoryBarrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
|
||||
imageMemoryBarrier.dstAccessMask = 0;
|
||||
imageMemoryBarrier.srcQueueFamilyIndex = vulkanDevice->queueFamilyIndices.graphics;
|
||||
imageMemoryBarrier.dstQueueFamilyIndex = vulkanDevice->queueFamilyIndices.compute;
|
||||
vkCmdPipelineBarrier(
|
||||
copyCmd,
|
||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
|
||||
VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
|
||||
VK_FLAGS_NONE,
|
||||
0, nullptr,
|
||||
0, nullptr,
|
||||
1, &imageMemoryBarrier);
|
||||
}
|
||||
vulkanDevice->flushCommandBuffer(copyCmd, queue, true);
|
||||
|
||||
stagingBuffer.destroy();
|
||||
|
|
@ -689,9 +795,9 @@ public:
|
|||
void prepare()
|
||||
{
|
||||
VulkanExampleBase::prepare();
|
||||
prepareTextureTarget(&textureComputeTarget, TEX_DIM, TEX_DIM, VK_FORMAT_R8G8B8A8_UNORM);
|
||||
prepareStorageBuffers();
|
||||
prepareUniformBuffers();
|
||||
prepareTextureTarget(&textureComputeTarget, TEX_DIM, TEX_DIM, VK_FORMAT_R8G8B8A8_UNORM);
|
||||
setupDescriptorSetLayout();
|
||||
preparePipelines();
|
||||
setupDescriptorPool();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue