graphics pipeline
This commit is contained in:
parent
11725fb9f4
commit
64ecba56ed
|
|
@ -50,4 +50,8 @@ namespace Nitric {
|
||||||
m_Context.reset();
|
m_Context.reset();
|
||||||
m_Window.reset();
|
m_Window.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ref<GraphicsContext> Application::GetGraphicsContext() {
|
||||||
|
return m_Context;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -24,13 +24,15 @@ namespace Nitric {
|
||||||
|
|
||||||
static Application* Get();
|
static Application* Get();
|
||||||
|
|
||||||
|
Ref<GraphicsContext> GetGraphicsContext();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static Application* s_Instance;
|
static Application* s_Instance;
|
||||||
|
|
||||||
void PollEvents();
|
void PollEvents();
|
||||||
void RenderFrame();
|
void RenderFrame();
|
||||||
|
|
||||||
Scope<GraphicsContext> m_Context;
|
Ref<GraphicsContext> m_Context;
|
||||||
Ref<Window> m_Window;
|
Ref<Window> m_Window;
|
||||||
|
|
||||||
bool m_Running;
|
bool m_Running;
|
||||||
|
|
|
||||||
31
Nitric/Source/Core/File.cpp
Normal file
31
Nitric/Source/Core/File.cpp
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
#include <Core/File.h>
|
||||||
|
|
||||||
|
namespace Nitric {
|
||||||
|
|
||||||
|
File::File(const std::string &filepath) {
|
||||||
|
m_Filepath = filepath;
|
||||||
|
std::ifstream file(filepath, std::ios::ate | std::ios::binary);
|
||||||
|
if (!file.is_open()) {
|
||||||
|
LogInternal::Error("Failed to open \"{}\"", filepath);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t fileSize = file.tellg();
|
||||||
|
m_Data.resize(fileSize);
|
||||||
|
file.seekg(0);
|
||||||
|
file.read(reinterpret_cast<char *>(m_Data.data()), fileSize);
|
||||||
|
file.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string File::AsString() {
|
||||||
|
return {reinterpret_cast<const char *const>(m_Data.data())};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::byte> File::AsBytes() {
|
||||||
|
return m_Data;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string& File::Filepath() {
|
||||||
|
return m_Filepath;
|
||||||
|
}
|
||||||
|
}
|
||||||
22
Nitric/Source/Core/File.h
Normal file
22
Nitric/Source/Core/File.h
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Core/LogInternal.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
namespace Nitric {
|
||||||
|
class File {
|
||||||
|
public:
|
||||||
|
File(const std::string& filepath);
|
||||||
|
|
||||||
|
std::string AsString();
|
||||||
|
std::vector<std::byte> AsBytes();
|
||||||
|
|
||||||
|
std::string& Filepath();
|
||||||
|
private:
|
||||||
|
std::vector<std::byte> m_Data;
|
||||||
|
std::string m_Filepath;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -19,6 +19,10 @@ namespace Nitric {
|
||||||
this->PickPhysicalDevice();
|
this->PickPhysicalDevice();
|
||||||
LogInternal::Debug("Creating logical device");
|
LogInternal::Debug("Creating logical device");
|
||||||
this->CreateLogicalDevice();
|
this->CreateLogicalDevice();
|
||||||
|
LogInternal::Debug("Creating swapchain");
|
||||||
|
this->CreateSwapchain();
|
||||||
|
LogInternal::Debug("Creating image views");
|
||||||
|
this->CreateImageViews();
|
||||||
}
|
}
|
||||||
|
|
||||||
void VkGraphicsContext::CreateInstance() {
|
void VkGraphicsContext::CreateInstance() {
|
||||||
|
|
@ -87,6 +91,12 @@ namespace Nitric {
|
||||||
};
|
};
|
||||||
|
|
||||||
VkGraphicsContext::~VkGraphicsContext() {
|
VkGraphicsContext::~VkGraphicsContext() {
|
||||||
|
LogInternal::Debug("Destroying image views");
|
||||||
|
for (auto imageView : m_SwapChainImageViews) {
|
||||||
|
vkDestroyImageView(m_Device, imageView, nullptr);
|
||||||
|
}
|
||||||
|
LogInternal::Debug("Destroying Vulkan Swapchain");
|
||||||
|
vkDestroySwapchainKHR(m_Device, m_SwapChain, nullptr);
|
||||||
LogInternal::Debug("Destroying Vulkan Device");
|
LogInternal::Debug("Destroying Vulkan Device");
|
||||||
vkDestroyDevice(m_Device, nullptr);
|
vkDestroyDevice(m_Device, nullptr);
|
||||||
LogInternal::Debug("Destroying Vulkan Surface");
|
LogInternal::Debug("Destroying Vulkan Surface");
|
||||||
|
|
@ -162,6 +172,9 @@ namespace Nitric {
|
||||||
createInfo.queueCreateInfoCount = static_cast<uint32_t>(queueCreateInfos.size());
|
createInfo.queueCreateInfoCount = static_cast<uint32_t>(queueCreateInfos.size());
|
||||||
createInfo.pQueueCreateInfos = queueCreateInfos.data();
|
createInfo.pQueueCreateInfos = queueCreateInfos.data();
|
||||||
|
|
||||||
|
createInfo.enabledExtensionCount = static_cast<uint32_t>(Vk::DeviceExtensions.size());
|
||||||
|
createInfo.ppEnabledExtensionNames = Vk::DeviceExtensions.data();
|
||||||
|
|
||||||
Vk::Validate(
|
Vk::Validate(
|
||||||
vkCreateDevice(m_PhysicalDevice, &createInfo, nullptr, &m_Device),
|
vkCreateDevice(m_PhysicalDevice, &createInfo, nullptr, &m_Device),
|
||||||
true,
|
true,
|
||||||
|
|
@ -186,24 +199,64 @@ namespace Nitric {
|
||||||
VkSwapchainCreateInfoKHR createInfo{};
|
VkSwapchainCreateInfoKHR createInfo{};
|
||||||
createInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
|
createInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
|
||||||
createInfo.surface = m_Surface;
|
createInfo.surface = m_Surface;
|
||||||
|
|
||||||
createInfo.minImageCount = imageCount;
|
createInfo.minImageCount = imageCount;
|
||||||
createInfo.imageFormat = surfaceFormat.format;
|
createInfo.imageFormat = surfaceFormat.format;
|
||||||
createInfo.imageColorSpace = surfaceFormat.colorSpace;
|
createInfo.imageColorSpace = surfaceFormat.colorSpace;
|
||||||
|
createInfo.imageExtent = extent;
|
||||||
createInfo.imageArrayLayers = 1;
|
createInfo.imageArrayLayers = 1;
|
||||||
createInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
createInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
||||||
|
|
||||||
Vk::QueueFamilyIndices indices = Vk::FindQueueFamilies(m_PhysicalDevice, m_Surface);
|
Vk::QueueFamilyIndices indices = Vk::FindQueueFamilies(m_PhysicalDevice, m_Surface);
|
||||||
uint32_t queueFamilyIncices[] = {indices.GraphicsFamily.value(), indices.PresentFamily.value()};
|
uint32_t queueFamilyIndices[] = {indices.GraphicsFamily.value(), indices.PresentFamily.value()};
|
||||||
|
|
||||||
if (indices.GraphicsFamily != indices.PresentFamily) {
|
if (indices.GraphicsFamily != indices.PresentFamily) {
|
||||||
createInfo.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
|
createInfo.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
|
||||||
createInfo.queueFamilyIndexCount = 2;
|
createInfo.queueFamilyIndexCount = 2;
|
||||||
createInfo.pQueueFamilyIndices = queueFamilyIncices;
|
createInfo.pQueueFamilyIndices = queueFamilyIndices;
|
||||||
} else {
|
} else {
|
||||||
createInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
createInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
createInfo.preTransform = swapChainSupport.Capabilities.currentTransform;
|
createInfo.preTransform = swapChainSupport.Capabilities.currentTransform;
|
||||||
createInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
|
createInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
|
||||||
|
createInfo.presentMode = presentMode;
|
||||||
|
createInfo.clipped = VK_TRUE;
|
||||||
|
|
||||||
|
createInfo.oldSwapchain = VK_NULL_HANDLE;
|
||||||
|
|
||||||
|
Vk::Validate(vkCreateSwapchainKHR(m_Device, &createInfo, nullptr, &m_SwapChain),
|
||||||
|
true,
|
||||||
|
"VkSwapchainKHR VkGraphicsPipeline::m_SwapChain failed to create.");
|
||||||
|
vkGetSwapchainImagesKHR(m_Device, m_SwapChain, &imageCount, nullptr);
|
||||||
|
m_SwapChainImages.resize(imageCount);
|
||||||
|
vkGetSwapchainImagesKHR(m_Device, m_SwapChain, &imageCount, m_SwapChainImages.data());
|
||||||
|
m_SwapChainFormat = surfaceFormat.format;
|
||||||
|
m_SwapChainExtent = extent;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VkGraphicsContext::CreateImageViews() {
|
||||||
|
m_SwapChainImageViews.resize(m_SwapChainImages.size());
|
||||||
|
|
||||||
|
for (size_t i = 0; i < m_SwapChainImages.size(); i++) {
|
||||||
|
VkImageViewCreateInfo createInfo{};
|
||||||
|
createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||||
|
createInfo.image = m_SwapChainImages[i];
|
||||||
|
createInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
||||||
|
createInfo.format = m_SwapChainFormat;
|
||||||
|
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;
|
||||||
|
|
||||||
|
Vk::Validate(vkCreateImageView(m_Device, &createInfo, nullptr, &m_SwapChainImageViews[i]),
|
||||||
|
true,
|
||||||
|
"Failed to create image view");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -17,6 +17,8 @@ namespace Nitric {
|
||||||
|
|
||||||
void Init() override;
|
void Init() override;
|
||||||
|
|
||||||
|
VkDevice GetDevice();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void CreateInstance();
|
void CreateInstance();
|
||||||
void CreateDebugMessenger();
|
void CreateDebugMessenger();
|
||||||
|
|
@ -24,6 +26,7 @@ namespace Nitric {
|
||||||
void CreateLogicalDevice();
|
void CreateLogicalDevice();
|
||||||
|
|
||||||
void CreateSwapchain();
|
void CreateSwapchain();
|
||||||
|
void CreateImageViews();
|
||||||
|
|
||||||
static bool CheckValidationLayerSupport();
|
static bool CheckValidationLayerSupport();
|
||||||
|
|
||||||
|
|
@ -31,16 +34,22 @@ namespace Nitric {
|
||||||
|
|
||||||
Ref<VkWindow> m_Window;
|
Ref<VkWindow> m_Window;
|
||||||
|
|
||||||
VkInstance m_Instance{};
|
VkInstance m_Instance = VK_NULL_HANDLE;
|
||||||
VkPhysicalDevice m_PhysicalDevice;
|
VkPhysicalDevice m_PhysicalDevice = VK_NULL_HANDLE;
|
||||||
|
|
||||||
VkSurfaceKHR m_Surface;
|
VkSurfaceKHR m_Surface = VK_NULL_HANDLE;
|
||||||
|
|
||||||
VkDevice m_Device;
|
VkDevice m_Device = VK_NULL_HANDLE;
|
||||||
|
|
||||||
VkQueue m_GraphicsQueue;
|
VkQueue m_GraphicsQueue = VK_NULL_HANDLE;
|
||||||
VkQueue m_PresentQueue;
|
VkQueue m_PresentQueue = VK_NULL_HANDLE;
|
||||||
|
|
||||||
VkDebugUtilsMessengerEXT m_DebugMessenger{};
|
VkSwapchainKHR m_SwapChain = VK_NULL_HANDLE;
|
||||||
|
std::vector<VkImage> m_SwapChainImages;
|
||||||
|
VkFormat m_SwapChainFormat;
|
||||||
|
VkExtent2D m_SwapChainExtent;
|
||||||
|
std::vector<VkImageView> m_SwapChainImageViews;
|
||||||
|
|
||||||
|
VkDebugUtilsMessengerEXT m_DebugMessenger = VK_NULL_HANDLE;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
30
Nitric/Source/Platform/Vulkan/VkShader.cpp
Normal file
30
Nitric/Source/Platform/Vulkan/VkShader.cpp
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
#include <Platform/Vulkan/VkShader.h>
|
||||||
|
|
||||||
|
#include <Core/Application.h>
|
||||||
|
#include <Platform/Vulkan/VkGraphicsContext.h>
|
||||||
|
|
||||||
|
namespace Nitric {
|
||||||
|
VkShader::VkShader(const std::string &filepath, ShaderType type) : m_Type(type) {
|
||||||
|
File file(filepath);
|
||||||
|
auto fileData = file.AsBytes();
|
||||||
|
VkShaderModuleCreateInfo createInfo{};
|
||||||
|
createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
|
||||||
|
createInfo.codeSize = fileData.size();
|
||||||
|
createInfo.pCode = reinterpret_cast<const uint32_t*>(fileData.data());
|
||||||
|
|
||||||
|
auto context = CastPtr<VkGraphicsContext>(Application::Get()->GetGraphicsContext());
|
||||||
|
|
||||||
|
Vk::Validate(vkCreateShaderModule(context->GetDevice(), &createInfo, nullptr, &m_Module),
|
||||||
|
false,
|
||||||
|
fmt::format("Failed to create shader \"{}\".", filepath));
|
||||||
|
}
|
||||||
|
|
||||||
|
VkShader::~VkShader() {
|
||||||
|
auto context = CastPtr<VkGraphicsContext>(Application::Get()->GetGraphicsContext());
|
||||||
|
vkDestroyShaderModule(context->GetDevice(), m_Module, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
VkShaderModule VkShader::GetModule() {
|
||||||
|
return m_Module;
|
||||||
|
}
|
||||||
|
};
|
||||||
20
Nitric/Source/Platform/Vulkan/VkShader.h
Normal file
20
Nitric/Source/Platform/Vulkan/VkShader.h
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Render/Shader.h>
|
||||||
|
#include <Core/File.h>
|
||||||
|
#include <Platform/Vulkan/VkBase.h>
|
||||||
|
|
||||||
|
#include <vulkan/vulkan.h>
|
||||||
|
|
||||||
|
namespace Nitric {
|
||||||
|
class VkShader : public Shader {
|
||||||
|
public:
|
||||||
|
VkShader(const std::string &filepath, ShaderType type);
|
||||||
|
~VkShader() override;
|
||||||
|
|
||||||
|
VkShaderModule GetModule();
|
||||||
|
private:
|
||||||
|
VkShaderModule m_Module;
|
||||||
|
ShaderType m_Type;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -5,10 +5,10 @@
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
namespace Nitric {
|
namespace Nitric {
|
||||||
Scope<GraphicsContext> GraphicsContext::Create(Ref<Window> window) {
|
Ref<GraphicsContext> GraphicsContext::Create(Ref<Window> window) {
|
||||||
switch (GraphicsAPI::GetAPI()) {
|
switch (GraphicsAPI::GetAPI()) {
|
||||||
case GraphicsAPI::Vulkan:
|
case GraphicsAPI::Vulkan:
|
||||||
return CreateScope<VkGraphicsContext>(CastPtr<VkWindow>(std::move(window)));
|
return CreateRef<VkGraphicsContext>(CastPtr<VkWindow>(std::move(window)));
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ namespace Nitric {
|
||||||
virtual ~GraphicsContext() = default;
|
virtual ~GraphicsContext() = default;
|
||||||
virtual void Init() = 0;
|
virtual void Init() = 0;
|
||||||
|
|
||||||
static Scope<GraphicsContext> Create(Ref<Window> window);
|
static Ref<GraphicsContext> Create(Ref<Window> window);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -2,5 +2,4 @@
|
||||||
|
|
||||||
namespace Nitric {
|
namespace Nitric {
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -12,19 +12,13 @@ namespace Nitric {
|
||||||
public:
|
public:
|
||||||
virtual ~Shader() = 0;
|
virtual ~Shader() = 0;
|
||||||
|
|
||||||
virtual uint64_t GetHash() = 0;
|
enum ShaderType {
|
||||||
virtual void Bind() = 0; // TODO: Bind(GraphicsPipeline);
|
Vertex,
|
||||||
|
Fragment
|
||||||
static Ref<Shader> Create(const std::string& filepath);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class ShaderCache {
|
virtual ShaderType GetType() = 0;
|
||||||
public:
|
|
||||||
static bool IsPresent(uint64_t hash);
|
|
||||||
static Ref<Shader> GetShader(uint64_t hash);
|
|
||||||
static void AddShader(Ref<Shader> shader);
|
|
||||||
|
|
||||||
private:
|
static Ref<Shader> Create(const std::string& filepath, ShaderType type);
|
||||||
static std::map<uint64_t, Ref<Shader>> s_Shaders;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue
Block a user