Kale
Loading...
Searching...
No Matches
Device.cpp
Go to the documentation of this file.
1/*
2 Copyright 2022 Rishi Challa
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15*/
16
17#ifdef KALE_VULKAN
18
19#include "Device.hpp"
20
24
25#include <algorithm>
26#include <stdexcept>
27#include <exception>
28
29using namespace Kale;
30using namespace Kale::Vulkan;
31
36 // Empty Body
37}
38
44Device::Device(const vk::PhysicalDevice& device) : physicalDevice(device), physicalDeviceProperties(device.getProperties()),
45 queueIndices(device) {
46
47 if (!deviceSupported(device)) throw std::runtime_error("Unsupported Device Used");
48
49 memoryProperties = physicalDevice.getMemoryProperties();
51 getQueues();
52}
53
59Device::Device(uint32_t deviceId) {
60 bool found = false;
61 for (const vk::PhysicalDevice& device : Device::availableDevices()) {
62 vk::PhysicalDeviceProperties properties = device.getProperties();
63 if (properties.deviceID != deviceId) continue;
64 physicalDevice = device;
65 physicalDeviceProperties = properties;
67 found = true;
68 break;
69 }
70
71 if (!found) throw std::runtime_error("Device not Found");
72
73 memoryProperties = physicalDevice.getMemoryProperties();
75 getQueues();
76}
77
78
83void Device::init(const vk::PhysicalDevice& device) {
85 physicalDevice = device;
86 physicalDeviceProperties = device.getProperties();
88
89 if (!deviceSupported(device)) throw std::runtime_error("Unsupported Device Used");
90
91 memoryProperties = physicalDevice.getMemoryProperties();
93 getQueues();
94}
95
100void Device::init(uint32_t deviceId) {
102 bool found = false;
103 for (const vk::PhysicalDevice& device : Device::availableDevices()) {
104 vk::PhysicalDeviceProperties properties = device.getProperties();
105 if (properties.deviceID != deviceId) continue;
106 physicalDevice = device;
107 physicalDeviceProperties = properties;
109 found = true;
110 break;
111 }
112
113 if (!found) throw std::runtime_error("Device not Found");
114
115 memoryProperties = physicalDevice.getMemoryProperties();
117 getQueues();
118}
119
124
125 // Create the queue create info
126 std::vector<float> priorities = {1.0f};
127 std::unordered_set<uint32_t> uniqueIndices = queueIndices.getUniqueIndices();
128 std::vector<vk::DeviceQueueCreateInfo> queueCreateInfo;
129
130 // Populate the queue create info vector
131 for (uint32_t i : uniqueIndices) {
132 queueCreateInfo.emplace_back(vk::DeviceQueueCreateFlags(), i, 1, priorities.data());
133 }
134
135 // Choose all required device features we desire
136 vk::PhysicalDeviceFeatures features;
137 // TODO - set the required device features to true
138
139 // Set all required device extensions
140 std::vector<const char*> extensions = getExtensions<vk::ExtensionProperties>(
141 physicalDevice.enumerateDeviceExtensionProperties(), requiredDeviceExtensions,
142 requestedDeviceExtensions, [](const vk::ExtensionProperties& p) {
143
144 // Map extension property to a const char*
145 return std::string(p.extensionName);
146 });
147
148 // Create the logical device create info
149 vk::DeviceCreateInfo createInfo(vk::DeviceCreateFlags(), static_cast<uint32_t>(queueCreateInfo.size()), queueCreateInfo.data(),
150 0, nullptr, static_cast<uint32_t>(extensions.size()), extensions.data(), &features);
151
152 // Create the logical device
153 logicalDevice = physicalDevice.createDeviceUnique(createInfo);
154}
155
163
171
178uint32_t Device::findMemoryType(uint32_t typeFilter, vk::MemoryPropertyFlags properties) const {
179 for (uint32_t i = 0; i < memoryProperties.memoryTypeCount; i++)
180 // Check that the filter is correct and that all properties are within the property flags
181 if (typeFilter & (1 << i) && (memoryProperties.memoryTypes[i].propertyFlags & properties) == properties)
182 return i;
183
184 throw std::runtime_error("Failed to find applicable memory type");
185}
186
191std::vector<vk::PhysicalDevice> Device::availableDevices() {
192 std::vector<vk::PhysicalDevice> devices = Core::instance->enumeratePhysicalDevices();
193 devices.erase(std::remove_if(devices.begin(), devices.end(), [](const vk::PhysicalDevice& device) {
194 return !Device::deviceSupported(device);
195 }), devices.end());
196 return devices;
197}
198
204bool Device::deviceSupported(const vk::PhysicalDevice& physicalDevice) {
205 // Ensure that the physical device is a GPU/has all required queue family indices
206 QueueFamilyIndices queueFamilyIndices(physicalDevice);
207 if (!queueFamilyIndices.hasAllIndices()) return false;
208
209 // Ensure the GPU has all required extensions
210 try {
211 getExtensions<vk::ExtensionProperties>(
212 physicalDevice.enumerateDeviceExtensionProperties(), requiredDeviceExtensions,
213 requestedDeviceExtensions, [](const vk::ExtensionProperties& p) {
214
215 // Map extension property to a const char*
216 return std::string(p.extensionName);
217 });
218 }
219 catch (const std::exception&) {
220 // This device is lacking a required extension
221 return false;
222 }
223
224 // Ensure the GPU has swap chain support
225 SwapChainSupportDetails swapChainSupport(physicalDevice);
226 if (!swapChainSupport.deviceIsAdequate()) return false;
227
228 // All checks passed
229 return true;
230}
231
232#endif
static vk::UniqueInstance instance
Definition Core.hpp:89
vk::PhysicalDevice physicalDevice
Definition Device.hpp:69
void init(const vk::PhysicalDevice &device)
Definition Device.cpp:83
static bool deviceSupported(const vk::PhysicalDevice &physicalDevice)
Definition Device.cpp:204
std::map< QueueType, vk::Queue > queueMap
Definition Device.hpp:74
vk::UniqueDevice logicalDevice
Definition Device.hpp:59
void createLogicalDevice()
Definition Device.cpp:123
uint32_t findMemoryType(uint32_t typeFilter, vk::MemoryPropertyFlags properties) const
Definition Device.cpp:178
QueueFamilyIndices queueIndices
Definition Device.hpp:79
vk::PhysicalDeviceProperties physicalDeviceProperties
Definition Device.hpp:64
vk::PhysicalDeviceMemoryProperties memoryProperties
Definition Device.hpp:84
static std::vector< vk::PhysicalDevice > availableDevices()
Definition Device.cpp:191
std::optional< uint32_t > graphicsFamilyIndex
std::unordered_set< uint32_t > getUniqueIndices() const
std::optional< uint32_t > presentFamilyIndex
const std::vector< std::string > requestedDeviceExtensions
const std::vector< std::string > requiredDeviceExtensions