Refactoring graphics
This commit is contained in:
+3
-3
@@ -1,6 +1,6 @@
|
||||
#include "VulkanAllocator.h"
|
||||
#include "VulkanGraphics.h"
|
||||
#include "VulkanInitializer.h"
|
||||
#include "Allocator.h"
|
||||
#include "Graphics.h"
|
||||
#include "Initializer.h"
|
||||
|
||||
using namespace Seele::Vulkan;
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
#include "MinimalEngine.h"
|
||||
#include "VulkanGraphicsEnums.h"
|
||||
#include "Enums.h"
|
||||
#include "Containers/Map.h"
|
||||
#include "Containers/Array.h"
|
||||
#include <mutex>
|
||||
@@ -1,8 +1,4 @@
|
||||
#include "VulkanGraphicsResources.h"
|
||||
#include "VulkanInitializer.h"
|
||||
#include "VulkanGraphics.h"
|
||||
#include "VulkanCommandBuffer.h"
|
||||
#include "VulkanAllocator.h"
|
||||
#include "Buffer.h"
|
||||
|
||||
using namespace Seele;
|
||||
using namespace Seele::Vulkan;
|
||||
@@ -16,7 +12,7 @@ struct PendingBuffer
|
||||
bool bWriteOnly;
|
||||
};
|
||||
|
||||
static std::map<ShaderBuffer *, PendingBuffer> pendingBuffers;
|
||||
static std::map<Vulkan::ShaderBuffer *, PendingBuffer> pendingBuffers;
|
||||
|
||||
ShaderBuffer::ShaderBuffer(PGraphics graphics, uint64 size, VkBufferUsageFlags usage, Gfx::QueueType& queueType, bool bDynamic)
|
||||
: graphics(graphics)
|
||||
@@ -0,0 +1,145 @@
|
||||
#pragma once
|
||||
#include "Graphics/Buffer.h"
|
||||
#include "Graphics.h"
|
||||
#include "Allocator.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
namespace Vulkan
|
||||
{
|
||||
|
||||
class ShaderBuffer
|
||||
{
|
||||
public:
|
||||
ShaderBuffer(PGraphics graphics, uint64 size, VkBufferUsageFlags usage, Gfx::QueueType& queueType, bool bDynamic = false);
|
||||
virtual ~ShaderBuffer();
|
||||
VkBuffer getHandle() const
|
||||
{
|
||||
return buffers[currentBuffer].buffer;
|
||||
}
|
||||
uint64 getSize() const
|
||||
{
|
||||
return size;
|
||||
}
|
||||
VkDeviceSize getOffset() const;
|
||||
void advanceBuffer()
|
||||
{
|
||||
currentBuffer = (currentBuffer + 1) % numBuffers;
|
||||
}
|
||||
virtual void *lock(bool bWriteOnly = true);
|
||||
virtual void *lockRegion(uint64 regionOffset, uint64 regionSize, bool bWriteOnly = true);
|
||||
virtual void unlock();
|
||||
|
||||
protected:
|
||||
struct BufferAllocation
|
||||
{
|
||||
VkBuffer buffer;
|
||||
PSubAllocation allocation;
|
||||
};
|
||||
PGraphics graphics;
|
||||
uint32 currentBuffer;
|
||||
uint64 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 ShaderBuffer : public Gfx::ShaderBuffer, public ShaderBuffer
|
||||
{
|
||||
public:
|
||||
ShaderBuffer(PGraphics graphics, const ShaderBufferCreateInfo &resourceData);
|
||||
virtual ~ShaderBuffer();
|
||||
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(ShaderBuffer)
|
||||
|
||||
class VertexBuffer : public Gfx::VertexBuffer, public ShaderBuffer
|
||||
{
|
||||
public:
|
||||
VertexBuffer(PGraphics graphics, const VertexBufferCreateInfo &resourceData);
|
||||
virtual ~VertexBuffer();
|
||||
|
||||
virtual void updateRegion(BulkResourceData update) override;
|
||||
virtual void download(Array<uint8>& buffer) 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);
|
||||
};
|
||||
DEFINE_REF(VertexBuffer)
|
||||
|
||||
class IndexBuffer : public Gfx::IndexBuffer, public ShaderBuffer
|
||||
{
|
||||
public:
|
||||
IndexBuffer(PGraphics graphics, const IndexBufferCreateInfo &resourceData);
|
||||
virtual ~IndexBuffer();
|
||||
|
||||
virtual void download(Array<uint8>& buffer) 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);
|
||||
};
|
||||
DEFINE_REF(IndexBuffer)
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,49 +1,55 @@
|
||||
target_sources(Engine
|
||||
PRIVATE
|
||||
VulkanAllocator.h
|
||||
VulkanAllocator.cpp
|
||||
VulkanBuffer.cpp
|
||||
VulkanCommandBuffer.h
|
||||
VulkanCommandBuffer.cpp
|
||||
VulkanFramebuffer.h
|
||||
VulkanFramebuffer.cpp
|
||||
VulkanGraphics.h
|
||||
VulkanGraphics.cpp
|
||||
VulkanGraphicsResources.h
|
||||
VulkanGraphicsResources.cpp
|
||||
VulkanDescriptorSets.h
|
||||
VulkanDescriptorSets.cpp
|
||||
VulkanGraphicsEnums.h
|
||||
VulkanGraphicsEnums.cpp
|
||||
VulkanInitializer.h
|
||||
VulkanInitializer.cpp
|
||||
VulkanRenderPass.h
|
||||
VulkanRenderPass.cpp
|
||||
VulkanPipeline.h
|
||||
VulkanPipeline.cpp
|
||||
VulkanPipelineCache.h
|
||||
VulkanPipelineCache.cpp
|
||||
VulkanShader.h
|
||||
VulkanShader.cpp
|
||||
VulkanTexture.cpp
|
||||
VulkanQueue.h
|
||||
VulkanQueue.cpp
|
||||
VulkanViewport.cpp)
|
||||
Allocator.h
|
||||
Allocator.cpp
|
||||
Buffer.h
|
||||
Buffer.cpp
|
||||
CommandBuffer.h
|
||||
CommandBuffer.cpp
|
||||
DescriptorSets.h
|
||||
DescriptorSets.cpp
|
||||
Enums.h
|
||||
Enums.cpp
|
||||
Framebuffer.h
|
||||
Framebuffer.cpp
|
||||
Graphics.h
|
||||
Graphics.cpp
|
||||
Initializer.h
|
||||
Initializer.cpp
|
||||
Pipeline.h
|
||||
Pipeline.cpp
|
||||
PipelineCache.h
|
||||
PipelineCache.cpp
|
||||
Queue.h
|
||||
Queue.cpp
|
||||
RenderPass.h
|
||||
RenderPass.cpp
|
||||
RenderTarget.h
|
||||
RenderTarget.cpp
|
||||
Resources.h
|
||||
Resources.cpp
|
||||
Shader.h
|
||||
Shader.cpp
|
||||
Texture.h
|
||||
Texture.cpp)
|
||||
|
||||
target_sources(Engine
|
||||
PUBLIC FILE_SET HEADERS
|
||||
FILES
|
||||
VulkanAllocator.h
|
||||
VulkanCommandBuffer.h
|
||||
VulkanFramebuffer.h
|
||||
VulkanGraphics.h
|
||||
VulkanGraphicsResources.h
|
||||
VulkanDescriptorSets.h
|
||||
VulkanGraphicsEnums.h
|
||||
VulkanInitializer.h
|
||||
VulkanRenderPass.h
|
||||
VulkanPipeline.h
|
||||
VulkanPipelineCache.h
|
||||
VulkanShader.h
|
||||
VulkanQueue.h)
|
||||
Allocator.h
|
||||
Buffer.h
|
||||
CommandBuffer.h
|
||||
DescriptorSets.h
|
||||
Enums.h
|
||||
Framebuffer.h
|
||||
Graphics.h
|
||||
Initializer.h
|
||||
Pipeline.h
|
||||
PipelineCache.h
|
||||
Queue.h
|
||||
RenderPass.h
|
||||
RenderTarget.h
|
||||
Resources.h
|
||||
Shader.h
|
||||
Texture.h)
|
||||
|
||||
+9
-10
@@ -1,13 +1,12 @@
|
||||
#include "VulkanCommandBuffer.h"
|
||||
#include "VulkanInitializer.h"
|
||||
#include "VulkanGraphics.h"
|
||||
#include "VulkanPipeline.h"
|
||||
#include "VulkanGraphicsEnums.h"
|
||||
#include "VulkanFramebuffer.h"
|
||||
#include "VulkanRenderPass.h"
|
||||
#include "VulkanPipeline.h"
|
||||
#include "VulkanDescriptorSets.h"
|
||||
#include "Graphics/MeshBatch.h"
|
||||
#include "CommandBuffer.h"
|
||||
#include "Initializer.h"
|
||||
#include "Graphics.h"
|
||||
#include "Pipeline.h"
|
||||
#include "Enums.h"
|
||||
#include "Framebuffer.h"
|
||||
#include "RenderPass.h"
|
||||
#include "Pipeline.h"
|
||||
#include "DescriptorSets.h"
|
||||
|
||||
using namespace Seele;
|
||||
using namespace Seele::Vulkan;
|
||||
+4
-3
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
#include "VulkanGraphicsResources.h"
|
||||
#include "VulkanQueue.h"
|
||||
#include "Queue.h"
|
||||
#include "DescriptorSets.h"
|
||||
#include "Buffer.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
@@ -87,7 +88,7 @@ public:
|
||||
virtual void bindPipeline(Gfx::PGraphicsPipeline pipeline) override;
|
||||
virtual void bindDescriptor(Gfx::PDescriptorSet descriptorSet) override;
|
||||
virtual void bindDescriptor(const Array<Gfx::PDescriptorSet>& descriptorSets) override;
|
||||
virtual void bindVertexBuffer(const Array<VertexInputStream>& streams) override;
|
||||
virtual void bindVertexBuffer(const Array<PVertexBuffer>& buffers) override;
|
||||
virtual void bindIndexBuffer(Gfx::PIndexBuffer indexBuffer) override;
|
||||
virtual void pushConstants(Gfx::PPipelineLayout layout, Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size, const void* data) override;
|
||||
virtual void draw(uint32 vertexCount, uint32 instanceCount, int32 firstVertex, uint32 firstInstance) override;
|
||||
+4
-6
@@ -1,9 +1,7 @@
|
||||
#include "VulkanDescriptorSets.h"
|
||||
#include "VulkanGraphicsResources.h"
|
||||
#include "VulkanGraphicsEnums.h"
|
||||
#include "VulkanGraphics.h"
|
||||
#include "VulkanInitializer.h"
|
||||
#include "VulkanCommandBuffer.h"
|
||||
#include "DescriptorSets.h"
|
||||
#include "Graphics.h"
|
||||
#include "Initializer.h"
|
||||
#include "CommandBuffer.h"
|
||||
|
||||
using namespace Seele;
|
||||
using namespace Seele::Vulkan;
|
||||
+4
-1
@@ -1,5 +1,8 @@
|
||||
#pragma once
|
||||
#include "VulkanGraphicsResources.h"
|
||||
#include "Enums.h"
|
||||
#include "Graphics/Descriptor.h"
|
||||
#include "Containers/List.h"
|
||||
#include "Resources.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
+5
-6
@@ -1,5 +1,5 @@
|
||||
#pragma once
|
||||
#include "Graphics/GraphicsEnums.h"
|
||||
#include "Graphics/Enums.h"
|
||||
#include <vulkan/vulkan.h>
|
||||
#include <iostream>
|
||||
|
||||
@@ -25,11 +25,10 @@ namespace Vulkan
|
||||
enum class ShaderType
|
||||
{
|
||||
VERTEX = 0,
|
||||
CONTROL = 1,
|
||||
EVALUATION = 2,
|
||||
GEOMETRY = 3,
|
||||
FRAGMENT = 4,
|
||||
COMPUTE = 5,
|
||||
FRAGMENT = 1,
|
||||
COMPUTE = 2,
|
||||
TASK = 3,
|
||||
MESH = 4,
|
||||
};
|
||||
|
||||
VkDescriptorType cast(const Gfx::SeDescriptorType &descriptorType);
|
||||
+6
-5
@@ -1,8 +1,9 @@
|
||||
#include "VulkanFramebuffer.h"
|
||||
#include "VulkanGraphicsEnums.h"
|
||||
#include "VulkanInitializer.h"
|
||||
#include "VulkanRenderPass.h"
|
||||
#include "VulkanGraphics.h"
|
||||
#include "Framebuffer.h"
|
||||
#include "Enums.h"
|
||||
#include "Initializer.h"
|
||||
#include "RenderPass.h"
|
||||
#include "Graphics.h"
|
||||
#include "Texture.h"
|
||||
|
||||
using namespace Seele;
|
||||
using namespace Seele::Vulkan;
|
||||
+3
-1
@@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
#include "VulkanGraphicsResources.h"
|
||||
#include "Enums.h"
|
||||
#include "Graphics.h"
|
||||
#include "Graphics/RenderTarget.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
@@ -1,5 +1,5 @@
|
||||
#pragma once
|
||||
#include "VulkanGraphicsResources.h"
|
||||
#include "Enums.h"
|
||||
#include "Graphics/Graphics.h"
|
||||
|
||||
namespace Seele
|
||||
@@ -14,6 +14,9 @@ DECLARE_REF(RenderPass)
|
||||
DECLARE_REF(Framebuffer)
|
||||
DECLARE_REF(RenderCommand)
|
||||
DECLARE_REF(PipelineCache)
|
||||
DECLARE_REF(Window)
|
||||
DECLARE_REF(RenderTargetLayout)
|
||||
DECLARE_REF(Viewport)
|
||||
class Graphics : public Gfx::Graphics
|
||||
{
|
||||
public:
|
||||
@@ -55,13 +58,13 @@ public:
|
||||
virtual Gfx::PComputeCommand createComputeCommand(const std::string& name) override;
|
||||
virtual Gfx::PVertexDeclaration createVertexDeclaration(const Array<Gfx::VertexElement>& element) override;
|
||||
virtual Gfx::PVertexShader createVertexShader(const ShaderCreateInfo& createInfo) override;
|
||||
virtual Gfx::PControlShader createControlShader(const ShaderCreateInfo& createInfo) override;
|
||||
virtual Gfx::PEvaluationShader createEvaluationShader(const ShaderCreateInfo& createInfo) override;
|
||||
virtual Gfx::PGeometryShader createGeometryShader(const ShaderCreateInfo& createInfo) override;
|
||||
virtual Gfx::PFragmentShader createFragmentShader(const ShaderCreateInfo& createInfo) override;
|
||||
virtual Gfx::PComputeShader createComputeShader(const ShaderCreateInfo& createInfo) override;
|
||||
virtual Gfx::PGraphicsPipeline createGraphicsPipeline(const GraphicsPipelineCreateInfo& createInfo) override;
|
||||
virtual Gfx::PComputePipeline createComputePipeline(const ComputePipelineCreateInfo& createInfo) override;
|
||||
virtual Gfx::PTaskShader createTaskShader(const ShaderCreateInfo& createInfo) override;
|
||||
virtual Gfx::PMeshShader createMeshShader(const ShaderCreateInfo& createInfo) override;
|
||||
virtual Gfx::PGraphicsPipeline createGraphicsPipeline(const Gfx::LegacyPipelineCreateInfo& createInfo) override;
|
||||
virtual Gfx::PGraphicsPipeline createGraphicsPipeline(const Gfx::MeshPipelineCreateInfo& createInfo) override;
|
||||
virtual Gfx::PComputePipeline createComputePipeline(const Gfx::ComputePipelineCreateInfo& createInfo) override;
|
||||
virtual Gfx::PSamplerState createSamplerState(const SamplerCreateInfo& createInfo) override;
|
||||
|
||||
virtual Gfx::PDescriptorLayout createDescriptorLayout(const std::string& name = "") override;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
#include "VulkanInitializer.h"
|
||||
#include "Initializer.h"
|
||||
#include <iostream>
|
||||
|
||||
using namespace Seele::Vulkan;
|
||||
+7
-7
@@ -1,12 +1,12 @@
|
||||
#include "VulkanPipeline.h"
|
||||
#include "VulkanDescriptorSets.h"
|
||||
#include "VulkanGraphics.h"
|
||||
#include "Pipeline.h"
|
||||
#include "DescriptorSets.h"
|
||||
#include "Graphics.h"
|
||||
|
||||
using namespace Seele;
|
||||
using namespace Seele::Vulkan;
|
||||
|
||||
GraphicsPipeline::GraphicsPipeline(PGraphics graphics, VkPipeline handle, PPipelineLayout pipelineLayout, const GraphicsPipelineCreateInfo& createInfo)
|
||||
: Gfx::GraphicsPipeline(createInfo, pipelineLayout)
|
||||
GraphicsPipeline::GraphicsPipeline(PGraphics graphics, VkPipeline handle, PPipelineLayout pipelineLayout)
|
||||
: Gfx::GraphicsPipeline(pipelineLayout)
|
||||
, graphics(graphics)
|
||||
, pipeline(handle)
|
||||
{
|
||||
@@ -26,8 +26,8 @@ VkPipelineLayout GraphicsPipeline::getLayout() const
|
||||
return layout.cast<PipelineLayout>()->getHandle();
|
||||
}
|
||||
|
||||
ComputePipeline::ComputePipeline(PGraphics graphics, VkPipeline handle, PPipelineLayout pipelineLayout, const ComputePipelineCreateInfo& createInfo)
|
||||
: Gfx::ComputePipeline(createInfo, pipelineLayout)
|
||||
ComputePipeline::ComputePipeline(PGraphics graphics, VkPipeline handle, PPipelineLayout pipelineLayout)
|
||||
: Gfx::ComputePipeline(pipelineLayout)
|
||||
, graphics(graphics)
|
||||
, pipeline(handle)
|
||||
{
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
#include "VulkanGraphicsResources.h"
|
||||
#include "Enums.h"
|
||||
#include "Graphics/Resources.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
@@ -10,7 +11,7 @@ DECLARE_REF(Graphics)
|
||||
class GraphicsPipeline : public Gfx::GraphicsPipeline
|
||||
{
|
||||
public:
|
||||
GraphicsPipeline(PGraphics graphics, VkPipeline handle, PPipelineLayout pipelineLayout, const GraphicsPipelineCreateInfo& createInfo);
|
||||
GraphicsPipeline(PGraphics graphics, VkPipeline handle, PPipelineLayout pipelineLayout);
|
||||
virtual ~GraphicsPipeline();
|
||||
void bind(VkCommandBuffer handle);
|
||||
VkPipelineLayout getLayout() const;
|
||||
@@ -22,7 +23,7 @@ DEFINE_REF(GraphicsPipeline)
|
||||
class ComputePipeline : public Gfx::ComputePipeline
|
||||
{
|
||||
public:
|
||||
ComputePipeline(PGraphics graphics, VkPipeline handle, PPipelineLayout pipelineLayout, const ComputePipelineCreateInfo& createInfo);
|
||||
ComputePipeline(PGraphics graphics, VkPipeline handle, PPipelineLayout pipelineLayout);
|
||||
virtual ~ComputePipeline();
|
||||
void bind(VkCommandBuffer handle);
|
||||
VkPipelineLayout getLayout() const;
|
||||
@@ -0,0 +1,393 @@
|
||||
#include "PipelineCache.h"
|
||||
#include "Graphics.h"
|
||||
#include "Enums.h"
|
||||
#include "Initializer.h"
|
||||
#include "RenderPass.h"
|
||||
#include "DescriptorSets.h"
|
||||
#include "Shader.h"
|
||||
#include <fstream>
|
||||
|
||||
using namespace Seele;
|
||||
using namespace Seele::Vulkan;
|
||||
|
||||
PipelineCache::PipelineCache(PGraphics graphics, const std::string& cacheFilePath)
|
||||
: graphics(graphics)
|
||||
, cacheFile(cacheFilePath)
|
||||
{
|
||||
std::ifstream stream(cacheFilePath, std::ios::binary | std::ios::ate);
|
||||
VkPipelineCacheCreateInfo cacheCreateInfo;
|
||||
cacheCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
|
||||
cacheCreateInfo.pNext = nullptr;
|
||||
cacheCreateInfo.flags = 0;
|
||||
cacheCreateInfo.initialDataSize = 0;
|
||||
if(stream.good())
|
||||
{
|
||||
Array<uint8> cacheData;
|
||||
uint32 fileSize = static_cast<uint32>(stream.tellg());
|
||||
cacheData.resize(fileSize);
|
||||
stream.seekg(0);
|
||||
stream.read((char*)cacheData.data(), fileSize);
|
||||
cacheCreateInfo.initialDataSize = fileSize;
|
||||
cacheCreateInfo.pInitialData = cacheData.data();
|
||||
std::cout << "Loaded " << fileSize << " bytes from pipeline cache" << std::endl;
|
||||
}
|
||||
VK_CHECK(vkCreatePipelineCache(graphics->getDevice(), &cacheCreateInfo, nullptr, &cache));
|
||||
}
|
||||
|
||||
PipelineCache::~PipelineCache()
|
||||
{
|
||||
VkDeviceSize cacheSize;
|
||||
vkGetPipelineCacheData(graphics->getDevice(), cache, &cacheSize, nullptr);
|
||||
Array<uint8> cacheData;
|
||||
vkGetPipelineCacheData(graphics->getDevice(), cache, &cacheSize, cacheData.data());
|
||||
std::ofstream stream(cacheFile, std::ios::binary);
|
||||
stream.write((char*)cacheData.data(), cacheSize);
|
||||
stream.flush();
|
||||
stream.close();
|
||||
vkDestroyPipelineCache(graphics->getDevice(), cache, nullptr);
|
||||
std::cout << "Written " << cacheSize << " bytes to cache" << std::endl;
|
||||
}
|
||||
|
||||
PGraphicsPipeline PipelineCache::createPipeline(const Gfx::LegacyPipelineCreateInfo& gfxInfo)
|
||||
{
|
||||
uint32 stageCount = 0;
|
||||
|
||||
VkPipelineShaderStageCreateInfo stageInfos[2];
|
||||
std::memset(stageInfos, 0, sizeof(stageInfos));
|
||||
|
||||
PVertexShader vertexShader = gfxInfo.vertexShader.cast<VertexShader>();
|
||||
stageInfos[stageCount++] = {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
|
||||
.stage = VK_SHADER_STAGE_VERTEX_BIT,
|
||||
.module = vertexShader->getModuleHandle(),
|
||||
.pName = vertexShader->getEntryPointName(),
|
||||
};
|
||||
|
||||
if(gfxInfo.fragmentShader != nullptr)
|
||||
{
|
||||
PFragmentShader fragment = gfxInfo.fragmentShader.cast<FragmentShader>();
|
||||
|
||||
stageInfos[stageCount++] = {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
|
||||
.stage = VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
.module = fragment->getModuleHandle(),
|
||||
.pName = fragment->getEntryPointName(),
|
||||
};
|
||||
}
|
||||
VkPipelineVertexInputStateCreateInfo vertexInput =
|
||||
init::PipelineVertexInputStateCreateInfo();
|
||||
|
||||
Array<VkVertexInputBindingDescription> bindings;
|
||||
Array<VkVertexInputAttributeDescription> attributes;
|
||||
if (gfxInfo.vertexDeclaration != nullptr)
|
||||
{
|
||||
PVertexDeclaration decl = gfxInfo.vertexDeclaration.cast<VertexDeclaration>();
|
||||
for (const auto& elem : decl->elementList)
|
||||
{
|
||||
attributes.add(VkVertexInputAttributeDescription{
|
||||
.location = elem.attributeIndex,
|
||||
.binding = elem.binding,
|
||||
.format = cast(elem.vertexFormat),
|
||||
.offset = elem.offset,
|
||||
});
|
||||
auto res = bindings.find([elem](const VkVertexInputBindingDescription& b) {return b.binding == elem.binding; });
|
||||
if (res == bindings.end())
|
||||
{
|
||||
bindings.add({});
|
||||
res = bindings.end();
|
||||
}
|
||||
*res = VkVertexInputBindingDescription{
|
||||
.binding = elem.binding,
|
||||
.stride = elem.stride,
|
||||
.inputRate = elem.bInstanced ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX,
|
||||
};
|
||||
}
|
||||
vertexInput.pVertexAttributeDescriptions = attributes.data();
|
||||
vertexInput.vertexAttributeDescriptionCount = attributes.size();
|
||||
vertexInput.pVertexBindingDescriptions = bindings.data();
|
||||
vertexInput.vertexBindingDescriptionCount = bindings.size();
|
||||
}
|
||||
|
||||
VkPipelineInputAssemblyStateCreateInfo assemblyInfo =
|
||||
init::PipelineInputAssemblyStateCreateInfo(
|
||||
cast(gfxInfo.topology),
|
||||
0,
|
||||
false
|
||||
);
|
||||
VkPipelineViewportStateCreateInfo viewportInfo =
|
||||
init::PipelineViewportStateCreateInfo(
|
||||
1,
|
||||
1,
|
||||
0
|
||||
);
|
||||
VkPipelineRasterizationStateCreateInfo rasterizationState =
|
||||
init::PipelineRasterizationStateCreateInfo(
|
||||
cast(gfxInfo.rasterizationState.polygonMode),
|
||||
gfxInfo.rasterizationState.cullMode,
|
||||
(VkFrontFace)gfxInfo.rasterizationState.frontFace,
|
||||
0
|
||||
);
|
||||
rasterizationState.depthBiasEnable = gfxInfo.rasterizationState.depthBiasEnable;
|
||||
rasterizationState.depthBiasClamp = gfxInfo.rasterizationState.depthBiasClamp;
|
||||
rasterizationState.depthBiasConstantFactor = gfxInfo.rasterizationState.depthBoasConstantFactor;
|
||||
rasterizationState.depthBiasSlopeFactor = gfxInfo.rasterizationState.depthBiasSlopeFactor;
|
||||
rasterizationState.depthClampEnable = gfxInfo.rasterizationState.depthClampEnable;
|
||||
rasterizationState.lineWidth = gfxInfo.rasterizationState.lineWidth;
|
||||
rasterizationState.rasterizerDiscardEnable = gfxInfo.rasterizationState.rasterizerDiscardEnable;
|
||||
|
||||
VkPipelineMultisampleStateCreateInfo multisampleState =
|
||||
init::PipelineMultisampleStateCreateInfo(
|
||||
(VkSampleCountFlagBits)gfxInfo.multisampleState.samples,
|
||||
0);
|
||||
multisampleState.alphaToCoverageEnable = gfxInfo.multisampleState.alphaCoverageEnable;
|
||||
multisampleState.alphaToOneEnable = gfxInfo.multisampleState.alphaToOneEnable;
|
||||
multisampleState.minSampleShading = gfxInfo.multisampleState.minSampleShading;
|
||||
multisampleState.sampleShadingEnable = gfxInfo.multisampleState.sampleShadingEnable;
|
||||
|
||||
VkPipelineDepthStencilStateCreateInfo depthStencilState =
|
||||
init::PipelineDepthStencilStateCreateInfo(
|
||||
gfxInfo.depthStencilState.depthTestEnable,
|
||||
gfxInfo.depthStencilState.depthWriteEnable,
|
||||
cast(gfxInfo.depthStencilState.depthCompareOp)
|
||||
);
|
||||
|
||||
const auto& colorAttachments = gfxInfo.renderPass->getLayout()->colorAttachments;
|
||||
Array<VkPipelineColorBlendAttachmentState> blendAttachments(colorAttachments.size());
|
||||
for(uint32 i = 0; i < colorAttachments.size(); ++i)
|
||||
{
|
||||
const Gfx::ColorBlendState::BlendAttachment& attachment = gfxInfo.colorBlend.blendAttachments[i];
|
||||
blendAttachments[i] = {
|
||||
.blendEnable = attachment.blendEnable,
|
||||
.srcColorBlendFactor = (VkBlendFactor)attachment.srcColorBlendFactor,
|
||||
.dstColorBlendFactor = (VkBlendFactor)attachment.dstColorBlendFactor,
|
||||
.colorBlendOp = (VkBlendOp)attachment.colorBlendOp,
|
||||
.srcAlphaBlendFactor = (VkBlendFactor)attachment.srcAlphaBlendFactor,
|
||||
.dstAlphaBlendFactor = (VkBlendFactor)attachment.dstAlphaBlendFactor,
|
||||
.alphaBlendOp = (VkBlendOp)attachment.alphaBlendOp,
|
||||
.colorWriteMask = attachment.colorWriteMask,
|
||||
};
|
||||
}
|
||||
VkPipelineColorBlendStateCreateInfo blendState =
|
||||
init::PipelineColorBlendStateCreateInfo(
|
||||
(uint32)blendAttachments.size(),
|
||||
blendAttachments.data()
|
||||
);
|
||||
blendState.logicOpEnable = gfxInfo.colorBlend.logicOpEnable;
|
||||
blendState.logicOp = (VkLogicOp)gfxInfo.colorBlend.logicOp;
|
||||
std::memcpy(blendState.blendConstants, gfxInfo.colorBlend.blendConstants, sizeof(gfxInfo.colorBlend.blendConstants));
|
||||
|
||||
uint32 numDynamicEnabled = 0;
|
||||
StaticArray<VkDynamicState, 2> dynamicEnabled;
|
||||
dynamicEnabled[numDynamicEnabled++] = VK_DYNAMIC_STATE_VIEWPORT;
|
||||
dynamicEnabled[numDynamicEnabled++] = VK_DYNAMIC_STATE_SCISSOR;
|
||||
|
||||
VkPipelineDynamicStateCreateInfo dynamicState =
|
||||
init::PipelineDynamicStateCreateInfo(
|
||||
dynamicEnabled.data(),
|
||||
numDynamicEnabled,
|
||||
0
|
||||
);
|
||||
|
||||
PPipelineLayout layout = gfxInfo.pipelineLayout.cast<PipelineLayout>();
|
||||
|
||||
VkPipeline pipelineHandle;
|
||||
|
||||
VkGraphicsPipelineCreateInfo createInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
|
||||
.pNext = 0,
|
||||
.flags = 0,
|
||||
.stageCount = stageCount,
|
||||
.pStages = stageInfos,
|
||||
.pVertexInputState = &vertexInput,
|
||||
.pInputAssemblyState = &assemblyInfo,
|
||||
.pViewportState = &viewportInfo,
|
||||
.pRasterizationState = &rasterizationState,
|
||||
.pMultisampleState = &multisampleState,
|
||||
.pDepthStencilState = &depthStencilState,
|
||||
.pColorBlendState = &blendState,
|
||||
.pDynamicState = &dynamicState,
|
||||
.layout = layout->getHandle(),
|
||||
.renderPass = gfxInfo.renderPass.cast<RenderPass>()->getHandle(),
|
||||
.subpass = 0,
|
||||
};
|
||||
auto beginTime = std::chrono::high_resolution_clock::now();
|
||||
VK_CHECK(vkCreateGraphicsPipelines(graphics->getDevice(), cache, 1, &createInfo, nullptr, &pipelineHandle));
|
||||
auto endTime = std::chrono::high_resolution_clock::now();
|
||||
int64 delta = std::chrono::duration_cast<std::chrono::microseconds>(endTime - beginTime).count();
|
||||
std::cout << "Gfx creation time: " << delta << std::endl;
|
||||
|
||||
|
||||
PGraphicsPipeline result = new GraphicsPipeline(graphics, pipelineHandle, layout);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
PGraphicsPipeline PipelineCache::createPipeline(const Gfx::MeshPipelineCreateInfo& gfxInfo)
|
||||
{
|
||||
uint32 stageCount = 0;
|
||||
|
||||
VkPipelineShaderStageCreateInfo stageInfos[3];
|
||||
std::memset(stageInfos, 0, sizeof(stageInfos));
|
||||
|
||||
if (gfxInfo.taskShader != nullptr)
|
||||
{
|
||||
PTaskShader taskShader = gfxInfo.taskShader.cast<TaskShader>();
|
||||
stageInfos[stageCount++] = {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
|
||||
.stage = VK_SHADER_STAGE_TASK_BIT_EXT,
|
||||
.module = taskShader->getModuleHandle(),
|
||||
.pName = taskShader->getEntryPointName(),
|
||||
};
|
||||
}
|
||||
|
||||
PMeshShader meshShader = gfxInfo.meshShader.cast<MeshShader>();
|
||||
stageInfos[stageCount++] = {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
|
||||
.stage = VK_SHADER_STAGE_MESH_BIT_EXT,
|
||||
.module = meshShader->getModuleHandle(),
|
||||
.pName = meshShader->getEntryPointName(),
|
||||
};
|
||||
|
||||
if (gfxInfo.fragmentShader != nullptr)
|
||||
{
|
||||
PFragmentShader fragment = gfxInfo.fragmentShader.cast<FragmentShader>();
|
||||
|
||||
stageInfos[stageCount++] = {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
|
||||
.stage = VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
.module = fragment->getModuleHandle(),
|
||||
.pName = fragment->getEntryPointName(),
|
||||
};
|
||||
}
|
||||
VkPipelineViewportStateCreateInfo viewportInfo =
|
||||
init::PipelineViewportStateCreateInfo(
|
||||
1,
|
||||
1,
|
||||
0
|
||||
);
|
||||
VkPipelineRasterizationStateCreateInfo rasterizationState =
|
||||
init::PipelineRasterizationStateCreateInfo(
|
||||
cast(gfxInfo.rasterizationState.polygonMode),
|
||||
gfxInfo.rasterizationState.cullMode,
|
||||
(VkFrontFace)gfxInfo.rasterizationState.frontFace,
|
||||
0
|
||||
);
|
||||
rasterizationState.depthBiasEnable = gfxInfo.rasterizationState.depthBiasEnable;
|
||||
rasterizationState.depthBiasClamp = gfxInfo.rasterizationState.depthBiasClamp;
|
||||
rasterizationState.depthBiasConstantFactor = gfxInfo.rasterizationState.depthBoasConstantFactor;
|
||||
rasterizationState.depthBiasSlopeFactor = gfxInfo.rasterizationState.depthBiasSlopeFactor;
|
||||
rasterizationState.depthClampEnable = gfxInfo.rasterizationState.depthClampEnable;
|
||||
rasterizationState.lineWidth = gfxInfo.rasterizationState.lineWidth;
|
||||
rasterizationState.rasterizerDiscardEnable = gfxInfo.rasterizationState.rasterizerDiscardEnable;
|
||||
|
||||
VkPipelineMultisampleStateCreateInfo multisampleState =
|
||||
init::PipelineMultisampleStateCreateInfo(
|
||||
(VkSampleCountFlagBits)gfxInfo.multisampleState.samples,
|
||||
0);
|
||||
multisampleState.alphaToCoverageEnable = gfxInfo.multisampleState.alphaCoverageEnable;
|
||||
multisampleState.alphaToOneEnable = gfxInfo.multisampleState.alphaToOneEnable;
|
||||
multisampleState.minSampleShading = gfxInfo.multisampleState.minSampleShading;
|
||||
multisampleState.sampleShadingEnable = gfxInfo.multisampleState.sampleShadingEnable;
|
||||
|
||||
VkPipelineDepthStencilStateCreateInfo depthStencilState =
|
||||
init::PipelineDepthStencilStateCreateInfo(
|
||||
gfxInfo.depthStencilState.depthTestEnable,
|
||||
gfxInfo.depthStencilState.depthWriteEnable,
|
||||
cast(gfxInfo.depthStencilState.depthCompareOp)
|
||||
);
|
||||
|
||||
const auto& colorAttachments = gfxInfo.renderPass->getLayout()->colorAttachments;
|
||||
Array<VkPipelineColorBlendAttachmentState> blendAttachments(colorAttachments.size());
|
||||
for (uint32 i = 0; i < colorAttachments.size(); ++i)
|
||||
{
|
||||
const Gfx::ColorBlendState::BlendAttachment& attachment = gfxInfo.colorBlend.blendAttachments[i];
|
||||
blendAttachments[i] = {
|
||||
.blendEnable = attachment.blendEnable,
|
||||
.srcColorBlendFactor = (VkBlendFactor)attachment.srcColorBlendFactor,
|
||||
.dstColorBlendFactor = (VkBlendFactor)attachment.dstColorBlendFactor,
|
||||
.colorBlendOp = (VkBlendOp)attachment.colorBlendOp,
|
||||
.srcAlphaBlendFactor = (VkBlendFactor)attachment.srcAlphaBlendFactor,
|
||||
.dstAlphaBlendFactor = (VkBlendFactor)attachment.dstAlphaBlendFactor,
|
||||
.alphaBlendOp = (VkBlendOp)attachment.alphaBlendOp,
|
||||
.colorWriteMask = attachment.colorWriteMask,
|
||||
};
|
||||
}
|
||||
VkPipelineColorBlendStateCreateInfo blendState =
|
||||
init::PipelineColorBlendStateCreateInfo(
|
||||
(uint32)blendAttachments.size(),
|
||||
blendAttachments.data()
|
||||
);
|
||||
blendState.logicOpEnable = gfxInfo.colorBlend.logicOpEnable;
|
||||
blendState.logicOp = (VkLogicOp)gfxInfo.colorBlend.logicOp;
|
||||
std::memcpy(blendState.blendConstants, gfxInfo.colorBlend.blendConstants, sizeof(gfxInfo.colorBlend.blendConstants));
|
||||
|
||||
uint32 numDynamicEnabled = 0;
|
||||
StaticArray<VkDynamicState, 2> dynamicEnabled;
|
||||
dynamicEnabled[numDynamicEnabled++] = VK_DYNAMIC_STATE_VIEWPORT;
|
||||
dynamicEnabled[numDynamicEnabled++] = VK_DYNAMIC_STATE_SCISSOR;
|
||||
|
||||
VkPipelineDynamicStateCreateInfo dynamicState =
|
||||
init::PipelineDynamicStateCreateInfo(
|
||||
dynamicEnabled.data(),
|
||||
numDynamicEnabled,
|
||||
0
|
||||
);
|
||||
|
||||
PPipelineLayout layout = gfxInfo.pipelineLayout.cast<PipelineLayout>();
|
||||
|
||||
VkPipeline pipelineHandle;
|
||||
|
||||
VkGraphicsPipelineCreateInfo createInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
|
||||
.pNext = 0,
|
||||
.flags = 0,
|
||||
.stageCount = stageCount,
|
||||
.pStages = stageInfos,
|
||||
.pVertexInputState = nullptr,
|
||||
.pInputAssemblyState = nullptr,
|
||||
.pViewportState = &viewportInfo,
|
||||
.pRasterizationState = &rasterizationState,
|
||||
.pMultisampleState = &multisampleState,
|
||||
.pDepthStencilState = &depthStencilState,
|
||||
.pColorBlendState = &blendState,
|
||||
.pDynamicState = &dynamicState,
|
||||
.layout = layout->getHandle(),
|
||||
.renderPass = gfxInfo.renderPass.cast<RenderPass>()->getHandle(),
|
||||
.subpass = 0,
|
||||
};
|
||||
auto beginTime = std::chrono::high_resolution_clock::now();
|
||||
VK_CHECK(vkCreateGraphicsPipelines(graphics->getDevice(), cache, 1, &createInfo, nullptr, &pipelineHandle));
|
||||
auto endTime = std::chrono::high_resolution_clock::now();
|
||||
int64 delta = std::chrono::duration_cast<std::chrono::microseconds>(endTime - beginTime).count();
|
||||
std::cout << "Gfx creation time: " << delta << std::endl;
|
||||
|
||||
|
||||
PGraphicsPipeline result = new GraphicsPipeline(graphics, pipelineHandle, layout);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
PComputePipeline PipelineCache::createPipeline(const Gfx::ComputePipelineCreateInfo& computeInfo)
|
||||
{
|
||||
VkComputePipelineCreateInfo createInfo;
|
||||
createInfo.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
|
||||
createInfo.pNext = 0;
|
||||
createInfo.flags = 0;
|
||||
createInfo.basePipelineIndex = 0;
|
||||
createInfo.basePipelineHandle = VK_NULL_HANDLE;
|
||||
auto layout = computeInfo.pipelineLayout.cast<PipelineLayout>();
|
||||
createInfo.layout = layout->getHandle();
|
||||
auto computeStage = computeInfo.computeShader.cast<ComputeShader>();
|
||||
createInfo.stage = init::PipelineShaderStageCreateInfo(
|
||||
VK_SHADER_STAGE_COMPUTE_BIT,
|
||||
computeStage->getModuleHandle(),
|
||||
computeStage->getEntryPointName());
|
||||
VkPipeline pipelineHandle;
|
||||
auto beginTime = std::chrono::high_resolution_clock::now();
|
||||
VK_CHECK(vkCreateComputePipelines(graphics->getDevice(), cache, 1, &createInfo, nullptr, &pipelineHandle));
|
||||
auto endTime = std::chrono::high_resolution_clock::now();
|
||||
int64 delta = std::chrono::duration_cast<std::chrono::microseconds>(endTime - beginTime).count();
|
||||
std::cout << "Compute creation time: " << delta << std::endl;
|
||||
PComputePipeline result = new ComputePipeline(graphics, pipelineHandle, layout);
|
||||
return result;
|
||||
}
|
||||
+4
-5
@@ -1,5 +1,5 @@
|
||||
#pragma once
|
||||
#include "VulkanPipeline.h"
|
||||
#include "Pipeline.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
@@ -10,14 +10,13 @@ class PipelineCache
|
||||
public:
|
||||
PipelineCache(PGraphics graphics, const std::string& cacheFilePath);
|
||||
~PipelineCache();
|
||||
PGraphicsPipeline createPipeline(const GraphicsPipelineCreateInfo& createInfo);
|
||||
PComputePipeline createPipeline(const ComputePipelineCreateInfo& createInfo);
|
||||
PGraphicsPipeline createPipeline(const Gfx::LegacyPipelineCreateInfo& createInfo);
|
||||
PGraphicsPipeline createPipeline(const Gfx::MeshPipelineCreateInfo& createInfo);
|
||||
PComputePipeline createPipeline(const Gfx::ComputePipelineCreateInfo& createInfo);
|
||||
private:
|
||||
VkPipelineCache cache;
|
||||
PGraphics graphics;
|
||||
std::string cacheFile;
|
||||
std::mutex createdPipelinesLock;
|
||||
Map<uint32, VkPipeline> createdPipelines;
|
||||
};
|
||||
DEFINE_REF(PipelineCache)
|
||||
} // namespace Vulkan
|
||||
@@ -1,9 +1,8 @@
|
||||
#include "VulkanQueue.h"
|
||||
#include "VulkanInitializer.h"
|
||||
#include "VulkanGraphics.h"
|
||||
#include "VulkanAllocator.h"
|
||||
#include "VulkanCommandBuffer.h"
|
||||
#include "VulkanGraphicsEnums.h"
|
||||
#include "Queue.h"
|
||||
#include "Initializer.h"
|
||||
#include "Graphics.h"
|
||||
#include "Allocator.h"
|
||||
#include "CommandBuffer.h"
|
||||
|
||||
using namespace Seele;
|
||||
using namespace Seele::Vulkan;
|
||||
@@ -1,5 +1,5 @@
|
||||
#pragma once
|
||||
#include "VulkanGraphicsResources.h"
|
||||
#include "Resources.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
+5
-5
@@ -1,8 +1,8 @@
|
||||
#include "VulkanRenderPass.h"
|
||||
#include "VulkanInitializer.h"
|
||||
#include "VulkanGraphicsEnums.h"
|
||||
#include "VulkanGraphics.h"
|
||||
#include "VulkanFramebuffer.h"
|
||||
#include "RenderPass.h"
|
||||
#include "Initializer.h"
|
||||
#include "Graphics.h"
|
||||
#include "Framebuffer.h"
|
||||
#include "Texture.h"
|
||||
|
||||
using namespace Seele;
|
||||
using namespace Seele::Vulkan;
|
||||
+2
-1
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
#include "VulkanGraphicsResources.h"
|
||||
#include "Graphics/RenderTarget.h"
|
||||
#include "Graphics.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
@@ -0,0 +1,83 @@
|
||||
#pragma once
|
||||
#include "Graphics/RenderTarget.h"
|
||||
#include "Graphics.h"
|
||||
#include "Texture.h"
|
||||
#include "Resources.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
namespace Vulkan
|
||||
{
|
||||
|
||||
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<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;
|
||||
virtual void setScrollCallback(std::function<void(double, double)> callback) override;
|
||||
virtual void setFileCallback(std::function<void(int, const char**)> callback) override;
|
||||
virtual void setCloseCallback(std::function<void()> callback);
|
||||
|
||||
VkFormat getPixelFormat() const
|
||||
{
|
||||
return cast(windowState.pixelFormat);
|
||||
}
|
||||
|
||||
std::function<void(KeyCode, InputAction, KeyModifier)> keyCallback;
|
||||
std::function<void(double, double)> mouseMoveCallback;
|
||||
std::function<void(MouseButton, InputAction, KeyModifier)> mouseButtonCallback;
|
||||
std::function<void(double, double)> scrollCallback;
|
||||
std::function<void(int, const char**)> fileCallback;
|
||||
std::function<void()> closeCallback;
|
||||
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);
|
||||
|
||||
PTexture2D backBufferImages[Gfx::numFramesBuffered];
|
||||
PSemaphore renderFinished[Gfx::numFramesBuffered];
|
||||
PSemaphore imageAcquired[Gfx::numFramesBuffered];
|
||||
PSemaphore imageAcquiredSemaphore;
|
||||
|
||||
PGraphics graphics;
|
||||
VkInstance instance;
|
||||
VkSwapchainKHR swapchain;
|
||||
VkSampleCountFlags numSamples;
|
||||
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)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
#pragma once
|
||||
#include <vulkan/vulkan.h>
|
||||
#include <functional>
|
||||
#include "Graphics/Resources.h"
|
||||
#include "Allocator.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& operator co_await()
|
||||
{
|
||||
return signaled;
|
||||
}*/
|
||||
bool operator<(const Fence &other) const
|
||||
{
|
||||
return fence < other.fence;
|
||||
}
|
||||
|
||||
private:
|
||||
PGraphics graphics;
|
||||
bool signaled;
|
||||
VkFence fence;
|
||||
};
|
||||
DEFINE_REF(Fence)
|
||||
|
||||
class VertexDeclaration : public Gfx::VertexDeclaration
|
||||
{
|
||||
public:
|
||||
Array<Gfx::VertexElement> elementList;
|
||||
|
||||
VertexDeclaration(const Array<Gfx::VertexElement>& elementList);
|
||||
virtual ~VertexDeclaration();
|
||||
private:
|
||||
};
|
||||
DEFINE_REF(VertexDeclaration)
|
||||
|
||||
class SamplerState : public Gfx::SamplerState
|
||||
{
|
||||
public:
|
||||
VkSampler sampler;
|
||||
};
|
||||
DEFINE_REF(SamplerState)
|
||||
|
||||
} // namespace Vulkan
|
||||
} // namespace Seele
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
#include "VulkanGraphicsResources.h"
|
||||
#include "VulkanGraphicsEnums.h"
|
||||
#include "Resources.h"
|
||||
#include "Enums.h"
|
||||
#include "Graphics/Shader.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
@@ -51,18 +52,16 @@ public:
|
||||
}
|
||||
};
|
||||
typedef ShaderBase<Gfx::VertexShader, ShaderType::VERTEX, VK_SHADER_STAGE_VERTEX_BIT> VertexShader;
|
||||
typedef ShaderBase<Gfx::ControlShader, ShaderType::CONTROL, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT> ControlShader;
|
||||
typedef ShaderBase<Gfx::EvaluationShader, ShaderType::EVALUATION, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT> EvaluationShader;
|
||||
typedef ShaderBase<Gfx::GeometryShader, ShaderType::GEOMETRY, VK_SHADER_STAGE_GEOMETRY_BIT> GeometryShader;
|
||||
typedef ShaderBase<Gfx::FragmentShader, ShaderType::FRAGMENT, VK_SHADER_STAGE_FRAGMENT_BIT> FragmentShader;
|
||||
typedef ShaderBase<Gfx::ComputeShader, ShaderType::COMPUTE, VK_SHADER_STAGE_COMPUTE_BIT> ComputeShader;
|
||||
typedef ShaderBase<Gfx::TaskShader, ShaderType::TASK, VK_SHADER_STAGE_TASK_BIT_EXT> TaskShader;
|
||||
typedef ShaderBase<Gfx::MeshShader, ShaderType::MESH, VK_SHADER_STAGE_MESH_BIT_EXT> MeshShader;
|
||||
|
||||
DEFINE_REF(VertexShader)
|
||||
DEFINE_REF(ControlShader)
|
||||
DEFINE_REF(EvaluationShader)
|
||||
DEFINE_REF(GeometryShader)
|
||||
DEFINE_REF(FragmentShader)
|
||||
DEFINE_REF(ComputeShader)
|
||||
DEFINE_REF(TaskShader)
|
||||
DEFINE_REF(MeshShader)
|
||||
|
||||
} // namespace Vulkan
|
||||
}
|
||||
@@ -0,0 +1,264 @@
|
||||
#pragma once
|
||||
#include "Graphics/Texture.h"
|
||||
#include "Graphics.h"
|
||||
#include "Allocator.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
namespace Vulkan
|
||||
{
|
||||
|
||||
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);
|
||||
void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer);
|
||||
|
||||
private:
|
||||
//Updates via reference
|
||||
Gfx::QueueType& currentOwner;
|
||||
PGraphics graphics;
|
||||
PSubAllocation allocation;
|
||||
uint32 sizeX;
|
||||
uint32 sizeY;
|
||||
uint32 sizeZ;
|
||||
uint32 arrayCount;
|
||||
uint32 layerCount;
|
||||
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 Texture3D;
|
||||
friend class TextureCube;
|
||||
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 download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer) 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 Texture3D : public Gfx::Texture3D, public TextureBase
|
||||
{
|
||||
public:
|
||||
Texture3D(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage = VK_NULL_HANDLE);
|
||||
virtual ~Texture3D();
|
||||
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 download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer) 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(Texture3D)
|
||||
|
||||
class TextureCube : public Gfx::TextureCube, public TextureBase
|
||||
{
|
||||
public:
|
||||
TextureCube(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage = VK_NULL_HANDLE);
|
||||
virtual ~TextureCube();
|
||||
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 download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer) 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(TextureCube)
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,535 +0,0 @@
|
||||
#pragma once
|
||||
#include <vulkan/vulkan.h>
|
||||
#include <functional>
|
||||
#include "Graphics/GraphicsResources.h"
|
||||
#include "VulkanAllocator.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& operator co_await()
|
||||
{
|
||||
return signaled;
|
||||
}*/
|
||||
bool operator<(const Fence &other) const
|
||||
{
|
||||
return fence < other.fence;
|
||||
}
|
||||
|
||||
private:
|
||||
PGraphics graphics;
|
||||
bool signaled;
|
||||
VkFence fence;
|
||||
};
|
||||
DEFINE_REF(Fence)
|
||||
|
||||
class VertexDeclaration : public Gfx::VertexDeclaration
|
||||
{
|
||||
public:
|
||||
Array<Gfx::VertexElement> elementList;
|
||||
|
||||
VertexDeclaration(const Array<Gfx::VertexElement>& elementList);
|
||||
virtual ~VertexDeclaration();
|
||||
private:
|
||||
};
|
||||
DEFINE_REF(VertexDeclaration)
|
||||
|
||||
class ShaderBuffer
|
||||
{
|
||||
public:
|
||||
ShaderBuffer(PGraphics graphics, uint64 size, VkBufferUsageFlags usage, Gfx::QueueType& queueType, bool bDynamic = false);
|
||||
virtual ~ShaderBuffer();
|
||||
VkBuffer getHandle() const
|
||||
{
|
||||
return buffers[currentBuffer].buffer;
|
||||
}
|
||||
uint64 getSize() const
|
||||
{
|
||||
return size;
|
||||
}
|
||||
VkDeviceSize getOffset() const;
|
||||
void advanceBuffer()
|
||||
{
|
||||
currentBuffer = (currentBuffer + 1) % numBuffers;
|
||||
}
|
||||
virtual void *lock(bool bWriteOnly = true);
|
||||
virtual void *lockRegion(uint64 regionOffset, uint64 regionSize, bool bWriteOnly = true);
|
||||
virtual void unlock();
|
||||
|
||||
protected:
|
||||
struct BufferAllocation
|
||||
{
|
||||
VkBuffer buffer;
|
||||
PSubAllocation allocation;
|
||||
};
|
||||
PGraphics graphics;
|
||||
uint32 currentBuffer;
|
||||
uint64 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 ShaderBuffer : public Gfx::ShaderBuffer, public ShaderBuffer
|
||||
{
|
||||
public:
|
||||
ShaderBuffer(PGraphics graphics, const ShaderBufferCreateInfo &resourceData);
|
||||
virtual ~ShaderBuffer();
|
||||
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(ShaderBuffer)
|
||||
|
||||
class VertexBuffer : public Gfx::VertexBuffer, public ShaderBuffer
|
||||
{
|
||||
public:
|
||||
VertexBuffer(PGraphics graphics, const VertexBufferCreateInfo &resourceData);
|
||||
virtual ~VertexBuffer();
|
||||
|
||||
virtual void updateRegion(BulkResourceData update) override;
|
||||
virtual void download(Array<uint8>& buffer) 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);
|
||||
};
|
||||
DEFINE_REF(VertexBuffer)
|
||||
|
||||
class IndexBuffer : public Gfx::IndexBuffer, public ShaderBuffer
|
||||
{
|
||||
public:
|
||||
IndexBuffer(PGraphics graphics, const IndexBufferCreateInfo &resourceData);
|
||||
virtual ~IndexBuffer();
|
||||
|
||||
virtual void download(Array<uint8>& buffer) 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);
|
||||
};
|
||||
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);
|
||||
void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer);
|
||||
|
||||
private:
|
||||
//Updates via reference
|
||||
Gfx::QueueType& currentOwner;
|
||||
PGraphics graphics;
|
||||
PSubAllocation allocation;
|
||||
uint32 sizeX;
|
||||
uint32 sizeY;
|
||||
uint32 sizeZ;
|
||||
uint32 arrayCount;
|
||||
uint32 layerCount;
|
||||
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 Texture3D;
|
||||
friend class TextureCube;
|
||||
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 download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer) 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 Texture3D : public Gfx::Texture3D, public TextureBase
|
||||
{
|
||||
public:
|
||||
Texture3D(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage = VK_NULL_HANDLE);
|
||||
virtual ~Texture3D();
|
||||
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 download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer) 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(Texture3D)
|
||||
|
||||
class TextureCube : public Gfx::TextureCube, public TextureBase
|
||||
{
|
||||
public:
|
||||
TextureCube(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage = VK_NULL_HANDLE);
|
||||
virtual ~TextureCube();
|
||||
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 download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer) 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(TextureCube)
|
||||
|
||||
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<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;
|
||||
virtual void setScrollCallback(std::function<void(double, double)> callback) override;
|
||||
virtual void setFileCallback(std::function<void(int, const char**)> callback) override;
|
||||
virtual void setCloseCallback(std::function<void()> callback);
|
||||
|
||||
VkFormat getPixelFormat() const
|
||||
{
|
||||
return cast(windowState.pixelFormat);
|
||||
}
|
||||
|
||||
std::function<void(KeyCode, InputAction, KeyModifier)> keyCallback;
|
||||
std::function<void(double, double)> mouseMoveCallback;
|
||||
std::function<void(MouseButton, InputAction, KeyModifier)> mouseButtonCallback;
|
||||
std::function<void(double, double)> scrollCallback;
|
||||
std::function<void(int, const char**)> fileCallback;
|
||||
std::function<void()> closeCallback;
|
||||
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);
|
||||
|
||||
PTexture2D backBufferImages[Gfx::numFramesBuffered];
|
||||
PSemaphore renderFinished[Gfx::numFramesBuffered];
|
||||
PSemaphore imageAcquired[Gfx::numFramesBuffered];
|
||||
PSemaphore imageAcquiredSemaphore;
|
||||
|
||||
PGraphics graphics;
|
||||
VkInstance instance;
|
||||
VkSwapchainKHR swapchain;
|
||||
VkSampleCountFlags numSamples;
|
||||
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
|
||||
@@ -1,381 +0,0 @@
|
||||
#include "VulkanPipelineCache.h"
|
||||
#include "VulkanGraphics.h"
|
||||
#include "VulkanGraphicsEnums.h"
|
||||
#include "VulkanInitializer.h"
|
||||
#include "VulkanRenderPass.h"
|
||||
#include "VulkanDescriptorSets.h"
|
||||
#include "VulkanShader.h"
|
||||
#include <fstream>
|
||||
|
||||
using namespace Seele;
|
||||
using namespace Seele::Vulkan;
|
||||
|
||||
PipelineCache::PipelineCache(PGraphics graphics, const std::string& cacheFilePath)
|
||||
: graphics(graphics)
|
||||
, cacheFile(cacheFilePath)
|
||||
{
|
||||
std::ifstream stream(cacheFilePath, std::ios::binary | std::ios::ate);
|
||||
VkPipelineCacheCreateInfo cacheCreateInfo;
|
||||
cacheCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
|
||||
cacheCreateInfo.pNext = nullptr;
|
||||
cacheCreateInfo.flags = 0;
|
||||
cacheCreateInfo.initialDataSize = 0;
|
||||
if(stream.good())
|
||||
{
|
||||
Array<uint8> cacheData;
|
||||
uint32 fileSize = static_cast<uint32>(stream.tellg());
|
||||
cacheData.resize(fileSize);
|
||||
stream.seekg(0);
|
||||
stream.read((char*)cacheData.data(), fileSize);
|
||||
cacheCreateInfo.initialDataSize = fileSize;
|
||||
cacheCreateInfo.pInitialData = cacheData.data();
|
||||
std::cout << "Loaded " << fileSize << " bytes from pipeline cache" << std::endl;
|
||||
}
|
||||
VK_CHECK(vkCreatePipelineCache(graphics->getDevice(), &cacheCreateInfo, nullptr, &cache));
|
||||
}
|
||||
|
||||
PipelineCache::~PipelineCache()
|
||||
{
|
||||
VkDeviceSize cacheSize;
|
||||
vkGetPipelineCacheData(graphics->getDevice(), cache, &cacheSize, nullptr);
|
||||
Array<uint8> cacheData;
|
||||
vkGetPipelineCacheData(graphics->getDevice(), cache, &cacheSize, cacheData.data());
|
||||
std::ofstream stream(cacheFile, std::ios::binary);
|
||||
stream.write((char*)cacheData.data(), cacheSize);
|
||||
stream.flush();
|
||||
stream.close();
|
||||
vkDestroyPipelineCache(graphics->getDevice(), cache, nullptr);
|
||||
std::cout << "Written " << cacheSize << " bytes to cache" << std::endl;
|
||||
}
|
||||
|
||||
struct PipelineCreateHashStruct
|
||||
{
|
||||
uint32 vertexHash;
|
||||
uint32 controlHash;
|
||||
uint32 evalHash;
|
||||
uint32 geometryHash;
|
||||
uint32 fragmentHash;
|
||||
uint32 pipelineLayoutHash;
|
||||
VkPipelineTessellationStateCreateInfo tess;
|
||||
VkVertexInputAttributeDescription attribs[16];
|
||||
VkVertexInputBindingDescription bindings[16];
|
||||
VkPipelineInputAssemblyStateCreateInfo inputAssembly;
|
||||
VkPipelineViewportStateCreateInfo viewport;
|
||||
VkPipelineRasterizationStateCreateInfo rasterization;
|
||||
VkPipelineMultisampleStateCreateInfo multisample;
|
||||
VkPipelineDepthStencilStateCreateInfo depthStencil;
|
||||
VkPipelineColorBlendAttachmentState blendAttachments[16];
|
||||
VkPipelineColorBlendStateCreateInfo blendState;
|
||||
};
|
||||
|
||||
PGraphicsPipeline PipelineCache::createPipeline(const GraphicsPipelineCreateInfo& gfxInfo)
|
||||
{
|
||||
VkGraphicsPipelineCreateInfo createInfo;
|
||||
createInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
|
||||
createInfo.pNext = 0;
|
||||
createInfo.flags = 0;
|
||||
createInfo.stageCount = 0;
|
||||
|
||||
VkPipelineTessellationStateCreateInfo tessInfo;
|
||||
std::memset(&tessInfo, 0, sizeof(VkPipelineTessellationStateCreateInfo));
|
||||
VkPipelineShaderStageCreateInfo stageInfos[5];
|
||||
std::memset(stageInfos, 0, sizeof(stageInfos));
|
||||
PipelineCreateHashStruct hashStruct;
|
||||
std::memset(&hashStruct, 0, sizeof(PipelineCreateHashStruct));
|
||||
|
||||
PVertexShader vertexShader = gfxInfo.vertexShader.cast<VertexShader>();
|
||||
VkPipelineShaderStageCreateInfo& vertInfo = stageInfos[createInfo.stageCount++];
|
||||
vertInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
|
||||
vertInfo.stage = VK_SHADER_STAGE_VERTEX_BIT;
|
||||
vertInfo.module = vertexShader->getModuleHandle();
|
||||
vertInfo.pName = vertexShader->getEntryPointName();
|
||||
hashStruct.vertexHash = vertexShader->getShaderHash();
|
||||
|
||||
if(gfxInfo.controlShader != nullptr)
|
||||
{
|
||||
assert(gfxInfo.evalShader != nullptr);
|
||||
PControlShader control = gfxInfo.controlShader.cast<ControlShader>();
|
||||
PEvaluationShader eval = gfxInfo.evalShader.cast<EvaluationShader>();
|
||||
|
||||
VkPipelineShaderStageCreateInfo& controlInfo = stageInfos[createInfo.stageCount++];
|
||||
controlInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
|
||||
controlInfo.stage = VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
|
||||
controlInfo.module = control->getModuleHandle();
|
||||
controlInfo.pName = control->getEntryPointName();
|
||||
|
||||
VkPipelineShaderStageCreateInfo& evalInfo = stageInfos[createInfo.stageCount++];
|
||||
evalInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
|
||||
evalInfo.stage = VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
|
||||
evalInfo.module = eval->getModuleHandle();
|
||||
evalInfo.pName = eval->getEntryPointName();
|
||||
|
||||
tessInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO;
|
||||
tessInfo.pNext = 0;
|
||||
tessInfo.flags = 0;
|
||||
tessInfo.patchControlPoints = control->getNumPatches();
|
||||
|
||||
hashStruct.controlHash = control->getShaderHash();
|
||||
hashStruct.evalHash = eval->getShaderHash();
|
||||
hashStruct.tess = tessInfo;
|
||||
}
|
||||
if(gfxInfo.geometryShader != nullptr)
|
||||
{
|
||||
PGeometryShader geometry = gfxInfo.geometryShader.cast<GeometryShader>();
|
||||
|
||||
VkPipelineShaderStageCreateInfo& geometryInfo = stageInfos[createInfo.stageCount++];
|
||||
geometryInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
|
||||
geometryInfo.stage = VK_SHADER_STAGE_GEOMETRY_BIT;
|
||||
geometryInfo.module = geometry->getModuleHandle();
|
||||
geometryInfo.pName = geometry->getEntryPointName();
|
||||
|
||||
hashStruct.geometryHash = geometry->getShaderHash();
|
||||
}
|
||||
if(gfxInfo.fragmentShader != nullptr)
|
||||
{
|
||||
PFragmentShader fragment = gfxInfo.fragmentShader.cast<FragmentShader>();
|
||||
|
||||
VkPipelineShaderStageCreateInfo& fragmentInfo = stageInfos[createInfo.stageCount++];
|
||||
fragmentInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
|
||||
fragmentInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||
fragmentInfo.module = fragment->getModuleHandle();
|
||||
fragmentInfo.pName = fragment->getEntryPointName();
|
||||
|
||||
hashStruct.fragmentHash = fragment->getShaderHash();
|
||||
}
|
||||
VkPipelineVertexInputStateCreateInfo vertexInput =
|
||||
init::PipelineVertexInputStateCreateInfo();
|
||||
PVertexDeclaration vertexDecl = gfxInfo.vertexDeclaration;
|
||||
auto vertexStreams = vertexDecl->elementList;
|
||||
uint32 bindingNum = 0;
|
||||
uint32 bindingsMask = 0;
|
||||
uint32 attributesNum = 0;
|
||||
Array<VkVertexInputBindingDescription> bindings;
|
||||
Array<VkVertexInputAttributeDescription> attributes;
|
||||
Map<uint32, uint32> bindingToStream;
|
||||
Map<uint32, uint32> streamToBinding;
|
||||
assert(DEFAULT_ALLOC_SIZE == 16);
|
||||
std::memset(bindings.data(), 0, sizeof(VkVertexInputBindingDescription) * 16);
|
||||
std::memset(attributes.data(), 0, sizeof(VkVertexInputAttributeDescription) * 16);
|
||||
for(auto& element : vertexStreams)
|
||||
{
|
||||
//if((1 << element.attributeIndex) & vertexAttributeMask) // TODO: attribute mask
|
||||
{
|
||||
if(element.streamIndex >= bindings.size())
|
||||
{
|
||||
bindings.resize(element.streamIndex + 1); // This should not cause any actual allocations
|
||||
}
|
||||
VkVertexInputBindingDescription& currBinding = bindings[element.streamIndex];
|
||||
if((bindingsMask & (1 << element.streamIndex)) != 0)
|
||||
{
|
||||
assert(currBinding.binding == element.streamIndex);
|
||||
assert(currBinding.inputRate == element.bInstanced ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX);
|
||||
assert(currBinding.stride == element.stride);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(currBinding.binding == 0 && currBinding.inputRate == 0 && currBinding.stride == 0);
|
||||
currBinding.binding = element.streamIndex;
|
||||
currBinding.inputRate = element.bInstanced ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX;
|
||||
currBinding.stride = element.stride;
|
||||
|
||||
bindingsMask |= 1 << element.streamIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(uint32 i = 0; i < bindings.size(); ++i)
|
||||
{
|
||||
if(!((1 << i) & bindingsMask))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
bindingToStream[bindingNum] = i;
|
||||
streamToBinding[i] = bindingNum;
|
||||
VkVertexInputBindingDescription& currBinding = bindings[bindingNum];
|
||||
currBinding = bindings[i];
|
||||
currBinding.binding = bindingNum;
|
||||
bindingNum++;
|
||||
}
|
||||
|
||||
for(auto& element : vertexStreams)
|
||||
{
|
||||
//TODO: vertex attribute mask
|
||||
if(attributesNum >= attributes.size())
|
||||
{
|
||||
attributes.resize(attributesNum + 1); // This should not cause any actual allocations
|
||||
}
|
||||
|
||||
VkVertexInputAttributeDescription& currAttribute = attributes[attributesNum++];
|
||||
currAttribute.location = element.attributeIndex;
|
||||
currAttribute.binding = streamToBinding[element.streamIndex];
|
||||
currAttribute.format = cast(element.vertexFormat);
|
||||
currAttribute.offset = element.offset;
|
||||
}
|
||||
|
||||
std::memcpy(hashStruct.bindings, bindings.data(), bindings.size() * sizeof(VkVertexInputBindingDescription));
|
||||
std::memcpy(hashStruct.attribs, attributes.data(), attributes.size() * sizeof(VkVertexInputAttributeDescription));
|
||||
|
||||
vertexInput.pVertexBindingDescriptions = bindings.data();
|
||||
vertexInput.vertexBindingDescriptionCount = (uint32)bindings.size();
|
||||
vertexInput.pVertexAttributeDescriptions = attributes.data();
|
||||
vertexInput.vertexAttributeDescriptionCount = (uint32)attributes.size();
|
||||
|
||||
VkPipelineInputAssemblyStateCreateInfo assemblyInfo =
|
||||
init::PipelineInputAssemblyStateCreateInfo(
|
||||
cast(gfxInfo.topology),
|
||||
0,
|
||||
false
|
||||
);
|
||||
hashStruct.inputAssembly = assemblyInfo;
|
||||
|
||||
VkPipelineViewportStateCreateInfo viewportInfo =
|
||||
init::PipelineViewportStateCreateInfo(
|
||||
1,
|
||||
1,
|
||||
0
|
||||
);
|
||||
hashStruct.viewport = viewportInfo;
|
||||
|
||||
VkPipelineRasterizationStateCreateInfo rasterizationState =
|
||||
init::PipelineRasterizationStateCreateInfo(
|
||||
cast(gfxInfo.rasterizationState.polygonMode),
|
||||
gfxInfo.rasterizationState.cullMode,
|
||||
(VkFrontFace)gfxInfo.rasterizationState.frontFace,
|
||||
0
|
||||
);
|
||||
rasterizationState.depthBiasEnable = gfxInfo.rasterizationState.depthBiasEnable;
|
||||
rasterizationState.depthBiasClamp = gfxInfo.rasterizationState.depthBiasClamp;
|
||||
rasterizationState.depthBiasConstantFactor = gfxInfo.rasterizationState.depthBoasConstantFactor;
|
||||
rasterizationState.depthBiasSlopeFactor = gfxInfo.rasterizationState.depthBiasSlopeFactor;
|
||||
rasterizationState.depthClampEnable = gfxInfo.rasterizationState.depthClampEnable;
|
||||
rasterizationState.lineWidth = gfxInfo.rasterizationState.lineWidth;
|
||||
rasterizationState.rasterizerDiscardEnable = gfxInfo.rasterizationState.rasterizerDiscardEnable;
|
||||
|
||||
hashStruct.rasterization = rasterizationState;
|
||||
|
||||
VkPipelineMultisampleStateCreateInfo multisampleState =
|
||||
init::PipelineMultisampleStateCreateInfo(
|
||||
(VkSampleCountFlagBits)gfxInfo.multisampleState.samples,
|
||||
0);
|
||||
multisampleState.alphaToCoverageEnable = gfxInfo.multisampleState.alphaCoverageEnable;
|
||||
multisampleState.alphaToOneEnable = gfxInfo.multisampleState.alphaToOneEnable;
|
||||
multisampleState.minSampleShading = gfxInfo.multisampleState.minSampleShading;
|
||||
multisampleState.sampleShadingEnable = gfxInfo.multisampleState.sampleShadingEnable;
|
||||
|
||||
hashStruct.multisample = multisampleState;
|
||||
|
||||
VkPipelineDepthStencilStateCreateInfo depthStencilState =
|
||||
init::PipelineDepthStencilStateCreateInfo(
|
||||
gfxInfo.depthStencilState.depthTestEnable,
|
||||
gfxInfo.depthStencilState.depthWriteEnable,
|
||||
cast(gfxInfo.depthStencilState.depthCompareOp)
|
||||
);
|
||||
|
||||
hashStruct.depthStencil = depthStencilState;
|
||||
|
||||
const auto& colorAttachments = gfxInfo.renderPass->getLayout()->colorAttachments;
|
||||
Array<VkPipelineColorBlendAttachmentState> blendAttachments(colorAttachments.size());
|
||||
for(uint32 i = 0; i < colorAttachments.size(); ++i)
|
||||
{
|
||||
const Gfx::ColorBlendState::BlendAttachment& attachment = gfxInfo.colorBlend.blendAttachments[i];
|
||||
VkPipelineColorBlendAttachmentState& blendAttachment = blendAttachments[i];
|
||||
blendAttachment.alphaBlendOp = (VkBlendOp)attachment.alphaBlendOp;
|
||||
blendAttachment.blendEnable = attachment.blendEnable;
|
||||
blendAttachment.colorBlendOp = (VkBlendOp)attachment.colorBlendOp;
|
||||
blendAttachment.colorWriteMask = attachment.colorWriteMask;
|
||||
blendAttachment.dstAlphaBlendFactor = (VkBlendFactor)attachment.dstAlphaBlendFactor;
|
||||
blendAttachment.srcAlphaBlendFactor = (VkBlendFactor)attachment.srcAlphaBlendFactor;
|
||||
blendAttachment.dstColorBlendFactor = (VkBlendFactor)attachment.dstColorBlendFactor;
|
||||
blendAttachment.srcColorBlendFactor = (VkBlendFactor)attachment.srcColorBlendFactor;
|
||||
|
||||
hashStruct.blendAttachments[i] = blendAttachment;
|
||||
}
|
||||
VkPipelineColorBlendStateCreateInfo blendState =
|
||||
init::PipelineColorBlendStateCreateInfo(
|
||||
(uint32)blendAttachments.size(),
|
||||
blendAttachments.data()
|
||||
);
|
||||
blendState.logicOpEnable = gfxInfo.colorBlend.logicOpEnable;
|
||||
blendState.logicOp = (VkLogicOp)gfxInfo.colorBlend.logicOp;
|
||||
std::memcpy(blendState.blendConstants, gfxInfo.colorBlend.blendConstants, sizeof(float)*4);
|
||||
|
||||
hashStruct.blendState = blendState;
|
||||
hashStruct.blendState.pAttachments = nullptr;
|
||||
|
||||
uint32 numDynamicEnabled = 0;
|
||||
StaticArray<VkDynamicState, 2> dynamicEnabled;
|
||||
dynamicEnabled[numDynamicEnabled++] = VK_DYNAMIC_STATE_VIEWPORT;
|
||||
dynamicEnabled[numDynamicEnabled++] = VK_DYNAMIC_STATE_SCISSOR;
|
||||
|
||||
VkPipelineDynamicStateCreateInfo dynamicState =
|
||||
init::PipelineDynamicStateCreateInfo(
|
||||
dynamicEnabled.data(),
|
||||
numDynamicEnabled,
|
||||
0
|
||||
);
|
||||
|
||||
PPipelineLayout layout = gfxInfo.pipelineLayout.cast<PipelineLayout>();
|
||||
hashStruct.pipelineLayoutHash = layout->getHash();
|
||||
|
||||
uint32 hash = CRC::Calculate(&hashStruct, sizeof(PipelineCreateHashStruct), CRC::CRC_32());
|
||||
VkPipeline pipelineHandle;
|
||||
|
||||
std::scoped_lock lock(createdPipelinesLock);
|
||||
auto foundPipeline = createdPipelines.find(hash);
|
||||
if (foundPipeline != createdPipelines.end())
|
||||
{
|
||||
pipelineHandle = foundPipeline->value;
|
||||
}
|
||||
else
|
||||
{
|
||||
createInfo.pStages = stageInfos;
|
||||
createInfo.pVertexInputState = &vertexInput;
|
||||
createInfo.pInputAssemblyState = &assemblyInfo;
|
||||
createInfo.pTessellationState = &tessInfo;
|
||||
createInfo.pViewportState = &viewportInfo;
|
||||
createInfo.pRasterizationState = &rasterizationState;
|
||||
createInfo.pMultisampleState = &multisampleState;
|
||||
createInfo.pDepthStencilState = &depthStencilState;
|
||||
createInfo.pColorBlendState = &blendState;
|
||||
createInfo.pDynamicState = &dynamicState;
|
||||
createInfo.renderPass = gfxInfo.renderPass.cast<RenderPass>()->getHandle();
|
||||
createInfo.layout = layout->getHandle();
|
||||
createInfo.subpass = 0;
|
||||
|
||||
auto beginTime = std::chrono::high_resolution_clock::now();
|
||||
VK_CHECK(vkCreateGraphicsPipelines(graphics->getDevice(), cache, 1, &createInfo, nullptr, &pipelineHandle));
|
||||
auto endTime = std::chrono::high_resolution_clock::now();
|
||||
int64 delta = std::chrono::duration_cast<std::chrono::microseconds>(endTime - beginTime).count();
|
||||
createdPipelines[hash] = pipelineHandle;
|
||||
std::cout << "Gfx creation time: " << delta << std::endl;
|
||||
}
|
||||
|
||||
PGraphicsPipeline result = new GraphicsPipeline(graphics, pipelineHandle, layout, gfxInfo);
|
||||
return result;
|
||||
}
|
||||
|
||||
PComputePipeline PipelineCache::createPipeline(const ComputePipelineCreateInfo& computeInfo)
|
||||
{
|
||||
VkComputePipelineCreateInfo createInfo;
|
||||
createInfo.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
|
||||
createInfo.pNext = 0;
|
||||
createInfo.flags = 0;
|
||||
createInfo.basePipelineIndex = 0;
|
||||
createInfo.basePipelineHandle = VK_NULL_HANDLE;
|
||||
auto layout = computeInfo.pipelineLayout.cast<PipelineLayout>();
|
||||
createInfo.layout = layout->getHandle();
|
||||
auto computeStage = computeInfo.computeShader.cast<ComputeShader>();
|
||||
createInfo.stage = init::PipelineShaderStageCreateInfo(
|
||||
VK_SHADER_STAGE_COMPUTE_BIT,
|
||||
computeStage->getModuleHandle(),
|
||||
computeStage->getEntryPointName());
|
||||
VkPipeline pipelineHandle;
|
||||
auto beginTime = std::chrono::high_resolution_clock::now();
|
||||
VK_CHECK(vkCreateComputePipelines(graphics->getDevice(), cache, 1, &createInfo, nullptr, &pipelineHandle));
|
||||
auto endTime = std::chrono::high_resolution_clock::now();
|
||||
int64 delta = std::chrono::duration_cast<std::chrono::microseconds>(endTime - beginTime).count();
|
||||
std::cout << "Compute creation time: " << delta << std::endl;
|
||||
PComputePipeline result = new ComputePipeline(graphics, pipelineHandle, layout, computeInfo);
|
||||
return result;
|
||||
}
|
||||
Reference in New Issue
Block a user