Ошибка при обновлении VertexBuffer с помощью vulkan - PullRequest
0 голосов
/ 29 марта 2020

В настоящее время я работаю над Trail Renderer в пользовательском движке, используя Vulkan. Я застреваю, когда пытаюсь обновить буфер вершин из me sh, который я использую для следа. Я использую промежуточный буфер.

Ошибка обновления информации:
Эти промежуточные буферы, кажется, являются источником ошибки, ошибка проверки возвращает меня "Невозможно освободить VkBuffer 0x8838a700000004fe [], который используется с помощью буфера команд "когда я пытаюсь визуализировать me sh"

Для конвейера "update" я проверяю, что это не так, пока выполняется проход graphi c.

Вот код для обновления буфера вершин и индексного буфера

template <typename T>
void Initialize(const std::vector<T>& vertices, const std::vector<uint32_t>& indices = {})
{
    static_assert(std::is_base_of<VertexMesh, T>::value, "T must derive from MeshVertex");

    if (!vertices.empty()) {
        std::vector<char> verticesData;
        verticesData.resize(sizeof(T) * vertices.size());
        std::memcpy(&verticesData[0], &vertices[0], sizeof(T) * vertices.size());

        const auto vertexStaging = Buffer(
                verticesData.size(),
                VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
                VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
                verticesData);

        //Optional 
        vertexBuffer_.emplace(
            sizeof(T) * vertices.
            size(),
            VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
            VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);

        vertexCount_ = static_cast<uint32_t>(vertices.size());

        auto commandBuffer = CommandBuffer();

        VkBufferCopy copyRegion = {};
        copyRegion.size = sizeof(T) * vertices.size();

        vkCmdCopyBuffer(
            commandBuffer,
            vertexStaging.GetBuffer(),
            vertexBuffer_->GetBuffer(),
            1,
            &copyRegion);

        commandBuffer.SubmitIdle();
    }

    if (!indices.empty()) {
        const auto indexStaging = Buffer(
            sizeof(uint32_t) * indices.size(),
            VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
            VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
            indices);

        indexBuffer_.emplace(
            sizeof(uint32_t) * indices.
            size(),
            VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
            VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);

        indexCount_ = static_cast<uint32_t>(indices.size());

        auto commandBuffer = CommandBuffer();

        VkBufferCopy copyRegion = {};
        copyRegion.size = sizeof(uint32_t) * indices.size();
        vkCmdCopyBuffer(
           commandBuffer,
           indexStaging.GetBuffer(),
           indexBuffer_->GetBuffer(),
           1,
           &copyRegion);

       commandBuffer.SubmitIdle();
   }
}

Эта же функция работает при загрузке при загрузке .obj или примитива

Конструктор для моего буфера команд: :

CommandBuffer(
    bool begin = true,
    VkQueueFlagBits queueType = VK_QUEUE_GRAPHICS_BIT,
    VkCommandBufferLevel bufferLevel = VK_COMMAND_BUFFER_LEVEL_PRIMARY);

И функция SubmitIdle:

void CommandBuffer::SubmitIdle()
{
    const auto queueSelected = GetQueue();

    if (running_) { End(); }

    VkSubmitInfo submitInfo = {};
    submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
    submitInfo.commandBufferCount = 1;
    submitInfo.pCommandBuffers = &commandBuffer_;

    //Code upadeted from Nicol Bolas tips
    CheckVk(vkQueueSubmit(queueSelected, 1, &submitInfo, nullptr));
    CheckVk(vkQueueWaitIdle(queueSelected));
}

Надеюсь, у вас есть все, чтобы видеть вещи более ясно, чем я!

...