직렬화 함수 작성 끝
This commit is contained in:
173
impl/vulkan_engine/vulkan/devices_and_queues.cpp
Normal file
173
impl/vulkan_engine/vulkan/devices_and_queues.cpp
Normal file
@@ -0,0 +1,173 @@
|
||||
#include <set>
|
||||
|
||||
#include "precomp.h"
|
||||
#include "vulkan_engine/vulkan/graphics.h"
|
||||
|
||||
namespace veng {
|
||||
|
||||
Graphics::QueueFamilyIndices Graphics::FindQueueFamilies(
|
||||
VkPhysicalDevice device) {
|
||||
std::uint32_t queue_familiy_count = 0;
|
||||
vkGetPhysicalDeviceQueueFamilyProperties(device, &queue_familiy_count,
|
||||
nullptr);
|
||||
std::vector<VkQueueFamilyProperties> families(queue_familiy_count);
|
||||
vkGetPhysicalDeviceQueueFamilyProperties(device, &queue_familiy_count,
|
||||
families.data());
|
||||
|
||||
auto graphics_family_it =
|
||||
std::find_if(families.begin(), families.end(),
|
||||
[](const VkQueueFamilyProperties& props) {
|
||||
return props.queueFlags &
|
||||
(VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_TRANSFER_BIT);
|
||||
});
|
||||
|
||||
QueueFamilyIndices result;
|
||||
result.graphics_family = graphics_family_it - families.begin();
|
||||
|
||||
for (std::uint32_t i = 0; i < families.size(); i++) {
|
||||
VkBool32 has_presentation_support = false;
|
||||
vkGetPhysicalDeviceSurfaceSupportKHR(device, i, surface_,
|
||||
&has_presentation_support);
|
||||
if (has_presentation_support) {
|
||||
result.presentation_family = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Graphics::SwapChainProperties Graphics::GetSwapChainProperties(
|
||||
VkPhysicalDevice device) {
|
||||
SwapChainProperties properties;
|
||||
|
||||
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(device, surface_,
|
||||
&properties.capabilities);
|
||||
|
||||
std::uint32_t format_count;
|
||||
vkGetPhysicalDeviceSurfaceFormatsKHR(device, surface_, &format_count,
|
||||
nullptr);
|
||||
properties.formats.resize(format_count);
|
||||
vkGetPhysicalDeviceSurfaceFormatsKHR(device, surface_, &format_count,
|
||||
properties.formats.data());
|
||||
|
||||
std::uint32_t modes_count;
|
||||
vkGetPhysicalDeviceSurfacePresentModesKHR(device, surface_, &modes_count,
|
||||
nullptr);
|
||||
properties.present_modes.resize(modes_count);
|
||||
vkGetPhysicalDeviceSurfacePresentModesKHR(device, surface_, &modes_count,
|
||||
properties.present_modes.data());
|
||||
|
||||
return properties;
|
||||
}
|
||||
|
||||
std::vector<VkExtensionProperties> Graphics::GetDeviceAvailableExtensions(
|
||||
VkPhysicalDevice device) {
|
||||
std::uint32_t available_extentions_count;
|
||||
vkEnumerateDeviceExtensionProperties(device, nullptr,
|
||||
&available_extentions_count, nullptr);
|
||||
std::vector<VkExtensionProperties> available_extentions(
|
||||
available_extentions_count);
|
||||
vkEnumerateDeviceExtensionProperties(device, nullptr,
|
||||
&available_extentions_count,
|
||||
available_extentions.data());
|
||||
return available_extentions;
|
||||
}
|
||||
|
||||
bool Graphics::AreAllDeviceExtensionsSupported(VkPhysicalDevice device) {
|
||||
std::vector<VkExtensionProperties> available_extentions =
|
||||
GetDeviceAvailableExtensions(device);
|
||||
return std::all_of(
|
||||
required_device_extentions_.begin(), required_device_extentions_.end(),
|
||||
std::bind_front(IsExtensionSupported, available_extentions));
|
||||
}
|
||||
|
||||
bool Graphics::IsDeviceSuitable(VkPhysicalDevice device) {
|
||||
QueueFamilyIndices families = FindQueueFamilies(device);
|
||||
return families.IsValid() && AreAllDeviceExtensionsSupported(device) &&
|
||||
GetSwapChainProperties(device).IsValid();
|
||||
}
|
||||
|
||||
void Graphics::PickPhysicalDevice() {
|
||||
std::vector<VkPhysicalDevice> devices = GetAvailableDevices();
|
||||
|
||||
std::erase_if(
|
||||
devices, std::not_fn(std::bind_front(&Graphics::IsDeviceSuitable, this)));
|
||||
|
||||
if (devices.empty()) {
|
||||
spdlog::error("No physical devices that match the criteria");
|
||||
std::exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
physical_device_ = devices[0];
|
||||
}
|
||||
|
||||
std::vector<VkPhysicalDevice> Graphics::GetAvailableDevices() {
|
||||
std::uint32_t device_count;
|
||||
vkEnumeratePhysicalDevices(instance_, &device_count, nullptr);
|
||||
|
||||
if (device_count == 0) return {};
|
||||
|
||||
std::vector<VkPhysicalDevice> devices(device_count);
|
||||
vkEnumeratePhysicalDevices(instance_, &device_count, devices.data());
|
||||
|
||||
return devices;
|
||||
}
|
||||
|
||||
void Graphics::CreateLogicalDeviceAndQueues() {
|
||||
QueueFamilyIndices picked_device_families =
|
||||
FindQueueFamilies(physical_device_);
|
||||
|
||||
if (!picked_device_families.IsValid()) {
|
||||
std::exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
std::set<std::uint32_t> unique_queue_families = {
|
||||
picked_device_families.graphics_family.value(),
|
||||
picked_device_families.presentation_family.value(),
|
||||
};
|
||||
|
||||
std::float_t queue_priority = 1.f;
|
||||
|
||||
std::vector<VkDeviceQueueCreateInfo> queue_create_infos;
|
||||
for (std::uint32_t unique_queue_family : unique_queue_families) {
|
||||
VkDeviceQueueCreateInfo queue_info = {};
|
||||
queue_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
|
||||
queue_info.queueFamilyIndex = unique_queue_family;
|
||||
queue_info.queueCount = 1;
|
||||
queue_info.pQueuePriorities = &queue_priority;
|
||||
queue_create_infos.push_back(queue_info);
|
||||
}
|
||||
|
||||
VkPhysicalDeviceFeatures required_features = {};
|
||||
VkPhysicalDeviceFeatures supported_features;
|
||||
vkGetPhysicalDeviceFeatures(physical_device_, &supported_features);
|
||||
|
||||
if (supported_features.depthBounds) {
|
||||
required_features.depthBounds = VK_TRUE;
|
||||
}
|
||||
if (supported_features.depthClamp) {
|
||||
required_features.depthClamp = VK_TRUE;
|
||||
}
|
||||
|
||||
VkDeviceCreateInfo device_info = {};
|
||||
device_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
|
||||
device_info.queueCreateInfoCount = queue_create_infos.size();
|
||||
device_info.pQueueCreateInfos = queue_create_infos.data();
|
||||
device_info.pEnabledFeatures = &required_features;
|
||||
device_info.enabledExtensionCount = required_device_extentions_.size();
|
||||
device_info.ppEnabledExtensionNames = required_device_extentions_.data();
|
||||
|
||||
VkResult result =
|
||||
vkCreateDevice(physical_device_, &device_info, nullptr, &logical_device_);
|
||||
if (result != VK_SUCCESS) std::exit(EXIT_FAILURE);
|
||||
|
||||
vkGetDeviceQueue(logical_device_,
|
||||
picked_device_families.graphics_family.value(), 0,
|
||||
&graphics_queue_);
|
||||
vkGetDeviceQueue(logical_device_,
|
||||
picked_device_families.presentation_family.value(), 0,
|
||||
&present_queue_);
|
||||
}
|
||||
|
||||
} // namespace veng
|
||||
Reference in New Issue
Block a user