Skip to content
Snippets Groups Projects
Select Git revision
  • c1be8669d73d3e1c7dd2833f90ad58f616d557a0
  • master default
2 results

README

Blame
  • Renderer.cpp 2.95 KiB
    #include "Renderer.hpp"
    
    #include <algorithm>
    #include <ranges>
    #include <vector>
    
    const std::vector<const char*> g_layers{
    #ifdef ENGINE_VULKAN_DEBUG
        "VK_LAYER_KHRONOS_validation"
    #endif
    };
    
    [[nodiscard]] static auto create_instance() -> vk::UniqueInstance
    {
        constexpr static vk::ApplicationInfo application_info{};
    
        const vk::InstanceCreateInfo create_info{
            .pApplicationInfo    = &application_info,
            .enabledLayerCount   = static_cast<uint32_t>(g_layers.size()),
            .ppEnabledLayerNames = g_layers.data(),
        };
    
        return vk::createInstanceUnique(create_info);
    }
    
    [[nodiscard]] static auto choose_physical_device(const vk::Instance t_instance)
        -> vk::PhysicalDevice
    {
        const auto physical_devices{ t_instance.enumeratePhysicalDevices() };
    
        if (std::ranges::empty(physical_devices)) {
            throw std::runtime_error{ "No Vulkan physical device is available." };
        }
    
        auto ranked_devices_view{
            physical_devices
            | std::views::transform([](vk::PhysicalDevice t_physical_device) {
                  switch (t_physical_device.getProperties().deviceType) {
                      case vk::PhysicalDeviceType::eDiscreteGpu:
                          return std::make_pair(t_physical_device, 2);
                      case vk::PhysicalDeviceType::eIntegratedGpu:
                          return std::make_pair(t_physical_device, 1);
                      default: return std::make_pair(t_physical_device, 0);
                  }
              })
        };
        std::vector ranked_devices(
            ranked_devices_view.begin(), ranked_devices_view.end()
        );
    
        std::ranges::sort(
            ranked_devices,
            std::ranges::greater{},
            &std::pair<vk::PhysicalDevice, int>::second
        );
    
        return ranked_devices.front().first;
    }
    
    [[nodiscard]] static auto find_graphics_queue_family(
        const vk::PhysicalDevice t_physical_device
    ) -> uint32_t
    {
        uint32_t index{};
        for (const auto& properties : t_physical_device.getQueueFamilyProperties())
        {
            if (properties.queueFlags & vk::QueueFlagBits::eGraphics) {
                return index;
            }
            index++;
        }
        throw std::runtime_error{ "Could not find graphics queue family" };
    }
    
    [[nodiscard]] static auto create_device(const vk::PhysicalDevice t_physical_device)
        -> vk::UniqueDevice
    {
        const vk::DeviceQueueCreateInfo queue_create_info{
            .queueFamilyIndex = find_graphics_queue_family(t_physical_device),
            .queueCount       = 1,
        };
    
        vk::DeviceCreateInfo device_create_info{
            .queueCreateInfoCount = 1,
            .pQueueCreateInfos    = &queue_create_info,
        };
    
        return t_physical_device.createDeviceUnique(device_create_info);
    }
    
    Renderer::Renderer()
        : m_instance{ create_instance() },
          m_physical_device{ choose_physical_device(*m_instance) },
          m_graphics_queue_family{ find_graphics_queue_family(m_physical_device) },
          m_device{ create_device(m_physical_device) },
          m_graphics_queue{ m_device->getQueue(m_graphics_queue_family, 0) }
    {}