Синхронизация вычислительных шейдеров VulkanC++

Программы на C++. Форум разработчиков
Anonymous
Синхронизация вычислительных шейдеров Vulkan

Сообщение Anonymous »

В своем приложении я использую вычислительный шейдер для быстрой обработки данных. Я отправляю вычислительный шейдер для каждого экземпляра моей модели. Например, у меня есть 30 экземпляров, я отправляю вычислительный шейдер 30 раз.

Код: Выделить всё

for(int i = 0; i < engineModLoader.instanceNumber; i++)
{
engineRenderer.DispatchCompute(phoenixMesh.totalMeshlets.size(), selectedMeshlet,
engineModLoader.instancesData[i].instancePos);
}
Я использую результат вычислительного шейдера для заполнения буфера глобального индекса, полезного для рисования экземпляров. Таким образом, все отправленные вычислительные шейдеры должны быть завершены до вызова DrawFrame(), который визуализирует экземпляры. Как можно дождаться завершения работы вычислительного шейдера на процессоре?
До сих пор я пытался синхронизировать свой вычислительный шейдер таким способом, но получал неправильные данные:

Код: Выделить всё

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

Вернуться в «C++»