Reached shader lessons. Stopping to refactor code.
This commit is contained in:
@@ -89,7 +89,6 @@ cpp_includes_use_forward_slash = true
|
|||||||
[*.{cpp,h}]
|
[*.{cpp,h}]
|
||||||
|
|
||||||
# Naming convention rules (note: currently need to be ordered from more to less specific)
|
# Naming convention rules (note: currently need to be ordered from more to less specific)
|
||||||
|
|
||||||
cpp_naming_rule.aactor_prefixed.symbols = aactor_class
|
cpp_naming_rule.aactor_prefixed.symbols = aactor_class
|
||||||
cpp_naming_rule.aactor_prefixed.style = aactor_style
|
cpp_naming_rule.aactor_prefixed.style = aactor_style
|
||||||
|
|
||||||
@@ -115,7 +114,6 @@ cpp_naming_rule.general_names.symbols = all_symbols
|
|||||||
cpp_naming_rule.general_names.style = unreal_engine_default
|
cpp_naming_rule.general_names.style = unreal_engine_default
|
||||||
|
|
||||||
# Naming convention symbols
|
# Naming convention symbols
|
||||||
|
|
||||||
cpp_naming_symbols.aactor_class.applicable_kinds = class
|
cpp_naming_symbols.aactor_class.applicable_kinds = class
|
||||||
cpp_naming_symbols.aactor_class.applicable_type = AActor
|
cpp_naming_symbols.aactor_class.applicable_type = AActor
|
||||||
|
|
||||||
@@ -137,6 +135,15 @@ cpp_naming_symbols.structs.applicable_kinds = struct
|
|||||||
cpp_naming_symbols.all_symbols.applicable_kinds = *
|
cpp_naming_symbols.all_symbols.applicable_kinds = *
|
||||||
|
|
||||||
# Naming convention styles
|
# Naming convention styles
|
||||||
|
cpp_naming_style.member_variables_style.capitalization = camel_case
|
||||||
|
cpp_naming_style.member_variables_style.required_prefix = m_
|
||||||
|
cpp_naming_style.member_variables_style.required_suffix =
|
||||||
|
cpp_naming_style.member_variables_style.word_separator =
|
||||||
|
|
||||||
|
cpp_naming_style.parameters_in_style.capitalization = camel_case
|
||||||
|
cpp_naming_style.parameters_in_style.required_prefix = in_
|
||||||
|
cpp_naming_style.parameters_in_style.required_suffix =
|
||||||
|
cpp_naming_style.parameters_in_style.word_separator =
|
||||||
|
|
||||||
cpp_naming_style.unreal_engine_default.capitalization = pascal_case
|
cpp_naming_style.unreal_engine_default.capitalization = pascal_case
|
||||||
cpp_naming_style.unreal_engine_default.required_prefix =
|
cpp_naming_style.unreal_engine_default.required_prefix =
|
||||||
|
|||||||
@@ -1,39 +1,40 @@
|
|||||||
#include "GlfwWindowManager.h"
|
#include "GlfwWindowManager.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#include "Logger.h"
|
#include "Logger.h"
|
||||||
|
|
||||||
// bool WindowManager::bGlfwInitialized = false;
|
VkSurfaceKHR GlfwWindowManager::Surface = VK_NULL_HANDLE;
|
||||||
|
GLFWwindow* GlfwWindowManager::Window = nullptr;
|
||||||
|
|
||||||
GlfwWindowManager::GlfwWindowManager() = default;
|
GlfwWindowManager::GlfwWindowManager() = default;
|
||||||
|
|
||||||
GlfwWindowManager::~GlfwWindowManager()
|
GlfwWindowManager::~GlfwWindowManager()
|
||||||
{
|
{
|
||||||
Cleanup();
|
// Cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
GlfwWindowManager::GlfwWindowManager(GlfwWindowManager&& Other) noexcept
|
// GlfwWindowManager::GlfwWindowManager(GlfwWindowManager&& Other) noexcept
|
||||||
: Window(Other.Window), Title(std::move(Other.Title)), Width(Other.Width), Height(Other.Height)
|
// : Window(Other.Window), Config(Other.Config), Surface(Other.Surface)
|
||||||
{
|
//{
|
||||||
Other.Window = nullptr;
|
// Other.Window = nullptr;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
GlfwWindowManager& GlfwWindowManager::operator=(GlfwWindowManager&& Other) noexcept
|
// GlfwWindowManager& GlfwWindowManager::operator=(GlfwWindowManager&& Other) noexcept
|
||||||
{
|
//{
|
||||||
if (this != &Other)
|
// if (this != &Other)
|
||||||
{
|
// {
|
||||||
Cleanup();
|
// Cleanup();
|
||||||
|
//
|
||||||
Window = Other.Window;
|
// Window = Other.Window;
|
||||||
Title = std::move(Other.Title);
|
// Config = Other.Config;
|
||||||
Width = Other.Width;
|
// Surface = Other.Surface;
|
||||||
Height = Other.Height;
|
//
|
||||||
|
// Other.Window = nullptr;
|
||||||
Other.Window = nullptr;
|
// }
|
||||||
}
|
//
|
||||||
|
// return *this;
|
||||||
return *this;
|
// }
|
||||||
}
|
|
||||||
|
|
||||||
void GlfwWindowManager::Initialize(const FWindowConfig& Config)
|
void GlfwWindowManager::Initialize(const FWindowConfig& Config)
|
||||||
{
|
{
|
||||||
@@ -42,29 +43,12 @@ void GlfwWindowManager::Initialize(const FWindowConfig& Config)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this->Config = Config;
|
||||||
|
|
||||||
InitializeGlfw();
|
InitializeGlfw();
|
||||||
|
|
||||||
Title = Config.Title;
|
|
||||||
Width = Config.Width;
|
|
||||||
Height = Config.Height;
|
|
||||||
|
|
||||||
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
|
||||||
glfwWindowHint(GLFW_RESIZABLE, Config.bResizable ? GLFW_TRUE : GLFW_FALSE);
|
|
||||||
|
|
||||||
Window = glfwCreateWindow(
|
|
||||||
Width,
|
|
||||||
Height,
|
|
||||||
Title.c_str(),
|
|
||||||
Config.bFullscreen ? glfwGetPrimaryMonitor() : nullptr,
|
|
||||||
nullptr);
|
|
||||||
|
|
||||||
if (!Window)
|
|
||||||
{
|
|
||||||
Log::Error("Failed to create GLFW window");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlfwWindowManager::Cleanup()
|
void GlfwWindowManager::Cleanup(VkInstance Instance)
|
||||||
{
|
{
|
||||||
if (!IsInitialized())
|
if (!IsInitialized())
|
||||||
{
|
{
|
||||||
@@ -100,7 +84,7 @@ void GlfwWindowManager::WaitEvents() const
|
|||||||
|
|
||||||
void GlfwWindowManager::SetTitle(const std::string& Title)
|
void GlfwWindowManager::SetTitle(const std::string& Title)
|
||||||
{
|
{
|
||||||
this->Title = Title;
|
// this->Title = Title;
|
||||||
|
|
||||||
if (Window)
|
if (Window)
|
||||||
{
|
{
|
||||||
@@ -108,20 +92,44 @@ void GlfwWindowManager::SetTitle(const std::string& Title)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VkSurfaceKHR GlfwWindowManager::CreateSurface(VkInstance Instance) const
|
void GlfwWindowManager::CreateSurface(VkInstance Instance)
|
||||||
{
|
{
|
||||||
if (!Window || !Instance)
|
if (!Window)
|
||||||
{
|
{
|
||||||
return VK_NULL_HANDLE;
|
Log::Error("Window not initialized.");
|
||||||
}
|
}
|
||||||
|
|
||||||
VkSurfaceKHR Surface = VK_NULL_HANDLE;
|
if (!Instance)
|
||||||
if (glfwCreateWindowSurface(Instance, Window, nullptr, &Surface) != VK_SUCCESS)
|
|
||||||
{
|
{
|
||||||
Log::Error("Failed to create window surface");
|
Log::Error("Instance is null.");
|
||||||
}
|
}
|
||||||
|
|
||||||
return Surface;
|
VkResult result = glfwCreateWindowSurface(Instance, Window, nullptr, &Surface);
|
||||||
|
if (result != VK_SUCCESS)
|
||||||
|
{
|
||||||
|
std::string errorMsg;
|
||||||
|
switch (result)
|
||||||
|
{
|
||||||
|
case VK_ERROR_EXTENSION_NOT_PRESENT:
|
||||||
|
errorMsg = "VK_ERROR_EXTENSION_NOT_PRESENT - Required extension not present";
|
||||||
|
break;
|
||||||
|
case VK_ERROR_INITIALIZATION_FAILED:
|
||||||
|
errorMsg = "VK_ERROR_INITIALIZATION_FAILED - Initialization failed";
|
||||||
|
break;
|
||||||
|
case VK_ERROR_NATIVE_WINDOW_IN_USE_KHR:
|
||||||
|
errorMsg = "VK_ERROR_NATIVE_WINDOW_IN_USE_KHR - Native window already in use";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
errorMsg = "Unknown error code: " + std::to_string(result);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log::Error("Failed to create window surface: " + errorMsg);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log::Info("Window surface created successfully.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlfwWindowManager::SetResizeCallback(GLFWwindowsizefun Callback)
|
void GlfwWindowManager::SetResizeCallback(GLFWwindowsizefun Callback)
|
||||||
@@ -182,4 +190,23 @@ void GlfwWindowManager::InitializeGlfw()
|
|||||||
Log::Error("Failed to initialize GLFW");
|
Log::Error("Failed to initialize GLFW");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
||||||
|
glfwWindowHint(GLFW_RESIZABLE, Config.bResizable ? GLFW_TRUE : GLFW_FALSE);
|
||||||
|
|
||||||
|
Window = glfwCreateWindow(
|
||||||
|
Config.Width,
|
||||||
|
Config.Height,
|
||||||
|
Config.Title.c_str(),
|
||||||
|
Config.bFullscreen ? glfwGetPrimaryMonitor() : nullptr,
|
||||||
|
nullptr);
|
||||||
|
|
||||||
|
if (!Window)
|
||||||
|
{
|
||||||
|
Log::Error("Failed to create GLFW window");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log::Info("Created GLFW window successfully.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,11 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#define VK_USE_PLATFORM_WIN32_KHR
|
||||||
#define GLFW_INCLUDE_VULKAN
|
#define GLFW_INCLUDE_VULKAN
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
#define GLFW_EXPOSE_NATIVE_WIN32
|
||||||
|
#include <GLFW/glfw3native.h>
|
||||||
|
|
||||||
struct FWindowConfig
|
struct FWindowConfig
|
||||||
{
|
{
|
||||||
@@ -20,14 +23,14 @@ public:
|
|||||||
GlfwWindowManager();
|
GlfwWindowManager();
|
||||||
~GlfwWindowManager();
|
~GlfwWindowManager();
|
||||||
|
|
||||||
GlfwWindowManager(const GlfwWindowManager&) = delete;
|
// GlfwWindowManager(const GlfwWindowManager&) = delete;
|
||||||
GlfwWindowManager& operator=(const GlfwWindowManager&) = delete;
|
// GlfwWindowManager& operator=(const GlfwWindowManager&) = delete;
|
||||||
|
|
||||||
GlfwWindowManager(GlfwWindowManager&& Other) noexcept;
|
// GlfwWindowManager(GlfwWindowManager&& Other) noexcept;
|
||||||
GlfwWindowManager& operator=(GlfwWindowManager&& Other) noexcept;
|
// GlfwWindowManager& operator=(GlfwWindowManager&& Other) noexcept;
|
||||||
|
|
||||||
void Initialize(const FWindowConfig& Config);
|
void Initialize(const FWindowConfig& Config);
|
||||||
void Cleanup();
|
void Cleanup(VkInstance Instance);
|
||||||
|
|
||||||
bool ShouldClose() const;
|
bool ShouldClose() const;
|
||||||
void PollEvents();
|
void PollEvents();
|
||||||
@@ -35,12 +38,11 @@ public:
|
|||||||
void SetTitle(const std::string& Title);
|
void SetTitle(const std::string& Title);
|
||||||
|
|
||||||
GLFWwindow* GetHandle() const { return Window; }
|
GLFWwindow* GetHandle() const { return Window; }
|
||||||
uint32_t GetWidth() const { return Width; }
|
uint32_t GetWidth() const { return Config.Width; }
|
||||||
uint32_t GetHeight() const { return Height; }
|
uint32_t GetHeight() const { return Config.Height; }
|
||||||
const std::string& GetTitle() const { return Title; }
|
const std::string& GetTitle() const { return Config.Title; }
|
||||||
bool IsInitialized() const { return Window != nullptr; }
|
|
||||||
|
|
||||||
VkSurfaceKHR CreateSurface(VkInstance Instance) const;
|
bool IsInitialized() const { return Window && Surface; }
|
||||||
|
|
||||||
void SetResizeCallback(GLFWwindowsizefun Callback);
|
void SetResizeCallback(GLFWwindowsizefun Callback);
|
||||||
void SetKeyCallback(GLFWkeyfun Callback);
|
void SetKeyCallback(GLFWkeyfun Callback);
|
||||||
@@ -48,14 +50,18 @@ public:
|
|||||||
void SetCursorPositionCallback(GLFWcursorposfun Callback);
|
void SetCursorPositionCallback(GLFWcursorposfun Callback);
|
||||||
void SetScrollCallback(GLFWscrollfun Callback);
|
void SetScrollCallback(GLFWscrollfun Callback);
|
||||||
|
|
||||||
private:
|
void CreateSurface(VkInstance Instance);
|
||||||
// static bool bGlfwInitialized;
|
|
||||||
void InitializeGlfw();
|
|
||||||
|
|
||||||
GLFWwindow* Window = nullptr;
|
static VkSurfaceKHR Surface;
|
||||||
std::string Title;
|
|
||||||
uint32_t Width = 0;
|
static GLFWwindow* Window;
|
||||||
uint32_t Height = 0;
|
|
||||||
|
private:
|
||||||
|
FWindowConfig Config;
|
||||||
|
|
||||||
|
// VkSurfaceKHR Surface = VK_NULL_HANDLE;
|
||||||
|
|
||||||
|
void InitializeGlfw();
|
||||||
|
|
||||||
void DestroyWindow();
|
void DestroyWindow();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -131,6 +131,7 @@
|
|||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClCompile Include="VulkanContext.cpp" />
|
||||||
<ClCompile Include="VulkanDebugManager.cpp" />
|
<ClCompile Include="VulkanDebugManager.cpp" />
|
||||||
<ClCompile Include="main.cpp" />
|
<ClCompile Include="main.cpp" />
|
||||||
<ClCompile Include="Logger.cpp" />
|
<ClCompile Include="Logger.cpp" />
|
||||||
@@ -139,6 +140,9 @@
|
|||||||
<ClCompile Include="GlfwWindowManager.cpp" />
|
<ClCompile Include="GlfwWindowManager.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClInclude Include="VulkanGraphicsPipeline.h" />
|
||||||
|
<ClInclude Include="Utilities\FileReader.h" />
|
||||||
|
<ClInclude Include="VulkanContext.h" />
|
||||||
<ClInclude Include="VulkanDebugManager.h" />
|
<ClInclude Include="VulkanDebugManager.h" />
|
||||||
<ClInclude Include="Logger.h" />
|
<ClInclude Include="Logger.h" />
|
||||||
<ClInclude Include="VulkanDeviceManager.h" />
|
<ClInclude Include="VulkanDeviceManager.h" />
|
||||||
@@ -147,6 +151,8 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include=".clang-format" />
|
<None Include=".clang-format" />
|
||||||
|
<None Include="Shaders\shader.frag" />
|
||||||
|
<None Include="Shaders\shader.vert" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
|||||||
@@ -13,6 +13,9 @@
|
|||||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
<Filter Include="Shaders">
|
||||||
|
<UniqueIdentifier>{699a4173-18fe-4109-979d-1612d035b2d6}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="main.cpp">
|
<ClCompile Include="main.cpp">
|
||||||
@@ -33,6 +36,9 @@
|
|||||||
<ClCompile Include="VulkanDeviceManager.cpp">
|
<ClCompile Include="VulkanDeviceManager.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="VulkanContext.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="Logger.h">
|
<ClInclude Include="Logger.h">
|
||||||
@@ -50,8 +56,23 @@
|
|||||||
<ClInclude Include="VulkanDeviceManager.h">
|
<ClInclude Include="VulkanDeviceManager.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="VulkanContext.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="VulkanGraphicsPipeline.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Utilities\FileReader.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include=".clang-format" />
|
<None Include=".clang-format" />
|
||||||
|
<None Include="Shaders\shader.vert">
|
||||||
|
<Filter>Shaders</Filter>
|
||||||
|
</None>
|
||||||
|
<None Include="Shaders\shader.frag">
|
||||||
|
<Filter>Shaders</Filter>
|
||||||
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
3
Shaders/compile.bat
Normal file
3
Shaders/compile.bat
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
C:/Users/jorda/Development/Libraries/Vulkan/1.4.335.0/Bin/glslc.exe shader.vert -o vert.spv
|
||||||
|
C:/Users/jorda/Development/Libraries/Vulkan/1.4.335.0/Bin/glslc.exe shader.frag -o frag.spv
|
||||||
|
pause
|
||||||
BIN
Shaders/frag.spv
Normal file
BIN
Shaders/frag.spv
Normal file
Binary file not shown.
9
Shaders/shader.frag
Normal file
9
Shaders/shader.frag
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
#version 450
|
||||||
|
|
||||||
|
layout(location = 0) in vec3 fragColor;
|
||||||
|
|
||||||
|
layout(location = 0) out vec4 outColor;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
outColor = vec4(fragColor, 1.0);
|
||||||
|
}
|
||||||
20
Shaders/shader.vert
Normal file
20
Shaders/shader.vert
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
#version 450
|
||||||
|
|
||||||
|
layout(location = 0) out vec3 fragColor;
|
||||||
|
|
||||||
|
vec2 positions[3] = vec2[](
|
||||||
|
vec2(0.0, -0.5),
|
||||||
|
vec2(0.5, 0.5),
|
||||||
|
vec2(-0.5, 0.5)
|
||||||
|
);
|
||||||
|
|
||||||
|
vec3 colors[3] = vec3[](
|
||||||
|
vec3(1.0, 0.0, 0.0),
|
||||||
|
vec3(0.0, 1.0, 0.0),
|
||||||
|
vec3(0.0, 0.0, 1.0)
|
||||||
|
);
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
gl_Position = vec4(positions[gl_VertexIndex], 0.0, 1.0);
|
||||||
|
fragColor = colors[gl_VertexIndex];
|
||||||
|
}
|
||||||
BIN
Shaders/vert.spv
Normal file
BIN
Shaders/vert.spv
Normal file
Binary file not shown.
26
Utilities/FileReader.h
Normal file
26
Utilities/FileReader.h
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "Logger.h"
|
||||||
|
|
||||||
|
static std::vector<char> ReadFile(const std::string& FileName)
|
||||||
|
{
|
||||||
|
std::ifstream File(FileName, std::ios::ate | std::ios::binary);
|
||||||
|
|
||||||
|
if (!File.is_open())
|
||||||
|
{
|
||||||
|
Log::Error("Failed to open file: " + FileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t FileSize = (size_t)File.tellg();
|
||||||
|
std::vector<char> Buffer(FileSize);
|
||||||
|
|
||||||
|
File.seekg(0);
|
||||||
|
File.read(Buffer.data(), FileSize);
|
||||||
|
|
||||||
|
File.close();
|
||||||
|
|
||||||
|
return Buffer;
|
||||||
|
}
|
||||||
77
VkDebug.h
77
VkDebug.h
@@ -1,77 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#define GLFW_INCLUDE_VULKAN
|
|
||||||
#include <GLFW/glfw3.h>
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#ifdef NDEBUG
|
|
||||||
const bool enableValidationLayers = false;
|
|
||||||
#else
|
|
||||||
const bool enableValidationLayers = true;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
VkDebugUtilsMessengerEXT debugMessenger;
|
|
||||||
|
|
||||||
VkResult CreateDebugUtilsMessengerEXT(
|
|
||||||
VkInstance instance,
|
|
||||||
const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo,
|
|
||||||
const VkAllocationCallbacks* pAllocator,
|
|
||||||
VkDebugUtilsMessengerEXT* pDebugMessenger)
|
|
||||||
{
|
|
||||||
auto func = (PFN_vkCreateDebugUtilsMessengerEXT)vkGetInstanceProcAddr(instance, "vkCreateDebugUtilsMessengerEXT");
|
|
||||||
if (func != nullptr)
|
|
||||||
{
|
|
||||||
return func(instance, pCreateInfo, pAllocator, pDebugMessenger);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return VK_ERROR_EXTENSION_NOT_PRESENT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static VKAPI_ATTR VkBool32 VKAPI_CALL DebugCallback(
|
|
||||||
VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
|
|
||||||
VkDebugUtilsMessageTypeFlagsEXT messageType,
|
|
||||||
const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,
|
|
||||||
void* pUserData)
|
|
||||||
{
|
|
||||||
std::cerr << "validation layer: " << pCallbackData->pMessage << std::endl;
|
|
||||||
|
|
||||||
if (messageSeverity >= VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
return VK_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CheckValidationLayerSupport()
|
|
||||||
{
|
|
||||||
uint32_t layerCount;
|
|
||||||
vkEnumerateInstanceLayerProperties(&layerCount, nullptr);
|
|
||||||
|
|
||||||
std::vector<VkLayerProperties> availableLayers(layerCount);
|
|
||||||
vkEnumerateInstanceLayerProperties(&layerCount, availableLayers.data());
|
|
||||||
|
|
||||||
for (const char* layerName : validationLayers)
|
|
||||||
{
|
|
||||||
bool layerFound = false;
|
|
||||||
|
|
||||||
for (const auto& layerProperties : availableLayers)
|
|
||||||
{
|
|
||||||
if (strcmp(layerName, layerProperties.layerName) == 0)
|
|
||||||
{
|
|
||||||
layerFound = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!layerFound)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
65
VkSetup.h
65
VkSetup.h
@@ -1,65 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#define GLFW_INCLUDE_VULKAN
|
|
||||||
#include <GLFW/glfw3.h>
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#ifdef NDEBUG
|
|
||||||
const bool enableValidationLayers = false;
|
|
||||||
#else
|
|
||||||
const bool enableValidationLayers = true;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
class VkSetup
|
|
||||||
{
|
|
||||||
GLFWwindow* window;
|
|
||||||
|
|
||||||
VkInstance instance;
|
|
||||||
|
|
||||||
std::vector<const char*> GetRequiredExtensions()
|
|
||||||
{
|
|
||||||
uint32_t glfwExtensionCount = 0;
|
|
||||||
const char** glfwExtensions;
|
|
||||||
glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount);
|
|
||||||
|
|
||||||
std::vector<const char*> extensions(glfwExtensions, glfwExtensions + glfwExtensionCount);
|
|
||||||
|
|
||||||
if (enableValidationLayers)
|
|
||||||
{
|
|
||||||
extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
|
|
||||||
}
|
|
||||||
|
|
||||||
return extensions;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CheckValidationLayerSupport()
|
|
||||||
{
|
|
||||||
uint32_t layerCount;
|
|
||||||
vkEnumerateInstanceLayerProperties(&layerCount, nullptr);
|
|
||||||
|
|
||||||
std::vector<VkLayerProperties> availableLayers(layerCount);
|
|
||||||
vkEnumerateInstanceLayerProperties(&layerCount, availableLayers.data());
|
|
||||||
|
|
||||||
for (const char* layerName : validationLayers)
|
|
||||||
{
|
|
||||||
bool layerFound = false;
|
|
||||||
|
|
||||||
for (const auto& layerProperties : availableLayers)
|
|
||||||
{
|
|
||||||
if (strcmp(layerName, layerProperties.layerName) == 0)
|
|
||||||
{
|
|
||||||
layerFound = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!layerFound)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -1,11 +1,12 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <vector>
|
// #include <vector>
|
||||||
#include <memory>
|
// #include <memory>
|
||||||
|
//
|
||||||
#include "Logger.h"
|
#include "Logger.h"
|
||||||
#include "VulkanInstanceManager.h"
|
#include "VulkanInstanceManager.h"
|
||||||
#include "VulkanDeviceManager.h"
|
#include "VulkanDeviceManager.h"
|
||||||
#include "VulkanDebugManager.h"
|
#include "VulkanDebugManager.h"
|
||||||
|
#include "VulkanGraphicsPipeline.h"
|
||||||
#include "GlfwWindowManager.h"
|
#include "GlfwWindowManager.h"
|
||||||
|
|
||||||
#define GLFW_INCLUDE_VULKAN
|
#define GLFW_INCLUDE_VULKAN
|
||||||
@@ -27,7 +28,7 @@ public:
|
|||||||
VulkanContext();
|
VulkanContext();
|
||||||
~VulkanContext();
|
~VulkanContext();
|
||||||
|
|
||||||
void Initialize(FVulkanConfig& inConfig);
|
void Initialize(FVulkanConfig& Config);
|
||||||
void Cleanup();
|
void Cleanup();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -40,6 +41,12 @@ private:
|
|||||||
VkSurfaceKHR Surface = VK_NULL_HANDLE;
|
VkSurfaceKHR Surface = VK_NULL_HANDLE;
|
||||||
VkDebugUtilsMessengerEXT debugMessenger = VK_NULL_HANDLE;
|
VkDebugUtilsMessengerEXT debugMessenger = VK_NULL_HANDLE;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static VulkanDebugManager DebugManager;
|
||||||
|
|
||||||
|
private:
|
||||||
|
VulkanInstanceManager InstanceManager;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
VkInstance GetInstance() const { return Instance; }
|
VkInstance GetInstance() const { return Instance; }
|
||||||
VkPhysicalDevice GetPhysicalDevice() const { return PhysicalDevice; }
|
VkPhysicalDevice GetPhysicalDevice() const { return PhysicalDevice; }
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ VulkanDebugManager::VulkanDebugManager()
|
|||||||
|
|
||||||
VulkanDebugManager::~VulkanDebugManager()
|
VulkanDebugManager::~VulkanDebugManager()
|
||||||
{
|
{
|
||||||
Cleanup();
|
// Cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
VulkanDebugManager::VulkanDebugManager(VulkanDebugManager&& Other) noexcept
|
VulkanDebugManager::VulkanDebugManager(VulkanDebugManager&& Other) noexcept
|
||||||
@@ -30,6 +30,7 @@ VulkanDebugManager& VulkanDebugManager::operator=(VulkanDebugManager&& Other) no
|
|||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanDebugManager::Initialize(VkInstance Instance)
|
void VulkanDebugManager::Initialize(VkInstance Instance)
|
||||||
{
|
{
|
||||||
if (IsInitialized())
|
if (IsInitialized())
|
||||||
|
|||||||
@@ -1,9 +1,16 @@
|
|||||||
#include "VulkanDeviceManager.h"
|
#include "VulkanDeviceManager.h"
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
|
#include <cstdint> // Necessary for uint32_t
|
||||||
|
#include <limits> // Necessary for std::numeric_limits
|
||||||
|
#include <algorithm> // Necessary for std::clamp
|
||||||
|
|
||||||
#include "Logger.h"
|
#include "Logger.h"
|
||||||
#include <map>
|
#include "GlfwWindowManager.h"
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
std::vector<VkImage> VulkanDeviceManager::SwapChainImages = {};
|
||||||
|
|
||||||
VulkanDeviceManager::VulkanDeviceManager()
|
VulkanDeviceManager::VulkanDeviceManager()
|
||||||
{
|
{
|
||||||
@@ -11,10 +18,16 @@ VulkanDeviceManager::VulkanDeviceManager()
|
|||||||
|
|
||||||
VulkanDeviceManager::~VulkanDeviceManager()
|
VulkanDeviceManager::~VulkanDeviceManager()
|
||||||
{
|
{
|
||||||
Cleanup();
|
// Cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
VulkanDeviceManager::VulkanDeviceManager(VulkanDeviceManager&& Other) noexcept
|
VulkanDeviceManager::VulkanDeviceManager(VulkanDeviceManager&& Other) noexcept
|
||||||
|
: PhysicalDevice(std::exchange(Other.PhysicalDevice, VK_NULL_HANDLE))
|
||||||
|
, Instance(std::exchange(Other.Instance, VK_NULL_HANDLE))
|
||||||
|
, Device(std::exchange(Other.Device, VK_NULL_HANDLE))
|
||||||
|
, GraphicsQueue(std::exchange(Other.GraphicsQueue, VK_NULL_HANDLE))
|
||||||
|
, bEnableValidationLayers(std::exchange(Other.bEnableValidationLayers, false))
|
||||||
|
, ValidationLayers(std::move(Other.ValidationLayers))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -22,25 +35,55 @@ VulkanDeviceManager& VulkanDeviceManager::operator=(VulkanDeviceManager&& Other)
|
|||||||
{
|
{
|
||||||
if (this != &Other)
|
if (this != &Other)
|
||||||
{
|
{
|
||||||
Cleanup();
|
Cleanup(); // Clean up current resources
|
||||||
}
|
|
||||||
|
|
||||||
|
// Transfer resources from Other
|
||||||
|
PhysicalDevice = std::exchange(Other.PhysicalDevice, VK_NULL_HANDLE);
|
||||||
|
Instance = std::exchange(Other.Instance, VK_NULL_HANDLE);
|
||||||
|
Device = std::exchange(Other.Device, VK_NULL_HANDLE);
|
||||||
|
GraphicsQueue = std::exchange(Other.GraphicsQueue, VK_NULL_HANDLE);
|
||||||
|
bEnableValidationLayers = std::exchange(Other.bEnableValidationLayers, false);
|
||||||
|
ValidationLayers = std::move(Other.ValidationLayers);
|
||||||
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
void VulkanDeviceManager::Initialize(VkInstance Instance)
|
|
||||||
|
void VulkanDeviceManager::Initialize(
|
||||||
|
VkInstance Instance,
|
||||||
|
bool bEnableValidationLayers,
|
||||||
|
const std::vector<const char*>& ValidationLayers)
|
||||||
{
|
{
|
||||||
if (IsInitialized())
|
if (IsInitialized())
|
||||||
{
|
{
|
||||||
|
Log::Warning("Already Initialized.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this->Instance = Instance;
|
||||||
|
this->bEnableValidationLayers = bEnableValidationLayers;
|
||||||
|
this->ValidationLayers = &ValidationLayers;
|
||||||
|
|
||||||
|
PickPhysicalDevice();
|
||||||
|
CreateLogicalDevice();
|
||||||
|
CreateSwapChain();
|
||||||
|
CreateImageViews();
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanDeviceManager::Cleanup()
|
void VulkanDeviceManager::Cleanup()
|
||||||
{
|
{
|
||||||
if (!IsInitialized())
|
if (!IsInitialized())
|
||||||
{
|
{
|
||||||
|
Log::Warning("Not Initialized.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
for (auto ImageView : SwapChainImageViews)
|
||||||
|
{
|
||||||
|
vkDestroyImageView(Device, ImageView, nullptr);
|
||||||
|
}
|
||||||
|
vkDestroySwapchainKHR(Device, SwapChain, nullptr);
|
||||||
|
|
||||||
|
vkDestroySurfaceKHR(Instance, GlfwWindowManager::Surface, nullptr);
|
||||||
|
vkDestroyDevice(Device, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanDeviceManager::PickPhysicalDevice()
|
void VulkanDeviceManager::PickPhysicalDevice()
|
||||||
@@ -50,7 +93,7 @@ void VulkanDeviceManager::PickPhysicalDevice()
|
|||||||
|
|
||||||
if (DeviceCount == 0)
|
if (DeviceCount == 0)
|
||||||
{
|
{
|
||||||
Log::Error("Failed to find GPU with Vulkan Support");
|
Log::Error("Failed to find GPU with Vulkan Support.");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<VkPhysicalDevice> Devices(DeviceCount);
|
std::vector<VkPhysicalDevice> Devices(DeviceCount);
|
||||||
@@ -59,31 +102,40 @@ void VulkanDeviceManager::PickPhysicalDevice()
|
|||||||
std::multimap<int, VkPhysicalDevice> Candidates;
|
std::multimap<int, VkPhysicalDevice> Candidates;
|
||||||
|
|
||||||
for (const auto& Device : Devices)
|
for (const auto& Device : Devices)
|
||||||
|
{
|
||||||
|
if (IsDeviceSuitable(Device))
|
||||||
{
|
{
|
||||||
int Score = RateDeviceSuitability(Device);
|
int Score = RateDeviceSuitability(Device);
|
||||||
Candidates.insert(std::make_pair(Score, Device));
|
Candidates.insert(std::make_pair(Score, Device));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (Candidates.rbegin()->first > 0)
|
if (Candidates.rbegin()->first > 0)
|
||||||
{
|
{
|
||||||
PhysicalDevice = Candidates.rbegin()->second;
|
PhysicalDevice = Candidates.rbegin()->second;
|
||||||
|
Log::Info("Suitable GPU found.");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Log::Error("Failed to find a suitable GPU");
|
Log::Error("Failed to find a suitable GPU.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// bool VulkanDeviceManager::IsDeviceSuitable(VkPhysicalDevice Device)
|
bool VulkanDeviceManager::IsDeviceSuitable(VkPhysicalDevice Device)
|
||||||
//{
|
{
|
||||||
// VkPhysicalDeviceProperties DeviceProperties;
|
QueueFamilyIndices Indices = FindQueueFamilies(Device);
|
||||||
// vkGetPhysicalDeviceProperties(Device, &DeviceProperties);
|
|
||||||
//
|
bool bExtensionsSupported = CheckDeviceExtensionSupport(Device);
|
||||||
// VkPhysicalDeviceFeatures DeviceFeatures;
|
|
||||||
// vkGetPhysicalDeviceFeatures(Device, &DeviceFeatures);
|
bool bSwapChainAdequate = false;
|
||||||
//
|
if (bExtensionsSupported)
|
||||||
// return DeviceProperties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU && DeviceFeatures.geometryShader;
|
{
|
||||||
// }
|
SwapChainSupportDetails SwapChainSupport = QuerySwapChainSupport(Device);
|
||||||
|
bSwapChainAdequate = !SwapChainSupport.Formats.empty() && !SwapChainSupport.PresentModes.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Indices.IsComplete() && bExtensionsSupported && bSwapChainAdequate;
|
||||||
|
}
|
||||||
|
|
||||||
int VulkanDeviceManager::RateDeviceSuitability(VkPhysicalDevice Device)
|
int VulkanDeviceManager::RateDeviceSuitability(VkPhysicalDevice Device)
|
||||||
{
|
{
|
||||||
@@ -109,3 +161,282 @@ int VulkanDeviceManager::RateDeviceSuitability(VkPhysicalDevice Device)
|
|||||||
|
|
||||||
return Score;
|
return Score;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool VulkanDeviceManager::CheckDeviceExtensionSupport(VkPhysicalDevice Device)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
return RequiredExtensions.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
QueueFamilyIndices VulkanDeviceManager::FindQueueFamilies(VkPhysicalDevice Device)
|
||||||
|
{
|
||||||
|
QueueFamilyIndices Indices;
|
||||||
|
|
||||||
|
uint32_t QueueFamilyCount = 0;
|
||||||
|
vkGetPhysicalDeviceQueueFamilyProperties(Device, &QueueFamilyCount, nullptr);
|
||||||
|
|
||||||
|
std::vector<VkQueueFamilyProperties> QueueFamilies(QueueFamilyCount);
|
||||||
|
vkGetPhysicalDeviceQueueFamilyProperties(Device, &QueueFamilyCount, QueueFamilies.data());
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
for (const auto& QueueFamily : QueueFamilies)
|
||||||
|
{
|
||||||
|
if (QueueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT)
|
||||||
|
{
|
||||||
|
Indices.GraphicsFamily = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
VkBool32 PresentSupport = false;
|
||||||
|
vkGetPhysicalDeviceSurfaceSupportKHR(Device, i, GlfwWindowManager::Surface, &PresentSupport);
|
||||||
|
|
||||||
|
if (PresentSupport)
|
||||||
|
{
|
||||||
|
Indices.PresentFamily = i;
|
||||||
|
}
|
||||||
|
if (Indices.IsComplete())
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Indices;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VulkanDeviceManager::CreateLogicalDevice()
|
||||||
|
{
|
||||||
|
QueueFamilyIndices Indices = FindQueueFamilies(PhysicalDevice);
|
||||||
|
|
||||||
|
std::vector<VkDeviceQueueCreateInfo> QueueCreateInfos;
|
||||||
|
std::set<uint32_t> UniqueQueueFamilies = { Indices.GraphicsFamily.value(), Indices.PresentFamily.value() };
|
||||||
|
|
||||||
|
float QueuePriority = 1.0f;
|
||||||
|
for (uint32_t QueueFamily : UniqueQueueFamilies)
|
||||||
|
{
|
||||||
|
VkDeviceQueueCreateInfo QueueCreateInfo{};
|
||||||
|
QueueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
|
||||||
|
QueueCreateInfo.queueFamilyIndex = Indices.GraphicsFamily.value();
|
||||||
|
QueueCreateInfo.queueCount = 1;
|
||||||
|
QueueCreateInfo.pQueuePriorities = &QueuePriority;
|
||||||
|
QueueCreateInfos.push_back(QueueCreateInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
VkPhysicalDeviceFeatures DeviceFeatures{};
|
||||||
|
|
||||||
|
VkDeviceCreateInfo CreateInfo{};
|
||||||
|
CreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
|
||||||
|
CreateInfo.queueCreateInfoCount = static_cast<uint32_t>(QueueCreateInfos.size());
|
||||||
|
CreateInfo.pQueueCreateInfos = QueueCreateInfos.data();
|
||||||
|
CreateInfo.pEnabledFeatures = &DeviceFeatures;
|
||||||
|
|
||||||
|
CreateInfo.enabledExtensionCount = static_cast<uint32_t>(DeviceExtensions.size());
|
||||||
|
CreateInfo.ppEnabledExtensionNames = DeviceExtensions.data();
|
||||||
|
|
||||||
|
if (bEnableValidationLayers)
|
||||||
|
{
|
||||||
|
CreateInfo.enabledLayerCount = static_cast<uint32_t>(ValidationLayers->size());
|
||||||
|
CreateInfo.ppEnabledLayerNames = ValidationLayers->data();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CreateInfo.enabledLayerCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vkCreateDevice(PhysicalDevice, &CreateInfo, nullptr, &Device) != VK_SUCCESS)
|
||||||
|
{
|
||||||
|
Log::Error("Failed to create logical device!");
|
||||||
|
}
|
||||||
|
|
||||||
|
vkGetDeviceQueue(Device, Indices.GraphicsFamily.value(), 0, &GraphicsQueue);
|
||||||
|
vkGetDeviceQueue(Device, Indices.PresentFamily.value(), 0, &PresentQueue);
|
||||||
|
}
|
||||||
|
|
||||||
|
SwapChainSupportDetails VulkanDeviceManager::QuerySwapChainSupport(VkPhysicalDevice Device)
|
||||||
|
{
|
||||||
|
SwapChainSupportDetails Details;
|
||||||
|
|
||||||
|
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(Device, GlfwWindowManager::Surface, &Details.Capabilities);
|
||||||
|
|
||||||
|
uint32_t FormatCount;
|
||||||
|
vkGetPhysicalDeviceSurfaceFormatsKHR(Device, GlfwWindowManager::Surface, &FormatCount, nullptr);
|
||||||
|
|
||||||
|
if (FormatCount != 0)
|
||||||
|
{
|
||||||
|
Details.Formats.resize(FormatCount);
|
||||||
|
vkGetPhysicalDeviceSurfaceFormatsKHR(Device, GlfwWindowManager::Surface, &FormatCount, Details.Formats.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t PresentModeCount;
|
||||||
|
vkGetPhysicalDeviceSurfacePresentModesKHR(Device, GlfwWindowManager::Surface, &PresentModeCount, nullptr);
|
||||||
|
|
||||||
|
if (PresentModeCount != 0)
|
||||||
|
{
|
||||||
|
Details.PresentModes.resize(PresentModeCount);
|
||||||
|
vkGetPhysicalDeviceSurfacePresentModesKHR(Device, GlfwWindowManager::Surface, &PresentModeCount, Details.PresentModes.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
return Details;
|
||||||
|
}
|
||||||
|
|
||||||
|
VkSurfaceFormatKHR VulkanDeviceManager::ChooseSwapSurfaceFormat(const std::vector<VkSurfaceFormatKHR>& AvailableFormats)
|
||||||
|
{
|
||||||
|
for (const auto& AvailableFormat : AvailableFormats)
|
||||||
|
{
|
||||||
|
if (AvailableFormat.format == VK_FORMAT_B8G8R8A8_SRGB && AvailableFormat.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR)
|
||||||
|
{
|
||||||
|
return AvailableFormat;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return AvailableFormats[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
VkPresentModeKHR VulkanDeviceManager::ChooseSwapPresentMode(const std::vector<VkPresentModeKHR>& AvailablePresentModes)
|
||||||
|
{
|
||||||
|
for (const auto& AvailablePresentMode : AvailablePresentModes)
|
||||||
|
{
|
||||||
|
if (AvailablePresentMode == VK_PRESENT_MODE_MAILBOX_KHR)
|
||||||
|
{
|
||||||
|
return AvailablePresentMode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return VK_PRESENT_MODE_FIFO_KHR;
|
||||||
|
}
|
||||||
|
|
||||||
|
VkExtent2D VulkanDeviceManager::ChooseSwapExtent(const VkSurfaceCapabilitiesKHR& Capabilities)
|
||||||
|
{
|
||||||
|
if (Capabilities.currentExtent.width != (std::numeric_limits<uint32_t>::max)())
|
||||||
|
{
|
||||||
|
return Capabilities.currentExtent;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int Width, Height;
|
||||||
|
glfwGetFramebufferSize(GlfwWindowManager::Window, &Width, &Height);
|
||||||
|
|
||||||
|
VkExtent2D ActualExtent = {
|
||||||
|
static_cast<uint32_t>(Width),
|
||||||
|
static_cast<uint32_t>(Height)
|
||||||
|
};
|
||||||
|
|
||||||
|
ActualExtent.width = std::clamp(ActualExtent.width, Capabilities.minImageExtent.width, Capabilities.maxImageExtent.width);
|
||||||
|
ActualExtent.height = std::clamp(ActualExtent.height, Capabilities.minImageExtent.height, Capabilities.maxImageExtent.height);
|
||||||
|
|
||||||
|
return ActualExtent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VulkanDeviceManager::CreateSwapChain()
|
||||||
|
{
|
||||||
|
SwapChainSupportDetails SwapChainSupport = QuerySwapChainSupport(PhysicalDevice);
|
||||||
|
|
||||||
|
VkSurfaceFormatKHR SurfaceFormat = ChooseSwapSurfaceFormat(SwapChainSupport.Formats);
|
||||||
|
VkPresentModeKHR PresentMode = ChooseSwapPresentMode(SwapChainSupport.PresentModes);
|
||||||
|
VkExtent2D Extent = ChooseSwapExtent(SwapChainSupport.Capabilities);
|
||||||
|
|
||||||
|
uint32_t ImageCount = SwapChainSupport.Capabilities.minImageCount + 1;
|
||||||
|
|
||||||
|
if (SwapChainSupport.Capabilities.maxImageCount > 0 && ImageCount > SwapChainSupport.Capabilities.maxImageCount)
|
||||||
|
{
|
||||||
|
ImageCount = SwapChainSupport.Capabilities.maxImageCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
VkSwapchainCreateInfoKHR CreateInfo{};
|
||||||
|
CreateInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
|
||||||
|
CreateInfo.surface = GlfwWindowManager::Surface;
|
||||||
|
|
||||||
|
CreateInfo.minImageCount = ImageCount;
|
||||||
|
CreateInfo.imageFormat = SurfaceFormat.format;
|
||||||
|
CreateInfo.imageColorSpace = SurfaceFormat.colorSpace;
|
||||||
|
CreateInfo.imageExtent = Extent;
|
||||||
|
CreateInfo.imageArrayLayers = 1;
|
||||||
|
CreateInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; // may need VK_IMAGE_USAGE_TRANSFER_DST_BIT for post processing https://vulkan-tutorial.com/Drawing_a_triangle/Presentation/Swap_chain#:~:text=VK%5FIMAGE%5FUSAGE%5FTRANSFER%5FDST%5FBIT
|
||||||
|
|
||||||
|
QueueFamilyIndices Indices = FindQueueFamilies(PhysicalDevice);
|
||||||
|
uint32_t QueueFamilyIndices[] = { Indices.GraphicsFamily.value(),
|
||||||
|
Indices.PresentFamily.value() };
|
||||||
|
|
||||||
|
if (Indices.GraphicsFamily != Indices.PresentFamily)
|
||||||
|
{
|
||||||
|
CreateInfo.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
|
||||||
|
CreateInfo.queueFamilyIndexCount = 2;
|
||||||
|
CreateInfo.pQueueFamilyIndices = QueueFamilyIndices;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CreateInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||||
|
CreateInfo.queueFamilyIndexCount = 0;
|
||||||
|
CreateInfo.pQueueFamilyIndices = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
CreateInfo.preTransform = SwapChainSupport.Capabilities.currentTransform;
|
||||||
|
CreateInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
|
||||||
|
CreateInfo.presentMode = PresentMode;
|
||||||
|
CreateInfo.clipped = VK_TRUE;
|
||||||
|
CreateInfo.oldSwapchain = VK_NULL_HANDLE;
|
||||||
|
|
||||||
|
if (vkCreateSwapchainKHR(Device, &CreateInfo, nullptr, &SwapChain) != VK_SUCCESS)
|
||||||
|
{
|
||||||
|
Log::Error("Failed to create swap chain.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log::Info("Successfully created swap chain.");
|
||||||
|
}
|
||||||
|
|
||||||
|
vkGetSwapchainImagesKHR(Device, SwapChain, &ImageCount, nullptr);
|
||||||
|
SwapChainImages.resize(ImageCount);
|
||||||
|
vkGetSwapchainImagesKHR(Device, SwapChain, &ImageCount, SwapChainImages.data());
|
||||||
|
|
||||||
|
SwapChainImageFormat = SurfaceFormat.format;
|
||||||
|
SwapChainExtent = Extent;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VulkanDeviceManager::CreateImageViews()
|
||||||
|
{
|
||||||
|
SwapChainImageViews.resize(SwapChainImages.size());
|
||||||
|
|
||||||
|
int CreatedViews = 0;
|
||||||
|
for (size_t i = 0; i < SwapChainImages.size(); i++)
|
||||||
|
{
|
||||||
|
VkImageViewCreateInfo CreateInfo{};
|
||||||
|
CreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||||
|
CreateInfo.image = SwapChainImages[i];
|
||||||
|
|
||||||
|
CreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
||||||
|
CreateInfo.format = SwapChainImageFormat;
|
||||||
|
CreateInfo.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||||
|
CreateInfo.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||||
|
CreateInfo.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||||
|
CreateInfo.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||||
|
|
||||||
|
CreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||||
|
CreateInfo.subresourceRange.baseMipLevel = 0;
|
||||||
|
CreateInfo.subresourceRange.levelCount = 1;
|
||||||
|
CreateInfo.subresourceRange.baseArrayLayer = 0;
|
||||||
|
CreateInfo.subresourceRange.layerCount = 1;
|
||||||
|
|
||||||
|
if (vkCreateImageView(Device, &CreateInfo, nullptr, &SwapChainImageViews[i]) != VK_SUCCESS)
|
||||||
|
{
|
||||||
|
Log::Error("Failed to create image views.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CreatedViews++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Log::Info("Successfully created " + std::to_string(CreatedViews) + " image views.");
|
||||||
|
}
|
||||||
@@ -1,22 +1,35 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
#include "Logger.h"
|
||||||
|
|
||||||
#define GLFW_INCLUDE_VULKAN
|
#define GLFW_INCLUDE_VULKAN
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
// struct FCreateDebugUtilsMessengerExtParams
|
const std::vector<const char*> DeviceExtensions = {
|
||||||
//{
|
VK_KHR_SWAPCHAIN_EXTENSION_NAME
|
||||||
// VkInstance Instance;
|
};
|
||||||
// const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo;
|
|
||||||
// const VkAllocationCallbacks* pAllocator;
|
struct QueueFamilyIndices
|
||||||
// VkDebugUtilsMessengerEXT* pDebugMessenger;
|
{
|
||||||
// };
|
std::optional<uint32_t> GraphicsFamily;
|
||||||
//
|
std::optional<uint32_t> PresentFamily;
|
||||||
// struct FDestroyDebugUtilsMessengerExtParams
|
|
||||||
//{
|
bool IsComplete()
|
||||||
// VkInstance Instance;
|
{
|
||||||
// VkDebugUtilsMessengerEXT DebugMessenger;
|
return GraphicsFamily.has_value() && PresentFamily.has_value();
|
||||||
// const VkAllocationCallbacks* pAllocator;
|
}
|
||||||
// };
|
};
|
||||||
|
|
||||||
|
struct SwapChainSupportDetails
|
||||||
|
{
|
||||||
|
VkSurfaceCapabilitiesKHR Capabilities;
|
||||||
|
std::vector<VkSurfaceFormatKHR> Formats;
|
||||||
|
std::vector<VkPresentModeKHR> PresentModes;
|
||||||
|
};
|
||||||
|
|
||||||
class VulkanDeviceManager
|
class VulkanDeviceManager
|
||||||
{
|
{
|
||||||
@@ -30,18 +43,59 @@ public:
|
|||||||
VulkanDeviceManager(VulkanDeviceManager&& Other) noexcept;
|
VulkanDeviceManager(VulkanDeviceManager&& Other) noexcept;
|
||||||
VulkanDeviceManager& operator=(VulkanDeviceManager&& Other) noexcept;
|
VulkanDeviceManager& operator=(VulkanDeviceManager&& Other) noexcept;
|
||||||
|
|
||||||
void Initialize(VkInstance Instance);
|
void Initialize(
|
||||||
|
VkInstance Instance,
|
||||||
|
bool EnableValidationLayers,
|
||||||
|
const std::vector<const char*>& ValidationLayers);
|
||||||
|
|
||||||
void Cleanup();
|
void Cleanup();
|
||||||
|
|
||||||
bool IsInitialized() const { return PhysicalDevice != VK_NULL_HANDLE; }
|
bool IsInitialized() const
|
||||||
|
{
|
||||||
|
bool bInitialized = PhysicalDevice && Device && Instance && GraphicsQueue;
|
||||||
|
return bInitialized;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<VkImage> SwapChainImages;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
VkPhysicalDevice PhysicalDevice = VK_NULL_HANDLE;
|
VkPhysicalDevice PhysicalDevice = VK_NULL_HANDLE;
|
||||||
VkInstance Instance = VK_NULL_HANDLE;
|
VkInstance Instance = VK_NULL_HANDLE;
|
||||||
|
VkDevice Device = VK_NULL_HANDLE;
|
||||||
|
VkQueue GraphicsQueue = VK_NULL_HANDLE;
|
||||||
|
VkQueue PresentQueue = VK_NULL_HANDLE;
|
||||||
|
|
||||||
|
VkSwapchainKHR SwapChain = VK_NULL_HANDLE;
|
||||||
|
VkFormat SwapChainImageFormat;
|
||||||
|
VkExtent2D SwapChainExtent;
|
||||||
|
|
||||||
|
std::vector<VkImageView> SwapChainImageViews;
|
||||||
|
|
||||||
|
bool bEnableValidationLayers = false;
|
||||||
|
|
||||||
|
const std::vector<const char*>* ValidationLayers = nullptr;
|
||||||
|
|
||||||
void PickPhysicalDevice();
|
void PickPhysicalDevice();
|
||||||
|
|
||||||
// bool IsDeviceSuitable(VkPhysicalDevice Device);
|
bool IsDeviceSuitable(VkPhysicalDevice Device);
|
||||||
|
|
||||||
int RateDeviceSuitability(VkPhysicalDevice Device);
|
int RateDeviceSuitability(VkPhysicalDevice Device);
|
||||||
|
|
||||||
|
bool CheckDeviceExtensionSupport(VkPhysicalDevice Device);
|
||||||
|
|
||||||
|
QueueFamilyIndices FindQueueFamilies(VkPhysicalDevice Device);
|
||||||
|
|
||||||
|
void CreateLogicalDevice();
|
||||||
|
|
||||||
|
SwapChainSupportDetails QuerySwapChainSupport(VkPhysicalDevice Device);
|
||||||
|
|
||||||
|
VkSurfaceFormatKHR ChooseSwapSurfaceFormat(const std::vector<VkSurfaceFormatKHR>& AvailableFormats);
|
||||||
|
|
||||||
|
VkPresentModeKHR ChooseSwapPresentMode(const std::vector<VkPresentModeKHR>& AvailablePresentModes);
|
||||||
|
|
||||||
|
VkExtent2D ChooseSwapExtent(const VkSurfaceCapabilitiesKHR& Capabilities);
|
||||||
|
|
||||||
|
void CreateSwapChain();
|
||||||
|
|
||||||
|
void CreateImageViews();
|
||||||
};
|
};
|
||||||
|
|||||||
27
VulkanGraphicsPipeline.h
Normal file
27
VulkanGraphicsPipeline.h
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Utilities/FileReader.h"
|
||||||
|
|
||||||
|
class VulkanGraphicsPipeline
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void CreateGraphicsPipeline()
|
||||||
|
{
|
||||||
|
auto VertShaderCode = ReadFile("Shaders/vert.spv");
|
||||||
|
auto FragShaderCode = ReadFile("Shaders/frag.spv");
|
||||||
|
|
||||||
|
Log::Info("Vert buffer size: " + std::to_string(VertShaderCode.size()));
|
||||||
|
Log::Info("Frag buffer size: " + std::to_string(FragShaderCode.size()));
|
||||||
|
}
|
||||||
|
|
||||||
|
VkShaderModule CreateShaderModule(const std::vector<char>& Code)
|
||||||
|
{
|
||||||
|
VkShaderModuleCreateInfo CreateInfo{};
|
||||||
|
CreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
|
||||||
|
CreateInfo.codeSize = Code.size();
|
||||||
|
CreateInfo.pCode = reinterpret_cast<const uint32_t*>(Code.data());
|
||||||
|
|
||||||
|
VkShaderModule ShaderModule;
|
||||||
|
if (vkCreateShaderModule(Device))
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -8,11 +8,11 @@ VulkanInstanceManager::VulkanInstanceManager()
|
|||||||
|
|
||||||
VulkanInstanceManager::~VulkanInstanceManager()
|
VulkanInstanceManager::~VulkanInstanceManager()
|
||||||
{
|
{
|
||||||
Cleanup();
|
// Cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
VulkanInstanceManager::VulkanInstanceManager(VulkanInstanceManager&& Other) noexcept
|
VulkanInstanceManager::VulkanInstanceManager(VulkanInstanceManager&& Other) noexcept
|
||||||
: Instance(Other.Instance), bValidationEnabled(Other.bValidationEnabled), bVerboseLogging(Other.bVerboseLogging), VkDebugManager(std::move(Other.VkDebugManager))
|
: Instance(Other.Instance) /*, bValidationEnabled(Other.bValidationEnabled), bVerboseLogging(Other.bVerboseLogging), VkDebugManager(std::move(Other.VkDebugManager))*/
|
||||||
{
|
{
|
||||||
Other.Instance = VK_NULL_HANDLE;
|
Other.Instance = VK_NULL_HANDLE;
|
||||||
Other.bValidationEnabled = false;
|
Other.bValidationEnabled = false;
|
||||||
@@ -34,7 +34,28 @@ VulkanInstanceManager& VulkanInstanceManager::operator=(VulkanInstanceManager&&
|
|||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
void VulkanInstanceManager::Initialize(const FVulkanConfig& Config)
|
|
||||||
|
// void VulkanInstanceManager::Initialize(const FVulkanConfig& Config)
|
||||||
|
//{
|
||||||
|
// if (IsInitialized())
|
||||||
|
// {
|
||||||
|
// Log::Warning("Already Initialized.");
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// bValidationEnabled = Config.bValidationEnabled;
|
||||||
|
// bVerboseLogging = Config.bVerboseLogging;
|
||||||
|
//
|
||||||
|
// if (bValidationEnabled)
|
||||||
|
// {
|
||||||
|
// Log::Info("DebugManager created with validation enabled.");
|
||||||
|
// VkDebugManager = std::make_unique<VulkanDebugManager>();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// CreateInstance();
|
||||||
|
// }
|
||||||
|
|
||||||
|
void VulkanInstanceManager::Initialize(bool bEnableValidationLayers)
|
||||||
{
|
{
|
||||||
if (IsInitialized())
|
if (IsInitialized())
|
||||||
{
|
{
|
||||||
@@ -42,24 +63,27 @@ void VulkanInstanceManager::Initialize(const FVulkanConfig& Config)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bValidationEnabled = Config.bValidationEnabled;
|
if (bEnableValidationLayers)
|
||||||
bVerboseLogging = Config.bVerboseLogging;
|
|
||||||
|
|
||||||
if (bValidationEnabled)
|
|
||||||
{
|
{
|
||||||
Log::Info("DebugManager created with validation enabled.");
|
Log::Info("DebugManager created with validation enabled.");
|
||||||
VkDebugManager = std::make_unique<VulkanDebugManager>();
|
VkDebugManager = std::make_unique<VulkanDebugManager>();
|
||||||
}
|
}
|
||||||
|
|
||||||
CreateInstance();
|
CreateInstance();
|
||||||
|
}
|
||||||
|
|
||||||
if (VkDebugManager)
|
void VulkanInstanceManager::SetupDebug()
|
||||||
|
{
|
||||||
|
if (bValidationEnabled)
|
||||||
{
|
{
|
||||||
VkDebugManager->Initialize(Instance);
|
VkDebugManager->Initialize(Instance);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VulkanInstanceManager::SetupDevice()
|
||||||
|
{
|
||||||
VkDeviceManager = std::make_unique<VulkanDeviceManager>();
|
VkDeviceManager = std::make_unique<VulkanDeviceManager>();
|
||||||
VkDeviceManager->Initialize(Instance);
|
VkDeviceManager->Initialize(Instance, bValidationEnabled, ValidationLayers);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanInstanceManager::Cleanup()
|
void VulkanInstanceManager::Cleanup()
|
||||||
@@ -70,16 +94,16 @@ void VulkanInstanceManager::Cleanup()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (VkDebugManager)
|
|
||||||
{
|
|
||||||
VkDebugManager->Cleanup();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (VkDeviceManager)
|
if (VkDeviceManager)
|
||||||
{
|
{
|
||||||
VkDeviceManager->Cleanup();
|
VkDeviceManager->Cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (VkDebugManager)
|
||||||
|
{
|
||||||
|
VkDebugManager->Cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
vkDestroyInstance(Instance, nullptr);
|
vkDestroyInstance(Instance, nullptr);
|
||||||
Instance = VK_NULL_HANDLE;
|
Instance = VK_NULL_HANDLE;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,11 +3,13 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#define GLFW_INCLUDE_VULKAN
|
#include "Logger.h"
|
||||||
#include <GLFW/glfw3.h>
|
|
||||||
|
|
||||||
#include "VulkanDebugManager.h"
|
#include "VulkanDebugManager.h"
|
||||||
#include "VulkanDeviceManager.h"
|
#include "VulkanDeviceManager.h"
|
||||||
|
#include "GlfwWindowManager.h"
|
||||||
|
|
||||||
|
#define GLFW_INCLUDE_VULKAN
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
const std::vector<const char*> ValidationLayers = {
|
const std::vector<const char*> ValidationLayers = {
|
||||||
"VK_LAYER_KHRONOS_validation"
|
"VK_LAYER_KHRONOS_validation"
|
||||||
@@ -31,11 +33,23 @@ public:
|
|||||||
VulkanInstanceManager(VulkanInstanceManager&& Other) noexcept;
|
VulkanInstanceManager(VulkanInstanceManager&& Other) noexcept;
|
||||||
VulkanInstanceManager& operator=(VulkanInstanceManager&& Other) noexcept;
|
VulkanInstanceManager& operator=(VulkanInstanceManager&& Other) noexcept;
|
||||||
|
|
||||||
void Initialize(const FVulkanConfig& Config);
|
// void Initialize(const FVulkanConfig& Config);
|
||||||
|
void Initialize(bool bEnableValidationLayers);
|
||||||
|
void SetupDebug();
|
||||||
|
void SetupDevice();
|
||||||
|
|
||||||
|
// void Initialize(VulkanDebugManager& inDebugManager, bool inValidationEnabled);
|
||||||
void Cleanup();
|
void Cleanup();
|
||||||
|
|
||||||
bool IsInitialized() const { return Instance != VK_NULL_HANDLE; }
|
bool IsInitialized() const { return Instance != VK_NULL_HANDLE; }
|
||||||
|
|
||||||
|
const std::vector<const char*>& GetValidationLayers() const
|
||||||
|
{
|
||||||
|
return ValidationLayers;
|
||||||
|
}
|
||||||
|
|
||||||
|
const VkInstance GetInstance() const { return Instance; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<VulkanDebugManager> VkDebugManager = nullptr;
|
std::unique_ptr<VulkanDebugManager> VkDebugManager = nullptr;
|
||||||
std::unique_ptr<VulkanDeviceManager> VkDeviceManager = nullptr;
|
std::unique_ptr<VulkanDeviceManager> VkDeviceManager = nullptr;
|
||||||
|
|||||||
46
main.cpp
46
main.cpp
@@ -1,7 +1,11 @@
|
|||||||
|
|
||||||
#include "Logger.h"
|
#include "Logger.h"
|
||||||
#include "VulkanInstanceManager.h"
|
#include "VulkanInstanceManager.h"
|
||||||
|
#include "VulkanDeviceManager.h"
|
||||||
|
#include "VulkanDebugManager.h"
|
||||||
#include "GlfwWindowManager.h"
|
#include "GlfwWindowManager.h"
|
||||||
|
#include "VulkanGraphicsPipeline.h"
|
||||||
|
// #include "VulkanContext.h"
|
||||||
|
|
||||||
struct AppConfig
|
struct AppConfig
|
||||||
{
|
{
|
||||||
@@ -19,41 +23,59 @@ class HelloTriangleApplication
|
|||||||
public:
|
public:
|
||||||
void Run()
|
void Run()
|
||||||
{
|
{
|
||||||
InitGlfw();
|
Initialization();
|
||||||
InitVulkan();
|
|
||||||
MainLoop();
|
MainLoop();
|
||||||
Cleanup();
|
Cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
VulkanInstanceManager VkInstanceManager;
|
|
||||||
GlfwWindowManager GlfwWindowManager;
|
|
||||||
AppConfig Settings = {};
|
AppConfig Settings = {};
|
||||||
|
|
||||||
|
VulkanInstanceManager InstanceManager;
|
||||||
|
GlfwWindowManager WindowManager;
|
||||||
|
|
||||||
|
void Initialization()
|
||||||
|
{
|
||||||
|
InitGlfw();
|
||||||
|
InitVulkan();
|
||||||
|
InstanceManager.SetupDebug();
|
||||||
|
WindowManager.CreateSurface(InstanceManager.GetInstance());
|
||||||
|
InstanceManager.SetupDevice();
|
||||||
|
}
|
||||||
|
|
||||||
void InitVulkan()
|
void InitVulkan()
|
||||||
{
|
{
|
||||||
FVulkanConfig Config = { Settings.bValidationEnabled, Settings.bVerboseLogging };
|
FVulkanConfig Config = {
|
||||||
VkInstanceManager.Initialize(Config);
|
Settings.bValidationEnabled,
|
||||||
|
Settings.bVerboseLogging
|
||||||
|
};
|
||||||
|
InstanceManager.Initialize(Config);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InitGlfw()
|
void InitGlfw()
|
||||||
{
|
{
|
||||||
FWindowConfig Config = { Settings.Title, Settings.Width, Settings.Height, Settings.bResizable, Settings.bFullscreen };
|
FWindowConfig Config = {
|
||||||
GlfwWindowManager.Initialize(Config);
|
Settings.Title,
|
||||||
|
Settings.Width,
|
||||||
|
Settings.Height,
|
||||||
|
Settings.bResizable,
|
||||||
|
Settings.bFullscreen
|
||||||
|
};
|
||||||
|
WindowManager.Initialize(Config);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainLoop()
|
void MainLoop()
|
||||||
{
|
{
|
||||||
while (!GlfwWindowManager.ShouldClose())
|
while (!WindowManager.ShouldClose())
|
||||||
{
|
{
|
||||||
GlfwWindowManager.PollEvents();
|
WindowManager.PollEvents();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cleanup()
|
void Cleanup()
|
||||||
{
|
{
|
||||||
// VkInstanceManager.Cleanup();
|
WindowManager.Cleanup(InstanceManager.GetInstance());
|
||||||
// GlfwWindowManager.Cleanup();
|
InstanceManager.Cleanup();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user