【问题标题】:Vulkan-hpp: cant allocate command buffers with no exceptionsVulkan-hpp:无法毫无例外地分配命令缓冲区
【发布时间】:2021-04-02 20:16:53
【问题描述】:

首先,我用独特的句柄在 vulkan-hpp 中重写了 Vulkan 教程三角形。关闭程序时,我得到以下断言:Assertion: m_dispatch && m_owner 查看代码,我发现启用 VULKAN_HPP_NO_EXCEPTIONS 会修复它,但现在我收到此错误:

vk::UniqueHandle<:commandbuffer> &vk::UniqueHandle<:commandbuffer>::operator =(const vk::UniqueHandle<:commandbuffer ::dispatchloaderstatic> &)': 试图引用已删除的函数

这是我的代码:

std::tie(res, commandBuffers) = device->allocateCommandBuffersUnique(allocInfo);

正确的使用方法是什么?

device->allocateCommandBuffersUnique();

【问题讨论】:

  • 它是独一无二的对象。试试std::move。或auto cmdbuffs = device-&gt;allocateCommandBuffersUnique(allocInfo);。那应该是一个移动构造函数。
  • 你能更精确一点吗?因为我在执行 cmdbuffsf = device->allocateCommand 时遇到错误... 那么如何使用 std::move 呢?
  • ResultValue 是一个结构,而不是一个元组,所以我怀疑 std::tie 是否可以工作。
  • 好的,那么使用 std::move 的正确方法是什么?
  • 我避免使用vulkan.hpp 完全是为了这个废话。也许最好坚持samples,尽管他们使用有点不同的风格。无论如何,我认为移动构造应该可以工作:auto cmdbuffs = device-&gt;allocateCommandBuffersUnique(allocInfo);。移动分配可能需要明确提示:cmdbuffs = std::move(device-&gt;allocateCommandBuffersUnique(allocInfo) );。请注意,我没有测试过这些;那里需要一些实验,而且 Vulkan-Hpp 文档有点缺乏。

标签: c++ vulkan


【解决方案1】:

这似乎对我有用:

#include <iostream>
#include <utility>
#include <vulkan/vulkan.hpp>

int main() try{
    const auto instance = vk::createInstanceUnique( {} );
    const auto physical_devices = instance->enumeratePhysicalDevices();

    const uint32_t q_family = 0;
    const uint32_t q_count = 1;
    const float q_prio[] = {1.0f};
    const vk::DeviceQueueCreateInfo queue_info( vk::DeviceQueueCreateFlags(), q_family, q_count, q_prio );
    const vk::DeviceCreateInfo device_info( vk::DeviceCreateFlags(), 1, &queue_info );
    const auto device = physical_devices[0].createDeviceUnique( device_info );

    const vk::CommandPoolCreateInfo cmd_pool_info( vk::CommandPoolCreateFlags(), q_family );
    const auto command_pool = device->createCommandPoolUnique( cmd_pool_info );

    const vk::CommandBufferAllocateInfo alloc_info( command_pool.get(), vk::CommandBufferLevel::ePrimary, 1 );
    const auto cmd_buffers = device->allocateCommandBuffersUnique( alloc_info );
}
catch ( ... ){
    std::cout << "error\n";
}

VULKAN_HPP_NO_EXCEPTIONS 环境中,结果只是valueresultstructs。所以:

    const vk::CommandBufferAllocateInfo alloc_info( command_pool.value.get(), vk::CommandBufferLevel::ePrimary, 1 );
    const auto cmd_buffers = device.value->allocateCommandBuffersUnique( alloc_info );
    if( cmd_buffers.result != vk::Result::eSuccess ) panic();

如果您想使用std::tie,通常应该可以:

vk::Result res;
vk::UniqueInstance instance;
std::tie(res, instance) = vk::createInstanceUnique( {} ).asTuple();

但对于allocateCommandBuffersUnique(可能还有所有std::vector 类型)似乎存在一些问题。我已经继续并在Vulkan-Hpp repo 报告了它。

虽然如果您可以访问 C++17,那么 结构化绑定 似乎可以工作:

    const vk::CommandBufferAllocateInfo alloc_info( command_pool.value.get(), vk::CommandBufferLevel::ePrimary, 1 );
    auto [res, cmd_buffers] = device.value->allocateCommandBuffersUnique( alloc_info );
    if( res != vk::Result::eSuccess ) panic();

最近在 Vulkan-Hpp 有一些 style change。他们现在建议改用vulkan_raii.hpp,尽管它还没有出现在 Vulkan SDK 中。要使用Create*Unique 获取官方示例,您必须转到older version of the repo

【讨论】:

  • 我正在使用 LunarG 的 SDK 并且 vulkan_raii 还不是 disponible。我想我还是会等谢谢!
猜你喜欢
  • 2016-09-25
  • 1970-01-01
  • 1970-01-01
  • 2020-08-07
  • 1970-01-01
  • 2019-09-08
  • 2021-07-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多