[译]Vulkan教程(08)逻辑设备和队列

Introduction 入门

After selecting a physical device to use we need to set up a logical device to interface with it. The logical device creation process is similar to the instance creation process and describes the features we want to use. We also need to specify which queues to create now that we've queried which queue families are available. You can even create multiple logical devices from the same physical device if you have varying requirements.

在选择了要用的物理设备后,我们需要设置一个逻辑设备,用以与其交互。逻辑设备的创建过程与instance的创建过程相似,它描述了我们想使用的特性。既然我们已经查询了有哪些队列家族可用,我们也需要标明想创建哪些队列。如果你又多种需求,你还可以从同一物理设备创建多个逻辑设备。

Start by adding a new class member to store the logical device handle in.

开始,添加一个新成员,用于存储逻辑设备的句柄。

VkDevice device;

Next, add a createLogicalDevice function that is called from initVulkan.

下一步,添加createLogicalDevice 函数,在initVulkan中调用它。

 void initVulkan() {
createInstance();
setupDebugCallback();
pickPhysicalDevice();
createLogicalDevice();
} void createLogicalDevice() { }

Specifying the queues to be created 标明要创建的队列

The creation of a logical device involves specifying a bunch of details in structs again, of which the first one will be VkDeviceQueueCreateInfo. This structure describes the number of queues we want for a single queue family. Right now we're only interested in a queue with graphics capabilities.

创建逻辑设备,需要标明若干struct中的很多细节问题,其中第一个是VkDeviceQueueCreateInfo。这个struct描述了我们想从一个队列家族中获取的队列的数量。现在我们只对有图形功能的队列感兴趣。

 QueueFamilyIndices indices = findQueueFamilies(physicalDevice);

 VkDeviceQueueCreateInfo queueCreateInfo = {};
queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
queueCreateInfo.queueFamilyIndex = indices.graphicsFamily.value();
queueCreateInfo.queueCount = ;

The currently available drivers will only allow you to create a small number of queues for each queue family and you don't really need more than one. That's because you can create all of the command buffers on multiple threads and then submit them all at once on the main thread with a single low-overhead call.

目前可用driver只允许你从每个队列家族中创建少量的队列,不过你也不需要创建超过1个。这是因为你可以在多线程上创建所有的命令缓存,然后在主线程一次性提交它们,这只需一次低开销的调用。

Vulkan lets you assign priorities to queues to influence the scheduling of command buffer execution using floating point numbers between 0.0 and 1.0. This is required even if there is only a single queue:

Vulkan让你对队列赋予优先级(0.01.0的浮点数),以影响命令缓存的执行安排。即使只有1个队列,这也是必要的:

 float queuePriority = 1.0f;
queueCreateInfo.pQueuePriorities = &queuePriority;

Specifying used device features 标明要用的设备特性

The next information to specify is the set of device features that we'll be using. These are the features that we queried support for with vkGetPhysicalDeviceFeatures in the previous chapter, like geometry shaders. Right now we don't need anything special, so we can simply define it and leave everything to VK_FALSE. We'll come back to this structure once we're about to start doing more interesting things with Vulkan.

下一个要标明的信息,是我们要用到的设备特性。它们是我们在之前的章节用vkGetPhysicalDeviceFeatures 函数查询过的被支持的那些特性。现在我们不需要任何特别的东西,所以我们可以简单地定义它,让一切保持VK_FALSE。等我们要开始用Vulkan做更多有兴趣的事的时候,我们将回到这个struct来。

VkPhysicalDeviceFeatures deviceFeatures = {};

Creating the logical device 创建逻辑设备

With the previous two structures in place, we can start filling in the main VkDeviceCreateInfo structure.

将前2个struct准备好后,我们可以开始填入VkDeviceCreateInfo 结构体了。

 VkDeviceCreateInfo createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;

First add pointers to the queue creation info and device features structs:

首先添加到创建信息和设备特性struct的指针:

 createInfo.pQueueCreateInfos = &queueCreateInfo;
createInfo.queueCreateInfoCount = ; createInfo.pEnabledFeatures = &deviceFeatures;

The remainder of the information bears a resemblance to the VkInstanceCreateInfo struct and requires you to specify extensions and validation layers. The difference is that these are device specific this time.、

剩下的信息与VkInstanceCreateInfo 相似,要求你标明扩展和验证层。区别是,这次是针对特定设备的。

An example of a device specific extension is VK_KHR_swapchain, which allows you to present rendered images from that device to windows. It is possible that there are Vulkan devices in the system that lack this ability, for example because they only support compute operations. We will come back to this extension in the swap chain chapter.

针对特定设备的扩展的一个例子是VK_KHR_swapchain,它允许你将图像从设备呈现到窗口。系统中可能存在缺少这个功能的Vulkan设备,例如只支持计算操作的设备。我们将在交换链章节再谈论这个扩展。

Previous implementations of Vulkan made a distinction between instance and device specific validation layers, but this is no longer the case. That means that the enabledLayerCount and ppEnabledLayerNames fields of VkDeviceCreateInfo are ignored by up-to-date implementations. However, it is still a good idea to set them anyway to be compatible with older implementations:

早前的Vulkan实现区分了instance和设备相关的验证层,但现在已经不是这样了。这意味着,VkDeviceCreateInfo 的enabledLayerCount 和ppEnabledLayerNames 字段被新版的实现忽略了。但是,为与旧实现兼容,设置它们仍旧是个好主意:

 createInfo.enabledExtensionCount = ;

 if (enableValidationLayers) {
createInfo.enabledLayerCount = static_cast<uint32_t>(validationLayers.size());
createInfo.ppEnabledLayerNames = validationLayers.data();
} else {
createInfo.enabledLayerCount = ;
}

We won't need any device specific extensions for now.

现在我们不需要任何设备相关的扩展了。

That's it, we're now ready to instantiate the logical device with a call to the appropriately named vkCreateDevicefunction.

就这样,我们现在准备好初始化逻辑设备了(用vkCreateDevicefunction函数)。

 if (vkCreateDevice(physicalDevice, &createInfo, nullptr, &device) != VK_SUCCESS) {
throw std::runtime_error("failed to create logical device!");
}

The parameters are the physical device to interface with, the queue and usage info we just specified, the optional allocation callbacks pointer and a pointer to a variable to store the logical device handle in. Similarly to the instance creation function, this call can return errors based on enabling non-existent extensions or specifying the desired usage of unsupported features.

这些参数分别是,与之交互的物理设备,队列及其用法(我们已标明),可选的回调函数指针,保存逻辑设备句柄的变量的地址。与创建instance的函数相似,这个调用会由于缺失扩展或标明了不支持的特性而返回错误码。

The device should be destroyed in cleanup with the vkDestroyDevice function:

设备应当在cleanup 函数中用vkDestroyDevice 函数销毁:

 void cleanup() {
vkDestroyDevice(device, nullptr);
...
}

Logical devices don't interact directly with instances, which is why it's not included as a parameter.

逻辑设备不直接与instance交互,这就是为什么它没有被作为参数传入设备。

Retrieving queue handles 检索队列的柄

The queues are automatically created along with the logical device, but we don't have a handle to interface with them yet. First add a class member to store a handle to the graphics queue:

队列随着逻辑设备的创建而自动创建了,但是我们没有与之交互的句柄。首先添加一个成员,用以保存对图形队列的句柄:

VkQueue graphicsQueue;

Device queues are implicitly cleaned up when the device is destroyed, so we don't need to do anything in cleanup.

设备队列会在设备被销毁时自动地隐式地销毁,所以我们不需要在cleanup中做什么。

We can use the vkGetDeviceQueue function to retrieve queue handles for each queue family. The parameters are the logical device, queue family, queue index and a pointer to the variable to store the queue handle in. Because we're only creating a single queue from this family, we'll simply use index 0.

我们可以用vkGetDeviceQueue 函数检索每个队列家族的队列句柄。其参数是,逻辑设备,队列家族,队列索引和保存队列句柄的变量的指针。因为我们只创建一个队列,我们用索引0即可。

vkGetDeviceQueue(device, indices.graphicsFamily.value(), , &graphicsQueue);

With the logical device and queue handles we can now actually start using the graphics card to do things! In the next few chapters we'll set up the resources to present results to the window system.

有了逻辑设备和队列句柄,我们现在可以真正地用图形卡做点事情了!接下来的几章,我们将设置资源,以呈现结果到窗口系统。

C++ code C++代码

[译]Vulkan教程(08)逻辑设备和队列的更多相关文章

  1. [译]Vulkan教程(07)物理设备和队列家族

    [译]Vulkan教程(07)物理设备和队列家族 Selecting a physical device 选择一个物理设备 After initializing the Vulkan library ...

  2. [译]Vulkan教程(19)渲染和呈现

    [译]Vulkan教程(19)渲染和呈现 Rendering and presentation 渲染和呈现 Setup 设置 This is the chapter where everything ...

  3. [译]Vulkan教程(10)交换链

    [译]Vulkan教程(10)交换链 Vulkan does not have the concept of a "default framebuffer", hence it r ...

  4. [译]Vulkan教程(09)窗口表面

    [译]Vulkan教程(09)窗口表面 Since Vulkan is a platform agnostic API, it can not interface directly with the ...

  5. [译]Vulkan教程(27)Image

    [译]Vulkan教程(27)Image Images Introduction 入门 The geometry has been colored using per-vertex colors so ...

  6. [译]Vulkan教程(23)暂存buffer

    [译]Vulkan教程(23)暂存buffer Staging buffer 暂存buffer Introduction 入门 The vertex buffer we have right now ...

  7. [译]Vulkan教程(22)创建顶点buffer

    [译]Vulkan教程(22)创建顶点buffer Vertex buffer creation 创建顶点buffer Introduction 入门 Buffers in Vulkan are re ...

  8. [译]Vulkan教程(18)命令buffers

    [译]Vulkan教程(18)命令buffers Command buffers 命令buffer Commands in Vulkan, like drawing operations and me ...

  9. [译]Vulkan教程(14)图形管道基础之固定功能

    [译]Vulkan教程(14)图形管道基础之固定功能 Fixed functions 固定功能 The older graphics APIs provided default state for m ...

随机推荐

  1. Python3 函数进阶3

    目录 匿名函数 定义匿名函数 匿名函数的使用 内置函数 匿名函数 定义匿名函数 我们之前定义的函数都是有名函数, 我们可以通过函数名来调用 匿名函数顾名思义就是一种没有绑定函数名的函数, 使用一次既被 ...

  2. 【Web技术】334- yarn、npm、cnpm 三者如何优雅的在一起使用 ?

    前端得包管理你有过几个? 一位用不好包管理器的前端,是一个入门级前端,一个用不好webpack的前端,是一个初级前端 三个包管理器是可以一起用的,只要你够胆大心细,就没任何问题! 在javeScrip ...

  3. 【重温基础】17.WebAPI介绍

    本文是 重温基础 系列文章的第十七篇. 今日感受:挑战. 系列目录: [复习资料]ES6/ES7/ES8/ES9资料整理(个人整理) [重温基础]1-14篇 [重温基础]15.JS对象介绍 [重温基础 ...

  4. 修改IE默认页的指向

    方法一: 1.打开IE浏览器 → 单击 工具 → Internet选项 2.填上你要设置的主页网址 3.重启IE浏览器,成功设置主页 方法二: 1.按住键盘"win+r" → 输入 ...

  5. HA-高可用集群

    原理:两台web服务器,通过心跳线进行通信,当主节点出现服务异常,备用节点通过探测判断主节点是否存活,若是不存活,就把服务接管过来. Web1和Web2中间有一根心跳线,检查对方的存活状态.流动IP: ...

  6. 解密国内BAT等大厂前端技术体系-携程篇(长文建议收藏)

    1 引言 为了了解当前前端的发展趋势,让我们从国内各大互联网大厂开始,了解他们的最新动态和未来规划.这是解密大厂前端技术体系的第四篇,前三篇已经讲述了阿里.腾讯.百度在前端技术这几年的技术发展. 这一 ...

  7. 咪咕音乐链接歌词封面搜索等接口API

    搜索 pd.musicapp.migu.cn/MIGUM2.0/v1.0/content/search_all.do?&ua=Android_migu&version=5.0.1&am ...

  8. Spring Boot 部署浅析(jar or war)

    对于传统的 ssm 或者 ssh 项目的部署,一般会打包成war包,或者是一个编译好的文件夹,再放到 tomcat 的 webapps 目录下,如果是 war 包,会自动解压出来.而 Spring B ...

  9. JAVA Socket API与LINUX Socket API探究

    代码 这是一个带有UI界面的JAVA网络聊天程序,使用Socket连接完成通信. JAVA服务端程序 import java.io.IOException; import java.io.InputS ...

  10. Hack the Breach 2.1 VM (CTF Challenge)

    主机扫描: ╰─ nmap -p- -A 192.168.110.151Starting Nmap 7.70 ( https://nmap.org ) at 2019-08-29 09:48 CSTN ...