代码之家  ›  专栏  ›  技术社区  ›  Francis Cugler

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

  •  0
  • Francis Cugler  · 技术社区  · 6 年前

    Vulkan Youtube video tutorial cout statement 其中我添加了测试。以下是队列系列的功能和结构:

    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;
    }
    

    vkGetPhysicalDeviceSurfaceSupportKHR(...) 正在被调用两次,因为在之后找到了两个队列系列 vkGetPhysicalDeviceQueueFamilyProperties(...) 已调用以填充 VkQueueFamilyProperties 结构。


    NVidia GeForce gtx 750 Ti Vulkan's Vulkan:Report 如果链接随时间而改变,这里是直接的信息:

    Queue family                          0     
    queueCount                            16 
    flags                                 GRAPHICS_BIT
                                          COMPUTE_BIT
                                          TRANSFER_BIT
                                          SPARSE_BINDING_BIT 
    timestampValidBits                    64 
    minImageTransferGranularity.width     1 
    minImageTransferGranularity.height    1
    minImageTransferGranularity.depth     1 
    supportsPresent                       1 
    
    Queue family                          1 
    queueCount                            1 
    flags                                 TRANSFER_BIT
    timestampValidBits                    64 
    minImageTransferGranularity.width     1 
    minImageTransferGranularity.height    1 
    minImageTransferGranularity.depth     1 
    supportsPresent                       0 
    

    现在根据这些规范,当我单步执行调试器时,结构向量中的值与这些规范一致 价值观:

     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循环中每个索引的有效条件

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

    然而,当我正在逐步通过这个函数来找出 indices.transferFamily i ;我注意到在循环的第二次迭代中,它与 transferFamilyQueue ,其参数值或标志。导致if语句返回false的原因是 presentSupport 0 在第二个调用中,它与上面的数据表匹配。所以产量和预期一样。

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

    transferQueueFamily 如果有的话,使用它来创建和使用 stagingBuffer vertex buffer(s) . 从我看来我的卡上有这个 转移家庭 supportPresent 为了这个家庭。但是,在考虑它时;如果您使用 转移家庭 - transferQueue 你不会想的 present vertexBuffer 在CPU上 顶点缓冲区 Vulkan 使应用程序正常工作。

    3 回复  |  直到 6 年前
        1
  •  2
  •   krOoze    6 年前

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

    supportsPresent 0

    E、 AMD似乎支持 VK_QUEUE_TRANSFER_BIT 排队族,但这完全是可选的(31.4款. 正在查询WSI支持):

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

        2
  •  1
  •   Jherico    6 年前

    presentSupport 搜索传输特定队列时。这可能是复制粘贴错误 在某处 . 通常情况下,除了图形队列之外,您不关心是否有其他东西支持表示。

        3
  •  0
  •   Francis Cugler    6 年前

    在阅读了这里的一些好的答案并做了更多的测试之后,我想我已经找到了一个适合应用程序代码设计的解决方案。这个函数在整个应用程序中被其他函数调用4到5次。它叫什么时候 Vulkan 正在初始化时,在评估设备是否适合选择可用的最佳设备时,将再次调用它;在创建逻辑设备时,也将调用它,以此类推。

    queueFamily's 计数和/或索引值,以确保使用 queueFamily

    graphicsQueue 我留下最后一个条件检查看看 presentSupport 当for循环迭代到下一个索引以检查 transferQueue 演示支持 一起。

    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;
    }
    

    indices.transferFamily 被设置为 i 在2号上 迭代;检查 indices.isComplete() staging buffers 正在被复制到 GPU CPU 对于 vertex buffer 物体。