Compare commits
2 Commits
f4e77e30a8
...
46d5e41e29
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
46d5e41e29 | ||
|
|
e887b2b393 |
6
main.cpp
6
main.cpp
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
namespace PB::Renderer
|
namespace PB::Renderer
|
||||||
{
|
{
|
||||||
void CleanupAllAndExit(int code)
|
void CleanupAllAndExit(const int code)
|
||||||
{
|
{
|
||||||
if (!GLFWManager::Cleanup())
|
if (!GLFWManager::Cleanup())
|
||||||
std::exit(EXIT_FAILURE);
|
std::exit(EXIT_FAILURE);
|
||||||
@@ -30,7 +30,7 @@ int main()
|
|||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* Runs Vulkan initialisation functions */
|
/* Runs Vulkan initialisation functions */
|
||||||
if (!VulkanManager::InitAll(window))
|
if (!VulkanManager::Init(window))
|
||||||
CleanupAllAndExit(EXIT_FAILURE);
|
CleanupAllAndExit(EXIT_FAILURE);
|
||||||
|
|
||||||
/* Polls window events whilst it is still open */
|
/* Polls window events whilst it is still open */
|
||||||
@@ -38,7 +38,7 @@ int main()
|
|||||||
{
|
{
|
||||||
glfwPollEvents();
|
glfwPollEvents();
|
||||||
|
|
||||||
if (!VulkanManager::RenderPass(window))
|
if (!VulkanManager::RenderPass())
|
||||||
CleanupAllAndExit(EXIT_FAILURE);
|
CleanupAllAndExit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,12 +6,16 @@ namespace PB::Renderer
|
|||||||
{
|
{
|
||||||
struct QueueFamilyIndices
|
struct QueueFamilyIndices
|
||||||
{
|
{
|
||||||
std::optional<uint32_t> graphicsFamily = std::nullopt;
|
static constexpr uint32_t UNDEFINED_UINT32_VALUE = 0xFFFFFFFF;
|
||||||
std::optional<uint32_t> presentFamily = std::nullopt;
|
|
||||||
|
uint32_t graphicsFamily = UNDEFINED_UINT32_VALUE;
|
||||||
|
uint32_t presentFamily = UNDEFINED_UINT32_VALUE;
|
||||||
|
|
||||||
[[nodiscard]] bool Complete() const
|
[[nodiscard]] bool Complete() const
|
||||||
{
|
{
|
||||||
return graphicsFamily && presentFamily;
|
return
|
||||||
|
graphicsFamily != UNDEFINED_UINT32_VALUE &&
|
||||||
|
presentFamily != UNDEFINED_UINT32_VALUE;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -25,14 +29,15 @@ namespace PB::Renderer
|
|||||||
class VulkanManager
|
class VulkanManager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
/* Static class so (de)constructors have been deleted to stop accidental creation */
|
||||||
VulkanManager() = delete;
|
VulkanManager() = delete;
|
||||||
~VulkanManager() = delete;
|
~VulkanManager() = delete;
|
||||||
|
|
||||||
static bool InitAll(GLFWwindow* window);
|
static bool Init(GLFWwindow* window);
|
||||||
static std::optional<VkInstance> Init();
|
|
||||||
static bool Cleanup();
|
static bool Cleanup();
|
||||||
|
|
||||||
static std::optional<VkSurfaceKHR> CreateSurface(GLFWwindow* window);
|
static bool CreateInstance();
|
||||||
|
static bool CreateSurface(GLFWwindow* window);
|
||||||
static bool PickPhysicalDevice();
|
static bool PickPhysicalDevice();
|
||||||
static bool CreateLogicalDevice();
|
static bool CreateLogicalDevice();
|
||||||
static bool CreateSwapChain(GLFWwindow* window);
|
static bool CreateSwapChain(GLFWwindow* window);
|
||||||
@@ -41,14 +46,14 @@ namespace PB::Renderer
|
|||||||
static bool CreateFramebuffer();
|
static bool CreateFramebuffer();
|
||||||
static bool CreateGraphicsPipeline();
|
static bool CreateGraphicsPipeline();
|
||||||
static bool CreateCommandBuffers();
|
static bool CreateCommandBuffers();
|
||||||
static void CreateSemaphores();
|
static bool CreateSemaphores();
|
||||||
|
|
||||||
static bool RenderPass(GLFWwindow* window);
|
static bool RenderPass();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static bool IsDeviceSuitable(VkPhysicalDevice device, VkSurfaceKHR surface);
|
static bool IsDeviceSuitable(const VkPhysicalDevice& device);
|
||||||
static QueueFamilyIndices FindQueueFamilies(VkPhysicalDevice device, VkSurfaceKHR surface);
|
static QueueFamilyIndices FindQueueFamilies(const VkPhysicalDevice& device);
|
||||||
static bool CheckDeviceExtensionSupport(VkPhysicalDevice device);
|
static bool CheckDeviceExtensionSupport(const VkPhysicalDevice& device);
|
||||||
|
|
||||||
static SwapChainSupportDetails QuerySwapChainSupport();
|
static SwapChainSupportDetails QuerySwapChainSupport();
|
||||||
static VkSurfaceFormatKHR ChooseSurfaceFormat(const std::vector<VkSurfaceFormatKHR>& availableFormats);
|
static VkSurfaceFormatKHR ChooseSurfaceFormat(const std::vector<VkSurfaceFormatKHR>& availableFormats);
|
||||||
@@ -57,8 +62,8 @@ namespace PB::Renderer
|
|||||||
|
|
||||||
static VkShaderModule CreateShaderModule(const std::string& filename);
|
static VkShaderModule CreateShaderModule(const std::string& filename);
|
||||||
|
|
||||||
static std::optional<VkInstance> s_Instance;
|
static VkInstance s_Instance;
|
||||||
static std::optional<VkSurfaceKHR> s_Surface;
|
static VkSurfaceKHR s_Surface;
|
||||||
|
|
||||||
static VkPhysicalDevice s_PhysicalDevice;
|
static VkPhysicalDevice s_PhysicalDevice;
|
||||||
static QueueFamilyIndices s_QueueIndices;
|
static QueueFamilyIndices s_QueueIndices;
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
namespace PB::Renderer
|
namespace PB::Renderer
|
||||||
{
|
{
|
||||||
std::optional<VkInstance> VulkanManager::s_Instance = std::nullopt;
|
VkInstance VulkanManager::s_Instance = VK_NULL_HANDLE;
|
||||||
std::optional<VkSurfaceKHR> VulkanManager::s_Surface = std::nullopt;
|
VkSurfaceKHR VulkanManager::s_Surface = VK_NULL_HANDLE;
|
||||||
|
|
||||||
VkPhysicalDevice VulkanManager::s_PhysicalDevice = VK_NULL_HANDLE;
|
VkPhysicalDevice VulkanManager::s_PhysicalDevice = VK_NULL_HANDLE;
|
||||||
QueueFamilyIndices VulkanManager::s_QueueIndices;
|
QueueFamilyIndices VulkanManager::s_QueueIndices;
|
||||||
@@ -14,54 +14,85 @@ namespace PB::Renderer
|
|||||||
VkQueue VulkanManager::s_PresentQueue = VK_NULL_HANDLE;
|
VkQueue VulkanManager::s_PresentQueue = VK_NULL_HANDLE;
|
||||||
|
|
||||||
VkSwapchainKHR VulkanManager::s_SwapChain = VK_NULL_HANDLE;
|
VkSwapchainKHR VulkanManager::s_SwapChain = VK_NULL_HANDLE;
|
||||||
std::vector<VkImage> VulkanManager::s_SwapChainImages = {};
|
std::vector<VkImage> VulkanManager::s_SwapChainImages;
|
||||||
std::vector<VkImageView> VulkanManager::s_SwapChainImageViews = {};
|
std::vector<VkImageView> VulkanManager::s_SwapChainImageViews;
|
||||||
VkFormat VulkanManager::s_SwapChainImageFormat = {};
|
VkFormat VulkanManager::s_SwapChainImageFormat = {};
|
||||||
VkExtent2D VulkanManager::s_SwapChainExtent = {};
|
VkExtent2D VulkanManager::s_SwapChainExtent;
|
||||||
|
|
||||||
VkRenderPass VulkanManager::s_RenderPass = VK_NULL_HANDLE;
|
VkRenderPass VulkanManager::s_RenderPass = VK_NULL_HANDLE;
|
||||||
std::vector<VkFramebuffer> VulkanManager::s_Framebuffers = {};
|
std::vector<VkFramebuffer> VulkanManager::s_Framebuffers;
|
||||||
|
|
||||||
VkPipelineLayout VulkanManager::s_PipelineLayout = {};
|
VkPipelineLayout VulkanManager::s_PipelineLayout = {};
|
||||||
VkPipeline VulkanManager::s_RenderPipeline = {};
|
VkPipeline VulkanManager::s_RenderPipeline = {};
|
||||||
|
|
||||||
VkCommandPool VulkanManager::s_CommandPool = VK_NULL_HANDLE;
|
VkCommandPool VulkanManager::s_CommandPool = VK_NULL_HANDLE;
|
||||||
std::vector<VkCommandBuffer> VulkanManager::s_CommandBuffers = {};
|
std::vector<VkCommandBuffer> VulkanManager::s_CommandBuffers;
|
||||||
|
|
||||||
VkSemaphore VulkanManager::s_ImageAvailableSemaphore = VK_NULL_HANDLE;
|
VkSemaphore VulkanManager::s_ImageAvailableSemaphore = VK_NULL_HANDLE;
|
||||||
VkSemaphore VulkanManager::s_RenderFinishedSemaphore = VK_NULL_HANDLE;
|
VkSemaphore VulkanManager::s_RenderFinishedSemaphore = VK_NULL_HANDLE;
|
||||||
|
|
||||||
bool VulkanManager::InitAll(GLFWwindow* window)
|
bool VulkanManager::Init(GLFWwindow* window)
|
||||||
{
|
{
|
||||||
if (const std::optional<VkInstance> instance = VulkanManager::Init(); !instance)
|
return
|
||||||
return false;
|
CreateInstance() &&
|
||||||
|
CreateSurface(window) &&
|
||||||
|
PickPhysicalDevice() &&
|
||||||
|
CreateLogicalDevice() &&
|
||||||
|
CreateSwapChain(window) &&
|
||||||
|
CreateImageViews() &&
|
||||||
|
CreateRenderPass() &&
|
||||||
|
CreateFramebuffer() &&
|
||||||
|
CreateGraphicsPipeline() &&
|
||||||
|
CreateCommandBuffers() &&
|
||||||
|
CreateSemaphores();
|
||||||
|
}
|
||||||
|
|
||||||
if (const std::optional<VkSurfaceKHR> surface = VulkanManager::CreateSurface(window); !surface)
|
bool VulkanManager::Cleanup()
|
||||||
return false;
|
{
|
||||||
|
if (s_Device != VK_NULL_HANDLE)
|
||||||
|
vkDeviceWaitIdle(s_Device);
|
||||||
|
|
||||||
if (!(
|
if (s_ImageAvailableSemaphore != VK_NULL_HANDLE)
|
||||||
VulkanManager::PickPhysicalDevice() &&
|
vkDestroySemaphore(s_Device, s_ImageAvailableSemaphore, nullptr);
|
||||||
VulkanManager::CreateLogicalDevice() &&
|
|
||||||
VulkanManager::CreateSwapChain(window) &&
|
if (s_RenderFinishedSemaphore != VK_NULL_HANDLE)
|
||||||
VulkanManager::CreateImageViews() &&
|
vkDestroySemaphore(s_Device, s_RenderFinishedSemaphore, nullptr);
|
||||||
VulkanManager::CreateRenderPass() &&
|
|
||||||
VulkanManager::CreateFramebuffer() &&
|
if (s_CommandPool != VK_NULL_HANDLE)
|
||||||
VulkanManager::CreateGraphicsPipeline() &&
|
vkDestroyCommandPool(s_Device, s_CommandPool, nullptr);
|
||||||
VulkanManager::CreateCommandBuffers()
|
|
||||||
)) {
|
for (const VkFramebuffer& fb : s_Framebuffers)
|
||||||
return false;
|
vkDestroyFramebuffer(s_Device, fb, nullptr);
|
||||||
}
|
|
||||||
|
if (s_RenderPipeline != VK_NULL_HANDLE)
|
||||||
|
vkDestroyPipeline(s_Device, s_RenderPipeline, nullptr);
|
||||||
|
|
||||||
|
if (s_PipelineLayout != VK_NULL_HANDLE)
|
||||||
|
vkDestroyPipelineLayout(s_Device, s_PipelineLayout, nullptr);
|
||||||
|
|
||||||
|
if (s_RenderPass != VK_NULL_HANDLE)
|
||||||
|
vkDestroyRenderPass(s_Device, s_RenderPass, nullptr);
|
||||||
|
|
||||||
|
for (const VkImageView& view : s_SwapChainImageViews)
|
||||||
|
vkDestroyImageView(s_Device, view, nullptr);
|
||||||
|
|
||||||
|
if (s_SwapChain != VK_NULL_HANDLE)
|
||||||
|
vkDestroySwapchainKHR(s_Device, s_SwapChain, nullptr);
|
||||||
|
|
||||||
|
if (s_Device != VK_NULL_HANDLE)
|
||||||
|
vkDestroyDevice(s_Device, nullptr);
|
||||||
|
|
||||||
|
if (s_Surface != VK_NULL_HANDLE)
|
||||||
|
vkDestroySurfaceKHR(s_Instance, s_Surface, nullptr);
|
||||||
|
|
||||||
|
if (s_Instance != VK_NULL_HANDLE)
|
||||||
|
vkDestroyInstance(s_Instance, nullptr);
|
||||||
|
|
||||||
VulkanManager::CreateSemaphores();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<VkInstance> VulkanManager::Init()
|
bool VulkanManager::CreateInstance()
|
||||||
{
|
{
|
||||||
/* Stops multi initialisation */
|
|
||||||
if (s_Instance != std::nullopt)
|
|
||||||
return s_Instance;
|
|
||||||
|
|
||||||
VkApplicationInfo appInfo;
|
VkApplicationInfo appInfo;
|
||||||
appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
|
appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
|
||||||
appInfo.pNext = nullptr;
|
appInfo.pNext = nullptr;
|
||||||
@@ -89,57 +120,30 @@ namespace PB::Renderer
|
|||||||
if (vkCreateInstance(&createInfo, nullptr, &instance) != VK_SUCCESS)
|
if (vkCreateInstance(&createInfo, nullptr, &instance) != VK_SUCCESS)
|
||||||
{
|
{
|
||||||
std::cout << "PB::Renderer::VulkanManager::Init(): Could not create Vulkan instance" << std::endl;
|
std::cout << "PB::Renderer::VulkanManager::Init(): Could not create Vulkan instance" << std::endl;
|
||||||
return std::nullopt;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
s_Instance = instance;
|
s_Instance = instance;
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool VulkanManager::Cleanup()
|
|
||||||
{
|
|
||||||
if (s_Surface != std::nullopt)
|
|
||||||
vkDestroySurfaceKHR(s_Instance.value(), s_Surface.value(), nullptr);
|
|
||||||
|
|
||||||
if (s_Instance != std::nullopt)
|
|
||||||
vkDestroyInstance(s_Instance.value(), nullptr);
|
|
||||||
|
|
||||||
s_Instance = std::nullopt;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<VkSurfaceKHR> VulkanManager::CreateSurface(GLFWwindow* window)
|
bool VulkanManager::CreateSurface(GLFWwindow* window)
|
||||||
{
|
{
|
||||||
if (s_Instance == std::nullopt)
|
|
||||||
{
|
|
||||||
std::cout << "PB::Renderer::VulkanManager::CreateSurface(): No Vulkan instance" << std::endl;
|
|
||||||
return std::nullopt;
|
|
||||||
}
|
|
||||||
|
|
||||||
VkSurfaceKHR surface;
|
VkSurfaceKHR surface;
|
||||||
if (glfwCreateWindowSurface(s_Instance.value(), window, nullptr, &surface) != VK_SUCCESS)
|
if (glfwCreateWindowSurface(s_Instance, window, nullptr, &surface) != VK_SUCCESS)
|
||||||
{
|
{
|
||||||
std::cout << "PB::Renderer::VulkanManager::CreateSurface(): Failed to create Vulkan Surface" << std::endl;
|
std::cout << "PB::Renderer::VulkanManager::CreateSurface(): Failed to create Vulkan Surface" << std::endl;
|
||||||
return std::nullopt;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
s_Surface = surface;
|
s_Surface = surface;
|
||||||
return surface;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VulkanManager::PickPhysicalDevice()
|
bool VulkanManager::PickPhysicalDevice()
|
||||||
{
|
{
|
||||||
if (s_Instance == std::nullopt || s_Surface == std::nullopt)
|
|
||||||
{
|
|
||||||
std::cout << "PB::Renderer::VulkanManager::PickPhysicalDevice(): No Vulkan instance or surface" << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const VkInstance& instance = s_Instance.value();
|
|
||||||
const VkSurfaceKHR& surface = s_Surface.value();
|
|
||||||
|
|
||||||
uint32_t deviceCount = 0;
|
uint32_t deviceCount = 0;
|
||||||
vkEnumeratePhysicalDevices(instance, &deviceCount, nullptr);
|
vkEnumeratePhysicalDevices(s_Instance, &deviceCount, nullptr);
|
||||||
if (deviceCount == 0)
|
if (deviceCount == 0)
|
||||||
{
|
{
|
||||||
std::cout << "PB::Renderer::VulkanManager::PickPhysicalDevice(): No GPU with Vulkan support" << std::endl;
|
std::cout << "PB::Renderer::VulkanManager::PickPhysicalDevice(): No GPU with Vulkan support" << std::endl;
|
||||||
@@ -147,14 +151,14 @@ namespace PB::Renderer
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::vector<VkPhysicalDevice> devices(deviceCount);
|
std::vector<VkPhysicalDevice> devices(deviceCount);
|
||||||
vkEnumeratePhysicalDevices(instance, &deviceCount, devices.data());
|
vkEnumeratePhysicalDevices(s_Instance, &deviceCount, devices.data());
|
||||||
|
|
||||||
for (const auto& device : devices)
|
for (const auto& device : devices)
|
||||||
{
|
{
|
||||||
if (IsDeviceSuitable(device, surface))
|
if (IsDeviceSuitable(device))
|
||||||
{
|
{
|
||||||
s_PhysicalDevice = device;
|
s_PhysicalDevice = device;
|
||||||
s_QueueIndices = FindQueueFamilies(device, surface);
|
s_QueueIndices = FindQueueFamilies(device);
|
||||||
|
|
||||||
VkPhysicalDeviceProperties deviceProperties;
|
VkPhysicalDeviceProperties deviceProperties;
|
||||||
vkGetPhysicalDeviceProperties(device, &deviceProperties);
|
vkGetPhysicalDeviceProperties(device, &deviceProperties);
|
||||||
@@ -169,9 +173,9 @@ namespace PB::Renderer
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VulkanManager::IsDeviceSuitable(VkPhysicalDevice device, VkSurfaceKHR surface)
|
bool VulkanManager::IsDeviceSuitable(const VkPhysicalDevice& device)
|
||||||
{
|
{
|
||||||
const QueueFamilyIndices indices = FindQueueFamilies(device, surface);
|
const QueueFamilyIndices indices = FindQueueFamilies(device);
|
||||||
|
|
||||||
if (const bool extensionsSupported = CheckDeviceExtensionSupport(device); !extensionsSupported)
|
if (const bool extensionsSupported = CheckDeviceExtensionSupport(device); !extensionsSupported)
|
||||||
return false;
|
return false;
|
||||||
@@ -179,9 +183,9 @@ namespace PB::Renderer
|
|||||||
VkSurfaceCapabilitiesKHR capabilities;
|
VkSurfaceCapabilitiesKHR capabilities;
|
||||||
uint32_t formatCount, presentCount;
|
uint32_t formatCount, presentCount;
|
||||||
|
|
||||||
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(device, surface, &capabilities);
|
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(device, s_Surface, &capabilities);
|
||||||
vkGetPhysicalDeviceSurfaceFormatsKHR(device, surface, &formatCount, nullptr);
|
vkGetPhysicalDeviceSurfaceFormatsKHR(device, s_Surface, &formatCount, nullptr);
|
||||||
vkGetPhysicalDeviceSurfacePresentModesKHR(device, surface, &presentCount, nullptr);
|
vkGetPhysicalDeviceSurfacePresentModesKHR(device, s_Surface, &presentCount, nullptr);
|
||||||
const bool swapChainAdequate = formatCount > 0 && presentCount > 0;
|
const bool swapChainAdequate = formatCount > 0 && presentCount > 0;
|
||||||
|
|
||||||
VkPhysicalDeviceProperties deviceProperties;
|
VkPhysicalDeviceProperties deviceProperties;
|
||||||
@@ -191,7 +195,7 @@ namespace PB::Renderer
|
|||||||
return indices.Complete() && swapChainAdequate && discreteGPU;
|
return indices.Complete() && swapChainAdequate && discreteGPU;
|
||||||
}
|
}
|
||||||
|
|
||||||
QueueFamilyIndices VulkanManager::FindQueueFamilies(VkPhysicalDevice device, VkSurfaceKHR surface)
|
QueueFamilyIndices VulkanManager::FindQueueFamilies(const VkPhysicalDevice& device)
|
||||||
{
|
{
|
||||||
QueueFamilyIndices indices;
|
QueueFamilyIndices indices;
|
||||||
|
|
||||||
@@ -209,7 +213,7 @@ namespace PB::Renderer
|
|||||||
}
|
}
|
||||||
|
|
||||||
VkBool32 presentSupport = false;
|
VkBool32 presentSupport = false;
|
||||||
vkGetPhysicalDeviceSurfaceSupportKHR(device, index, surface, &presentSupport);
|
vkGetPhysicalDeviceSurfaceSupportKHR(device, index, s_Surface, &presentSupport);
|
||||||
if (presentSupport)
|
if (presentSupport)
|
||||||
{
|
{
|
||||||
indices.presentFamily = index;
|
indices.presentFamily = index;
|
||||||
@@ -226,9 +230,9 @@ namespace PB::Renderer
|
|||||||
return indices;
|
return indices;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VulkanManager::CheckDeviceExtensionSupport(VkPhysicalDevice device)
|
bool VulkanManager::CheckDeviceExtensionSupport(const VkPhysicalDevice& device)
|
||||||
{
|
{
|
||||||
const std::vector<const char*> REQUIRED_EXTENSIONS = {
|
const std::vector REQUIRED_EXTENSIONS = {
|
||||||
VK_KHR_SWAPCHAIN_EXTENSION_NAME,
|
VK_KHR_SWAPCHAIN_EXTENSION_NAME,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -244,15 +248,14 @@ namespace PB::Renderer
|
|||||||
}
|
}
|
||||||
|
|
||||||
return required.empty();
|
return required.empty();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VulkanManager::CreateLogicalDevice()
|
bool VulkanManager::CreateLogicalDevice()
|
||||||
{
|
{
|
||||||
std::set<uint32_t> uniqueQueueFamilies =
|
std::set uniqueQueueFamilies =
|
||||||
{
|
{
|
||||||
s_QueueIndices.graphicsFamily.value(),
|
s_QueueIndices.graphicsFamily,
|
||||||
s_QueueIndices.presentFamily.value()
|
s_QueueIndices.presentFamily
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<VkDeviceQueueCreateInfo> queueCreateInfos;
|
std::vector<VkDeviceQueueCreateInfo> queueCreateInfos;
|
||||||
@@ -270,7 +273,7 @@ namespace PB::Renderer
|
|||||||
|
|
||||||
VkPhysicalDeviceFeatures deviceFeatures{};
|
VkPhysicalDeviceFeatures deviceFeatures{};
|
||||||
|
|
||||||
const std::vector<const char*> extensions = {
|
const std::vector extensions = {
|
||||||
VK_KHR_SWAPCHAIN_EXTENSION_NAME
|
VK_KHR_SWAPCHAIN_EXTENSION_NAME
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -288,8 +291,8 @@ namespace PB::Renderer
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
vkGetDeviceQueue(s_Device, s_QueueIndices.graphicsFamily.value(), 0, &s_GraphicsQueue);
|
vkGetDeviceQueue(s_Device, s_QueueIndices.graphicsFamily, 0, &s_GraphicsQueue);
|
||||||
vkGetDeviceQueue(s_Device, s_QueueIndices.presentFamily.value(), 0, &s_PresentQueue);
|
vkGetDeviceQueue(s_Device, s_QueueIndices.presentFamily, 0, &s_PresentQueue);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -308,7 +311,7 @@ namespace PB::Renderer
|
|||||||
|
|
||||||
VkSwapchainCreateInfoKHR createInfo{};
|
VkSwapchainCreateInfoKHR createInfo{};
|
||||||
createInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
|
createInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
|
||||||
createInfo.surface = s_Surface.value();
|
createInfo.surface = s_Surface;
|
||||||
|
|
||||||
createInfo.minImageCount = imageCount;
|
createInfo.minImageCount = imageCount;
|
||||||
createInfo.imageFormat = format;
|
createInfo.imageFormat = format;
|
||||||
@@ -319,11 +322,11 @@ namespace PB::Renderer
|
|||||||
|
|
||||||
const uint32_t queueFamilyIndices[] =
|
const uint32_t queueFamilyIndices[] =
|
||||||
{
|
{
|
||||||
s_QueueIndices.graphicsFamily.value(),
|
s_QueueIndices.graphicsFamily,
|
||||||
s_QueueIndices.presentFamily.value()
|
s_QueueIndices.presentFamily
|
||||||
};
|
};
|
||||||
|
|
||||||
if (s_QueueIndices.graphicsFamily.value() != s_QueueIndices.presentFamily.value())
|
if (s_QueueIndices.graphicsFamily != s_QueueIndices.presentFamily)
|
||||||
{
|
{
|
||||||
createInfo.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
|
createInfo.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
|
||||||
createInfo.queueFamilyIndexCount = 2;
|
createInfo.queueFamilyIndexCount = 2;
|
||||||
@@ -361,18 +364,17 @@ namespace PB::Renderer
|
|||||||
SwapChainSupportDetails VulkanManager::QuerySwapChainSupport()
|
SwapChainSupportDetails VulkanManager::QuerySwapChainSupport()
|
||||||
{
|
{
|
||||||
SwapChainSupportDetails details;
|
SwapChainSupportDetails details;
|
||||||
const VkSurfaceKHR surface = s_Surface.value();
|
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(s_PhysicalDevice, s_Surface, &details.capabilities);
|
||||||
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(s_PhysicalDevice, surface, &details.capabilities);
|
|
||||||
|
|
||||||
uint32_t formatCount;
|
uint32_t formatCount;
|
||||||
vkGetPhysicalDeviceSurfaceFormatsKHR(s_PhysicalDevice, surface, &formatCount, nullptr);
|
vkGetPhysicalDeviceSurfaceFormatsKHR(s_PhysicalDevice, s_Surface, &formatCount, nullptr);
|
||||||
details.formats.resize(formatCount);
|
details.formats.resize(formatCount);
|
||||||
vkGetPhysicalDeviceSurfaceFormatsKHR(s_PhysicalDevice, surface, &formatCount, details.formats.data());
|
vkGetPhysicalDeviceSurfaceFormatsKHR(s_PhysicalDevice, s_Surface, &formatCount, details.formats.data());
|
||||||
|
|
||||||
uint32_t presentModeCount;
|
uint32_t presentModeCount;
|
||||||
vkGetPhysicalDeviceSurfacePresentModesKHR(s_PhysicalDevice, surface, &presentModeCount, nullptr);
|
vkGetPhysicalDeviceSurfacePresentModesKHR(s_PhysicalDevice, s_Surface, &presentModeCount, nullptr);
|
||||||
details.presentModes.resize(presentModeCount);
|
details.presentModes.resize(presentModeCount);
|
||||||
vkGetPhysicalDeviceSurfacePresentModesKHR(s_PhysicalDevice, surface, &presentModeCount, details.presentModes.data());
|
vkGetPhysicalDeviceSurfacePresentModesKHR(s_PhysicalDevice, s_Surface, &presentModeCount, details.presentModes.data());
|
||||||
|
|
||||||
return details;
|
return details;
|
||||||
}
|
}
|
||||||
@@ -614,7 +616,10 @@ namespace PB::Renderer
|
|||||||
pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
|
pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
|
||||||
|
|
||||||
if (vkCreatePipelineLayout(s_Device, &pipelineLayoutInfo, nullptr, &s_PipelineLayout) != VK_SUCCESS)
|
if (vkCreatePipelineLayout(s_Device, &pipelineLayoutInfo, nullptr, &s_PipelineLayout) != VK_SUCCESS)
|
||||||
|
{
|
||||||
|
std::cout << "PB::Renderer::VulkanManager::CreateGraphicsPipeline(): Could not make pipeline layout" << std::endl;
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
VkGraphicsPipelineCreateInfo pipelineInfo{};
|
VkGraphicsPipelineCreateInfo pipelineInfo{};
|
||||||
pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
|
pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
|
||||||
@@ -631,7 +636,10 @@ namespace PB::Renderer
|
|||||||
pipelineInfo.subpass = 0;
|
pipelineInfo.subpass = 0;
|
||||||
|
|
||||||
if (vkCreateGraphicsPipelines(s_Device, VK_NULL_HANDLE, 1, &pipelineInfo, nullptr, &s_RenderPipeline) != VK_SUCCESS)
|
if (vkCreateGraphicsPipelines(s_Device, VK_NULL_HANDLE, 1, &pipelineInfo, nullptr, &s_RenderPipeline) != VK_SUCCESS)
|
||||||
|
{
|
||||||
|
std::cout << "PB::Renderer::VulkanManager::CreateGraphicsPipeline(): Could not make graphics pipeline" << std::endl;
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
vkDestroyShaderModule(s_Device, vertShaderModule, nullptr);
|
vkDestroyShaderModule(s_Device, vertShaderModule, nullptr);
|
||||||
vkDestroyShaderModule(s_Device, fragShaderModule, nullptr);
|
vkDestroyShaderModule(s_Device, fragShaderModule, nullptr);
|
||||||
@@ -651,7 +659,7 @@ namespace PB::Renderer
|
|||||||
const size_t fileSize = file.tellg();
|
const size_t fileSize = file.tellg();
|
||||||
std::vector<char> buffer(fileSize);
|
std::vector<char> buffer(fileSize);
|
||||||
file.seekg(0);
|
file.seekg(0);
|
||||||
file.read(buffer.data(), fileSize);
|
file.read(buffer.data(), static_cast<std::streamsize>(fileSize));
|
||||||
file.close();
|
file.close();
|
||||||
|
|
||||||
VkShaderModuleCreateInfo createInfo{};
|
VkShaderModuleCreateInfo createInfo{};
|
||||||
@@ -673,10 +681,13 @@ namespace PB::Renderer
|
|||||||
VkCommandPoolCreateInfo poolInfo{};
|
VkCommandPoolCreateInfo poolInfo{};
|
||||||
poolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
|
poolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
|
||||||
poolInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
|
poolInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
|
||||||
poolInfo.queueFamilyIndex = s_QueueIndices.graphicsFamily.value();
|
poolInfo.queueFamilyIndex = s_QueueIndices.graphicsFamily;
|
||||||
|
|
||||||
if (vkCreateCommandPool(s_Device, &poolInfo, nullptr, &s_CommandPool) != VK_SUCCESS)
|
if (vkCreateCommandPool(s_Device, &poolInfo, nullptr, &s_CommandPool) != VK_SUCCESS)
|
||||||
|
{
|
||||||
|
std::cout << "PB::Renderer::VulkanManager::CreateCommandBuffers(): Could not create command pool" << std::endl;
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
s_CommandBuffers.resize(s_Framebuffers.size());
|
s_CommandBuffers.resize(s_Framebuffers.size());
|
||||||
|
|
||||||
@@ -686,8 +697,11 @@ namespace PB::Renderer
|
|||||||
allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
|
allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
|
||||||
allocInfo.commandBufferCount = static_cast<uint32_t>(s_CommandBuffers.size());
|
allocInfo.commandBufferCount = static_cast<uint32_t>(s_CommandBuffers.size());
|
||||||
|
|
||||||
if (vkAllocateCommandBuffers(s_Device, &allocInfo, s_CommandBuffers.data()) != VK_SUCCESS) // <- Crashes here
|
if (vkAllocateCommandBuffers(s_Device, &allocInfo, s_CommandBuffers.data()) != VK_SUCCESS)
|
||||||
|
{
|
||||||
|
std::cout << "PB::Renderer::VulkanManager::CreateCommandBuffers(): Could not allocate command buffers" << std::endl;
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < s_CommandBuffers.size(); i++)
|
for (size_t i = 0; i < s_CommandBuffers.size(); i++)
|
||||||
{
|
{
|
||||||
@@ -716,18 +730,32 @@ namespace PB::Renderer
|
|||||||
vkCmdEndRenderPass(s_CommandBuffers[i]);
|
vkCmdEndRenderPass(s_CommandBuffers[i]);
|
||||||
|
|
||||||
if (vkEndCommandBuffer(s_CommandBuffers[i]) != VK_SUCCESS)
|
if (vkEndCommandBuffer(s_CommandBuffers[i]) != VK_SUCCESS)
|
||||||
|
{
|
||||||
|
std::cout << "PB::Renderer::VulkanManager::CreateCommandBuffers(): Could not end command buffer" << std::endl;
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanManager::CreateSemaphores()
|
bool VulkanManager::CreateSemaphores()
|
||||||
{
|
{
|
||||||
VkSemaphoreCreateInfo createInfo{};
|
VkSemaphoreCreateInfo createInfo{};
|
||||||
createInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
|
createInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
|
||||||
|
|
||||||
vkCreateSemaphore(s_Device, &createInfo, nullptr, &s_ImageAvailableSemaphore);
|
if (vkCreateSemaphore(s_Device, &createInfo, nullptr, &s_ImageAvailableSemaphore) != VK_SUCCESS)
|
||||||
vkCreateSemaphore(s_Device, &createInfo, nullptr, &s_RenderFinishedSemaphore);
|
{
|
||||||
|
std::cout << "PB::Renderer::VulkanManager::CreateSemaphores(): Could not create semaphore" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vkCreateSemaphore(s_Device, &createInfo, nullptr, &s_RenderFinishedSemaphore) != VK_SUCCESS)
|
||||||
|
{
|
||||||
|
std::cout << "PB::Renderer::VulkanManager::CreateSemaphores(): Could not create semaphore" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
namespace PB::Renderer
|
namespace PB::Renderer
|
||||||
{
|
{
|
||||||
bool VulkanManager::RenderPass(GLFWwindow* window)
|
bool VulkanManager::RenderPass()
|
||||||
{
|
{
|
||||||
uint32_t imageIndex;
|
uint32_t imageIndex;
|
||||||
VkResult result = vkAcquireNextImageKHR(
|
VkResult result = vkAcquireNextImageKHR(
|
||||||
@@ -28,8 +28,8 @@ namespace PB::Renderer
|
|||||||
VkSubmitInfo submitInfo{};
|
VkSubmitInfo submitInfo{};
|
||||||
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||||
|
|
||||||
VkSemaphore waitSemaphores[] = { s_ImageAvailableSemaphore };
|
const VkSemaphore waitSemaphores[] = { s_ImageAvailableSemaphore };
|
||||||
VkPipelineStageFlags waitStages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT };
|
constexpr VkPipelineStageFlags waitStages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT };
|
||||||
submitInfo.waitSemaphoreCount = 1;
|
submitInfo.waitSemaphoreCount = 1;
|
||||||
submitInfo.pWaitSemaphores = waitSemaphores;
|
submitInfo.pWaitSemaphores = waitSemaphores;
|
||||||
submitInfo.pWaitDstStageMask = waitStages;
|
submitInfo.pWaitDstStageMask = waitStages;
|
||||||
@@ -37,7 +37,7 @@ namespace PB::Renderer
|
|||||||
submitInfo.commandBufferCount = 1;
|
submitInfo.commandBufferCount = 1;
|
||||||
submitInfo.pCommandBuffers = &s_CommandBuffers[imageIndex];
|
submitInfo.pCommandBuffers = &s_CommandBuffers[imageIndex];
|
||||||
|
|
||||||
VkSemaphore signalSemaphores[] = { s_RenderFinishedSemaphore };
|
const VkSemaphore signalSemaphores[] = { s_RenderFinishedSemaphore };
|
||||||
submitInfo.signalSemaphoreCount = 1;
|
submitInfo.signalSemaphoreCount = 1;
|
||||||
submitInfo.pSignalSemaphores = signalSemaphores;
|
submitInfo.pSignalSemaphores = signalSemaphores;
|
||||||
|
|
||||||
@@ -52,7 +52,7 @@ namespace PB::Renderer
|
|||||||
presentInfo.waitSemaphoreCount = 1;
|
presentInfo.waitSemaphoreCount = 1;
|
||||||
presentInfo.pWaitSemaphores = signalSemaphores;
|
presentInfo.pWaitSemaphores = signalSemaphores;
|
||||||
|
|
||||||
VkSwapchainKHR swapChains[] = { s_SwapChain };
|
const VkSwapchainKHR swapChains[] = { s_SwapChain };
|
||||||
presentInfo.swapchainCount = 1;
|
presentInfo.swapchainCount = 1;
|
||||||
presentInfo.pSwapchains = swapChains;
|
presentInfo.pSwapchains = swapChains;
|
||||||
presentInfo.pImageIndices = &imageIndex;
|
presentInfo.pImageIndices = &imageIndex;
|
||||||
@@ -64,7 +64,7 @@ namespace PB::Renderer
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (result != VK_SUCCESS)
|
if (result != VK_SUCCESS)
|
||||||
{
|
{
|
||||||
std::cout << "PB::Renderer::VulkanManager::RenderPass(): Failed to present swap chain image!" << std::endl;
|
std::cout << "PB::Renderer::VulkanManager::RenderPass(): Failed to present swap chain image!" << std::endl;
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
Reference in New Issue
Block a user