Reworked compute shader n-body synchronization
This commit is contained in:
parent
958f0cb65e
commit
0e9ab19fad
1 changed files with 10 additions and 49 deletions
|
|
@ -184,7 +184,7 @@ public:
|
|||
drawUI(drawCmdBuffers[i]);
|
||||
|
||||
vkCmdEndRenderPass(drawCmdBuffers[i]);
|
||||
|
||||
|
||||
VK_CHECK_RESULT(vkEndCommandBuffer(drawCmdBuffers[i]));
|
||||
}
|
||||
|
||||
|
|
@ -196,41 +196,20 @@ public:
|
|||
|
||||
VK_CHECK_RESULT(vkBeginCommandBuffer(compute.commandBuffer, &cmdBufInfo));
|
||||
|
||||
// Compute particle movement
|
||||
// First pass: Calculate particle movement
|
||||
// -------------------------------------------------------------------------------------------------------
|
||||
vkCmdBindPipeline(compute.commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, compute.pipelineCalculate);
|
||||
vkCmdBindDescriptorSets(compute.commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, compute.pipelineLayout, 0, 1, &compute.descriptorSet, 0, 0);
|
||||
vkCmdDispatch(compute.commandBuffer, numParticles / 256, 1, 1);
|
||||
|
||||
// Add memory barrier to ensure that the (graphics) vertex shader has fetched attributes before compute starts to write to the buffer
|
||||
// Add memory barrier to ensure that the computer shader has finished writing to the buffer
|
||||
VkBufferMemoryBarrier bufferBarrier = vks::initializers::bufferMemoryBarrier();
|
||||
bufferBarrier.buffer = compute.storageBuffer.buffer;
|
||||
bufferBarrier.size = compute.storageBuffer.descriptor.range;
|
||||
bufferBarrier.srcAccessMask = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT; // Vertex shader invocations have finished reading from the buffer
|
||||
bufferBarrier.dstAccessMask = VK_ACCESS_SHADER_WRITE_BIT; // Compute shader wants to write to the buffer
|
||||
bufferBarrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
|
||||
bufferBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
|
||||
// Transfer ownership if compute and graphics queue familiy indices differ
|
||||
bufferBarrier.srcQueueFamilyIndex = vulkanDevice->queueFamilyIndices.graphics;
|
||||
bufferBarrier.dstQueueFamilyIndex = vulkanDevice->queueFamilyIndices.compute;
|
||||
|
||||
vkCmdPipelineBarrier(
|
||||
compute.commandBuffer,
|
||||
VK_PIPELINE_STAGE_VERTEX_SHADER_BIT,
|
||||
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||
VK_FLAGS_NONE,
|
||||
0, nullptr,
|
||||
1, &bufferBarrier,
|
||||
0, nullptr);
|
||||
|
||||
vkCmdBindPipeline(compute.commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, compute.pipelineCalculate);
|
||||
vkCmdBindDescriptorSets(compute.commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, compute.pipelineLayout, 0, 1, &compute.descriptorSet, 0, 0);
|
||||
|
||||
// First pass: Calculate particle movement
|
||||
// -------------------------------------------------------------------------------------------------------
|
||||
vkCmdDispatch(compute.commandBuffer, numParticles / 256, 1, 1);
|
||||
|
||||
// Add memory barrier to ensure that compute shader has finished writing to the buffer
|
||||
bufferBarrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT; // Compute shader has finished writes to the buffer
|
||||
bufferBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
|
||||
bufferBarrier.buffer = compute.storageBuffer.buffer;
|
||||
bufferBarrier.size = compute.storageBuffer.descriptor.range;
|
||||
// No ownership transfer necessary
|
||||
bufferBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
bufferBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
bufferBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
|
||||
vkCmdPipelineBarrier(
|
||||
|
|
@ -246,24 +225,6 @@ public:
|
|||
// -------------------------------------------------------------------------------------------------------
|
||||
vkCmdBindPipeline(compute.commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, compute.pipelineIntegrate);
|
||||
vkCmdDispatch(compute.commandBuffer, numParticles / 256, 1, 1);
|
||||
// Add memory barrier to ensure that compute shader has finished writing to the buffer
|
||||
// Without this the (rendering) vertex shader may display incomplete results (partial data from last frame)
|
||||
bufferBarrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT; // Compute shader has finished writes to the buffer
|
||||
bufferBarrier.dstAccessMask = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT; // Vertex shader invocations want to read from the buffer
|
||||
bufferBarrier.buffer = compute.storageBuffer.buffer;
|
||||
bufferBarrier.size = compute.storageBuffer.descriptor.range;
|
||||
// Transfer ownership if compute and graphics queue familiy indices differ
|
||||
bufferBarrier.srcQueueFamilyIndex = vulkanDevice->queueFamilyIndices.compute;
|
||||
bufferBarrier.dstQueueFamilyIndex = vulkanDevice->queueFamilyIndices.graphics;
|
||||
|
||||
vkCmdPipelineBarrier(
|
||||
compute.commandBuffer,
|
||||
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||
VK_PIPELINE_STAGE_VERTEX_SHADER_BIT,
|
||||
VK_FLAGS_NONE,
|
||||
0, nullptr,
|
||||
1, &bufferBarrier,
|
||||
0, nullptr);
|
||||
|
||||
vkEndCommandBuffer(compute.commandBuffer);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue