Fix submit wait stages, support same family for graphics & compute

This commit is contained in:
Brad Davis 2020-01-03 09:25:24 -08:00
parent 055d90ea30
commit 19f80fe423

View file

@ -32,6 +32,7 @@ public:
uint32_t readSet = 0; uint32_t readSet = 0;
uint32_t indexCount; uint32_t indexCount;
bool simulateWind = false; bool simulateWind = false;
bool specializedComputeQueue = false;
vks::Texture2D textureCloth; vks::Texture2D textureCloth;
@ -157,25 +158,27 @@ public:
void addGraphicsToComputeBarriers(VkCommandBuffer commandBuffer) void addGraphicsToComputeBarriers(VkCommandBuffer commandBuffer)
{ {
VkBufferMemoryBarrier bufferBarrier = vks::initializers::bufferMemoryBarrier(); if (specializedComputeQueue) {
bufferBarrier.srcAccessMask = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT; VkBufferMemoryBarrier bufferBarrier = vks::initializers::bufferMemoryBarrier();
bufferBarrier.dstAccessMask = VK_ACCESS_SHADER_WRITE_BIT; bufferBarrier.srcAccessMask = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;
bufferBarrier.srcQueueFamilyIndex = vulkanDevice->queueFamilyIndices.graphics; bufferBarrier.dstAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
bufferBarrier.dstQueueFamilyIndex = vulkanDevice->queueFamilyIndices.compute; bufferBarrier.srcQueueFamilyIndex = vulkanDevice->queueFamilyIndices.graphics;
bufferBarrier.size = VK_WHOLE_SIZE; bufferBarrier.dstQueueFamilyIndex = vulkanDevice->queueFamilyIndices.compute;
bufferBarrier.size = VK_WHOLE_SIZE;
std::vector<VkBufferMemoryBarrier> bufferBarriers; std::vector<VkBufferMemoryBarrier> bufferBarriers;
bufferBarrier.buffer = compute.storageBuffers.input.buffer; bufferBarrier.buffer = compute.storageBuffers.input.buffer;
bufferBarriers.push_back(bufferBarrier); bufferBarriers.push_back(bufferBarrier);
bufferBarrier.buffer = compute.storageBuffers.output.buffer; bufferBarrier.buffer = compute.storageBuffers.output.buffer;
bufferBarriers.push_back(bufferBarrier); bufferBarriers.push_back(bufferBarrier);
vkCmdPipelineBarrier(commandBuffer, vkCmdPipelineBarrier(commandBuffer,
VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT,
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
VK_FLAGS_NONE, VK_FLAGS_NONE,
0, nullptr, 0, nullptr,
static_cast<uint32_t>(bufferBarriers.size()), bufferBarriers.data(), static_cast<uint32_t>(bufferBarriers.size()), bufferBarriers.data(),
0, nullptr); 0, nullptr);
}
} }
void addComputeToComputeBarriers(VkCommandBuffer commandBuffer) void addComputeToComputeBarriers(VkCommandBuffer commandBuffer)
@ -203,25 +206,27 @@ public:
void addComputeToGraphicsBarriers(VkCommandBuffer commandBuffer) void addComputeToGraphicsBarriers(VkCommandBuffer commandBuffer)
{ {
VkBufferMemoryBarrier bufferBarrier = vks::initializers::bufferMemoryBarrier(); if (specializedComputeQueue) {
bufferBarrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT; VkBufferMemoryBarrier bufferBarrier = vks::initializers::bufferMemoryBarrier();
bufferBarrier.dstAccessMask = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT; bufferBarrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
bufferBarrier.srcQueueFamilyIndex = vulkanDevice->queueFamilyIndices.compute; bufferBarrier.dstAccessMask = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;
bufferBarrier.dstQueueFamilyIndex = vulkanDevice->queueFamilyIndices.graphics; bufferBarrier.srcQueueFamilyIndex = vulkanDevice->queueFamilyIndices.compute;
bufferBarrier.size = VK_WHOLE_SIZE; bufferBarrier.dstQueueFamilyIndex = vulkanDevice->queueFamilyIndices.graphics;
std::vector<VkBufferMemoryBarrier> bufferBarriers; bufferBarrier.size = VK_WHOLE_SIZE;
bufferBarrier.buffer = compute.storageBuffers.input.buffer; std::vector<VkBufferMemoryBarrier> bufferBarriers;
bufferBarriers.push_back(bufferBarrier); bufferBarrier.buffer = compute.storageBuffers.input.buffer;
bufferBarrier.buffer = compute.storageBuffers.output.buffer; bufferBarriers.push_back(bufferBarrier);
bufferBarriers.push_back(bufferBarrier); bufferBarrier.buffer = compute.storageBuffers.output.buffer;
vkCmdPipelineBarrier( bufferBarriers.push_back(bufferBarrier);
commandBuffer, vkCmdPipelineBarrier(
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, commandBuffer,
VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
VK_FLAGS_NONE, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT,
0, nullptr, VK_FLAGS_NONE,
static_cast<uint32_t>(bufferBarriers.size()), bufferBarriers.data(), 0, nullptr,
0, nullptr); static_cast<uint32_t>(bufferBarriers.size()), bufferBarriers.data(),
0, nullptr);
}
} }
void buildCommandBuffers() void buildCommandBuffers()
@ -740,7 +745,7 @@ public:
static bool firstDraw = true; static bool firstDraw = true;
VkSubmitInfo computeSubmitInfo = vks::initializers::submitInfo(); VkSubmitInfo computeSubmitInfo = vks::initializers::submitInfo();
// FIXME find a better way to do this (without using fences, which is much slower) // FIXME find a better way to do this (without using fences, which is much slower)
VkPipelineStageFlags computeWaitDstStageMask = VK_PIPELINE_STAGE_VERTEX_INPUT_BIT; VkPipelineStageFlags computeWaitDstStageMask = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
if (!firstDraw) { if (!firstDraw) {
computeSubmitInfo.waitSemaphoreCount = 1; computeSubmitInfo.waitSemaphoreCount = 1;
computeSubmitInfo.pWaitSemaphores = &compute.semaphores.ready; computeSubmitInfo.pWaitSemaphores = &compute.semaphores.ready;
@ -759,7 +764,7 @@ public:
VulkanExampleBase::prepareFrame(); VulkanExampleBase::prepareFrame();
VkPipelineStageFlags waitDstStageMask[2] = { VkPipelineStageFlags waitDstStageMask[2] = {
submitPipelineStages, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT submitPipelineStages, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT
}; };
VkSemaphore waitSemaphores[2] = { VkSemaphore waitSemaphores[2] = {
semaphores.presentComplete, compute.semaphores.complete semaphores.presentComplete, compute.semaphores.complete
@ -783,6 +788,12 @@ public:
void prepare() void prepare()
{ {
VulkanExampleBase::prepare(); VulkanExampleBase::prepare();
// Make sure the code works properly both with different queues families for graphics and compute and the same queue family
#ifdef DEBUG_FORCE_SHARED_GRAPHICS_COMPUTE_QUEUE
vulkanDevice->queueFamilyIndices.compute = vulkanDevice->queueFamilyIndices.graphics;
#endif
// Check whether the compute queue family is distinct from the graphics queue family
specializedComputeQueue = vulkanDevice->queueFamilyIndices.graphics != vulkanDevice->queueFamilyIndices.compute;
loadAssets(); loadAssets();
prepareStorageBuffers(); prepareStorageBuffers();
prepareUniformBuffers(); prepareUniformBuffers();