Add vulkan surface

This commit is contained in:
Bailey Harrison 2022-09-21 20:52:26 +01:00
parent d455b8d4f7
commit 47dbfd4dfe
2 changed files with 60 additions and 30 deletions

View File

@ -10,13 +10,13 @@ struct SDL_Window;
namespace engine::gfx { namespace engine::gfx {
struct ENGINE_API Device { struct ENGINE_API GFXDevice {
Device(AppInfo appInfo, SDL_Window* window); GFXDevice(AppInfo appInfo, SDL_Window* window);
Device(const Device&) = delete; GFXDevice(const GFXDevice&) = delete;
Device& operator=(const Device&) = delete; GFXDevice& operator=(const GFXDevice&) = delete;
~Device(); ~GFXDevice();
private: private:
class Impl; class Impl;

View File

@ -32,33 +32,40 @@ namespace engine::gfx {
return requiredExtensions; return requiredExtensions;
} }
class Device::Impl { static VkSurfaceKHR createSurface(SDL_Window* window, VkInstance instance)
{
VkSurfaceKHR surface;
if (SDL_Vulkan_CreateSurface(window, instance, &surface) == false) {
throw std::runtime_error("Unable to create window surface");
}
return surface;
}
class GFXDevice::Impl {
public: public:
Impl(AppInfo appInfo, SDL_Window* window) Impl(AppInfo appInfo, SDL_Window* window)
{ {
#ifdef NDEBUG #ifdef NDEBUG
// release mode; don't use validation layer // release mode: don't use validation layer
m_layerInfo = std::make_unique<LayerInfo>(false); m_layerInfo = std::make_unique<LayerInfo>(false);
#else #else
// debug mode; use validation layer // debug mode: use validation layer
m_layerInfo = std::make_unique<LayerInfo>(true); m_layerInfo = std::make_unique<LayerInfo>(true);
#endif #endif
m_instance = std::make_shared<Instance>(appInfo, *m_layerInfo, getRequiredVulkanExtensions(window)); m_instance = std::make_shared<Instance>(appInfo, *m_layerInfo, getRequiredVulkanExtensions(window));
volkLoadInstanceOnly(m_instance->getHandle()); volkLoadInstanceOnly(m_instance->getHandle());
m_debugMessenger = std::make_unique<DebugMessenger>(m_instance); m_debugMessenger = std::make_unique<DebugMessenger>(m_instance);
m_surface = std::make_unique<Surface>(window, m_instance);
m_device = std::make_unique<Device>(m_instance); m_device = std::make_unique<Device>(m_instance);
volkLoadDevice(m_device->getHandle());
} }
private: private:
// VkSurfaceKHR m_surface;
struct LayerInfo { struct LayerInfo {
LayerInfo(bool useValidation) LayerInfo(bool useValidation)
@ -162,6 +169,7 @@ namespace engine::gfx {
Instance& operator=(const Instance&) = delete; Instance& operator=(const Instance&) = delete;
~Instance() ~Instance()
{ {
TRACE("Destroying instance...");
vkDestroyInstance(m_handle, nullptr); vkDestroyInstance(m_handle, nullptr);
} }
@ -190,6 +198,7 @@ namespace engine::gfx {
DebugMessenger& operator=(const DebugMessenger&) = delete; DebugMessenger& operator=(const DebugMessenger&) = delete;
~DebugMessenger() ~DebugMessenger()
{ {
TRACE("Destroying debug messenger...");
vkDestroyDebugUtilsMessengerEXT(m_instance->getHandle(), m_messengerHandle, nullptr); vkDestroyDebugUtilsMessengerEXT(m_instance->getHandle(), m_messengerHandle, nullptr);
} }
@ -277,6 +286,28 @@ namespace engine::gfx {
}; };
class Surface {
public:
Surface(SDL_Window* window, std::shared_ptr<Instance> instance) : m_instance(instance)
{
m_handle = createSurface(window, instance->getHandle());
}
Surface(const Surface&) = delete;
Surface& operator=(const Surface&) = delete;
~Surface()
{
TRACE("Destroying surface...");
vkDestroySurfaceKHR(m_instance->getHandle(), m_handle, nullptr);
}
private:
std::shared_ptr<Instance> m_instance;
VkSurfaceKHR m_handle;
};
class Device { class Device {
public: public:
@ -340,7 +371,7 @@ namespace engine::gfx {
VkPhysicalDeviceProperties devProps; VkPhysicalDeviceProperties devProps;
vkGetPhysicalDeviceProperties(physicalDevice, &devProps); vkGetPhysicalDeviceProperties(physicalDevice, &devProps);
TRACE("Selected physical device: {}", devProps.deviceName); INFO("Selected physical device: {}", devProps.deviceName);
// queue families // queue families
@ -411,12 +442,18 @@ namespace engine::gfx {
if (res != VK_SUCCESS) { if (res != VK_SUCCESS) {
throw std::runtime_error("Unable to create Vulkan logical device, error code: " + std::to_string(res)); throw std::runtime_error("Unable to create Vulkan logical device, error code: " + std::to_string(res));
} }
volkLoadDevice(m_handle);
vkGetDeviceQueue(m_handle, graphicsFamilyIndex.value(), 0, &graphicsQueue);
} }
Device(const Device&) = delete; Device(const Device&) = delete;
Device& operator=(const Device&) = delete; Device& operator=(const Device&) = delete;
~Device() ~Device()
{ {
TRACE("Destroying device...");
vkDestroyDevice(m_handle, nullptr); vkDestroyDevice(m_handle, nullptr);
} }
@ -429,27 +466,19 @@ namespace engine::gfx {
std::shared_ptr<Instance> m_instance; std::shared_ptr<Instance> m_instance;
VkDevice m_handle; VkDevice m_handle;
VkQueue graphicsQueue = VK_NULL_HANDLE;
}; };
std::unique_ptr<LayerInfo> m_layerInfo; std::unique_ptr<LayerInfo> m_layerInfo;
std::shared_ptr<Instance> m_instance; std::shared_ptr<Instance> m_instance;
std::unique_ptr<DebugMessenger> m_debugMessenger; // uses instance std::unique_ptr<DebugMessenger> m_debugMessenger; // uses instance
std::unique_ptr<Surface> m_surface; // uses instance
std::unique_ptr<Device> m_device; // uses instance std::unique_ptr<Device> m_device; // uses instance
/*
void createSurface(SDL_Window* window)
{
if (SDL_Vulkan_CreateSurface(window, m_instance, &m_surface) == false) {
CRITICAL("Unable to create window surface");
throw std::runtime_error("Unable to create window surface");
}
}
*/
}; };
Device::Device(AppInfo appInfo, SDL_Window* window) GFXDevice::GFXDevice(AppInfo appInfo, SDL_Window* window)
{ {
VkResult res; VkResult res;
res = volkInitialize(); res = volkInitialize();
@ -463,10 +492,11 @@ namespace engine::gfx {
} }
Device::~Device() GFXDevice::~GFXDevice()
{ {
TRACE("Destroying GFXDevice...");
} }
} }
#endif #endif