Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/161.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ Vulkan';s传输队列系列功能和视频卡支持:条件检查是否准确?_C++_Specifications_Vulkan - Fatal编程技术网

C++ Vulkan';s传输队列系列功能和视频卡支持:条件检查是否准确?

C++ Vulkan';s传输队列系列功能和视频卡支持:条件检查是否准确?,c++,specifications,vulkan,C++,Specifications,Vulkan,下面是Joshua Shucker的文章。我现在正在看他的第14个视频,他正在为顶点缓冲区创建一个辅助队列族。本文重点介绍顶点缓冲区的暂存过程。我的代码与他的视频中的代码相匹配,除了我添加用于测试的cout语句的代码。以下是队列族的功能和结构: struct QueueFamilyIndices { int graphicsFamily = -1; int transferFamily = -1; bool isComplete() { return (

下面是Joshua Shucker的文章。我现在正在看他的第14个视频,他正在为顶点缓冲区创建一个辅助队列族。本文重点介绍顶点缓冲区的暂存过程。我的代码与他的视频中的代码相匹配,除了我添加用于测试的
cout语句的代码。以下是队列族的功能和结构:

struct QueueFamilyIndices {
    int graphicsFamily = -1;
    int transferFamily = -1;

    bool isComplete() {
        return (graphicsFamily >= 0 && transferFamily >= 0);
    }
};

QueueFamilyIndices FindQueueFamilies( const VkPhysicalDevice* device, const VkSurfaceKHR* surface ) {
    QueueFamilyIndices indices;
    uint32_t queueFamilyCount = 0;
    vkGetPhysicalDeviceQueueFamilyProperties( *device, &queueFamilyCount, nullptr );
    std::vector<VkQueueFamilyProperties> queueFamilies( queueFamilyCount );
    vkGetPhysicalDeviceQueueFamilyProperties( *device, &queueFamilyCount, queueFamilies.data() );

    int i = 0;
    for( const auto &queueFamily : queueFamilies ) {
        VkBool32 presentSupport = false;
        vkGetPhysicalDeviceSurfaceSupportKHR( *device, i, *surface, &presentSupport );

        if( queueFamily.queueCount > 0 && (queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT) && presentSupport ) {
            indices.graphicsFamily = i;
        }

        if( queueFamily.queueCount > 0 && (queueFamily.queueFlags & VK_QUEUE_TRANSFER_BIT) && 
            !(queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT) && presentSupport ) {
            indices.transferFamily = i;
        }

        if( indices.isComplete() ) {
            break;
        }
        i++;
    }

    if( indices.graphicsFamily >= 0 && indices.transferFamily == -1 ) {
        std::cout << "Graphics family found, transfer family missing: using graphics family" << std::endl;
        indices.transferFamily = indices.graphicsFamily;
    }

    return indices;
}
现在,根据这些规范,当我通过调试器时,这些规范与我的结构向量中的值一致,我的结构被填充 以下各项的价值:

 queueFamilies[0].queueFlags = 15;
 queueFamilies[0].queueCount = 16;
 queueFamilies[0].timestampValidBits = 64;
 queueFamilies[0].minImageTransferGranularity = { width = 1, height = 1, depth = 1 };

 queueFamilies[1].queueFlags = 4;
 queueFamilies[1].queueCount = 1;
 queueFamilies[1].timestampValidBits = 64;
 queueFamilies[1].minImageTransferGranularity = { width = 1, height = 1, depth = 1 };
因此,在我看来,我的卡确实支持一个单独的
queueFamily
,特别是
transferFamily


基于我对这种支持的假设,并逐步使用这个函数,他有两个if语句来检查for循环中每个索引
queueFamily
对象的有效条件。if语句返回的正是它们应该返回的结果。我的代码编译和生成时没有任何错误或警告,当我没有通过调试器运行它时,它仍然会呈现三角形,并且它会以代码(0)退出。所以代码看起来很好。然而,我没有得到我至少预期的结果

我不确定他的代码中是否有他碰巧漏掉的bug,我是否误解了我的视频卡对Vulkan功能的支持,或者这可能是Vulkan API bug或NVidia驱动程序bug

但是,当我单步执行此函数以找出
index.transferFamily
变量未设置为
I
的原因时;我注意到,在循环的第二次迭代中,它与
transferFamilyQueue
的存在、其参数值或标志无关。导致此if语句返回false的原因是
presentSupport
变量,因为在第二次调用时它被设置为
0
,这与上面的数据表匹配。因此,输出与预期一致

我的问题是:第二个if语句中的条件检查是否存在实际的实现问题


这就是我被卡住的地方,因为我有点困惑,因为我们正在检查是否有可用的
transferQueueFamily
,如果有,则使用它创建并使用
stagingBuffer
将内容从CPU复制到
顶点缓冲区的GPU
。从我所看到的情况来看,我的卡似乎有此
transferFamily
,但没有此家族的
supportPresent
。但是,想起来,;如果您使用的是
transferFamily
-
transferQueue
您不想直接
显示它,因为您只需要将数据从CPU上的临时
vertexBuffer
复制到GPU上使用的
vertexBuffer
。所以我想知道这个if语句中的最终检查是否正确。如果我对Vulkan如何工作的假设不正确,请毫不犹豫地纠正我,因为这是我第一次尝试让
Vulkan
渲染应用程序工作

在搜索特定于换乘的队列时,没有很好的理由检查
presentSupport
。这可能是某个地方的复制粘贴错误。通常,您不关心图形队列以外的任何东西是否支持表示


确实希望使用未设置图形位的传输队列,因为这样的队列可能对应于专用传输硬件,不会影响在图形队列上完成的工作的性能

在搜索特定于换乘的队列时,没有很好的理由检查
presentSupport
。这可能是某个地方的复制粘贴错误。通常,您不关心图形队列以外的任何东西是否支持表示


确实希望使用未设置图形位的传输队列,因为这样的队列可能对应于专用传输硬件,不会影响在图形队列上完成的工作的性能

没有Vulkan API或NVidia驱动程序错误。就在你的报告单上:

支持当前0

例如,AMD似乎确实支持
VK\u QUEUE\u TRANSFER\u BIT
队列系列上的显示,但它是纯可选的(31.4.查询WSI支持):

并非所有物理设备都将包括WSI支持。在物理设备中,并非所有队列族都支持表示


没有Vulkan API或NVidia驱动程序错误。就在你的报告单上:

支持当前0

例如,AMD似乎确实支持
VK\u QUEUE\u TRANSFER\u BIT
队列系列上的显示,但它是纯可选的(31.4.查询WSI支持):

并非所有物理设备都将包括WSI支持。在物理设备中,并非所有队列族都支持表示


在阅读了这里的一些好的答案并在我这方面做了更多的测试之后,我认为我已经找到了应用程序代码设计的适当解决方案。此函数在整个应用程序中被其他函数调用大约4或5次。当初始化
Vulkan
时调用,当评估设备是否适合选择可用的最佳设备时再次调用,在创建逻辑设备时也会调用,等等

所有这些初始调用通常只需要
queueFamily的
计数和/或索引值,以确保具有
queueFamily
的适当图形设备可用于图形处理和渲染<
 queueFamilies[0].queueFlags = 15;
 queueFamilies[0].queueCount = 16;
 queueFamilies[0].timestampValidBits = 64;
 queueFamilies[0].minImageTransferGranularity = { width = 1, height = 1, depth = 1 };

 queueFamilies[1].queueFlags = 4;
 queueFamilies[1].queueCount = 1;
 queueFamilies[1].timestampValidBits = 64;
 queueFamilies[1].minImageTransferGranularity = { width = 1, height = 1, depth = 1 };
QueueFamilyIndices FindQueueFamilies( const VkPhysicalDevice* device, const VkSurfaceKHR* surface ) {
    QueueFamilyIndices indices;
    uint32_t queueFamilyCount = 0;
    vkGetPhysicalDeviceQueueFamilyProperties( *device, &queueFamilyCount, nullptr );
    std::vector<VkQueueFamilyProperties> queueFamilies( queueFamilyCount );
    vkGetPhysicalDeviceQueueFamilyProperties( *device, &queueFamilyCount, queueFamilies.data() );

    int i = 0;
    for( const auto &queueFamily : queueFamilies ) {
        VkBool32 presentSupport = false;
        vkGetPhysicalDeviceSurfaceSupportKHR( *device, i, *surface, &presentSupport );

        if( queueFamily.queueCount > 0 && (queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT) && presentSupport ) {
            indices.graphicsFamily = i;
        }

        if( queueFamily.queueCount > 0 && (queueFamily.queueFlags & VK_QUEUE_TRANSFER_BIT) && 
            !(queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT) /*&& presentSupport*/ ) {
            indices.transferFamily = i;
        }

        if( indices.isComplete() ) {
            break;
        }
        i++;
    }

    if( indices.graphicsFamily >= 0 && indices.transferFamily == -1 ) {
        std::cout << "Graphics family found, transfer family missing: using graphics family" << std::endl;
        indices.transferFamily = indices.graphicsFamily;
    }

    return indices;
}