From 3b55755f0cf3c413522cb85a779992ff0716c2d9 Mon Sep 17 00:00:00 2001 From: HOEGLER Stefan Date: Sun, 15 Mar 2020 15:58:01 +0100 Subject: [PATCH] Graphics is now a global object, instead of a per-window one --- src/Engine/Containers/Array.h | 7 +- src/Engine/Graphics/Graphics.h | 4 +- src/Engine/Graphics/GraphicsResources.h | 4 + src/Engine/Graphics/RenderPath.cpp | 2 +- src/Engine/Graphics/RenderPath.h | 4 +- src/Engine/Graphics/SceneRenderPath.cpp | 2 +- src/Engine/Graphics/SceneRenderPath.h | 2 +- src/Engine/Graphics/SceneView.cpp | 2 +- src/Engine/Graphics/SceneView.h | 2 +- src/Engine/Graphics/View.cpp | 2 +- src/Engine/Graphics/View.h | 6 +- src/Engine/Graphics/Vulkan/VulkanGraphics.cpp | 99 ++++++++++++------- src/Engine/Graphics/Vulkan/VulkanGraphics.h | 3 + .../Graphics/Vulkan/VulkanGraphicsEnums.cpp | 4 + .../Graphics/Vulkan/VulkanGraphicsResources.h | 22 ++++- src/Engine/Graphics/Window.cpp | 4 +- src/Engine/Graphics/Window.h | 2 +- src/Engine/Graphics/WindowManager.cpp | 4 + src/Engine/Graphics/WindowManager.h | 1 + src/Engine/MinimalEngine.h | 4 +- 20 files changed, 121 insertions(+), 59 deletions(-) diff --git a/src/Engine/Containers/Array.h b/src/Engine/Containers/Array.h index d482e75..302855b 100644 --- a/src/Engine/Containers/Array.h +++ b/src/Engine/Containers/Array.h @@ -26,6 +26,7 @@ namespace Seele , arraySize(size) { _data = (T*)malloc(size * sizeof(T)); + assert(_data != nullptr); for (int i = 0; i < size; ++i) { _data[i] = value; @@ -38,10 +39,10 @@ namespace Seele { _data = (T*)malloc(init.size() * sizeof(T)); auto it = init.begin(); - for (size_t i = 0; i < init.size(); i++) + for (size_t i = 0; it != init.end(); i++, it++) { + assert(i < init.size()); _data[i] = *it; - it++; } refreshIterators(); } @@ -50,6 +51,7 @@ namespace Seele , arraySize(other.arraySize) { _data = (T*)malloc(other.allocated * sizeof(T)); + assert(_data != nullptr); std::memcpy(_data, other._data, sizeof(T) * allocated); refreshIterators(); } @@ -174,6 +176,7 @@ namespace Seele { allocated += DEFAULT_ALLOC_SIZE; void* tempArray = malloc(sizeof(T) * allocated); + assert(tempArray != nullptr); std::memcpy(tempArray, _data, arraySize * sizeof(T)); memset(tempArray, 0, sizeof(T) * allocated); delete _data; diff --git a/src/Engine/Graphics/Graphics.h b/src/Engine/Graphics/Graphics.h index d8e7dfe..fb5c933 100644 --- a/src/Engine/Graphics/Graphics.h +++ b/src/Engine/Graphics/Graphics.h @@ -8,13 +8,13 @@ namespace Seele { class Graphics { public: + Graphics(); + ~Graphics(); virtual void init(GraphicsInitializer initializer) = 0; virtual void beginFrame(void* windowHandle) = 0; virtual void endFrame(void* windowHandle) = 0; virtual void* createWindow(const WindowCreateInfo& createInfo) = 0; protected: - Graphics(); - ~Graphics(); friend class Window; }; DEFINE_REF(Graphics); diff --git a/src/Engine/Graphics/GraphicsResources.h b/src/Engine/Graphics/GraphicsResources.h index 148feb0..d247a92 100644 --- a/src/Engine/Graphics/GraphicsResources.h +++ b/src/Engine/Graphics/GraphicsResources.h @@ -20,6 +20,7 @@ namespace Seele const char* windowLayoutFile; const char* applicationName; const char* engineName; + void* windowHandle; /** * layers defines the enabled Vulkan layers used in the instance, * if ENABLE_VALIDATION is defined, standard validation is already enabled @@ -34,6 +35,7 @@ namespace Seele , layers{ "VK_LAYER_LUNARG_standard_validation" } , instanceExtensions{} , deviceExtensions{ "VK_KHR_swapchain" } + , windowHandle(nullptr) {} GraphicsInitializer(const GraphicsInitializer& other) : applicationName(other.applicationName) @@ -44,12 +46,14 @@ namespace Seele { } }; + DECLARE_REF(Graphics); struct WindowCreateInfo { int32 width; int32 height; const char* title; bool bFullscreen; + PGraphics graphics; }; class RenderCommandBase diff --git a/src/Engine/Graphics/RenderPath.cpp b/src/Engine/Graphics/RenderPath.cpp index eaeea80..bfae90a 100644 --- a/src/Engine/Graphics/RenderPath.cpp +++ b/src/Engine/Graphics/RenderPath.cpp @@ -1,6 +1,6 @@ #include "RenderPath.h" -Seele::RenderPath::RenderPath(Graphics* graphics) +Seele::RenderPath::RenderPath(PGraphics graphics) : graphics(graphics) { } diff --git a/src/Engine/Graphics/RenderPath.h b/src/Engine/Graphics/RenderPath.h index d987018..1a1a128 100644 --- a/src/Engine/Graphics/RenderPath.h +++ b/src/Engine/Graphics/RenderPath.h @@ -6,7 +6,7 @@ namespace Seele class RenderPath { public: - RenderPath(Graphics* graphics); + RenderPath(PGraphics graphics); virtual ~RenderPath(); virtual void applyArea(Rect area) = 0; virtual void init() = 0; @@ -14,7 +14,7 @@ namespace Seele virtual void render() = 0; virtual void endFrame() = 0; protected: - Graphics* graphics; + PGraphics graphics; Rect area; }; DEFINE_REF(RenderPath); diff --git a/src/Engine/Graphics/SceneRenderPath.cpp b/src/Engine/Graphics/SceneRenderPath.cpp index 7821405..8f60046 100644 --- a/src/Engine/Graphics/SceneRenderPath.cpp +++ b/src/Engine/Graphics/SceneRenderPath.cpp @@ -1,6 +1,6 @@ #include "SceneRenderPath.h" -Seele::SceneRenderPath::SceneRenderPath(Graphics* graphics) +Seele::SceneRenderPath::SceneRenderPath(PGraphics graphics) : RenderPath(graphics) { } diff --git a/src/Engine/Graphics/SceneRenderPath.h b/src/Engine/Graphics/SceneRenderPath.h index 75ccc42..d2c9b4a 100644 --- a/src/Engine/Graphics/SceneRenderPath.h +++ b/src/Engine/Graphics/SceneRenderPath.h @@ -6,7 +6,7 @@ namespace Seele class SceneRenderPath : public RenderPath { public: - SceneRenderPath(Graphics* graphics); + SceneRenderPath(PGraphics graphics); virtual ~SceneRenderPath(); virtual void applyArea(Rect area) override; virtual void init() override; diff --git a/src/Engine/Graphics/SceneView.cpp b/src/Engine/Graphics/SceneView.cpp index 1ea9f6b..aa05832 100644 --- a/src/Engine/Graphics/SceneView.cpp +++ b/src/Engine/Graphics/SceneView.cpp @@ -1,7 +1,7 @@ #include "SceneView.h" #include "SceneRenderPath.h" -Seele::SceneView::SceneView(Graphics* graphics) +Seele::SceneView::SceneView(PGraphics graphics) : View(graphics) { renderer = new SceneRenderPath(graphics); diff --git a/src/Engine/Graphics/SceneView.h b/src/Engine/Graphics/SceneView.h index 7ffe538..2a5c4ac 100644 --- a/src/Engine/Graphics/SceneView.h +++ b/src/Engine/Graphics/SceneView.h @@ -5,7 +5,7 @@ namespace Seele class SceneView : public View { public: - SceneView(Graphics* graphics); + SceneView(PGraphics graphics); ~SceneView(); }; } \ No newline at end of file diff --git a/src/Engine/Graphics/View.cpp b/src/Engine/Graphics/View.cpp index 24c4e9f..817b8b2 100644 --- a/src/Engine/Graphics/View.cpp +++ b/src/Engine/Graphics/View.cpp @@ -1,6 +1,6 @@ #include "View.h" -Seele::View::View(Graphics* graphics) +Seele::View::View(PGraphics graphics) : graphics(graphics) { } diff --git a/src/Engine/Graphics/View.h b/src/Engine/Graphics/View.h index c0fad61..96da4f3 100644 --- a/src/Engine/Graphics/View.h +++ b/src/Engine/Graphics/View.h @@ -2,18 +2,18 @@ #include "RenderPath.h" namespace Seele { - class Graphics; + DECLARE_REF(Graphics); // A view is a part of the window, which can be anything from a viewport to an editor class View { public: - View(Graphics* graphics); + View(PGraphics graphics); virtual ~View(); void beginFrame(); void endFrame(); void applyArea(Rect area); protected: - Graphics* graphics; + PGraphics graphics; PRenderPath renderer; }; diff --git a/src/Engine/Graphics/Vulkan/VulkanGraphics.cpp b/src/Engine/Graphics/Vulkan/VulkanGraphics.cpp index 759c1c2..6f29d93 100644 --- a/src/Engine/Graphics/Vulkan/VulkanGraphics.cpp +++ b/src/Engine/Graphics/Vulkan/VulkanGraphics.cpp @@ -4,34 +4,27 @@ #include "VulkanInitializer.h" #include + +Seele::VulkanGraphics::VulkanGraphics() + : callback(VK_NULL_HANDLE) + , handle(VK_NULL_HANDLE) + , instance(VK_NULL_HANDLE) + , physicalDevice(VK_NULL_HANDLE) +{ + glfwInit(); + glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); +} + +Seele::VulkanGraphics::~VulkanGraphics() +{ + glfwTerminate(); +} + void Seele::VulkanGraphics::init(GraphicsInitializer initInfo) { - VkApplicationInfo appInfo = {}; - appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; - appInfo.pApplicationName = initInfo.applicationName; - appInfo.applicationVersion = VK_MAKE_VERSION(0, 0, 1); - appInfo.pEngineName = initInfo.engineName; - appInfo.engineVersion = VK_MAKE_VERSION(0, 0, 1); - appInfo.apiVersion = VK_API_VERSION_1_1; - - VkInstanceCreateInfo info = {}; - info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; - info.pApplicationInfo = &appInfo; - Array extensions = getRequiredExtensions(); - for (uint32 i = 0; i < initInfo.instanceExtensions.size(); ++i) - { - extensions.add(initInfo.instanceExtensions[i]); - } - info.enabledExtensionCount = (uint32)extensions.size(); - info.ppEnabledExtensionNames = extensions.data(); -#ifdef ENABLE_VALIDATION - info.enabledLayerCount = (uint32)initInfo.layers.size(); - info.ppEnabledLayerNames = initInfo.layers.data(); -#else - info.enabledLayerCount = 0; -#endif - VK_CHECK(vkCreateInstance(&info, nullptr, &instance)); + initInstance(initInfo); setupDebugCallback(); + pickPhysicalDevice(); allocator = new VulkanAllocator(this); } @@ -52,17 +45,6 @@ void* Seele::VulkanGraphics::createWindow(const WindowCreateInfo& createInfo) return window; } -Seele::VulkanGraphics::VulkanGraphics() -{ - glfwInit(); - glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); -} - -Seele::VulkanGraphics::~VulkanGraphics() -{ - glfwTerminate(); -} - VkDevice Seele::VulkanGraphics::getDevice() const { return handle; @@ -88,6 +70,34 @@ Seele::Array Seele::VulkanGraphics::getRequiredExtensions() #endif // ENABLE_VALIDATION return extensions; } +void Seele::VulkanGraphics::initInstance(GraphicsInitializer initInfo) +{ + VkApplicationInfo appInfo = {}; + appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; + appInfo.pApplicationName = initInfo.applicationName; + appInfo.applicationVersion = VK_MAKE_VERSION(0, 0, 1); + appInfo.pEngineName = initInfo.engineName; + appInfo.engineVersion = VK_MAKE_VERSION(0, 0, 1); + appInfo.apiVersion = VK_API_VERSION_1_1; + + VkInstanceCreateInfo info = {}; + info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; + info.pApplicationInfo = &appInfo; + Array extensions = getRequiredExtensions(); + for (uint32 i = 0; i < initInfo.instanceExtensions.size(); ++i) + { + extensions.add(initInfo.instanceExtensions[i]); + } + info.enabledExtensionCount = (uint32)extensions.size(); + info.ppEnabledExtensionNames = extensions.data(); +#ifdef ENABLE_VALIDATION + info.enabledLayerCount = (uint32)initInfo.layers.size(); + info.ppEnabledLayerNames = initInfo.layers.data(); +#else + info.enabledLayerCount = 0; +#endif + VK_CHECK(vkCreateInstance(&info, nullptr, &instance)); +} void Seele::VulkanGraphics::setupDebugCallback() { VkDebugReportCallbackCreateInfoEXT createInfo = @@ -95,4 +105,19 @@ void Seele::VulkanGraphics::setupDebugCallback() VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT); VK_CHECK(CreateDebugReportCallbackEXT(instance, &createInfo, nullptr, &callback)); -} \ No newline at end of file +} + +void Seele::VulkanGraphics::pickPhysicalDevice() +{ + uint32 physicalDeviceCount; + vkEnumeratePhysicalDevices(instance, &physicalDeviceCount, nullptr); + Array physicalDevices(physicalDeviceCount); + vkEnumeratePhysicalDevices(instance, &physicalDeviceCount, physicalDevices.data()); + VkPhysicalDevice bestDevice; + uint32 deviceRating = 0; + for (auto physicalDevice : physicalDevices) + { + VkPhysicalDeviceProperties props; + vkGetPhysicalDeviceProperties(physicalDevice, &props); + } +} diff --git a/src/Engine/Graphics/Vulkan/VulkanGraphics.h b/src/Engine/Graphics/Vulkan/VulkanGraphics.h index 7b32f83..caa42e0 100644 --- a/src/Engine/Graphics/Vulkan/VulkanGraphics.h +++ b/src/Engine/Graphics/Vulkan/VulkanGraphics.h @@ -19,12 +19,15 @@ namespace Seele virtual void* createWindow(const WindowCreateInfo& createInfo) override; protected: Array getRequiredExtensions(); + void initInstance(GraphicsInitializer initInfo); void setupDebugCallback(); + void pickPhysicalDevice(); VkDevice handle; VkPhysicalDevice physicalDevice; VkInstance instance; VkDebugReportCallbackEXT callback; + Array viewports; PVulkanAllocator allocator; friend class Window; }; diff --git a/src/Engine/Graphics/Vulkan/VulkanGraphicsEnums.cpp b/src/Engine/Graphics/Vulkan/VulkanGraphicsEnums.cpp index 3c801d1..63a2c23 100644 --- a/src/Engine/Graphics/Vulkan/VulkanGraphicsEnums.cpp +++ b/src/Engine/Graphics/Vulkan/VulkanGraphicsEnums.cpp @@ -35,6 +35,7 @@ VkDescriptorType Seele::cast(const SeDescriptorType& descriptorType) default: break; } + return VK_DESCRIPTOR_TYPE_MAX_ENUM; } SeDescriptorType Seele::cast(const VkDescriptorType& descriptorType) @@ -71,6 +72,7 @@ SeDescriptorType Seele::cast(const VkDescriptorType& descriptorType) default: break; } + return SE_DESCRIPTOR_TYPE_MAX_ENUM; } VkShaderStageFlagBits Seele::cast(const SeShaderStageFlagBits& stage) @@ -113,6 +115,7 @@ VkShaderStageFlagBits Seele::cast(const SeShaderStageFlagBits& stage) default: break; } + return VK_SHADER_STAGE_ALL; } SeShaderStageFlagBits Seele::cast(const VkShaderStageFlagBits& stage) @@ -154,4 +157,5 @@ SeShaderStageFlagBits Seele::cast(const VkShaderStageFlagBits& stage) default: break; } + return SE_SHADER_STAGE_ALL; } \ No newline at end of file diff --git a/src/Engine/Graphics/Vulkan/VulkanGraphicsResources.h b/src/Engine/Graphics/Vulkan/VulkanGraphicsResources.h index 5bc8246..74936a6 100644 --- a/src/Engine/Graphics/Vulkan/VulkanGraphicsResources.h +++ b/src/Engine/Graphics/Vulkan/VulkanGraphicsResources.h @@ -11,6 +11,7 @@ namespace Seele public: VulkanDescriptorLayout(PVulkanGraphics graphics) : graphics(graphics) + , layoutHandle(VK_NULL_HANDLE) {} virtual ~VulkanDescriptorLayout(); virtual void create(); @@ -30,6 +31,8 @@ namespace Seele public: VulkanPipelineLayout(PVulkanGraphics graphics) : graphics(graphics) + , layoutHash(0) + , layoutHandle(VK_NULL_HANDLE) {} virtual ~VulkanPipelineLayout(); virtual void create(); @@ -53,7 +56,11 @@ namespace Seele class VulkanDescriptorSet : public DescriptorSet { public: - VulkanDescriptorSet(PVulkanGraphics graphics, PVulkanDescriptorAllocator owner) : graphics(graphics), owner(owner) {} + VulkanDescriptorSet(PVulkanGraphics graphics, PVulkanDescriptorAllocator owner) + : graphics(graphics) + , owner(owner) + , setHandle(VK_NULL_HANDLE) + {} virtual ~VulkanDescriptorSet(); virtual void updateBuffer(uint32_t binding, PUniformBuffer uniformBuffer); virtual void updateBuffer(uint32_t binding, PStructuredBuffer uniformBuffer); @@ -132,4 +139,17 @@ namespace Seele VkSampler sampler; }; DEFINE_REF(VulkanSamplerState); + + class VulkanViewport : public Viewport + { + public: + private: + uint32 sizeX; + uint32 sizeY; + uint32 offsetX; + uint32 offsetY; + VkSwapchainKHR swapchain; + void* windowHandle; + }; + DECLARE_REF(VulkanViewport); } \ No newline at end of file diff --git a/src/Engine/Graphics/Window.cpp b/src/Engine/Graphics/Window.cpp index bcf9f50..215c7b3 100644 --- a/src/Engine/Graphics/Window.cpp +++ b/src/Engine/Graphics/Window.cpp @@ -1,17 +1,15 @@ #include "Window.h" -#include "Vulkan/VulkanGraphics.h" #include "SceneView.h" Seele::Window::Window(const WindowCreateInfo& createInfo) : width(createInfo.width) , height(createInfo.height) { - graphics = new VulkanGraphics(); + graphics = createInfo.graphics; center = new Section(); center->resizeArea(Rect(1, 1, 0, 0)); center->addView(new SceneView(graphics)); windowHandle = graphics->createWindow(createInfo); - graphics->init(GraphicsInitializer()); } Seele::Window::~Window() diff --git a/src/Engine/Graphics/Window.h b/src/Engine/Graphics/Window.h index d3ba86b..8e9c7b6 100644 --- a/src/Engine/Graphics/Window.h +++ b/src/Engine/Graphics/Window.h @@ -62,7 +62,7 @@ namespace Seele { PSection center; uint32 width; uint32 height; - Graphics* graphics; + PGraphics graphics; }; DEFINE_REF(Window) } \ No newline at end of file diff --git a/src/Engine/Graphics/WindowManager.cpp b/src/Engine/Graphics/WindowManager.cpp index 3d1806c..9dce07c 100644 --- a/src/Engine/Graphics/WindowManager.cpp +++ b/src/Engine/Graphics/WindowManager.cpp @@ -1,7 +1,11 @@ #include "WindowManager.h" +#include "Vulkan/VulkanGraphics.h" Seele::WindowManager::WindowManager() { + graphics = new VulkanGraphics(); + GraphicsInitializer initializer; + graphics->init(initializer); } Seele::WindowManager::~WindowManager() diff --git a/src/Engine/Graphics/WindowManager.h b/src/Engine/Graphics/WindowManager.h index 0b94fc3..7dd9813 100644 --- a/src/Engine/Graphics/WindowManager.h +++ b/src/Engine/Graphics/WindowManager.h @@ -15,6 +15,7 @@ namespace Seele void endFrame(); private: Array windows; + PGraphics graphics; }; DEFINE_REF(WindowManager); } \ No newline at end of file diff --git a/src/Engine/MinimalEngine.h b/src/Engine/MinimalEngine.h index 483791c..e2c8a11 100644 --- a/src/Engine/MinimalEngine.h +++ b/src/Engine/MinimalEngine.h @@ -104,13 +104,13 @@ namespace Seele } template - RefPtr& cast() + RefPtr cast() { T* t = object->getHandle(); F* f = dynamic_cast(t); if (f == nullptr) { - return RefPtr(); + return nullptr; } RefObject* newObject = (RefObject*)object; RefPtr result(newObject);