graphics pipeline
This commit is contained in:
parent
11725fb9f4
commit
64ecba56ed
|
|
@ -50,4 +50,8 @@ namespace Nitric {
|
|||
m_Context.reset();
|
||||
m_Window.reset();
|
||||
}
|
||||
|
||||
Ref<GraphicsContext> Application::GetGraphicsContext() {
|
||||
return m_Context;
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
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();
|
||||
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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
};
|
||||
}
|
||||
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>
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
@ -2,5 +2,4 @@
|
|||
|
||||
namespace Nitric {
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -12,19 +12,13 @@ namespace Nitric {
|
|||
public:
|
||||
virtual ~Shader() = 0;
|
||||
|
||||
virtual uint64_t GetHash() = 0;
|
||||
virtual void Bind() = 0; // TODO: Bind(GraphicsPipeline);
|
||||
|
||||
static Ref<Shader> Create(const std::string& filepath);
|
||||
enum ShaderType {
|
||||
Vertex,
|
||||
Fragment
|
||||
};
|
||||
|
||||
class ShaderCache {
|
||||
public:
|
||||
static bool IsPresent(uint64_t hash);
|
||||
static Ref<Shader> GetShader(uint64_t hash);
|
||||
static void AddShader(Ref<Shader> shader);
|
||||
virtual ShaderType GetType() = 0;
|
||||
|
||||
private:
|
||||
static std::map<uint64_t, Ref<Shader>> s_Shaders;
|
||||
static Ref<Shader> Create(const std::string& filepath, ShaderType type);
|
||||
};
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user