Vulkan device initialization moved to KRDevice
This commit is contained in:
@@ -809,11 +809,6 @@ void
|
|||||||
KRContext::destroyDeviceContexts()
|
KRContext::destroyDeviceContexts()
|
||||||
{
|
{
|
||||||
const std::lock_guard<std::mutex> lock(KRContext::g_DeviceInfoMutex);
|
const std::lock_guard<std::mutex> lock(KRContext::g_DeviceInfoMutex);
|
||||||
for (auto itr = m_devices.begin(); itr != m_devices.end(); itr++) {
|
|
||||||
KRDevice* deviceInfo = &(*itr).second;
|
|
||||||
deviceInfo->destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
m_devices.clear();
|
m_devices.clear();
|
||||||
if (m_vulkanInstance != VK_NULL_HANDLE) {
|
if (m_vulkanInstance != VK_NULL_HANDLE) {
|
||||||
vkDestroyInstance(m_vulkanInstance, NULL);
|
vkDestroyInstance(m_vulkanInstance, NULL);
|
||||||
@@ -964,12 +959,12 @@ KrResult KRContext::createWindowSurface(const KrCreateWindowSurfaceInfo* createW
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (auto itr = m_devices.begin(); itr != m_devices.end(); itr++) {
|
for (auto itr = m_devices.begin(); itr != m_devices.end(); itr++) {
|
||||||
KRDevice* device = &(*itr).second;
|
KRDevice& device = *(*itr).second;
|
||||||
VkBool32 canPresent = false;
|
VkBool32 canPresent = false;
|
||||||
vkGetPhysicalDeviceSurfaceSupportKHR(device->m_device, device->m_graphicsFamilyQueueIndex, info.surface, &canPresent);
|
vkGetPhysicalDeviceSurfaceSupportKHR(device.m_device, device.m_graphicsFamilyQueueIndex, info.surface, &canPresent);
|
||||||
if (canPresent) {
|
if (canPresent) {
|
||||||
info.deviceHandle = (*itr).first;
|
info.deviceHandle = (*itr).first;
|
||||||
deviceInfo = device;
|
deviceInfo = &device;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1301,7 +1296,7 @@ KRSurface& KRContext::GetSurfaceInfo(KrSurfaceHandle handle)
|
|||||||
|
|
||||||
KRDevice& KRContext::GetDeviceInfo(KrDeviceHandle handle)
|
KRDevice& KRContext::GetDeviceInfo(KrDeviceHandle handle)
|
||||||
{
|
{
|
||||||
return m_devices[handle];
|
return *m_devices[handle];
|
||||||
}
|
}
|
||||||
|
|
||||||
void KRContext::createDevices()
|
void KRContext::createDevices()
|
||||||
@@ -1316,175 +1311,49 @@ void KRContext::createDevices()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<VkPhysicalDevice> devices(deviceCount);
|
std::vector<VkPhysicalDevice> physicalDevices(deviceCount);
|
||||||
vkEnumeratePhysicalDevices(m_vulkanInstance, &deviceCount, devices.data());
|
vkEnumeratePhysicalDevices(m_vulkanInstance, &deviceCount, physicalDevices.data());
|
||||||
|
|
||||||
const std::vector<const char*> deviceExtensions = {
|
const std::vector<const char*> deviceExtensions = {
|
||||||
VK_KHR_SWAPCHAIN_EXTENSION_NAME
|
VK_KHR_SWAPCHAIN_EXTENSION_NAME
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<KRDevice> deviceInfos;
|
std::vector<std::unique_ptr<KRDevice>> candidateDevices;
|
||||||
|
|
||||||
for (const VkPhysicalDevice& device : devices) {
|
for (const VkPhysicalDevice& physicalDevice : physicalDevices) {
|
||||||
VkPhysicalDeviceProperties deviceProperties;
|
std::unique_ptr<KRDevice> device = std::make_unique<KRDevice>(physicalDevice);
|
||||||
VkPhysicalDeviceFeatures deviceFeatures;
|
if (!device->initialize(deviceExtensions)) {
|
||||||
vkGetPhysicalDeviceProperties(device, &deviceProperties);
|
|
||||||
vkGetPhysicalDeviceFeatures(device, &deviceFeatures);
|
|
||||||
|
|
||||||
uint32_t queueFamilyCount = 0;
|
|
||||||
vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, nullptr);
|
|
||||||
|
|
||||||
std::vector<VkQueueFamilyProperties> queueFamilies(queueFamilyCount);
|
|
||||||
vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, queueFamilies.data());
|
|
||||||
|
|
||||||
uint32_t graphicsFamilyQueue = -1;
|
|
||||||
uint32_t computeFamilyQueue = -1;
|
|
||||||
uint32_t i = 0;
|
|
||||||
for (const auto& queueFamily : queueFamilies) {
|
|
||||||
if (queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT) {
|
|
||||||
graphicsFamilyQueue = i;
|
|
||||||
}
|
|
||||||
if (queueFamily.queueFlags & VK_QUEUE_COMPUTE_BIT) {
|
|
||||||
computeFamilyQueue = i;
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
if (graphicsFamilyQueue == -1) {
|
|
||||||
// No graphics queue family, not suitable
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (computeFamilyQueue == -1) {
|
|
||||||
// No compute queue family, not suitable
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t extensionCount;
|
|
||||||
vkEnumerateDeviceExtensionProperties(device, nullptr, &extensionCount, nullptr);
|
|
||||||
|
|
||||||
std::vector<VkExtensionProperties> availableExtensions(extensionCount);
|
|
||||||
vkEnumerateDeviceExtensionProperties(device, nullptr, &extensionCount, availableExtensions.data());
|
|
||||||
|
|
||||||
std::set<std::string> requiredExtensions(deviceExtensions.begin(), deviceExtensions.end());
|
|
||||||
|
|
||||||
for (const auto& extension : availableExtensions) {
|
|
||||||
requiredExtensions.erase(extension.extensionName);
|
|
||||||
}
|
|
||||||
if (!requiredExtensions.empty()) {
|
|
||||||
// Missing a required extension
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool addDevice = false;
|
bool addDevice = false;
|
||||||
|
if (candidateDevices.empty()) {
|
||||||
|
|
||||||
if (deviceInfos.empty()) {
|
|
||||||
addDevice = true;
|
addDevice = true;
|
||||||
} else {
|
} else {
|
||||||
VkPhysicalDeviceType collectedType = deviceInfos[0].m_deviceProperties.deviceType;
|
VkPhysicalDeviceType collectedType = candidateDevices[0]->m_deviceProperties.deviceType;
|
||||||
if (collectedType == deviceProperties.deviceType) {
|
if (collectedType == device->m_deviceProperties.deviceType) {
|
||||||
addDevice = true;
|
addDevice = true;
|
||||||
} else if (deviceProperties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) {
|
} else if (device->m_deviceProperties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) {
|
||||||
// Discrete GPU's are always the best choice
|
// Discrete GPU's are always the best choice
|
||||||
deviceInfos.clear();
|
candidateDevices.clear();
|
||||||
addDevice = true;
|
addDevice = true;
|
||||||
} else if (collectedType != VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU && deviceProperties.deviceType == VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU) {
|
} else if (collectedType != VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU && device->m_deviceProperties.deviceType == VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU) {
|
||||||
// Integrated GPU's are the second best choice
|
// Integrated GPU's are the second best choice
|
||||||
deviceInfos.clear();
|
candidateDevices.clear();
|
||||||
addDevice = true;
|
addDevice = true;
|
||||||
} else if (collectedType != VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU && collectedType != VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU && deviceProperties.deviceType == VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU) {
|
} else if (collectedType != VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU && collectedType != VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU && device->m_deviceProperties.deviceType == VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU) {
|
||||||
// Virtual GPU's are the 3rd best choice
|
// Virtual GPU's are the 3rd best choice
|
||||||
deviceInfos.clear();
|
candidateDevices.clear();
|
||||||
addDevice = true;
|
addDevice = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (addDevice) {
|
if (addDevice) {
|
||||||
KRDevice& info = deviceInfos.emplace_back(KRDevice{});
|
candidateDevices.push_back(std::move(device));
|
||||||
info.m_device = device;
|
|
||||||
info.m_deviceProperties = deviceProperties;
|
|
||||||
info.m_deviceFeatures = deviceFeatures;
|
|
||||||
info.m_graphicsFamilyQueueIndex = graphicsFamilyQueue;
|
|
||||||
info.m_computeFamilyQueueIndex = computeFamilyQueue;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (KRDevice& info: deviceInfos) {
|
for (auto itr = candidateDevices.begin(); itr != candidateDevices.end(); itr++) {
|
||||||
VkDeviceQueueCreateInfo queueCreateInfo[2]{};
|
std::unique_ptr<KRDevice> device = std::move(*itr);
|
||||||
float queuePriority = 1.0f;
|
m_devices[++m_topDeviceHandle] = std::move(device);
|
||||||
queueCreateInfo[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
|
|
||||||
queueCreateInfo[0].queueFamilyIndex = info.m_graphicsFamilyQueueIndex;
|
|
||||||
queueCreateInfo[0].queueCount = 1;
|
|
||||||
queueCreateInfo[0].pQueuePriorities = &queuePriority;
|
|
||||||
if (info.m_graphicsFamilyQueueIndex != info.m_computeFamilyQueueIndex) {
|
|
||||||
queueCreateInfo[1].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
|
|
||||||
queueCreateInfo[1].queueFamilyIndex = info.m_computeFamilyQueueIndex;
|
|
||||||
queueCreateInfo[1].queueCount = 1;
|
|
||||||
queueCreateInfo[1].pQueuePriorities = &queuePriority;
|
|
||||||
}
|
|
||||||
|
|
||||||
VkDeviceCreateInfo deviceCreateInfo{};
|
|
||||||
deviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
|
|
||||||
deviceCreateInfo.pQueueCreateInfos = queueCreateInfo;
|
|
||||||
deviceCreateInfo.queueCreateInfoCount = info.m_graphicsFamilyQueueIndex == info.m_computeFamilyQueueIndex ? 1 : 2;
|
|
||||||
VkPhysicalDeviceFeatures deviceFeatures{};
|
|
||||||
deviceCreateInfo.pEnabledFeatures = &deviceFeatures;
|
|
||||||
deviceCreateInfo.enabledExtensionCount = static_cast<uint32_t>(deviceExtensions.size());
|
|
||||||
deviceCreateInfo.ppEnabledExtensionNames = deviceExtensions.data();
|
|
||||||
if (vkCreateDevice(info.m_device, &deviceCreateInfo, nullptr, &info.m_logicalDevice) != VK_SUCCESS) {
|
|
||||||
// TODO - Log a warning...
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
vkGetDeviceQueue(info.m_logicalDevice, info.m_graphicsFamilyQueueIndex, 0, &info.m_graphicsQueue);
|
|
||||||
vkGetDeviceQueue(info.m_logicalDevice, info.m_computeFamilyQueueIndex, 0, &info.m_computeQueue);
|
|
||||||
|
|
||||||
VkCommandPoolCreateInfo poolInfo{};
|
|
||||||
poolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
|
|
||||||
poolInfo.queueFamilyIndex = info.m_graphicsFamilyQueueIndex;
|
|
||||||
poolInfo.flags = 0;
|
|
||||||
|
|
||||||
if (vkCreateCommandPool(info.m_logicalDevice, &poolInfo, nullptr, &info.m_graphicsCommandPool) != VK_SUCCESS) {
|
|
||||||
vkDestroyDevice(info.m_logicalDevice, nullptr);
|
|
||||||
// TODO - Log a warning...
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
poolInfo.queueFamilyIndex = info.m_computeFamilyQueueIndex;
|
|
||||||
if (vkCreateCommandPool(info.m_logicalDevice, &poolInfo, nullptr, &info.m_computeCommandPool) != VK_SUCCESS) {
|
|
||||||
vkDestroyCommandPool(info.m_logicalDevice, info.m_graphicsCommandPool, nullptr);
|
|
||||||
vkDestroyDevice(info.m_logicalDevice, nullptr);
|
|
||||||
// TODO - Log a warning...
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const int kMaxGraphicsCommandBuffers = 10; // TODO - This needs to be dynamic?
|
|
||||||
info.m_graphicsCommandBuffers.resize(kMaxGraphicsCommandBuffers);
|
|
||||||
|
|
||||||
const int kMaxComputeCommandBuffers = 4; // TODO - This needs to be dynamic?
|
|
||||||
info.m_computeCommandBuffers.resize(kMaxComputeCommandBuffers);
|
|
||||||
|
|
||||||
VkCommandBufferAllocateInfo allocInfo{};
|
|
||||||
allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
|
||||||
allocInfo.commandPool = info.m_graphicsCommandPool;
|
|
||||||
allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
|
|
||||||
allocInfo.commandBufferCount = (uint32_t)info.m_graphicsCommandBuffers.size();
|
|
||||||
|
|
||||||
if (vkAllocateCommandBuffers(info.m_logicalDevice, &allocInfo, info.m_graphicsCommandBuffers.data()) != VK_SUCCESS) {
|
|
||||||
vkDestroyCommandPool(info.m_logicalDevice, info.m_computeCommandPool, nullptr);
|
|
||||||
vkDestroyCommandPool(info.m_logicalDevice, info.m_graphicsCommandPool, nullptr);
|
|
||||||
vkDestroyDevice(info.m_logicalDevice, nullptr);
|
|
||||||
// TODO - Log a warning
|
|
||||||
}
|
|
||||||
|
|
||||||
allocInfo.commandPool = info.m_computeCommandPool;
|
|
||||||
allocInfo.commandBufferCount = (uint32_t)info.m_computeCommandBuffers.size();
|
|
||||||
if (vkAllocateCommandBuffers(info.m_logicalDevice, &allocInfo, info.m_computeCommandBuffers.data()) != VK_SUCCESS) {
|
|
||||||
// Note - this repeated cleanup will likely be eliminated with later refactoring to split vulkan
|
|
||||||
// object generation out of KRContext
|
|
||||||
vkDestroyCommandPool(info.m_logicalDevice, info.m_computeCommandPool, nullptr);
|
|
||||||
vkDestroyCommandPool(info.m_logicalDevice, info.m_graphicsCommandPool, nullptr);
|
|
||||||
vkDestroyDevice(info.m_logicalDevice, nullptr);
|
|
||||||
// TODO - Log a warning
|
|
||||||
}
|
|
||||||
|
|
||||||
m_devices[++m_topDeviceHandle] = info;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -215,7 +215,7 @@ private:
|
|||||||
std::atomic<bool> m_stop;
|
std::atomic<bool> m_stop;
|
||||||
void renderFrame();
|
void renderFrame();
|
||||||
|
|
||||||
unordered_map<KrDeviceHandle, KRDevice> m_devices;
|
unordered_map<KrDeviceHandle, std::unique_ptr<KRDevice>> m_devices;
|
||||||
KrDeviceHandle m_topDeviceHandle;
|
KrDeviceHandle m_topDeviceHandle;
|
||||||
|
|
||||||
unordered_map<KrSurfaceHandle, KRSurface> m_surfaces;
|
unordered_map<KrSurfaceHandle, KRSurface> m_surfaces;
|
||||||
|
|||||||
@@ -31,9 +31,175 @@
|
|||||||
|
|
||||||
#include "KRDevice.h"
|
#include "KRDevice.h"
|
||||||
|
|
||||||
|
KRDevice::KRDevice(const VkPhysicalDevice& device)
|
||||||
|
: m_device(device)
|
||||||
|
, m_logicalDevice(VK_NULL_HANDLE)
|
||||||
|
, m_deviceProperties {}
|
||||||
|
, m_deviceFeatures{}
|
||||||
|
, m_graphicsFamilyQueueIndex(0)
|
||||||
|
, m_graphicsQueue(VK_NULL_HANDLE)
|
||||||
|
, m_computeFamilyQueueIndex(0)
|
||||||
|
, m_computeQueue(VK_NULL_HANDLE)
|
||||||
|
, m_graphicsCommandPool(VK_NULL_HANDLE)
|
||||||
|
, m_computeCommandPool(VK_NULL_HANDLE)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
KRDevice::~KRDevice()
|
||||||
|
{
|
||||||
|
destroy();
|
||||||
|
}
|
||||||
|
|
||||||
void KRDevice::destroy()
|
void KRDevice::destroy()
|
||||||
{
|
{
|
||||||
vkDestroyCommandPool(m_logicalDevice, m_graphicsCommandPool, nullptr);
|
if (m_logicalDevice != VK_NULL_HANDLE) {
|
||||||
vkDestroyCommandPool(m_logicalDevice, m_computeCommandPool, nullptr);
|
vkDestroyCommandPool(m_logicalDevice, m_graphicsCommandPool, nullptr);
|
||||||
vkDestroyDevice(m_logicalDevice, nullptr);
|
m_graphicsCommandPool = VK_NULL_HANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_computeCommandPool != VK_NULL_HANDLE) {
|
||||||
|
vkDestroyCommandPool(m_logicalDevice, m_computeCommandPool, nullptr);
|
||||||
|
m_computeCommandPool = VK_NULL_HANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_logicalDevice != VK_NULL_HANDLE) {
|
||||||
|
vkDestroyDevice(m_logicalDevice, nullptr);
|
||||||
|
m_logicalDevice = VK_NULL_HANDLE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool KRDevice::initialize(const std::vector<const char*>& deviceExtensions)
|
||||||
|
{
|
||||||
|
vkGetPhysicalDeviceProperties(m_device, &m_deviceProperties);
|
||||||
|
vkGetPhysicalDeviceFeatures(m_device, &m_deviceFeatures);
|
||||||
|
|
||||||
|
uint32_t queueFamilyCount = 0;
|
||||||
|
vkGetPhysicalDeviceQueueFamilyProperties(m_device, &queueFamilyCount, nullptr);
|
||||||
|
|
||||||
|
std::vector<VkQueueFamilyProperties> queueFamilies(queueFamilyCount);
|
||||||
|
vkGetPhysicalDeviceQueueFamilyProperties(m_device, &queueFamilyCount, queueFamilies.data());
|
||||||
|
|
||||||
|
uint32_t graphicsFamilyQueue = -1;
|
||||||
|
uint32_t computeFamilyQueue = -1;
|
||||||
|
uint32_t i = 0;
|
||||||
|
for (const auto& queueFamily : queueFamilies) {
|
||||||
|
if (queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT) {
|
||||||
|
graphicsFamilyQueue = i;
|
||||||
|
}
|
||||||
|
if (queueFamily.queueFlags & VK_QUEUE_COMPUTE_BIT) {
|
||||||
|
computeFamilyQueue = i;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if (graphicsFamilyQueue == -1) {
|
||||||
|
// No graphics queue family, not suitable
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (computeFamilyQueue == -1) {
|
||||||
|
// No compute queue family, not suitable
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_graphicsFamilyQueueIndex = graphicsFamilyQueue;
|
||||||
|
m_computeFamilyQueueIndex = computeFamilyQueue;
|
||||||
|
|
||||||
|
uint32_t extensionCount;
|
||||||
|
vkEnumerateDeviceExtensionProperties(m_device, nullptr, &extensionCount, nullptr);
|
||||||
|
|
||||||
|
std::vector<VkExtensionProperties> availableExtensions(extensionCount);
|
||||||
|
vkEnumerateDeviceExtensionProperties(m_device, nullptr, &extensionCount, availableExtensions.data());
|
||||||
|
|
||||||
|
std::set<std::string> requiredExtensions(deviceExtensions.begin(), deviceExtensions.end());
|
||||||
|
|
||||||
|
for (const auto& extension : availableExtensions) {
|
||||||
|
requiredExtensions.erase(extension.extensionName);
|
||||||
|
}
|
||||||
|
if (!requiredExtensions.empty()) {
|
||||||
|
// Missing a required extension
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----
|
||||||
|
|
||||||
|
VkDeviceQueueCreateInfo queueCreateInfo[2]{};
|
||||||
|
float queuePriority = 1.0f;
|
||||||
|
queueCreateInfo[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
|
||||||
|
queueCreateInfo[0].queueFamilyIndex = m_graphicsFamilyQueueIndex;
|
||||||
|
queueCreateInfo[0].queueCount = 1;
|
||||||
|
queueCreateInfo[0].pQueuePriorities = &queuePriority;
|
||||||
|
if (m_graphicsFamilyQueueIndex != m_computeFamilyQueueIndex) {
|
||||||
|
queueCreateInfo[1].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
|
||||||
|
queueCreateInfo[1].queueFamilyIndex = m_computeFamilyQueueIndex;
|
||||||
|
queueCreateInfo[1].queueCount = 1;
|
||||||
|
queueCreateInfo[1].pQueuePriorities = &queuePriority;
|
||||||
|
}
|
||||||
|
|
||||||
|
VkDeviceCreateInfo deviceCreateInfo{};
|
||||||
|
deviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
|
||||||
|
deviceCreateInfo.pQueueCreateInfos = queueCreateInfo;
|
||||||
|
deviceCreateInfo.queueCreateInfoCount = m_graphicsFamilyQueueIndex == m_computeFamilyQueueIndex ? 1 : 2;
|
||||||
|
VkPhysicalDeviceFeatures deviceFeatures{};
|
||||||
|
deviceCreateInfo.pEnabledFeatures = &deviceFeatures;
|
||||||
|
deviceCreateInfo.enabledExtensionCount = static_cast<uint32_t>(deviceExtensions.size());
|
||||||
|
deviceCreateInfo.ppEnabledExtensionNames = deviceExtensions.data();
|
||||||
|
if (vkCreateDevice(m_device, &deviceCreateInfo, nullptr, &m_logicalDevice) != VK_SUCCESS) {
|
||||||
|
// TODO - Log a warning...
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
vkGetDeviceQueue(m_logicalDevice, m_graphicsFamilyQueueIndex, 0, &m_graphicsQueue);
|
||||||
|
vkGetDeviceQueue(m_logicalDevice, m_computeFamilyQueueIndex, 0, &m_computeQueue);
|
||||||
|
|
||||||
|
VkCommandPoolCreateInfo poolInfo{};
|
||||||
|
poolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
|
||||||
|
poolInfo.queueFamilyIndex = m_graphicsFamilyQueueIndex;
|
||||||
|
poolInfo.flags = 0;
|
||||||
|
|
||||||
|
if (vkCreateCommandPool(m_logicalDevice, &poolInfo, nullptr, &m_graphicsCommandPool) != VK_SUCCESS) {
|
||||||
|
vkDestroyDevice(m_logicalDevice, nullptr);
|
||||||
|
// TODO - Log a warning...
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
poolInfo.queueFamilyIndex = m_computeFamilyQueueIndex;
|
||||||
|
if (vkCreateCommandPool(m_logicalDevice, &poolInfo, nullptr, &m_computeCommandPool) != VK_SUCCESS) {
|
||||||
|
vkDestroyCommandPool(m_logicalDevice, m_graphicsCommandPool, nullptr);
|
||||||
|
vkDestroyDevice(m_logicalDevice, nullptr);
|
||||||
|
// TODO - Log a warning...
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int kMaxGraphicsCommandBuffers = 10; // TODO - This needs to be dynamic?
|
||||||
|
m_graphicsCommandBuffers.resize(kMaxGraphicsCommandBuffers);
|
||||||
|
|
||||||
|
const int kMaxComputeCommandBuffers = 4; // TODO - This needs to be dynamic?
|
||||||
|
m_computeCommandBuffers.resize(kMaxComputeCommandBuffers);
|
||||||
|
|
||||||
|
VkCommandBufferAllocateInfo allocInfo{};
|
||||||
|
allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
||||||
|
allocInfo.commandPool = m_graphicsCommandPool;
|
||||||
|
allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
|
||||||
|
allocInfo.commandBufferCount = (uint32_t)m_graphicsCommandBuffers.size();
|
||||||
|
|
||||||
|
if (vkAllocateCommandBuffers(m_logicalDevice, &allocInfo, m_graphicsCommandBuffers.data()) != VK_SUCCESS) {
|
||||||
|
vkDestroyCommandPool(m_logicalDevice, m_computeCommandPool, nullptr);
|
||||||
|
vkDestroyCommandPool(m_logicalDevice, m_graphicsCommandPool, nullptr);
|
||||||
|
vkDestroyDevice(m_logicalDevice, nullptr);
|
||||||
|
// TODO - Log a warning
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
allocInfo.commandPool = m_computeCommandPool;
|
||||||
|
allocInfo.commandBufferCount = (uint32_t)m_computeCommandBuffers.size();
|
||||||
|
if (vkAllocateCommandBuffers(m_logicalDevice, &allocInfo, m_computeCommandBuffers.data()) != VK_SUCCESS) {
|
||||||
|
// Note - this repeated cleanup will likely be eliminated with later refactoring to split vulkan
|
||||||
|
// object generation out of KRContext
|
||||||
|
vkDestroyCommandPool(m_logicalDevice, m_computeCommandPool, nullptr);
|
||||||
|
vkDestroyCommandPool(m_logicalDevice, m_graphicsCommandPool, nullptr);
|
||||||
|
vkDestroyDevice(m_logicalDevice, nullptr);
|
||||||
|
// TODO - Log a warning
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
@@ -37,8 +37,14 @@
|
|||||||
class KRDevice
|
class KRDevice
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
KRDevice(const VkPhysicalDevice& device);
|
||||||
|
~KRDevice();
|
||||||
|
|
||||||
|
KRDevice(const KRDevice&) = delete;
|
||||||
|
KRDevice& operator=(const KRDevice&) = delete;
|
||||||
|
|
||||||
void destroy();
|
void destroy();
|
||||||
|
bool initialize(const std::vector<const char*>& deviceExtensions);
|
||||||
|
|
||||||
VkPhysicalDevice m_device;
|
VkPhysicalDevice m_device;
|
||||||
VkDevice m_logicalDevice;
|
VkDevice m_logicalDevice;
|
||||||
|
|||||||
Reference in New Issue
Block a user