graphics pipeline

This commit is contained in:
Nepgfurmixpro 2023-11-17 12:09:10 -05:00
parent 11725fb9f4
commit 64ecba56ed
12 changed files with 190 additions and 26 deletions

View File

@ -50,4 +50,8 @@ namespace Nitric {
m_Context.reset();
m_Window.reset();
}
Ref<GraphicsContext> Application::GetGraphicsContext() {
return m_Context;
}
}

View File

@ -24,13 +24,15 @@ namespace Nitric {
static Application* Get();
Ref<GraphicsContext> GetGraphicsContext();
private:
static Application* s_Instance;
void PollEvents();
void RenderFrame();
Scope<GraphicsContext> m_Context;
Ref<GraphicsContext> m_Context;
Ref<Window> m_Window;
bool m_Running;

View 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
View 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;
};
}

View File

@ -19,6 +19,10 @@ namespace Nitric {
this->PickPhysicalDevice();
LogInternal::Debug("Creating logical device");
this->CreateLogicalDevice();
LogInternal::Debug("Creating swapchain");
this->CreateSwapchain();
LogInternal::Debug("Creating image views");
this->CreateImageViews();
}
void VkGraphicsContext::CreateInstance() {
@ -87,6 +91,12 @@ namespace Nitric {
};
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");
vkDestroyDevice(m_Device, nullptr);
LogInternal::Debug("Destroying Vulkan Surface");
@ -162,6 +172,9 @@ namespace Nitric {
createInfo.queueCreateInfoCount = static_cast<uint32_t>(queueCreateInfos.size());
createInfo.pQueueCreateInfos = queueCreateInfos.data();
createInfo.enabledExtensionCount = static_cast<uint32_t>(Vk::DeviceExtensions.size());
createInfo.ppEnabledExtensionNames = Vk::DeviceExtensions.data();
Vk::Validate(
vkCreateDevice(m_PhysicalDevice, &createInfo, nullptr, &m_Device),
true,
@ -186,24 +199,64 @@ namespace Nitric {
VkSwapchainCreateInfoKHR createInfo{};
createInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
createInfo.surface = m_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;
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) {
createInfo.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
createInfo.queueFamilyIndexCount = 2;
createInfo.pQueueFamilyIndices = queueFamilyIncices;
createInfo.pQueueFamilyIndices = queueFamilyIndices;
} else {
createInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
}
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;
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");
}
}
}

View File

@ -17,6 +17,8 @@ namespace Nitric {
void Init() override;
VkDevice GetDevice();
private:
void CreateInstance();
void CreateDebugMessenger();
@ -24,6 +26,7 @@ namespace Nitric {
void CreateLogicalDevice();
void CreateSwapchain();
void CreateImageViews();
static bool CheckValidationLayerSupport();
@ -31,16 +34,22 @@ namespace Nitric {
Ref<VkWindow> m_Window;
VkInstance m_Instance{};
VkPhysicalDevice m_PhysicalDevice;
VkInstance m_Instance = VK_NULL_HANDLE;
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_PresentQueue;
VkQueue m_GraphicsQueue = VK_NULL_HANDLE;
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;
};
}

View 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;
}
};

View 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;
};
}

View File

@ -5,10 +5,10 @@
#include <utility>
namespace Nitric {
Scope<GraphicsContext> GraphicsContext::Create(Ref<Window> window) {
Ref<GraphicsContext> GraphicsContext::Create(Ref<Window> window) {
switch (GraphicsAPI::GetAPI()) {
case GraphicsAPI::Vulkan:
return CreateScope<VkGraphicsContext>(CastPtr<VkWindow>(std::move(window)));
return CreateRef<VkGraphicsContext>(CastPtr<VkWindow>(std::move(window)));
default:
break;
}

View File

@ -11,7 +11,7 @@ namespace Nitric {
virtual ~GraphicsContext() = default;
virtual void Init() = 0;
static Scope<GraphicsContext> Create(Ref<Window> window);
static Ref<GraphicsContext> Create(Ref<Window> window);
};
}

View File

@ -2,5 +2,4 @@
namespace Nitric {
}

View File

@ -12,19 +12,13 @@ namespace Nitric {
public:
virtual ~Shader() = 0;
virtual uint64_t GetHash() = 0;
virtual void Bind() = 0; // TODO: Bind(GraphicsPipeline);
enum ShaderType {
Vertex,
Fragment
};
static Ref<Shader> Create(const std::string& filepath);
};
virtual ShaderType GetType() = 0;
class ShaderCache {
public:
static bool IsPresent(uint64_t hash);
static Ref<Shader> GetShader(uint64_t hash);
static void AddShader(Ref<Shader> shader);
private:
static std::map<uint64_t, Ref<Shader>> s_Shaders;
static Ref<Shader> Create(const std::string& filepath, ShaderType type);
};
}