Files
Seele/src/Engine/Graphics/Vulkan/VulkanGraphicsResources.h
T

425 lines
11 KiB
C++
Raw Normal View History

#pragma once
2020-03-13 12:44:33 +01:00
#include <vulkan/vulkan.h>
2020-08-11 22:38:19 +02:00
#include <functional>
2021-05-10 23:57:55 +02:00
#include "Graphics/GraphicsResources.h"
2020-03-09 12:30:07 +01:00
namespace Seele
{
2020-03-24 21:05:32 +01:00
namespace Vulkan
{
2021-04-01 16:40:14 +02:00
DECLARE_REF(DescriptorAllocator)
DECLARE_REF(CommandBufferManager)
DECLARE_REF(CmdBuffer)
DECLARE_REF(Graphics)
DECLARE_REF(SubAllocation)
2020-03-24 21:05:32 +01:00
class Semaphore
{
public:
2020-04-01 02:17:49 +02:00
Semaphore(PGraphics graphics);
2020-03-24 21:05:32 +01:00
virtual ~Semaphore();
2020-04-01 02:17:49 +02:00
inline VkSemaphore getHandle() const
{
return handle;
}
2020-04-12 15:47:19 +02:00
2020-03-24 21:05:32 +01:00
private:
VkSemaphore handle;
2020-04-01 02:17:49 +02:00
PGraphics graphics;
2020-03-24 21:05:32 +01:00
};
2021-04-01 16:40:14 +02:00
DEFINE_REF(Semaphore)
2020-03-24 21:05:32 +01:00
2020-04-12 15:47:19 +02:00
class Fence
2020-03-24 21:05:32 +01:00
{
public:
2020-04-12 15:47:19 +02:00
Fence(PGraphics graphics);
~Fence();
bool isSignaled();
void reset();
inline VkFence getHandle() const
2020-03-09 12:30:07 +01:00
{
2020-04-12 15:47:19 +02:00
return fence;
}
2020-04-12 15:47:19 +02:00
void wait(uint32 timeout);
2020-05-05 01:51:13 +02:00
bool operator<(const Fence &other) const
{
return fence < other.fence;
}
2020-03-24 21:05:32 +01:00
private:
2021-04-01 16:40:14 +02:00
PGraphics graphics;
2020-04-12 15:47:19 +02:00
bool signaled;
VkFence fence;
2020-03-24 21:05:32 +01:00
};
2021-04-01 16:40:14 +02:00
DEFINE_REF(Fence)
2020-03-24 21:05:32 +01:00
2020-10-03 11:00:10 +02:00
class VertexDeclaration : public Gfx::VertexDeclaration
{
public:
Array<Gfx::VertexElement> elementList;
VertexDeclaration(const Array<Gfx::VertexElement>& elementList);
virtual ~VertexDeclaration();
private:
};
2021-04-01 16:40:14 +02:00
DEFINE_REF(VertexDeclaration)
2020-10-03 11:00:10 +02:00
2020-05-05 01:51:13 +02:00
class QueueOwnedResourceDeletion
{
public:
QueueOwnedResourceDeletion();
virtual ~QueueOwnedResourceDeletion();
2020-09-19 14:36:50 +02:00
static void addPendingDelete(PCmdBuffer fence, std::function<void()> function);
2020-05-05 01:51:13 +02:00
private:
std::thread worker;
static volatile bool running;
static void run();
struct PendingItem
{
2020-09-19 14:36:50 +02:00
PCmdBuffer cmdBuffer;
2020-05-05 01:51:13 +02:00
std::function<void()> func;
};
static std::mutex mutex;
static std::condition_variable cv;
static List<PendingItem> deletionQueue;
};
2020-03-24 21:05:32 +01:00
2020-09-19 14:36:50 +02:00
class ShaderBuffer
2020-03-24 21:05:32 +01:00
{
public:
2021-05-10 23:57:55 +02:00
ShaderBuffer(PGraphics graphics, uint32 size, VkBufferUsageFlags usage, Gfx::QueueType& queueType, bool bDynamic = false);
2020-09-19 14:36:50 +02:00
virtual ~ShaderBuffer();
2020-04-12 15:47:19 +02:00
VkBuffer getHandle() const
{
return buffers[currentBuffer].buffer;
}
2020-10-03 11:00:10 +02:00
uint32 getSize() const
{
return size;
}
VkDeviceSize getOffset() const;
2020-04-12 15:47:19 +02:00
void advanceBuffer()
{
currentBuffer = (currentBuffer + 1) % numBuffers;
}
virtual void *lock(bool bWriteOnly = true);
virtual void unlock();
2020-04-12 15:47:19 +02:00
protected:
struct BufferAllocation
{
VkBuffer buffer;
PSubAllocation allocation;
};
2021-04-01 16:40:14 +02:00
PGraphics graphics;
2020-04-12 15:47:19 +02:00
uint32 currentBuffer;
uint32 size;
2021-05-10 23:57:55 +02:00
Gfx::QueueType& owner;
2021-04-01 16:40:14 +02:00
BufferAllocation buffers[Gfx::numFramesBuffered];
uint32 numBuffers;
2020-06-02 11:46:18 +02:00
void executeOwnershipBarrier(Gfx::QueueType newOwner);
2021-05-10 23:57:55 +02:00
void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage);
2020-06-02 11:46:18 +02:00
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner) = 0;
2020-03-24 21:05:32 +01:00
virtual VkAccessFlags getSourceAccessMask() = 0;
virtual VkAccessFlags getDestAccessMask() = 0;
};
2021-04-01 16:40:14 +02:00
DEFINE_REF(ShaderBuffer)
2020-03-24 21:05:32 +01:00
2021-04-01 16:40:14 +02:00
DECLARE_REF(StagingBuffer)
2020-09-19 14:36:50 +02:00
class UniformBuffer : public Gfx::UniformBuffer, public ShaderBuffer
2020-03-24 21:05:32 +01:00
{
2020-04-12 15:47:19 +02:00
public:
UniformBuffer(PGraphics graphics, const UniformBufferCreateInfo &resourceData);
2020-04-12 15:47:19 +02:00
virtual ~UniformBuffer();
2021-04-25 23:43:40 +02:00
virtual bool updateContents(const BulkResourceData &resourceData);
virtual void* lock(bool bWriteOnly = true) override;
virtual void unlock() override;
2020-04-12 15:47:19 +02:00
protected:
2020-06-02 11:46:18 +02:00
// Inherited via Vulkan::Buffer
2020-04-12 15:47:19 +02:00
virtual VkAccessFlags getSourceAccessMask();
virtual VkAccessFlags getDestAccessMask();
2021-05-10 23:57:55 +02:00
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner);
2020-06-02 11:46:18 +02:00
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner);
2021-05-10 23:57:55 +02:00
virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage);
private:
PStagingBuffer dedicatedStagingBuffer;
2020-03-24 21:05:32 +01:00
};
2021-04-01 16:40:14 +02:00
DEFINE_REF(UniformBuffer)
2020-03-24 21:05:32 +01:00
2020-09-19 14:36:50 +02:00
class StructuredBuffer : public Gfx::StructuredBuffer, public ShaderBuffer
2020-03-24 21:05:32 +01:00
{
2020-04-12 15:47:19 +02:00
public:
2021-05-10 23:57:55 +02:00
StructuredBuffer(PGraphics graphics, const StructuredBufferCreateInfo &resourceData);
2020-04-12 15:47:19 +02:00
virtual ~StructuredBuffer();
virtual bool updateContents(const BulkResourceData &resourceData);
2020-04-12 15:47:19 +02:00
virtual void* lock(bool bWriteOnly = true) override;
virtual void unlock() override;
2020-04-12 15:47:19 +02:00
protected:
2020-06-02 11:46:18 +02:00
// Inherited via Vulkan::Buffer
2020-04-12 15:47:19 +02:00
virtual VkAccessFlags getSourceAccessMask();
virtual VkAccessFlags getDestAccessMask();
2020-06-02 11:46:18 +02:00
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner);
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner);
2021-05-10 23:57:55 +02:00
virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage);
private:
PStagingBuffer dedicatedStagingBuffer;
2020-03-24 21:05:32 +01:00
};
2021-04-01 16:40:14 +02:00
DEFINE_REF(StructuredBuffer)
2020-03-24 21:05:32 +01:00
2020-09-19 14:36:50 +02:00
class VertexBuffer : public Gfx::VertexBuffer, public ShaderBuffer
2020-03-24 21:05:32 +01:00
{
public:
2020-05-05 01:51:13 +02:00
VertexBuffer(PGraphics graphics, const VertexBufferCreateInfo &resourceData);
2020-04-12 15:47:19 +02:00
virtual ~VertexBuffer();
2020-04-01 02:17:49 +02:00
2020-04-12 15:47:19 +02:00
protected:
2020-06-02 11:46:18 +02:00
// Inherited via Vulkan::Buffer
2020-04-12 15:47:19 +02:00
virtual VkAccessFlags getSourceAccessMask();
virtual VkAccessFlags getDestAccessMask();
2020-06-02 11:46:18 +02:00
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner);
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner);
2021-05-10 23:57:55 +02:00
virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage);
2020-04-12 15:47:19 +02:00
};
2021-04-01 16:40:14 +02:00
DEFINE_REF(VertexBuffer)
2020-04-12 15:47:19 +02:00
2020-09-19 14:36:50 +02:00
class IndexBuffer : public Gfx::IndexBuffer, public ShaderBuffer
2020-04-12 15:47:19 +02:00
{
public:
2020-05-05 01:51:13 +02:00
IndexBuffer(PGraphics graphics, const IndexBufferCreateInfo &resourceData);
2020-04-12 15:47:19 +02:00
virtual ~IndexBuffer();
protected:
2020-06-02 11:46:18 +02:00
// Inherited via Vulkan::Buffer
2020-04-12 15:47:19 +02:00
virtual VkAccessFlags getSourceAccessMask();
virtual VkAccessFlags getDestAccessMask();
2021-05-10 23:57:55 +02:00
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner);
2020-06-02 11:46:18 +02:00
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner);
2021-05-10 23:57:55 +02:00
virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage);
2020-04-12 15:47:19 +02:00
};
2021-04-01 16:40:14 +02:00
DEFINE_REF(IndexBuffer)
2020-04-12 15:47:19 +02:00
2020-06-02 11:46:18 +02:00
class TextureHandle
2020-04-12 15:47:19 +02:00
{
public:
2020-06-02 11:46:18 +02:00
TextureHandle(PGraphics graphics, VkImageViewType viewType,
2021-05-10 23:57:55 +02:00
const TextureCreateInfo& createInfo, Gfx::QueueType& owner, VkImage existingImage = VK_NULL_HANDLE);
2020-04-12 15:47:19 +02:00
virtual ~TextureHandle();
2021-05-10 23:57:55 +02:00
inline VkImage getImage() const
{
return image;
}
2020-04-12 15:47:19 +02:00
inline VkImageView getView() const
{
return defaultView;
}
2021-05-10 23:57:55 +02:00
inline Gfx::SeImageLayout getLayout() const
2020-04-12 15:47:19 +02:00
{
return layout;
}
inline VkImageAspectFlags getAspect() const
{
return aspect;
}
inline VkImageUsageFlags getUsage() const
{
return usage;
}
inline Gfx::SeFormat getFormat() const
{
return format;
}
2020-08-11 21:23:20 +02:00
inline Gfx::SeSampleCountFlags getNumSamples() const
{
return samples;
}
2021-08-22 23:07:38 +02:00
inline uint32 getMipLevels() const
{
return mipLevels;
}
2020-04-12 15:47:19 +02:00
inline bool isDepthStencil() const
{
return aspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT);
}
2020-06-02 11:46:18 +02:00
void executeOwnershipBarrier(Gfx::QueueType newOwner);
2021-05-10 23:57:55 +02:00
void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage);
void changeLayout(Gfx::SeImageLayout newLayout);
2020-04-12 15:47:19 +02:00
private:
2021-05-10 23:57:55 +02:00
//Updates via reference
Gfx::QueueType& currentOwner;
2020-04-01 02:17:49 +02:00
PGraphics graphics;
2020-04-12 15:47:19 +02:00
PSubAllocation allocation;
2020-03-24 21:05:32 +01:00
uint32 sizeX;
uint32 sizeY;
uint32 sizeZ;
uint32 arrayCount;
2020-04-01 02:17:49 +02:00
uint32 mipLevels;
2020-04-12 15:47:19 +02:00
uint32 samples;
2020-04-01 02:17:49 +02:00
Gfx::SeFormat format;
2020-04-12 15:47:19 +02:00
Gfx::SeImageUsageFlags usage;
2020-03-24 21:05:32 +01:00
VkImage image;
2020-04-01 02:17:49 +02:00
VkImageView defaultView;
VkImageAspectFlags aspect;
2021-05-10 23:57:55 +02:00
Gfx::SeImageLayout layout;
2020-04-12 15:47:19 +02:00
friend class TextureBase;
friend class Texture2D;
2021-05-10 23:57:55 +02:00
friend class Graphics;
2020-04-12 15:47:19 +02:00
};
class TextureBase
{
public:
2020-10-03 11:00:10 +02:00
static TextureHandle* cast(Gfx::PTexture texture);
2020-04-12 15:47:19 +02:00
protected:
2020-10-03 11:00:10 +02:00
TextureHandle* textureHandle;
2021-05-10 23:57:55 +02:00
friend class Graphics;
2020-03-24 21:05:32 +01:00
};
2021-05-10 23:57:55 +02:00
DECLARE_REF(TextureBase)
2020-09-19 14:36:50 +02:00
class Texture2D : public Gfx::Texture2D, public TextureBase
2020-03-24 21:05:32 +01:00
{
public:
2020-06-02 11:46:18 +02:00
Texture2D(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage = VK_NULL_HANDLE);
2020-04-01 02:17:49 +02:00
virtual ~Texture2D();
2020-08-11 21:23:20 +02:00
virtual uint32 getSizeX() const override
2020-04-01 02:17:49 +02:00
{
return textureHandle->sizeX;
}
2020-08-11 21:23:20 +02:00
virtual uint32 getSizeY() const override
2020-04-01 02:17:49 +02:00
{
return textureHandle->sizeY;
}
2021-08-22 23:07:38 +02:00
virtual uint32 getSizeZ() const override
{
return textureHandle->sizeZ;
}
2020-08-11 21:23:20 +02:00
virtual Gfx::SeFormat getFormat() const override
2020-04-01 02:17:49 +02:00
{
return textureHandle->format;
}
2020-08-11 21:23:20 +02:00
virtual Gfx::SeSampleCountFlags getNumSamples() const override
{
return textureHandle->getNumSamples();
}
2021-08-22 23:07:38 +02:00
virtual uint32 getMipLevels() const override
{
return textureHandle->getMipLevels();
}
2021-05-10 23:57:55 +02:00
virtual void changeLayout(Gfx::SeImageLayout newLayout) override;
virtual void* getNativeHandle() override
{
return textureHandle;
}
2020-04-01 02:17:49 +02:00
inline VkImage getHandle() const
{
return textureHandle->image;
}
inline VkImageView getView() const
{
return textureHandle->defaultView;
}
2020-04-12 15:47:19 +02:00
inline bool isDepthStencil() const
{
return textureHandle->isDepthStencil();
}
2020-06-02 11:46:18 +02:00
protected:
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner);
2021-05-10 23:57:55 +02:00
virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage);
2020-04-12 15:47:19 +02:00
2020-03-24 21:05:32 +01:00
};
2021-04-01 16:40:14 +02:00
DEFINE_REF(Texture2D)
2020-03-24 21:05:32 +01:00
2020-10-03 11:00:10 +02:00
class SamplerState : public Gfx::SamplerState
2020-03-24 21:05:32 +01:00
{
public:
VkSampler sampler;
};
2021-04-01 16:40:14 +02:00
DEFINE_REF(SamplerState)
2020-03-24 21:05:32 +01:00
2020-04-12 15:47:19 +02:00
class Window : public Gfx::Window
{
public:
Window(PGraphics graphics, const WindowCreateInfo &createInfo);
virtual ~Window();
virtual void beginFrame() override;
virtual void endFrame() override;
2021-05-06 17:02:10 +02:00
virtual Gfx::PTexture2D getBackBuffer() const override;
2020-04-12 15:47:19 +02:00
virtual void onWindowCloseEvent() override;
virtual void setKeyCallback(std::function<void(KeyCode, InputAction, KeyModifier)> callback) override;
virtual void setMouseMoveCallback(std::function<void(double, double)> callback) override;
virtual void setMouseButtonCallback(std::function<void(MouseButton, InputAction, KeyModifier)> callback) override;
2021-01-19 15:30:00 +01:00
virtual void setScrollCallback(std::function<void(double, double)> callback) override;
virtual void setFileCallback(std::function<void(int, const char**)> callback) override;
2020-04-12 15:47:19 +02:00
std::function<void(KeyCode, InputAction, KeyModifier)> keyCallback;
std::function<void(double, double)> mouseMoveCallback;
std::function<void(MouseButton, InputAction, KeyModifier)> mouseButtonCallback;
2021-01-19 15:30:00 +01:00
std::function<void(double, double)> scrollCallback;
std::function<void(int, const char**)> fileCallback;
2020-04-12 15:47:19 +02:00
protected:
void advanceBackBuffer();
void recreateSwapchain(const WindowCreateInfo &createInfo);
void present();
void destroySwapchain();
void createSwapchain();
void chooseSurfaceFormat(const Array<VkSurfaceFormatKHR> &available, Gfx::SeFormat preferred);
void choosePresentMode(const Array<VkPresentModeKHR> &modes);
2020-10-29 02:22:01 +01:00
2020-04-12 15:47:19 +02:00
PTexture2D backBufferImages[Gfx::numFramesBuffered];
PSemaphore renderFinished[Gfx::numFramesBuffered];
PSemaphore imageAcquired[Gfx::numFramesBuffered];
PSemaphore imageAcquiredSemaphore;
PGraphics graphics;
2021-04-01 16:40:14 +02:00
VkInstance instance;
2020-04-12 15:47:19 +02:00
VkSwapchainKHR swapchain;
2021-04-01 16:40:14 +02:00
VkSampleCountFlags numSamples;
VkFormat pixelFormat;
VkPresentModeKHR presentMode;
2020-04-12 15:47:19 +02:00
VkSurfaceKHR surface;
VkSurfaceFormatKHR surfaceFormat;
void *windowHandle;
int32 currentImageIndex;
int32 acquiredImageIndex;
int32 preAcquiredImageIndex;
int32 semaphoreIndex;
};
2021-04-01 16:40:14 +02:00
DEFINE_REF(Window)
2020-04-12 15:47:19 +02:00
2020-03-24 21:05:32 +01:00
class Viewport : public Gfx::Viewport
{
public:
2020-04-12 15:47:19 +02:00
Viewport(PGraphics graphics, PWindow owner, const ViewportCreateInfo &createInfo);
virtual ~Viewport();
2020-04-15 02:03:56 +02:00
virtual void resize(uint32 newX, uint32 newY);
virtual void move(uint32 newOffsetX, uint32 newOffsetY);
2020-10-03 11:00:10 +02:00
VkViewport getHandle() const { return handle; }
2020-03-24 21:05:32 +01:00
private:
2020-10-03 11:00:10 +02:00
VkViewport handle;
2020-04-12 15:47:19 +02:00
PGraphics graphics;
friend class Graphics;
2020-03-24 21:05:32 +01:00
};
2021-04-01 16:40:14 +02:00
DECLARE_REF(Viewport)
2020-03-24 21:05:32 +01:00
} // namespace Vulkan
} // namespace Seele