Код: Выделить всё
for(int i = 0; i < engineModLoader.instanceNumber; i++)
{
engineRenderer.DispatchCompute(phoenixMesh.totalMeshlets.size(), selectedMeshlet,
engineModLoader.instancesData[i].instancePos);
}
До сих пор я пытался синхронизировать свой вычислительный шейдер таким способом, но получал неправильные данные:
Код: Выделить всё
void Renderer::DispatchCompute(int numberOfElements, std::vector
& selectedMeshlet,
const glm::vec3& instancePos)
{
VkSubmitInfo computeSubmitInfo{};
computeSubmitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
vkWaitForFences(engineDevice.logicalDevice, 1, &computeInFlightFences[currentComputeFrame], VK_TRUE, UINT64_MAX);
engineTransform.ubo.instancePos = instancePos;
UpdateUniformBuffer(currentComputeFrame);
vkResetFences(engineDevice.logicalDevice, 1, &computeInFlightFences[currentComputeFrame]);
vkResetCommandBuffer(computeCommandBuffers[currentComputeFrame], 0);
RecordComputeBuffer(numberOfElements, computeCommandBuffers[currentComputeFrame]);
computeSubmitInfo.commandBufferCount = 1;
computeSubmitInfo.pCommandBuffers = &computeCommandBuffers[currentComputeFrame];
computeSubmitInfo.signalSemaphoreCount = 1;
computeSubmitInfo.pSignalSemaphores = &computeSemaphores[currentComputeFrame];
if (vkQueueSubmit(engineDevice.computeQueue, 1, &computeSubmitInfo, computeInFlightFences[currentComputeFrame]) != VK_SUCCESS)
{
throw std::runtime_error("failed to submit compute command buffer!");
}
VkDeviceSize bufferSize = sizeof(Phoenix::DataToCompute) * numberOfElements;
VkBuffer stagingBuffer;
VkDeviceMemory stagingBufferMemory;
CreateBuffer(bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
stagingBuffer, stagingBufferMemory);
CopyBuffer(SSBOBuffers[currentComputeFrame], stagingBuffer, bufferSize,
&computeSemaphores[currentComputeFrame]);
void* bufferData = nullptr;
vkMapMemory(engineDevice.logicalDevice, stagingBufferMemory, 0, bufferSize, 0, &bufferData);
memcpy(selectedMeshlet.data(), bufferData, bufferSize);
vkUnmapMemory(engineDevice.logicalDevice, stagingBufferMemory);
currentComputeFrame = (currentComputeFrame + 1) % MAX_FRAMES_IN_FLIGHT;
vkDestroyBuffer(engineDevice.logicalDevice, stagingBuffer, nullptr);
vkFreeMemory(engineDevice.logicalDevice, stagingBufferMemory, nullptr);
}
void Renderer::RecordComputeBuffer(int numberOfElements, VkCommandBuffer commandBuffer)
{
VkCommandBufferBeginInfo beginInfo{};
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
if (vkBeginCommandBuffer(commandBuffer, &beginInfo) != VK_SUCCESS)
{
throw std::runtime_error("failed to begin recording command buffer!");
}
VkDeviceSize ssboSize = sizeof(Phoenix::DataToCompute) * numberOfElements;
vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, enginePipeline.computePipeline);
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, enginePipeline.computePipelineLayout, 0, 1,
&descriptorSets[currentComputeFrame], 0, 0);
vkCmdDispatch(commandBuffer, numberOfElements / 32, 1, 1);
if (vkEndCommandBuffer(commandBuffer) != VK_SUCCESS)
{
throw std::runtime_error("failed to record command buffer!");
}
}
Подробнее здесь: https://stackoverflow.com/questions/787 ... ronization