當前位置:
首頁 > 知識 > Vulkan Tutorial 06 邏輯設備與隊列

Vulkan Tutorial 06 邏輯設備與隊列

操作系統:Windows8.1

顯卡:Nivida GTX965M

開發工具:Visual Studio 2017

Introduction

在選擇要使用的物理設備之後,我們需要設置一個邏輯設備用於交互。邏輯設備創建過程與instance創建過程類似,也需要描述我們需要使用的功能。因為我們已經查詢過哪些隊列簇可用,在這裡需要進一步為邏輯設備創建具體類型的命令隊列。如果有不同的需求,也可以基於同一個物理設備創建多個邏輯設備。

首先添加一個新的類成員來存儲邏輯設備句柄。

VkDevice device;

接下來創建一個新的函數createLogicalDevice,並在initVulkan函數中調用,以創建邏輯設備。

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

void createLogicalDevice {

}

Specifying the queues to be created

創建邏輯設備需要在結構體中明確具體的信息,首先第一個結構體VkDeviceQueueCreateInfo。這個結構體描述隊列簇中預要申請使用的隊列數量。現在我們僅關心具備圖形能力的隊列。

QueueFamilyIndices indices = findQueueFamilies(physicalDevice);

VkDeviceQueueCreateInfo queueCreateInfo = {};
queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
queueCreateInfo.queueFamilyIndex = indices.graphicsFamily;
queueCreateInfo.queueCount = 1;

當前可用的驅動程序所提供的隊列簇只允許創建少量的隊列,並且很多時候沒有必要創建多個隊列。這是因為可以在多個線程上創建所有命令緩衝區,然後在主線程一次性的以較低開銷的調用提交隊列。

Vulkan允許使用0.0到1.0之間的浮點數分配隊列優先順序來影響命令緩衝區執行的調用。即使只有一個隊列也是必須的:

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

Specifying used device features

下一個要明確的信息有關設備要使用的功能特性。這些是我們在上一節中用vkGetPhysicalDeviceFeatures查詢支持的功能,比如geometry shaders。現在我們不需要任何特殊的功能,所以我們可以簡單的定義它並將所有內容保留到VK_FALSE。一旦我們要開始用Vulkan做更多的事情,我們會回到這個結構體,進一步設置。

VkPhysicalDeviceFeatures deviceFeatures = {};

Creating the logical device

使用前面的兩個結構體,我們可以填充VkDeviceCreateInfo結構。

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

首先添加指向隊列創建信息的結構體和設備功能結構體:

createInfo.pQueueCreateInfos = &queueCreateInfo;
createInfo.queueCreateInfoCount = 1;

createInfo.pEnabledFeatures = &deviceFeatures;

結構體其餘的部分與VkInstanceCreateInfo相似,需要指定擴展和validation layers,總而言之這次不同之處是為具體的設備設置信息。

設置具體擴展的一個案例是VK_KHR_swapchain,它允許將來自設備的渲染圖形呈現到Windows。系統中的Vulkan設備可能缺少該功能,例如僅僅支持計算操作。我們將在交換鏈章節中展開這個擴展。

就像之前validation layers小節中提到的,允許為instance開啟validation layers,現在我們將為設備開啟validation layers,而不需要為設備指定任何擴展。

createInfo.enabledExtensionCount = 0;

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

就這樣,我們現在可以通過調用vkCreateDevice函數來創建實例化邏輯設備。

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

這些參數分別是包含具體隊列使用信息的物理設備,可選的分配器回調指針以及用於存儲邏輯設備的句柄。與instance創建類似,此調用可能由於啟用不存在的擴展或者指定不支持的功能,導致返回錯誤。

cleanup函數中邏輯設備需要調用vkDestroyDevice銷毀:

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

邏輯設備不與instance交互,所以參數中不包含instance。

Retrieving queue handles

這些隊列與邏輯設備自動的一同創建,但是我們還沒有一個與它們進行交互的句柄。在這裡添加一個新的類成員來存儲圖形隊列句柄:

VkQueue graphicsQueue;

設備隊列在設備被銷毀的時候隱式清理,所以我們不需要在cleanup函數中做任何操作。

我們可以使用vkGetDeviceQueue函數來檢測每個隊列簇中隊列的句柄。參數是邏輯設備,隊列簇,隊列索引和存儲獲取隊列變數句柄的指針。因為我們只是從這個隊列簇創建一個隊列,所以需要使用索引0

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

在成功獲取邏輯設備和隊列句柄後,我們可以通過顯卡做一些實際的事情了!在接下來的幾章節中,我們會設置資源並將相應的結果提交到窗體系統。

獲取工程代碼 Github checkout

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 科技優家 的精彩文章:

nodeJS之路徑PATH模塊
Ajax請求匯總(一)
opcache開啟前後性能對比
Ionic進行PC端Web開發時通過腳本壓縮提高第一次載入效率

TAG:科技優家 |

您可能感興趣

被視為代替Kafka的消息隊列:Apache Pulsar設計簡介
React、頁面渲染、任務隊列、Node.js
消息隊列CKafka
簡析Python中的四種隊列
RabbitMQ 高級篇八 消費端ACK與重回隊列
分散式隊列神器 Celery
kafka消息隊列學習整理
RabbitMQ高級篇九TTL設置隊列或消息有效期隊列及消息
RabbitMQ消息中間件技術精講17 高級篇十 死信隊列
linux內核對網卡驅動多隊列的支持
Rocketmq之消息隊列分配策略演算法實現的源碼分析
用於腹側疝修復的改良Chevrel技術:單個中心隊列的長期結果
日常生活中的膳食蛋白質來源和肌肉質量 「Lifelines」 隊列研究
進程間的通信 IPC——實現消息隊列(msg)
Nature:氣勢磅礴!中國最大出生隊列研究碩果累累,引國際「圍觀」
Linux 下的進程間通信:使用管道和消息隊列
List順序表,鏈表隊列,棧,字典
日本航空自衛隊列裝首架F-35A戰機
日航空自衛隊列裝 首架F-35A戰機
攝影師意外拍到G27K清晰照 德軍KSK特種部隊列裝新型步槍