verus/RendererVulkan/src/CGI/RendererVulkan.h

223 lines
8.4 KiB
C++

// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once
namespace verus::CGI
{
enum class HostAccess : int
{
forbidden,
sequentialWrite,
random
};
struct BaseShaderInclude
{
virtual void Open(CSZ filename, void** ppData, UINT32* pBytes) = 0;
virtual void Close(void* pData) = 0;
};
typedef Store<CommandBufferVulkan> TStoreCommandBuffers;
typedef Store<GeometryVulkan> TStoreGeometry;
typedef Store<PipelineVulkan> TStorePipelines;
typedef Store<ShaderVulkan> TStoreShaders;
typedef Store<TextureVulkan> TStoreTextures;
class RendererVulkan : public Singleton<RendererVulkan>, public BaseRenderer,
private TStoreCommandBuffers, private TStoreGeometry, private TStorePipelines, private TStoreShaders, private TStoreTextures
{
public:
struct Framebuffer
{
VkFramebuffer _framebuffer = VK_NULL_HANDLE;
int _width = 0;
int _height = 0;
};
VERUS_TYPEDEFS(Framebuffer);
private:
struct QueueFamilyIndices
{
int _graphicsFamilyIndex = -1;
int _presentFamilyIndex = -1;
bool IsComplete() const
{
return _graphicsFamilyIndex >= 0 && _presentFamilyIndex >= 0;
}
bool IsSameQueue() const
{
return _graphicsFamilyIndex == _presentFamilyIndex;
}
};
struct SwapChainInfo
{
VkSurfaceCapabilitiesKHR _surfaceCapabilities = {};
Vector<VkSurfaceFormatKHR> _vSurfaceFormats;
Vector<VkPresentModeKHR> _vSurfacePresentModes;
};
static const uint32_t s_apiVersion = VK_API_VERSION_1_1;
static CSZ s_requiredValidationLayers[];
static CSZ s_requiredDeviceExtensions[];
ExtRealityVulkan _extReality;
VkInstance _instance = VK_NULL_HANDLE;
VkDebugUtilsMessengerEXT _debugUtilsMessenger = VK_NULL_HANDLE;
VkSurfaceKHR _surface = VK_NULL_HANDLE;
VkPhysicalDevice _physicalDevice = VK_NULL_HANDLE;
VkDevice _device = VK_NULL_HANDLE;
VkQueue _graphicsQueue = VK_NULL_HANDLE;
VkQueue _presentQueue = VK_NULL_HANDLE;
VmaAllocator _vmaAllocator = VK_NULL_HANDLE;
VkSwapchainKHR _swapChain = VK_NULL_HANDLE;
Vector<VkImage> _vSwapChainImages;
Vector<VkImageView> _vSwapChainImageViews;
VkCommandPool _commandPools[s_ringBufferSize] = {};
VkSemaphore _acquireNextImageSemaphores[s_ringBufferSize] = {};
VkSemaphore _queueSubmitSemaphores[s_ringBufferSize] = {};
VkSemaphore _acquireNextImageSemaphore = VK_NULL_HANDLE;
VkSemaphore _queueSubmitSemaphore = VK_NULL_HANDLE;
VkFence _queueSubmitFences[s_ringBufferSize] = {};
QueueFamilyIndices _queueFamilyIndices;
VkDescriptorPool _descriptorPoolImGui = VK_NULL_HANDLE;
Vector<VkSampler> _vSamplers;
Vector<VkRenderPass> _vRenderPasses;
Vector<Framebuffer> _vFramebuffers;
bool _advancedLineRasterization = false;
public:
RendererVulkan();
~RendererVulkan();
virtual void ReleaseMe() override;
void Init();
void Done();
static void VulkanCompilerInit();
static void VulkanCompilerDone();
static bool VulkanCompile(CSZ source, CSZ sourceName, CSZ* defines, BaseShaderInclude* pInclude,
CSZ entryPoint, CSZ target, UINT32 flags, UINT32** ppCode, UINT32* pSize, CSZ* ppErrorMsgs);
private:
static VKAPI_ATTR VkBool32 VKAPI_CALL DebugUtilsMessengerCallback(
VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverityFlagBits,
VkDebugUtilsMessageTypeFlagsEXT messageTypeFlags,
const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,
void* pUserData);
bool CheckRequiredValidationLayers();
Vector<CSZ> GetRequiredExtensions();
void CreateInstance();
void FillDebugUtilsMessengerCreateInfo(VkDebugUtilsMessengerCreateInfoEXT& vkdumci);
void CreateDebugUtilsMessenger();
void CreateSurface();
QueueFamilyIndices FindQueueFamilyIndices(VkPhysicalDevice device);
bool CheckRequiredDeviceExtensions(VkPhysicalDevice device);
bool IsDeviceSuitable(VkPhysicalDevice device);
void PickPhysicalDevice();
void CreateDevice();
SwapChainInfo GetSwapChainInfo(VkPhysicalDevice device);
void CreateSwapChain(VkSwapchainKHR oldSwapchain = VK_NULL_HANDLE);
void CreateImageViews();
void CreateCommandPools();
void CreateSyncObjects();
void CreateSamplers();
public:
// <CreateAndGet>
VkCommandBuffer CreateVkCommandBuffer(VkCommandPool commandPool);
VkInstance GetVkInstance() const { return _instance; }
VkPhysicalDevice GetVkPhysicalDevice() const { return _physicalDevice; }
VkDevice GetVkDevice() const { return _device; }
int GetGraphicsQueueFamilyIndex() const { return _queueFamilyIndices._graphicsFamilyIndex; }
VkQueue GetVkGraphicsQueue() const { return _graphicsQueue; }
const VkAllocationCallbacks* GetAllocator() const { return nullptr; }
VmaAllocator GetVmaAllocator() const { return _vmaAllocator; }
VkCommandPool GetVkCommandPool(int ringBufferIndex) const { return _commandPools[ringBufferIndex]; }
const VkSampler* GetImmutableSampler(Sampler s) const;
// </CreateAndGet>
static void ImGuiCheckVkResultFn(VkResult res);
virtual void ImGuiInit(RPHandle renderPassHandle) override;
virtual void ImGuiRenderDrawData() override;
virtual void ResizeSwapChain() override;
virtual PBaseExtReality GetExtReality() override;
// Which graphics API?
virtual Gapi GetGapi() override { return Gapi::vulkan; }
// <FrameCycle>
virtual void BeginFrame() override;
virtual void AcquireSwapChainImage() override;
virtual void EndFrame() override;
virtual void WaitIdle() override;
virtual void OnMinimized() override;
// </FrameCycle>
// <Resources>
virtual PBaseCommandBuffer InsertCommandBuffer() override;
virtual PBaseGeometry InsertGeometry() override;
virtual PBasePipeline InsertPipeline() override;
virtual PBaseShader InsertShader() override;
virtual PBaseTexture InsertTexture() override;
virtual void DeleteCommandBuffer(PBaseCommandBuffer p) override;
virtual void DeleteGeometry(PBaseGeometry p) override;
virtual void DeletePipeline(PBasePipeline p) override;
virtual void DeleteShader(PBaseShader p) override;
virtual void DeleteTexture(PBaseTexture p) override;
virtual RPHandle CreateRenderPass(std::initializer_list<RP::Attachment> ilA, std::initializer_list<RP::Subpass> ilS, std::initializer_list<RP::Dependency> ilD) override;
virtual FBHandle CreateFramebuffer(RPHandle renderPassHandle, std::initializer_list<TexturePtr> il, int w, int h,
int swapChainBufferIndex = -1, CubeMapFace cubeMapFace = CubeMapFace::none) override;
virtual void DeleteRenderPass(RPHandle handle) override;
virtual void DeleteFramebuffer(FBHandle handle) override;
int GetNextRenderPassIndex() const;
int GetNextFramebufferIndex() const;
VkRenderPass GetRenderPass(RPHandle handle) const;
RcFramebuffer GetFramebuffer(FBHandle handle) const;
// </Resources>
// <BufferAndImage>
void CreateBuffer(VkDeviceSize size, VkBufferUsageFlags usage, HostAccess hostAccess, VkBuffer& buffer, VmaAllocation& vmaAllocation);
void CopyBuffer(VkBuffer srcBuffer, VkBuffer dstBuffer, VkDeviceSize size, PBaseCommandBuffer pCB = nullptr);
void CreateImage(const VkImageCreateInfo* pImageCreateInfo, HostAccess hostAccess, VkImage& image, VmaAllocation& vmaAllocation);
void CopyImage(
VkImage srcImage, uint32_t srcMipLevel, uint32_t srcArrayLayer,
VkImage dstImage, uint32_t dstMipLevel, uint32_t dstArrayLayer,
uint32_t width, uint32_t height,
PBaseCommandBuffer pCB = nullptr);
void CopyBufferToImage(
VkBuffer buffer,
VkImage image, uint32_t mipLevel, uint32_t arrayLayer,
uint32_t width, uint32_t height,
PBaseCommandBuffer pCB = nullptr);
void CopyImageToBuffer(
VkImage image, uint32_t mipLevel, uint32_t arrayLayer,
uint32_t width, uint32_t height,
VkBuffer buffer,
PBaseCommandBuffer pCB = nullptr);
// </BufferAndImage>
virtual void UpdateUtilization() override;
bool IsAdvancedLineRasterizationSupported() const { return _advancedLineRasterization; }
};
VERUS_TYPEDEFS(RendererVulkan);
extern "C"
{
typedef void(*PFNVULKANCOMPILERINIT)();
typedef void(*PFNVULKANCOMPILERDONE)();
typedef bool(*PFNVULKANCOMPILE)(CSZ source, CSZ sourceName, CSZ* defines, CGI::BaseShaderInclude* pInclude,
CSZ entryPoint, CSZ target, UINT32 flags, UINT32** ppCode, UINT32* pSize, CSZ* ppErrorMsgs);
}
}
#define VERUS_QREF_RENDERER_VULKAN CGI::PRendererVulkan pRendererVulkan = CGI::RendererVulkan::P()