Vulkan Cookbook 第一章 18 使用几何着色器,图形和计算队列创建逻辑设备

使用几何着色器,图形和计算队列创建逻辑设备

译者注:示例代码点击此处

在Vulkan中,当我们创建各种对象时,需要准备许多描述创建过程本身的不同结构体,但是它们也可能需要创建其他对象。逻辑设备也不例外:我们需要枚举物理设备,检查它们的属性和支持的队列族,并准备一个需要更多信息的VkDeviceCreateInfo结构。

为了组织这些操作,我们将提供一个示例,用于从支持几何着色器,图形和计算队列的可用物理设备之一创建逻辑设备。

怎么做...

1.准备名为logical_device的VkDevice类型变量。
2.准备两个VkQueue类型的变量,分别名为graphics_queue和compute_queue。
3.准备名为physical_devices的std::vector<VkPhysicalDevice>类型变量。
4.获取给定平台上可用的所有物理设备列表,并将其储存在physical_devices向量中(请参阅枚举可用的物理设备)。
5.对physical_devices向量中的每个物理设备:
    1.准备一个名为device_features的VkPhysicalDeviceFeatures类型变量。
    2.获取给定物理设备支持的功能列表,并将其储存在device_features变量中。
    3.检查device_features变量的geometryShader成员是否等于VK_TRUE(不为0)。如果是,则重置device_features变量的所有其他成员(将其值设置为零)译者注:因为我们不需要其他功能,只想使用geometryShader功能所以,设置device_features变量的所有其他功能为零,只留下geometryShader功能,如果不是,用一个物理设备重新开始。
    4.备两个uint32_t类型的变量,分别名为graphics_queue_family_index和compute_queue_family_index。
    5.获取支持图形和计算操作的队列族的索引。
    6.分别储存在graphics_queue_family_index和compute_queue_family_index变量中(参见选择具有期望能力的队列族的索引)。如果不支持这些操作中的任何一个,则搜索另一个物理设备。
    7.在requested_queues变量中储存graphics_queue_family_index变量和浮点向量,其值全为1.0f(译者注:这个向量是每个队列的优先级)。如果compute_queue_family_index变量的值不同于graphics_queue_family_index变量的值,则将另一个元素添加到requested_queues向量(译者注:可能一个族同时支持图形和计算操作,也可能被两个族分别独立支持),其中包括compute_queue_family_index变量和具有值全为1.0f的浮点向量。
    8.如果使用physical_device、requested_queues、device_features和logical_device变量创建逻辑设备(请参创建逻辑设备)操作失败,请使用其他物理设备重复上述操作。
    9.如果逻辑设备已成功创建,请加载设备级函数(请参阅加载设备级函数)。从graphics_queue_family_index族获取队列句柄并将其存储在graphics_queue变量中。 从compute_queue_family_index族获取队列并将其存储在compute_queue变量中。

这个怎么运作...

要开始创建逻辑设备的过程,我们需要获取给定计算机上可用的所有物理设备的句柄:

std::vector<VkPhysicalDevice> physical_devices; 
EnumerateAvailablePhysicalDevices( instance, physical_devices );

接下来,需要遍历所有可用的物理设备并获得他们的功能。 这将为我们提供有关给定物理设备是否支持几何着色器的信息:

for( auto & physical_device : physical_devices ) {
  VkPhysicalDeviceFeatures device_features;
  VkPhysicalDeviceProperties device_properties;
  GetTheFeaturesAndPropertiesOfAPhysicalDevice( physical_device, &device_features, device_properties );

  if( !device_features.geometryShader ) { 
    continue;
  } else {
    device_features = {}; 
    device_features.geometryShader = VK_TRUE;
  }

如果支持几何着色器,我们可以重置device_features所有其他成员。 我们将在逻辑设备创建期间提供此列表,但我们不希望启用任何其他功能。 在此示例中,几何着色器是我们想要使用的唯一附加功能。

接下来,我们需要检查给定的物理设备是否支持图形和计算操作的队列族。可能一个族同时支持图形和计算操作,也可能被两个族分别独立支持。如下获取这些队列族的索引:

uint32_t graphics_queue_family_index;
if( !SelectIndexOfQueueFamilyWithDesiredCapabilities( physical_device, VK_QUEUE_GRAPHICS_BIT, graphics_queue_family_index)
  continue; 
}

uint32_t compute_queue_family_index;
if( !SelectIndexOfQueueFamilyWithDesiredCapabilities( physical_device, VK_QUEUE_COMPUTE_BIT, graphics_queue_family_index)
  continue; 
}

然后,需要准备一个队列族列表,我们放入要请求的队列。还需要为每个族的每个队列分配优先级:

std::vector<QueueInfo> requested_queues = { { graphics_queue_family_index, { 1.0f } } }; 
if( graphics_queue_family_index != compute_queue_family_index ) {
  requested_queues.push_back( { compute_queue_family_index, { 1.0f } } ); 
}

如果图形和计算队列族具有相同的索引,则只请求一个队列族中的一个队列。如果它们是不同的,我们需要请求两个队列:一个来自图形族,一个来自计算族。
我们准备创建一个逻辑设备,提供准备好的数据。 成功后,我们可以加载设备级功能并获取所请求队列的句柄:

  if( !CreateLogicalDevice( physical_device, requested_queues, {}, &device_features, logical_device ) ) {
    continue;
  } else {
    if( !LoadDeviceLevelFunctions( logical_device, {} ) ) {
      return false; 
    }
    GetDeviceQueue( logical_device, graphics_queue_family_index, 0, graphics_queue ); 
    GetDeviceQueue( logical_device, compute_queue_family_index, 0, compute_queue ); 
    return true;
  } 
}
return false;

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值