#pragma once #include #include #include "Graphics/GraphicsResources.h" #include "VulkanAllocator.h" #include "ThreadPool.h" namespace Seele { namespace Vulkan { DECLARE_REF(DescriptorAllocator) DECLARE_REF(CommandBufferManager) DECLARE_REF(CmdBuffer) DECLARE_REF(Graphics) DECLARE_REF(SubAllocation) class Semaphore { public: Semaphore(PGraphics graphics); virtual ~Semaphore(); inline VkSemaphore getHandle() const { return handle; } private: VkSemaphore handle; PGraphics graphics; }; DEFINE_REF(Semaphore) class Fence { public: Fence(PGraphics graphics); ~Fence(); bool isSignaled(); void reset(); inline VkFence getHandle() const { return fence; } void wait(uint32 timeout); Event asyncWait() const; bool operator<(const Fence &other) const { return fence < other.fence; } private: PGraphics graphics; Event signaled; VkFence fence; }; DEFINE_REF(Fence) class VertexDeclaration : public Gfx::VertexDeclaration { public: Array elementList; VertexDeclaration(const Array& elementList); virtual ~VertexDeclaration(); private: }; DEFINE_REF(VertexDeclaration) class ShaderBuffer { public: ShaderBuffer(PGraphics graphics, uint32 size, VkBufferUsageFlags usage, Gfx::QueueType& queueType, bool bDynamic = false); virtual ~ShaderBuffer(); VkBuffer getHandle() const { return buffers[currentBuffer].buffer; } uint32 getSize() const { return size; } VkDeviceSize getOffset() const; void advanceBuffer() { currentBuffer = (currentBuffer + 1) % numBuffers; } virtual void *lock(bool bWriteOnly = true); virtual void unlock(); protected: struct BufferAllocation { VkBuffer buffer; PSubAllocation allocation; }; PGraphics graphics; uint32 currentBuffer; uint32 size; Gfx::QueueType& owner; BufferAllocation buffers[Gfx::numFramesBuffered]; uint32 numBuffers; void executeOwnershipBarrier(Gfx::QueueType newOwner); void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess, VkPipelineStageFlags dstStage); virtual void requestOwnershipTransfer(Gfx::QueueType newOwner) = 0; virtual VkAccessFlags getSourceAccessMask() = 0; virtual VkAccessFlags getDestAccessMask() = 0; }; DEFINE_REF(ShaderBuffer) DECLARE_REF(StagingBuffer) class UniformBuffer : public Gfx::UniformBuffer, public ShaderBuffer { public: UniformBuffer(PGraphics graphics, const UniformBufferCreateInfo &resourceData); virtual ~UniformBuffer(); virtual bool updateContents(const BulkResourceData &resourceData); virtual void* lock(bool bWriteOnly = true) override; virtual void unlock() override; protected: // Inherited via Vulkan::Buffer virtual VkAccessFlags getSourceAccessMask(); virtual VkAccessFlags getDestAccessMask(); virtual void requestOwnershipTransfer(Gfx::QueueType newOwner); // Inherited via QueueOwnedResource virtual void executeOwnershipBarrier(Gfx::QueueType newOwner); virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess, VkPipelineStageFlags dstStage); private: PStagingBuffer dedicatedStagingBuffer; }; DEFINE_REF(UniformBuffer) class StructuredBuffer : public Gfx::StructuredBuffer, public ShaderBuffer { public: StructuredBuffer(PGraphics graphics, const StructuredBufferCreateInfo &resourceData); virtual ~StructuredBuffer(); virtual bool updateContents(const BulkResourceData &resourceData); virtual void* lock(bool bWriteOnly = true) override; virtual void unlock() override; protected: // Inherited via Vulkan::Buffer virtual VkAccessFlags getSourceAccessMask(); virtual VkAccessFlags getDestAccessMask(); virtual void requestOwnershipTransfer(Gfx::QueueType newOwner); // Inherited via QueueOwnedResource virtual void executeOwnershipBarrier(Gfx::QueueType newOwner); virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess, VkPipelineStageFlags dstStage); private: PStagingBuffer dedicatedStagingBuffer; }; DEFINE_REF(StructuredBuffer) class VertexBuffer : public Gfx::VertexBuffer, public ShaderBuffer { public: VertexBuffer(PGraphics graphics, const VertexBufferCreateInfo &resourceData); virtual ~VertexBuffer(); protected: // Inherited via Vulkan::Buffer virtual VkAccessFlags getSourceAccessMask(); virtual VkAccessFlags getDestAccessMask(); virtual void requestOwnershipTransfer(Gfx::QueueType newOwner); // Inherited via QueueOwnedResource virtual void executeOwnershipBarrier(Gfx::QueueType newOwner); virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess, VkPipelineStageFlags dstStage); }; DEFINE_REF(VertexBuffer) class IndexBuffer : public Gfx::IndexBuffer, public ShaderBuffer { public: IndexBuffer(PGraphics graphics, const IndexBufferCreateInfo &resourceData); virtual ~IndexBuffer(); protected: // Inherited via Vulkan::Buffer virtual VkAccessFlags getSourceAccessMask(); virtual VkAccessFlags getDestAccessMask(); virtual void requestOwnershipTransfer(Gfx::QueueType newOwner); // Inherited via QueueOwnedResource virtual void executeOwnershipBarrier(Gfx::QueueType newOwner); virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess, VkPipelineStageFlags dstStage); }; DEFINE_REF(IndexBuffer) class TextureHandle { public: TextureHandle(PGraphics graphics, VkImageViewType viewType, const TextureCreateInfo& createInfo, Gfx::QueueType& owner, VkImage existingImage = VK_NULL_HANDLE); virtual ~TextureHandle(); inline VkImage getImage() const { return image; } inline VkImageView getView() const { return defaultView; } inline Gfx::SeImageLayout getLayout() const { return layout; } inline VkImageAspectFlags getAspect() const { return aspect; } inline VkImageUsageFlags getUsage() const { return usage; } inline Gfx::SeFormat getFormat() const { return format; } inline Gfx::SeSampleCountFlags getNumSamples() const { return samples; } inline uint32 getMipLevels() const { return mipLevels; } inline bool isDepthStencil() const { return aspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT); } void executeOwnershipBarrier(Gfx::QueueType newOwner); void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess, VkPipelineStageFlags dstStage); void changeLayout(Gfx::SeImageLayout newLayout); private: //Updates via reference Gfx::QueueType& currentOwner; PGraphics graphics; PSubAllocation allocation; uint32 sizeX; uint32 sizeY; uint32 sizeZ; uint32 arrayCount; uint32 mipLevels; uint32 samples; Gfx::SeFormat format; Gfx::SeImageUsageFlags usage; VkImage image; VkImageView defaultView; VkImageAspectFlags aspect; Gfx::SeImageLayout layout; friend class TextureBase; friend class Texture2D; friend class Graphics; }; class TextureBase { public: static TextureHandle* cast(Gfx::PTexture texture); protected: TextureHandle* textureHandle; friend class Graphics; }; DECLARE_REF(TextureBase) class Texture2D : public Gfx::Texture2D, public TextureBase { public: Texture2D(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage = VK_NULL_HANDLE); virtual ~Texture2D(); virtual uint32 getSizeX() const override { return textureHandle->sizeX; } virtual uint32 getSizeY() const override { return textureHandle->sizeY; } virtual uint32 getSizeZ() const override { return textureHandle->sizeZ; } virtual Gfx::SeFormat getFormat() const override { return textureHandle->format; } virtual Gfx::SeSampleCountFlags getNumSamples() const override { return textureHandle->getNumSamples(); } virtual uint32 getMipLevels() const override { return textureHandle->getMipLevels(); } virtual void changeLayout(Gfx::SeImageLayout newLayout) override; virtual void* getNativeHandle() override { return textureHandle; } inline VkImage getHandle() const { return textureHandle->image; } inline VkImageView getView() const { return textureHandle->defaultView; } inline bool isDepthStencil() const { return textureHandle->isDepthStencil(); } protected: // Inherited via QueueOwnedResource virtual void executeOwnershipBarrier(Gfx::QueueType newOwner); virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess, VkPipelineStageFlags dstStage); }; DEFINE_REF(Texture2D) class SamplerState : public Gfx::SamplerState { public: VkSampler sampler; }; DEFINE_REF(SamplerState) class Window : public Gfx::Window { public: Window(PGraphics graphics, const WindowCreateInfo &createInfo); virtual ~Window(); virtual void beginFrame() override; virtual void endFrame() override; virtual Gfx::PTexture2D getBackBuffer() const override; virtual void onWindowCloseEvent() override; virtual void setKeyCallback(std::function callback) override; virtual void setMouseMoveCallback(std::function callback) override; virtual void setMouseButtonCallback(std::function callback) override; virtual void setScrollCallback(std::function callback) override; virtual void setFileCallback(std::function callback) override; virtual void setCloseCallback(std::function callback); std::function keyCallback; std::function mouseMoveCallback; std::function mouseButtonCallback; std::function scrollCallback; std::function fileCallback; std::function closeCallback; protected: void advanceBackBuffer(); void recreateSwapchain(const WindowCreateInfo &createInfo); void present(); void destroySwapchain(); void createSwapchain(); void chooseSurfaceFormat(const Array &available, Gfx::SeFormat preferred); void choosePresentMode(const Array &modes); PTexture2D backBufferImages[Gfx::numFramesBuffered]; PSemaphore renderFinished[Gfx::numFramesBuffered]; PSemaphore imageAcquired[Gfx::numFramesBuffered]; PSemaphore imageAcquiredSemaphore; PGraphics graphics; VkInstance instance; VkSwapchainKHR swapchain; VkSampleCountFlags numSamples; VkFormat pixelFormat; VkPresentModeKHR presentMode; VkSurfaceKHR surface; VkSurfaceFormatKHR surfaceFormat; void *windowHandle; int32 currentImageIndex; int32 acquiredImageIndex; int32 preAcquiredImageIndex; int32 semaphoreIndex; }; DEFINE_REF(Window) class Viewport : public Gfx::Viewport { public: Viewport(PGraphics graphics, PWindow owner, const ViewportCreateInfo &createInfo); virtual ~Viewport(); virtual void resize(uint32 newX, uint32 newY); virtual void move(uint32 newOffsetX, uint32 newOffsetY); VkViewport getHandle() const { return handle; } private: VkViewport handle; PGraphics graphics; friend class Graphics; }; DECLARE_REF(Viewport) } // namespace Vulkan } // namespace Seele