diff --git a/res/shaders/lib/BRDF.slang b/res/shaders/lib/BRDF.slang index 0cc3c3a..82b83e6 100644 --- a/res/shaders/lib/BRDF.slang +++ b/res/shaders/lib/BRDF.slang @@ -29,7 +29,7 @@ struct BlinnPhong : IBRDF float3 h = normalize(lightDir_TS + viewDir_TS); float nDotH = saturate(dot(normal, h)); - return baseColor * (nDotL + nDotH) * lightColor; + return baseColor; } }; diff --git a/src/Engine/Asset/FontAsset.cpp b/src/Engine/Asset/FontAsset.cpp index a9a599f..43a8c99 100644 --- a/src/Engine/Asset/FontAsset.cpp +++ b/src/Engine/Asset/FontAsset.cpp @@ -32,19 +32,19 @@ void FontAsset::save(ArchiveBuffer& buffer) const .glInternalformat = 0, .vkFormat = (uint32_t)usedTextures[x]->getFormat(), .pDfd = nullptr, - .baseWidth = usedTextures[x]->getSizeX(), - .baseHeight = usedTextures[x]->getSizeY(), - .baseDepth = usedTextures[x]->getSizeZ(), - .numDimensions = usedTextures[x]->getSizeZ() > 1 ? 3u : usedTextures[x]->getSizeY() > 1 ? 2u : 1u, + .baseWidth = usedTextures[x]->getWidth(), + .baseHeight = usedTextures[x]->getHeight(), + .baseDepth = usedTextures[x]->getDepth(), + .numDimensions = usedTextures[x]->getDepth() > 1 ? 3u : usedTextures[x]->getHeight() > 1 ? 2u : 1u, .numLevels = usedTextures[x]->getMipLevels(), - .numLayers = usedTextures[x]->getSizeZ(), + .numLayers = usedTextures[x]->getDepth(), .numFaces = usedTextures[x]->getNumFaces(), .isArray = false, .generateMipmaps = false, }; ktxTexture2_Create(&createInfo, KTX_TEXTURE_CREATE_ALLOC_STORAGE, &kTexture); - for (uint32 depth = 0; depth < usedTextures[x]->getSizeZ(); ++depth) + for (uint32 depth = 0; depth < usedTextures[x]->getDepth(); ++depth) { for (uint32 face = 0; face < usedTextures[x]->getNumFaces(); ++face) { diff --git a/src/Engine/Asset/TextureAsset.cpp b/src/Engine/Asset/TextureAsset.cpp index c7b8717..f43a713 100644 --- a/src/Engine/Asset/TextureAsset.cpp +++ b/src/Engine/Asset/TextureAsset.cpp @@ -123,10 +123,10 @@ void TextureAsset::setTexture(Gfx::OTexture _texture) uint32 TextureAsset::getWidth() { - return texture->getSizeX(); + return texture->getWidth(); } uint32 TextureAsset::getHeight() { - return texture->getSizeY(); + return texture->getHeight(); } diff --git a/src/Engine/Graphics/Buffer.cpp b/src/Engine/Graphics/Buffer.cpp index 6232045..79ccf24 100644 --- a/src/Engine/Graphics/Buffer.cpp +++ b/src/Engine/Graphics/Buffer.cpp @@ -12,6 +12,35 @@ Buffer::~Buffer() { } +VertexBuffer::VertexBuffer(QueueFamilyMapping mapping, uint32 numVertices, uint32 vertexSize, QueueType startQueueType) + : Buffer(mapping, startQueueType) + , numVertices(numVertices) + , vertexSize(vertexSize) +{ +} +VertexBuffer::~VertexBuffer() +{ +} + +IndexBuffer::IndexBuffer(QueueFamilyMapping mapping, uint64 size, Gfx::SeIndexType indexType, QueueType startQueueType) + : Buffer(mapping, startQueueType) + , indexType(indexType) +{ + switch (indexType) + { + case SE_INDEX_TYPE_UINT16: + numIndices = size / sizeof(uint16); + break; + case SE_INDEX_TYPE_UINT32: + numIndices = size / sizeof(uint32); + break; + default: + break; + } +} +IndexBuffer::~IndexBuffer() +{ +} UniformBuffer::UniformBuffer(QueueFamilyMapping mapping, const DataSource& sourceData) : Buffer(mapping, sourceData.owner) , contents(sourceData.size) @@ -37,17 +66,17 @@ bool UniformBuffer::updateContents(const DataSource& sourceData) return true; } -ShaderBuffer::ShaderBuffer(QueueFamilyMapping mapping, uint32 stride, uint32 numElements, const DataSource& sourceData) +ShaderBuffer::ShaderBuffer(QueueFamilyMapping mapping, uint32 numElements, const DataSource& sourceData) : Buffer(mapping, sourceData.owner) , contents(sourceData.size) , numElements(numElements) - , stride(stride) { if (sourceData.data != nullptr) { std::memcpy(contents.data(), sourceData.data, sourceData.size); } } + ShaderBuffer::~ShaderBuffer() { } @@ -62,31 +91,3 @@ bool ShaderBuffer::updateContents(const DataSource& sourceData) std::memcpy(contents.data(), sourceData.data, sourceData.size); return true; } -VertexBuffer::VertexBuffer(QueueFamilyMapping mapping, uint32 numVertices, uint32 vertexSize, QueueType startQueueType) - : Buffer(mapping, startQueueType) - , numVertices(numVertices) - , vertexSize(vertexSize) -{ -} -VertexBuffer::~VertexBuffer() -{ -} -IndexBuffer::IndexBuffer(QueueFamilyMapping mapping, uint64 size, Gfx::SeIndexType indexType, QueueType startQueueType) - : Buffer(mapping, startQueueType) - , indexType(indexType) -{ - switch (indexType) - { - case SE_INDEX_TYPE_UINT16: - numIndices = size / sizeof(uint16); - break; - case SE_INDEX_TYPE_UINT32: - numIndices = size / sizeof(uint32); - break; - default: - break; - } -} -IndexBuffer::~IndexBuffer() -{ -} diff --git a/src/Engine/Graphics/Buffer.h b/src/Engine/Graphics/Buffer.h index 1d2db24..4bed3bb 100644 --- a/src/Engine/Graphics/Buffer.h +++ b/src/Engine/Graphics/Buffer.h @@ -23,39 +23,6 @@ protected: virtual void executeOwnershipBarrier(QueueType newOwner) = 0; }; -DECLARE_REF(UniformBuffer) -class UniformBuffer : public Buffer -{ -public: - UniformBuffer(QueueFamilyMapping mapping, const DataSource& sourceData); - virtual ~UniformBuffer(); - // returns true if an update was performed, false if the old contents == new contents - virtual bool updateContents(const DataSource& sourceData); - bool isDataEquals(PUniformBuffer other) - { - if(other == nullptr) - { - return false; - } - if(contents.size() != other->contents.size()) - { - return false; - } - if(std::memcmp(contents.data(), other->contents.data(), contents.size()) != 0) - { - return false; - } - return true; - } -protected: - Array contents; - // Inherited via QueueOwnedResource - virtual void executeOwnershipBarrier(QueueType newOwner) = 0; - virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage, - SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0; -}; -DEFINE_REF(UniformBuffer) - class VertexBuffer : public Buffer { public: @@ -108,10 +75,42 @@ protected: }; DEFINE_REF(IndexBuffer) +DECLARE_REF(UniformBuffer) +class UniformBuffer : public Buffer +{ +public: + UniformBuffer(QueueFamilyMapping mapping, const DataSource& sourceData); + virtual ~UniformBuffer(); + // returns true if an update was performed, false if the old contents == new contents + virtual bool updateContents(const DataSource& sourceData); + bool isDataEquals(PUniformBuffer other) + { + if (other == nullptr) + { + return false; + } + if (contents.size() != other->contents.size()) + { + return false; + } + if (std::memcmp(contents.data(), other->contents.data(), contents.size()) != 0) + { + return false; + } + return true; + } +protected: + Array contents; + // Inherited via QueueOwnedResource + virtual void executeOwnershipBarrier(QueueType newOwner) = 0; + virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage, + SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0; +}; +DEFINE_REF(UniformBuffer) class ShaderBuffer : public Buffer { public: - ShaderBuffer(QueueFamilyMapping mapping, uint32 stride, uint32 numElements, const DataSource& bulkResourceData); + ShaderBuffer(QueueFamilyMapping mapping, uint32 numElements, const DataSource& bulkResourceData); virtual ~ShaderBuffer(); virtual bool updateContents(const DataSource& sourceData); bool isDataEquals(ShaderBuffer* other) @@ -134,10 +133,6 @@ public: { return numElements; } - constexpr uint32 getStride() const - { - return stride; - } protected: // Inherited via QueueOwnedResource virtual void executeOwnershipBarrier(QueueType newOwner) = 0; @@ -146,9 +141,7 @@ protected: Array contents; uint32 numElements; - uint32 stride; }; DEFINE_REF(ShaderBuffer) - } } \ No newline at end of file diff --git a/src/Engine/Graphics/CMakeLists.txt b/src/Engine/Graphics/CMakeLists.txt index 3aa2cf5..883ad83 100644 --- a/src/Engine/Graphics/CMakeLists.txt +++ b/src/Engine/Graphics/CMakeLists.txt @@ -2,6 +2,8 @@ target_sources(Engine PRIVATE Buffer.h Buffer.cpp + Command.h + Command.cpp DebugVertex.h Descriptor.h Descriptor.cpp @@ -13,6 +15,8 @@ target_sources(Engine Initializer.cpp Mesh.h Mesh.cpp + Pipeline.h + Pipeline.cpp RenderTarget.h RenderTarget.cpp Resources.h @@ -30,12 +34,14 @@ target_sources(Engine PUBLIC FILE_SET HEADERS FILES Buffer.h + Command.h DebugVertex.h Descriptor.h Enums.h Graphics.h Initializer.h Mesh.h + Pipeline.h RenderTarget.h Resources.h Shader.h diff --git a/src/Engine/Graphics/Command.cpp b/src/Engine/Graphics/Command.cpp new file mode 100644 index 0000000..5e4203b --- /dev/null +++ b/src/Engine/Graphics/Command.cpp @@ -0,0 +1,21 @@ +#include "Command.h" + +using namespace Seele; +using namespace Seele::Gfx; + + +RenderCommand::RenderCommand() +{ +} + +RenderCommand::~RenderCommand() +{ +} + +ComputeCommand::ComputeCommand() +{ +} + +ComputeCommand::~ComputeCommand() +{ +} diff --git a/src/Engine/Graphics/Command.h b/src/Engine/Graphics/Command.h new file mode 100644 index 0000000..84bf3c6 --- /dev/null +++ b/src/Engine/Graphics/Command.h @@ -0,0 +1,44 @@ +#pragma once +#include "Enums.h" + +namespace Seele +{ +namespace Gfx +{ +DECLARE_REF(Viewport) +class RenderCommand +{ +public: + RenderCommand(); + virtual ~RenderCommand(); + virtual bool isReady() = 0; + virtual void setViewport(Gfx::PViewport viewport) = 0; + virtual void bindPipeline(Gfx::PGraphicsPipeline pipeline) = 0; + virtual void bindDescriptor(Gfx::PDescriptorSet set) = 0; + virtual void bindDescriptor(const Array& sets) = 0; + virtual void bindVertexBuffer(const Array& buffer) = 0; + virtual void bindIndexBuffer(Gfx::PIndexBuffer indexBuffer) = 0; + virtual void pushConstants(Gfx::PPipelineLayout layout, Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size, const void* data) = 0; + virtual void draw(uint32 vertexCount, uint32 instanceCount, int32 firstVertex, uint32 firstInstance) = 0; + virtual void drawIndexed(uint32 indexCount, uint32 instanceCount, int32 firstIndex, uint32 vertexOffset, uint32 firstInstance) = 0; + virtual void dispatch(uint32 groupX, uint32 groupY, uint32 groupZ) = 0; + std::string name; +}; +DEFINE_REF(RenderCommand) + class ComputeCommand +{ +public: + ComputeCommand(); + virtual ~ComputeCommand(); + virtual bool isReady() = 0; + virtual void bindPipeline(Gfx::PComputePipeline pipeline) = 0; + virtual void bindDescriptor(Gfx::PDescriptorSet set) = 0; + virtual void bindDescriptor(const Array& sets) = 0; + virtual void pushConstants(Gfx::PPipelineLayout layout, Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size, const void* data) = 0; + virtual void dispatch(uint32 threadX, uint32 threadY, uint32 threadZ) = 0; + std::string name; +}; +DEFINE_REF(ComputeCommand) + +} +} \ No newline at end of file diff --git a/src/Engine/Graphics/Descriptor.cpp b/src/Engine/Graphics/Descriptor.cpp index bb820e0..f25eb66 100644 --- a/src/Engine/Graphics/Descriptor.cpp +++ b/src/Engine/Graphics/Descriptor.cpp @@ -3,6 +3,74 @@ using namespace Seele; using namespace Seele::Gfx; +DescriptorBinding::DescriptorBinding() + : binding(0) + , descriptorType(SE_DESCRIPTOR_TYPE_MAX_ENUM) + , descriptorCount(0x7fff) + , shaderStages(SE_SHADER_STAGE_ALL) +{ +} + +DescriptorBinding::DescriptorBinding(const DescriptorBinding& other) + : binding(other.binding) + , descriptorType(other.descriptorType) + , descriptorCount(other.descriptorCount) + , shaderStages(other.shaderStages) +{ +} + +DescriptorBinding& DescriptorBinding::operator=(const DescriptorBinding& other) +{ + if (this != &other) + { + binding = other.binding; + descriptorType = other.descriptorType; + descriptorCount = other.descriptorCount; + shaderStages = other.shaderStages; + } + return *this; +} + +DescriptorAllocator::DescriptorAllocator() +{ +} + +DescriptorAllocator::~DescriptorAllocator() +{ +} + +DescriptorLayout::DescriptorLayout(const std::string& name) + : setIndex(0) + , name(name) +{ +} + +DescriptorLayout::DescriptorLayout(const DescriptorLayout& other) +{ + descriptorBindings.resize(other.descriptorBindings.size()); + for (uint32 i = 0; i < descriptorBindings.size(); ++i) + { + descriptorBindings[i] = other.descriptorBindings[i]; + } +} + +DescriptorLayout& DescriptorLayout::operator=(const DescriptorLayout& other) +{ + if (this != &other) + { + descriptorBindings.resize(other.descriptorBindings.size()); + for (uint32 i = 0; i < descriptorBindings.size(); ++i) + { + descriptorBindings[i] = other.descriptorBindings[i]; + } + } + return *this; +} + +DescriptorLayout::~DescriptorLayout() +{ +} + void DescriptorLayout::addDescriptorBinding(uint32 bindingIndex, SeDescriptorType type, uint32 arrayCount, SeDescriptorBindingFlags bindingFlags, SeShaderStageFlags shaderStages) { if (descriptorBindings.size() <= bindingIndex) @@ -19,16 +87,31 @@ void DescriptorLayout::addDescriptorBinding(uint32 bindingIndex, SeDescriptorTyp PDescriptorSet DescriptorLayout::allocateDescriptorSet() { - std::scoped_lock lock(allocatorLock); return allocator->allocateDescriptorSet(); } void DescriptorLayout::reset() { - std::scoped_lock lock(allocatorLock); allocator->reset(); } +PipelineLayout::PipelineLayout() +{ +} + +PipelineLayout::PipelineLayout(PPipelineLayout baseLayout) +{ + if (baseLayout != nullptr) + { + descriptorSetLayouts = baseLayout->descriptorSetLayouts; + pushConstants = baseLayout->pushConstants; + } +} + +PipelineLayout::~PipelineLayout() +{ +} + void PipelineLayout::addDescriptorLayout(uint32 setIndex, PDescriptorLayout layout) { if (descriptorSetLayouts.size() <= setIndex) diff --git a/src/Engine/Graphics/Descriptor.h b/src/Engine/Graphics/Descriptor.h index 06e3434..680513a 100644 --- a/src/Engine/Graphics/Descriptor.h +++ b/src/Engine/Graphics/Descriptor.h @@ -6,29 +6,12 @@ namespace Seele { namespace Gfx { - class DescriptorBinding { public: - DescriptorBinding() - : binding(0), descriptorType(SE_DESCRIPTOR_TYPE_MAX_ENUM), descriptorCount(0x7fff), shaderStages(SE_SHADER_STAGE_ALL) - { - } - DescriptorBinding(const DescriptorBinding& other) - : binding(other.binding), descriptorType(other.descriptorType), descriptorCount(other.descriptorCount), shaderStages(other.shaderStages) - { - } - DescriptorBinding& operator=(const DescriptorBinding& other) - { - if(this != &other) - { - binding = other.binding; - descriptorType = other.descriptorType; - descriptorCount = other.descriptorCount; - shaderStages = other.shaderStages; - } - return *this; - } + DescriptorBinding(); + DescriptorBinding(const DescriptorBinding& other); + DescriptorBinding& operator=(const DescriptorBinding& other); uint32 binding; SeDescriptorType descriptorType; uint32 descriptorCount; @@ -41,8 +24,8 @@ DECLARE_REF(DescriptorSet) class DescriptorAllocator { public: - DescriptorAllocator() {} - virtual ~DescriptorAllocator() {} + DescriptorAllocator(); + virtual ~DescriptorAllocator(); virtual PDescriptorSet allocateDescriptorSet() = 0; virtual void reset() = 0; }; @@ -50,7 +33,7 @@ DEFINE_REF(DescriptorAllocator) DECLARE_REF(UniformBuffer) DECLARE_REF(ShaderBuffer) DECLARE_REF(Texture) -DECLARE_REF(SamplerState) +DECLARE_REF(Sampler) class DescriptorSet { public: @@ -59,8 +42,8 @@ public: virtual void writeChanges() = 0; virtual void updateBuffer(uint32 binding, PUniformBuffer uniformBuffer) = 0; virtual void updateBuffer(uint32 binding, PShaderBuffer ShaderBuffer) = 0; - virtual void updateSampler(uint32 binding, PSamplerState samplerState) = 0; - virtual void updateTexture(uint32 binding, PTexture texture, PSamplerState samplerState = nullptr) = 0; + virtual void updateSampler(uint32 binding, PSampler sampler) = 0; + virtual void updateTexture(uint32 binding, PTexture texture, PSampler samplerState = nullptr) = 0; virtual void updateTextureArray(uint32_t binding, Array texture) = 0; virtual bool operator<(PDescriptorSet other) = 0; @@ -71,44 +54,21 @@ DEFINE_REF(DescriptorSet) class DescriptorLayout { public: - DescriptorLayout(const std::string& name) - : setIndex(0) - , name(name) - { - } - DescriptorLayout(const DescriptorLayout& other) - { - descriptorBindings.resize(other.descriptorBindings.size()); - for(uint32 i = 0; i < descriptorBindings.size(); ++i) - { - descriptorBindings[i] = other.descriptorBindings[i]; - } - } - DescriptorLayout& operator=(const DescriptorLayout& other) - { - if (this != &other) - { - descriptorBindings.resize(other.descriptorBindings.size()); - for (uint32 i = 0; i < descriptorBindings.size(); ++i) - { - descriptorBindings[i] = other.descriptorBindings[i]; - } - } - return *this; - } - virtual ~DescriptorLayout() {} + DescriptorLayout(const std::string& name); + DescriptorLayout(const DescriptorLayout& other); + DescriptorLayout& operator=(const DescriptorLayout& other); + virtual ~DescriptorLayout(); virtual void create() = 0; virtual void addDescriptorBinding(uint32 binding, SeDescriptorType type, uint32 arrayCount = 1, SeDescriptorBindingFlags bindingFlags = 0, SeShaderStageFlags shaderStages = SeShaderStageFlagBits::SE_SHADER_STAGE_ALL); virtual void reset(); virtual PDescriptorSet allocateDescriptorSet(); - const Array& getBindings() const { return descriptorBindings; } + constexpr const Array& getBindings() const { return descriptorBindings; } constexpr uint32 getSetIndex() const { return setIndex; } constexpr void setSetIndex(uint32 _setIndex) { setIndex = _setIndex; } protected: Array descriptorBindings; ODescriptorAllocator allocator; - std::mutex allocatorLock; uint32 setIndex; std::string name; friend class PipelineLayout; @@ -118,18 +78,9 @@ DEFINE_REF(DescriptorLayout) class PipelineLayout { public: - PipelineLayout() - { - } - PipelineLayout(PPipelineLayout baseLayout) - { - if (baseLayout != nullptr) - { - descriptorSetLayouts = baseLayout->descriptorSetLayouts; - pushConstants = baseLayout->pushConstants; - } - } - virtual ~PipelineLayout() {} + PipelineLayout(); + PipelineLayout(PPipelineLayout baseLayout); + virtual ~PipelineLayout(); virtual void create() = 0; virtual void reset() = 0; void addDescriptorLayout(uint32 setIndex, PDescriptorLayout layout); diff --git a/src/Engine/Graphics/Enums.cpp b/src/Engine/Graphics/Enums.cpp index 7fa2a0e..7dc5253 100644 --- a/src/Engine/Graphics/Enums.cpp +++ b/src/Engine/Graphics/Enums.cpp @@ -3,7 +3,6 @@ using namespace Seele; using namespace Seele::Gfx; - FormatCompatibilityInfo Gfx::getFormatInfo(SeFormat format) { switch(format) { diff --git a/src/Engine/Graphics/Graphics.h b/src/Engine/Graphics/Graphics.h index 9037f3d..2e4fa8d 100644 --- a/src/Engine/Graphics/Graphics.h +++ b/src/Engine/Graphics/Graphics.h @@ -1,8 +1,8 @@ #pragma once #include "MinimalEngine.h" +#include "Initializer.h" #include "Resources.h" #include "Containers/Array.h" -#include "Shader.h" namespace Seele { @@ -27,6 +27,8 @@ DECLARE_REF(VertexBuffer) DECLARE_REF(IndexBuffer) DECLARE_REF(UniformBuffer) DECLARE_REF(PipelineLayout) +DECLARE_REF(GraphicsPipeline) +DECLARE_REF(ComputePipeline) class Graphics { public: @@ -65,7 +67,6 @@ public: virtual PRenderCommand createRenderCommand(const std::string& name = "") = 0; virtual PComputeCommand createComputeCommand(const std::string& name = "") = 0; - virtual OVertexDeclaration createVertexDeclaration(const Array& element) = 0; virtual OVertexShader createVertexShader(const ShaderCreateInfo& createInfo) = 0; virtual OFragmentShader createFragmentShader(const ShaderCreateInfo& createInfo) = 0; virtual OComputeShader createComputeShader(const ShaderCreateInfo& createInfo) = 0; @@ -74,12 +75,11 @@ public: virtual PGraphicsPipeline createGraphicsPipeline(LegacyPipelineCreateInfo createInfo) = 0; virtual PGraphicsPipeline createGraphicsPipeline(MeshPipelineCreateInfo createInfo) = 0; virtual PComputePipeline createComputePipeline(ComputePipelineCreateInfo createInfo) = 0; - virtual OSamplerState createSamplerState(const SamplerCreateInfo& createInfo) = 0; + virtual OSampler createSamplerState(const SamplerCreateInfo& createInfo) = 0; virtual ODescriptorLayout createDescriptorLayout(const std::string& name = "") = 0; virtual OPipelineLayout createPipelineLayout(PPipelineLayout baseLayout = nullptr) = 0; - virtual void copyTexture(Gfx::PTexture srcTexture, Gfx::PTexture dstTexture) = 0; bool supportMeshShading() const { return meshShadingEnabled; } protected: QueueFamilyMapping queueMapping; diff --git a/src/Engine/Graphics/Initializer.h b/src/Engine/Graphics/Initializer.h index 1efe867..20b948b 100644 --- a/src/Engine/Graphics/Initializer.h +++ b/src/Engine/Graphics/Initializer.h @@ -56,16 +56,15 @@ struct DataSource }; struct TextureCreateInfo { - DataSource sourceData = DataSource(); - uint32 width = 1; - uint32 height = 1; - uint32 depth = 1; - bool bArray = false; - uint32 arrayLayers = 1; - uint32 mipLevels = 1; - uint32 samples = 1; - Gfx::SeFormat format = Gfx::SE_FORMAT_R32G32B32A32_SFLOAT; - Gfx::SeImageUsageFlagBits usage = Gfx::SE_IMAGE_USAGE_SAMPLED_BIT; + DataSource sourceData = DataSource(); + Gfx::SeFormat format = Gfx::SE_FORMAT_R32G32B32A32_SFLOAT; + uint32 width = 1; + uint32 height = 1; + uint32 depth = 1; + uint32 mipLevels = 1; + uint32 arrayLayers = 1; + uint32 samples = 1; + Gfx::SeImageUsageFlagBits usage = Gfx::SE_IMAGE_USAGE_SAMPLED_BIT; }; struct SamplerCreateInfo { @@ -88,107 +87,97 @@ struct SamplerCreateInfo }; struct VertexBufferCreateInfo { - DataSource sourceData = DataSource(); + DataSource sourceData = DataSource(); // bytes per vertex - uint32 vertexSize = 0; - uint32 numVertices = 0; + uint32 vertexSize = 0; + uint32 numVertices = 0; }; struct IndexBufferCreateInfo { - DataSource sourceData = DataSource(); - Gfx::SeIndexType indexType = Gfx::SeIndexType::SE_INDEX_TYPE_UINT16; + DataSource sourceData = DataSource(); + Gfx::SeIndexType indexType = Gfx::SeIndexType::SE_INDEX_TYPE_UINT16; }; struct UniformBufferCreateInfo { - DataSource sourceData = DataSource(); - uint8 dynamic = 0; + DataSource sourceData = DataSource(); + uint8 dynamic = 0; }; struct ShaderBufferCreateInfo { - DataSource sourceData = DataSource(); - uint32 stride; - uint8 dynamic = 0; + DataSource sourceData = DataSource(); + uint8 dynamic = 0; }; struct ShaderCreateInfo { - std::string mainModule; - Array additionalModules; - std::string name; // Debug info - std::string entryPoint; - Array> typeParameter; - Map defines; + std::string mainModule; + Array additionalModules; + std::string name; // Debug info + std::string entryPoint; + Array> typeParameter; + Map defines; }; namespace Gfx { struct SePushConstantRange { - SeShaderStageFlags stageFlags; - uint32_t offset; - uint32_t size; + SeShaderStageFlags stageFlags; + uint32 offset; + uint32 size; }; -struct VertexElement -{ - uint8 binding; - uint8 offset; - SeFormat vertexFormat; - uint8 attributeIndex; - uint8 stride; - uint8 instanced = 0; -}; -static_assert(std::is_aggregate_v); struct RasterizationState { - uint8 depthClampEnable : 1 = 0; - uint8 rasterizerDiscardEnable : 1 = 0; - uint8 depthBiasEnable : 1 = 0; - float depthBiasConstantFactor = 0; - float depthBiasClamp = 0; - float depthBiasSlopeFactor = 0; - float lineWidth = 0; - SePolygonMode polygonMode; - SeCullModeFlags cullMode; - SeFrontFace frontFace; + uint32 depthClampEnable = 0; + uint32 rasterizerDiscardEnable = 0; + SePolygonMode polygonMode; + SeCullModeFlags cullMode; + SeFrontFace frontFace; + uint32 depthBiasEnable = 0; + float depthBiasConstantFactor = 0; + float depthBiasClamp = 0; + float depthBiasSlopeFactor = 0; + float lineWidth = 0; }; struct MultisampleState { - uint32 samples = 1; - float minSampleShading = 1; - uint8 sampleShadingEnable : 1 = 0; - uint8 alphaCoverageEnable = 0; - uint8 alphaToOneEnable = 0; + SeSampleCountFlags samples = 1; + uint32 sampleShadingEnable = 0; + float minSampleShading = 1; + uint8 alphaCoverageEnable = 0; + uint8 alphaToOneEnable = 0; }; struct DepthStencilState { - uint8 depthTestEnable : 1 = 0; - uint8 depthWriteEnable : 1 = 0; - uint8 depthBoundsTestEnable : 1 = 0; - uint8 stencilTestEnable : 1 = 0; - SeCompareOp depthCompareOp; + uint32 depthTestEnable = 0; + uint32 depthWriteEnable = 0; + SeCompareOp depthCompareOp = Gfx::SE_COMPARE_OP_LESS; + uint32 depthBoundsTestEnable = 0; + uint32 stencilTestEnable = 0; SeStencilOp front = Gfx::SE_STENCIL_OP_END_RANGE; SeStencilOp back = Gfx::SE_STENCIL_OP_END_RANGE; - float minDepthBounds; - float maxDepthBounds; + float minDepthBounds; + float maxDepthBounds; }; struct ColorBlendState { - uint8 logicOpEnable : 1; - SeLogicOp logicOp = Gfx::SE_LOGIC_OP_OR; - uint32 attachmentCount; struct BlendAttachment { - uint8 blendEnable = 0; - SeBlendFactor srcColorBlendFactor = Gfx::SE_BLEND_FACTOR_SRC_ALPHA; - SeBlendFactor dstColorBlendFactor = Gfx::SE_BLEND_FACTOR_SRC_ALPHA; - SeBlendOp colorBlendOp = Gfx::SE_BLEND_OP_ADD; - SeBlendFactor srcAlphaBlendFactor = Gfx::SE_BLEND_FACTOR_SRC_ALPHA; - SeBlendFactor dstAlphaBlendFactor = Gfx::SE_BLEND_FACTOR_SRC_ALPHA; - SeBlendOp alphaBlendOp = Gfx::SE_BLEND_OP_ADD; - SeColorComponentFlags colorWriteMask = 0; - } blendAttachments[16]; - float blendConstants[4]; + uint32 blendEnable = 0; + SeBlendFactor srcColorBlendFactor = Gfx::SE_BLEND_FACTOR_SRC_ALPHA; + SeBlendFactor dstColorBlendFactor = Gfx::SE_BLEND_FACTOR_SRC_ALPHA; + SeBlendOp colorBlendOp = Gfx::SE_BLEND_OP_ADD; + SeBlendFactor srcAlphaBlendFactor = Gfx::SE_BLEND_FACTOR_SRC_ALPHA; + SeBlendFactor dstAlphaBlendFactor = Gfx::SE_BLEND_FACTOR_SRC_ALPHA; + SeBlendOp alphaBlendOp = Gfx::SE_BLEND_OP_ADD; + SeColorComponentFlags colorWriteMask = 0; + }; + uint32 logicOpEnable; + SeLogicOp logicOp = Gfx::SE_LOGIC_OP_OR; + uint32 attachmentCount; + StaticArray blendAttachments; + StaticArray blendConstants; }; -DECLARE_REF(VertexDeclaration) + DECLARE_REF(VertexShader) DECLARE_REF(TaskShader) DECLARE_REF(MeshShader) @@ -198,16 +187,15 @@ DECLARE_REF(RenderPass) DECLARE_REF(PipelineLayout) struct LegacyPipelineCreateInfo { - PVertexDeclaration vertexDeclaration; SePrimitiveTopology topology; - PVertexShader vertexShader; - PFragmentShader fragmentShader; - PRenderPass renderPass; - OPipelineLayout pipelineLayout; - MultisampleState multisampleState; - RasterizationState rasterizationState; - DepthStencilState depthStencilState; - ColorBlendState colorBlend; + PVertexShader vertexShader; + PFragmentShader fragmentShader; + PRenderPass renderPass; + OPipelineLayout pipelineLayout; + MultisampleState multisampleState; + RasterizationState rasterizationState; + DepthStencilState depthStencilState; + ColorBlendState colorBlend; LegacyPipelineCreateInfo(); LegacyPipelineCreateInfo(LegacyPipelineCreateInfo&& rhs) = default; LegacyPipelineCreateInfo& operator=(LegacyPipelineCreateInfo&& rhs) = default; @@ -216,15 +204,15 @@ struct LegacyPipelineCreateInfo struct MeshPipelineCreateInfo { - PTaskShader taskShader; - PMeshShader meshShader; - PFragmentShader fragmentShader; - PRenderPass renderPass; - OPipelineLayout pipelineLayout; - MultisampleState multisampleState; - RasterizationState rasterizationState; - DepthStencilState depthStencilState; - ColorBlendState colorBlend; + PTaskShader taskShader; + PMeshShader meshShader; + PFragmentShader fragmentShader; + PRenderPass renderPass; + OPipelineLayout pipelineLayout; + MultisampleState multisampleState; + RasterizationState rasterizationState; + DepthStencilState depthStencilState; + ColorBlendState colorBlend; MeshPipelineCreateInfo(); MeshPipelineCreateInfo(MeshPipelineCreateInfo&& rhs) = default; MeshPipelineCreateInfo& operator=(MeshPipelineCreateInfo&& rhs) = default; @@ -232,8 +220,8 @@ struct MeshPipelineCreateInfo }; struct ComputePipelineCreateInfo { - Gfx::PComputeShader computeShader; - Gfx::OPipelineLayout pipelineLayout; + Gfx::PComputeShader computeShader; + Gfx::OPipelineLayout pipelineLayout; ComputePipelineCreateInfo(); ComputePipelineCreateInfo(ComputePipelineCreateInfo&& rhs) = default; ComputePipelineCreateInfo& operator=(ComputePipelineCreateInfo&& rhs) = default; diff --git a/src/Engine/Graphics/Pipeline.cpp b/src/Engine/Graphics/Pipeline.cpp new file mode 100644 index 0000000..a4bb120 --- /dev/null +++ b/src/Engine/Graphics/Pipeline.cpp @@ -0,0 +1,32 @@ +#include "Pipeline.h" + +using namespace Seele; +using namespace Seele::Gfx; + +GraphicsPipeline::GraphicsPipeline(OPipelineLayout layout) + : layout(std::move(layout)) {} +{ +} + +GraphicsPipeline::~GraphicsPipeline() +{ +} + +PPipelineLayout GraphicsPipeline::getPipelineLayout() const +{ + return layout; +} + +ComputePipeline::ComputePipeline(OPipelineLayout layout) + : layout(std::move(layout)) +{ +} + +ComputePipeline::~ComputePipeline() +{ +} + +PPipelineLayout ComputePipeline::getPipelineLayout() const +{ + return layout; +} diff --git a/src/Engine/Graphics/Pipeline.h b/src/Engine/Graphics/Pipeline.h new file mode 100644 index 0000000..81febba --- /dev/null +++ b/src/Engine/Graphics/Pipeline.h @@ -0,0 +1,31 @@ +#pragma once +#include "Enums.h" +#include "Descriptor.h" + +namespace Seele +{ +namespace Gfx +{ +class GraphicsPipeline +{ +public: + GraphicsPipeline(OPipelineLayout layout); + virtual ~GraphicsPipeline(); + PPipelineLayout getPipelineLayout() const; +protected: + OPipelineLayout layout; +}; +DEFINE_REF(GraphicsPipeline) + +class ComputePipeline +{ +public: + ComputePipeline(OPipelineLayout layout); + virtual ~ComputePipeline(); + PPipelineLayout getPipelineLayout() const; +protected: + OPipelineLayout layout; +}; +DEFINE_REF(ComputePipeline) +} +} \ No newline at end of file diff --git a/src/Engine/Graphics/RenderPass/DepthPrepass.cpp b/src/Engine/Graphics/RenderPass/DepthPrepass.cpp index 9a7fa57..d29cd6c 100644 --- a/src/Engine/Graphics/RenderPass/DepthPrepass.cpp +++ b/src/Engine/Graphics/RenderPass/DepthPrepass.cpp @@ -144,8 +144,8 @@ void DepthPrepass::publishOutputs() TextureCreateInfo depthBufferInfo; // If we render to a part of an image, the depth buffer itself must // still match the size of the whole image or their coordinate systems go out of sync - depthBufferInfo.width = viewport->getOwner()->getSizeX(); - depthBufferInfo.height = viewport->getOwner()->getSizeY(); + depthBufferInfo.width = viewport->getOwner()->getWidth(); + depthBufferInfo.height = viewport->getOwner()->getHeight(); depthBufferInfo.format = Gfx::SE_FORMAT_D32_SFLOAT; depthBufferInfo.usage = Gfx::SE_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; depthBuffer = graphics->createTexture2D(depthBufferInfo); diff --git a/src/Engine/Graphics/RenderPass/LightCullingPass.cpp b/src/Engine/Graphics/RenderPass/LightCullingPass.cpp index 470c9a8..30ab14f 100644 --- a/src/Engine/Graphics/RenderPass/LightCullingPass.cpp +++ b/src/Engine/Graphics/RenderPass/LightCullingPass.cpp @@ -78,8 +78,8 @@ void LightCullingPass::endFrame() void LightCullingPass::publishOutputs() { setupFrustums(); - uint32_t viewportWidth = viewport->getSizeX(); - uint32_t viewportHeight = viewport->getSizeY(); + uint32_t viewportWidth = viewport->getWidth(); + uint32_t viewportHeight = viewport->getHeight(); glm::uvec3 numThreadGroups = glm::ceil(glm::vec3(viewportWidth / (float)BLOCK_SIZE, viewportHeight / (float)BLOCK_SIZE, 1)); dispatchParams.numThreadGroups = numThreadGroups; dispatchParams.numThreads = numThreadGroups * glm::uvec3(BLOCK_SIZE, BLOCK_SIZE, 1); @@ -184,8 +184,8 @@ void LightCullingPass::modifyRenderPassMacros(Map&) void LightCullingPass::setupFrustums() { - uint32_t viewportWidth = viewport->getSizeX(); - uint32_t viewportHeight = viewport->getSizeY(); + uint32_t viewportWidth = viewport->getWidth(); + uint32_t viewportHeight = viewport->getHeight(); glm::uvec3 numThreads = glm::ceil(glm::vec3(viewportWidth / (float)BLOCK_SIZE, viewportHeight / (float)BLOCK_SIZE, 1)); glm::uvec3 numThreadGroups = glm::ceil(glm::vec3(numThreads.x / (float)BLOCK_SIZE, numThreads.y / (float)BLOCK_SIZE, 1)); diff --git a/src/Engine/Graphics/RenderPass/RenderPass.cpp b/src/Engine/Graphics/RenderPass/RenderPass.cpp index d58db43..abe5c9c 100644 --- a/src/Engine/Graphics/RenderPass/RenderPass.cpp +++ b/src/Engine/Graphics/RenderPass/RenderPass.cpp @@ -29,7 +29,7 @@ void RenderPass::beginFrame(const Component::Camera& cam) .viewMatrix = cam.getViewMatrix(), .projectionMatrix = viewport->getProjectionMatrix(), .cameraPosition = Vector4(cam.getCameraPosition(), 1), - .screenDimensions = Vector2(static_cast(viewport->getSizeX()), static_cast(viewport->getSizeY())), + .screenDimensions = Vector2(static_cast(viewport->getWidth()), static_cast(viewport->getHeight())), }; DataSource uniformUpdate = { .size = sizeof(ViewParameter), diff --git a/src/Engine/Graphics/RenderPass/SkyboxRenderPass.cpp b/src/Engine/Graphics/RenderPass/SkyboxRenderPass.cpp index f7de63e..bdb08d6 100644 --- a/src/Engine/Graphics/RenderPass/SkyboxRenderPass.cpp +++ b/src/Engine/Graphics/RenderPass/SkyboxRenderPass.cpp @@ -92,7 +92,7 @@ void SkyboxRenderPass::beginFrame(const Component::Camera& cam) viewParams.viewMatrix = cam.getViewMatrix(); viewParams.projectionMatrix = viewport->getProjectionMatrix(); viewParams.cameraPosition = Vector4(cam.getCameraPosition(), 1); - viewParams.screenDimensions = Vector2(static_cast(viewport->getSizeX()), static_cast(viewport->getSizeY())); + viewParams.screenDimensions = Vector2(static_cast(viewport->getWidth()), static_cast(viewport->getHeight())); uniformUpdate.size = sizeof(ViewParameter); uniformUpdate.data = (uint8*)&viewParams; viewParamsBuffer->updateContents(uniformUpdate); diff --git a/src/Engine/Graphics/RenderPass/UIPass.cpp b/src/Engine/Graphics/RenderPass/UIPass.cpp index 1fed55b..ec3f58d 100644 --- a/src/Engine/Graphics/RenderPass/UIPass.cpp +++ b/src/Engine/Graphics/RenderPass/UIPass.cpp @@ -61,8 +61,8 @@ void UIPass::endFrame() void UIPass::publishOutputs() { TextureCreateInfo depthBufferInfo = { - .width = viewport->getSizeX(), - .height = viewport->getSizeY(), + .width = viewport->getWidth(), + .height = viewport->getHeight(), .format = Gfx::SE_FORMAT_D32_SFLOAT, .usage = Gfx::SE_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, }; @@ -74,8 +74,8 @@ void UIPass::publishOutputs() resources->registerRenderPassOutput("UIPASS_DEPTH", depthAttachment); TextureCreateInfo colorBufferInfo = { - .width = viewport->getSizeX(), - .height = viewport->getSizeY(), + .width = viewport->getWidth(), + .height = viewport->getHeight(), .format = Gfx::SE_FORMAT_R16G16B16A16_SFLOAT, .usage = Gfx::SE_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, }; diff --git a/src/Engine/Graphics/RenderTarget.cpp b/src/Engine/Graphics/RenderTarget.cpp index 8e0a911..a63f38d 100644 --- a/src/Engine/Graphics/RenderTarget.cpp +++ b/src/Engine/Graphics/RenderTarget.cpp @@ -3,50 +3,6 @@ using namespace Seele; using namespace Seele::Gfx; - -RenderTargetLayout::RenderTargetLayout() - : inputAttachments() - , colorAttachments() - , depthAttachment() - , width(0) - , height(0) -{ -} - -RenderTargetLayout::RenderTargetLayout(PRenderTargetAttachment depthAttachment) - : inputAttachments() - , colorAttachments() - , depthAttachment(depthAttachment) - , width(depthAttachment->getTexture()->getSizeX()) - , height(depthAttachment->getTexture()->getSizeY()) -{ -} - -RenderTargetLayout::RenderTargetLayout(PRenderTargetAttachment colorAttachment, PRenderTargetAttachment depthAttachment) - : inputAttachments() - , depthAttachment(depthAttachment) - , width(depthAttachment->getTexture()->getSizeX()) - , height(depthAttachment->getTexture()->getSizeY()) -{ - colorAttachments.add(colorAttachment); -} -RenderTargetLayout::RenderTargetLayout(Array colorAttachments, PRenderTargetAttachment depthAttachment) - : inputAttachments() - , colorAttachments(colorAttachments) - , depthAttachment(depthAttachment) - , width(depthAttachment->getTexture()->getSizeX()) - , height(depthAttachment->getTexture()->getSizeY()) -{ -} -RenderTargetLayout::RenderTargetLayout(Array inputAttachments, Array colorAttachments, PRenderTargetAttachment depthAttachment) - : inputAttachments(inputAttachments) - , colorAttachments(colorAttachments) - , depthAttachment(depthAttachment) - , width(depthAttachment->getTexture()->getSizeX()) - , height(depthAttachment->getTexture()->getSizeY()) -{ -} - Window::Window(const WindowCreateInfo& createInfo) : windowState(createInfo) { @@ -57,8 +13,8 @@ Window::~Window() } Viewport::Viewport(PWindow owner, const ViewportCreateInfo& viewportInfo) - : sizeX(std::min(owner->getSizeX(), viewportInfo.dimensions.size.x)) - , sizeY(std::min(owner->getSizeY(), viewportInfo.dimensions.size.y)) + : sizeX(std::min(owner->getWidth(), viewportInfo.dimensions.size.x)) + , sizeY(std::min(owner->getHeight(), viewportInfo.dimensions.size.y)) , offsetX(viewportInfo.dimensions.offset.x) , offsetY(viewportInfo.dimensions.offset.y) , fieldOfView(viewportInfo.fieldOfView) @@ -81,3 +37,83 @@ Matrix4 Viewport::getProjectionMatrix() const return glm::ortho(0.0f, (float)sizeX, (float)sizeY, 0.0f); } } +RenderTargetAttachment::RenderTargetAttachment(PTexture2D texture, + SeAttachmentLoadOp loadOp = SE_ATTACHMENT_LOAD_OP_LOAD, + SeAttachmentStoreOp storeOp = SE_ATTACHMENT_STORE_OP_STORE, + SeAttachmentLoadOp stencilLoadOp = SE_ATTACHMENT_LOAD_OP_DONT_CARE, + SeAttachmentStoreOp stencilStoreOp = SE_ATTACHMENT_STORE_OP_DONT_CARE) + : clear() + , componentFlags(0) + , loadOp(loadOp) + , storeOp(storeOp) + , stencilLoadOp(stencilLoadOp) + , stencilStoreOp(stencilStoreOp) + , texture(texture) +{ +} + +RenderTargetAttachment::~RenderTargetAttachment() +{ +} + +SwapchainAttachment::SwapchainAttachment(PWindow owner, + SeAttachmentLoadOp loadOp = SE_ATTACHMENT_LOAD_OP_LOAD, + SeAttachmentStoreOp storeOp = SE_ATTACHMENT_STORE_OP_STORE, + SeAttachmentLoadOp stencilLoadOp = SE_ATTACHMENT_LOAD_OP_DONT_CARE, + SeAttachmentStoreOp stencilStoreOp = SE_ATTACHMENT_STORE_OP_DONT_CARE) + : RenderTargetAttachment(nullptr, loadOp, storeOp, stencilLoadOp, stencilStoreOp), owner(owner) +{ + clear.color.float32[0] = 0.0f; + clear.color.float32[1] = 0.0f; + clear.color.float32[2] = 0.0f; + clear.color.float32[3] = 1.0f; + componentFlags = SE_COLOR_COMPONENT_R_BIT | SE_COLOR_COMPONENT_G_BIT | SE_COLOR_COMPONENT_B_BIT | SE_COLOR_COMPONENT_A_BIT; +} + +SwapchainAttachment::~SwapchainAttachment() +{ +} + + +RenderTargetLayout::RenderTargetLayout() + : inputAttachments() + , colorAttachments() + , depthAttachment() + , width(0) + , height(0) +{ +} + +RenderTargetLayout::RenderTargetLayout(PRenderTargetAttachment depthAttachment) + : inputAttachments() + , colorAttachments() + , depthAttachment(depthAttachment) + , width(depthAttachment->getTexture()->getWidth()) + , height(depthAttachment->getTexture()->getHeight()) +{ +} + +RenderTargetLayout::RenderTargetLayout(PRenderTargetAttachment colorAttachment, PRenderTargetAttachment depthAttachment) + : inputAttachments() + , depthAttachment(depthAttachment) + , width(depthAttachment->getTexture()->getWidth()) + , height(depthAttachment->getTexture()->getHeight()) +{ + colorAttachments.add(colorAttachment); +} +RenderTargetLayout::RenderTargetLayout(Array colorAttachments, PRenderTargetAttachment depthAttachment) + : inputAttachments() + , colorAttachments(colorAttachments) + , depthAttachment(depthAttachment) + , width(depthAttachment->getTexture()->getWidth()) + , height(depthAttachment->getTexture()->getHeight()) +{ +} +RenderTargetLayout::RenderTargetLayout(Array inputAttachments, Array colorAttachments, PRenderTargetAttachment depthAttachment) + : inputAttachments(inputAttachments) + , colorAttachments(colorAttachments) + , depthAttachment(depthAttachment) + , width(depthAttachment->getTexture()->getWidth()) + , height(depthAttachment->getTexture()->getHeight()) +{ +} \ No newline at end of file diff --git a/src/Engine/Graphics/RenderTarget.h b/src/Engine/Graphics/RenderTarget.h index 299d588..f00ec4f 100644 --- a/src/Engine/Graphics/RenderTarget.h +++ b/src/Engine/Graphics/RenderTarget.h @@ -6,7 +6,6 @@ namespace Seele { namespace Gfx { - class Window { public: @@ -22,19 +21,19 @@ public: virtual void setScrollCallback(std::function callback) = 0; virtual void setFileCallback(std::function callback) = 0; virtual void setCloseCallback(std::function callback) = 0; - SeFormat getSwapchainFormat() const + constexpr SeFormat getSwapchainFormat() const { return windowState.pixelFormat; } - SeSampleCountFlags getNumSamples() const + constexpr SeSampleCountFlags getNumSamples() const { return windowState.numSamples; } - uint32 getSizeX() const + constexpr uint32 getWidth() const { return windowState.width; } - uint32 getSizeY() const + constexpr uint32 getHeight() const { return windowState.height; } @@ -52,8 +51,8 @@ public: virtual void resize(uint32 newX, uint32 newY) = 0; virtual void move(uint32 newOffsetX, uint32 newOffsetY) = 0; constexpr PWindow getOwner() const {return owner;} - constexpr uint32 getSizeX() const {return sizeX;} - constexpr uint32 getSizeY() const {return sizeY;} + constexpr uint32 getWidth() const {return sizeX;} + constexpr uint32 getHeight() const {return sizeY;} constexpr uint32 getOffsetX() const {return offsetX;} constexpr uint32 getOffsetY() const {return offsetY;} Matrix4 getProjectionMatrix() const; @@ -71,22 +70,11 @@ class RenderTargetAttachment { public: RenderTargetAttachment(PTexture2D texture, - SeAttachmentLoadOp loadOp = SE_ATTACHMENT_LOAD_OP_LOAD, - SeAttachmentStoreOp storeOp = SE_ATTACHMENT_STORE_OP_STORE, - SeAttachmentLoadOp stencilLoadOp = SE_ATTACHMENT_LOAD_OP_DONT_CARE, - SeAttachmentStoreOp stencilStoreOp = SE_ATTACHMENT_STORE_OP_DONT_CARE) - : clear() - , componentFlags(0) - , loadOp(loadOp) - , storeOp(storeOp) - , stencilLoadOp(stencilLoadOp) - , stencilStoreOp(stencilStoreOp) - , texture(texture) - { - } - virtual ~RenderTargetAttachment() - { - } + SeAttachmentLoadOp loadOp = SE_ATTACHMENT_LOAD_OP_LOAD, + SeAttachmentStoreOp storeOp = SE_ATTACHMENT_STORE_OP_STORE, + SeAttachmentLoadOp stencilLoadOp = SE_ATTACHMENT_LOAD_OP_DONT_CARE, + SeAttachmentStoreOp stencilStoreOp = SE_ATTACHMENT_STORE_OP_DONT_CARE); + virtual ~RenderTargetAttachment(); virtual PTexture2D getTexture() { return texture; @@ -99,13 +87,13 @@ public: { return texture->getNumSamples(); } - virtual uint32 getSizeX() const + virtual uint32 getWidth() const { - return texture->getSizeX(); + return texture->getWidth(); } - virtual uint32 getSizeY() const + virtual uint32 getHeight() const { - return texture->getSizeY(); + return texture->getHeight(); } inline SeAttachmentLoadOp getLoadOp() const { return loadOp; } inline SeAttachmentStoreOp getStoreOp() const { return storeOp; } @@ -126,18 +114,11 @@ class SwapchainAttachment : public RenderTargetAttachment { public: SwapchainAttachment(PWindow owner, - SeAttachmentLoadOp loadOp = SE_ATTACHMENT_LOAD_OP_LOAD, - SeAttachmentStoreOp storeOp = SE_ATTACHMENT_STORE_OP_STORE, - SeAttachmentLoadOp stencilLoadOp = SE_ATTACHMENT_LOAD_OP_DONT_CARE, - SeAttachmentStoreOp stencilStoreOp = SE_ATTACHMENT_STORE_OP_DONT_CARE) - : RenderTargetAttachment(nullptr, loadOp, storeOp, stencilLoadOp, stencilStoreOp), owner(owner) - { - clear.color.float32[0] = 0.0f; - clear.color.float32[1] = 0.0f; - clear.color.float32[2] = 0.0f; - clear.color.float32[3] = 1.0f; - componentFlags = SE_COLOR_COMPONENT_R_BIT | SE_COLOR_COMPONENT_G_BIT | SE_COLOR_COMPONENT_B_BIT | SE_COLOR_COMPONENT_A_BIT; - } + SeAttachmentLoadOp loadOp = SE_ATTACHMENT_LOAD_OP_LOAD, + SeAttachmentStoreOp storeOp = SE_ATTACHMENT_STORE_OP_STORE, + SeAttachmentLoadOp stencilLoadOp = SE_ATTACHMENT_LOAD_OP_DONT_CARE, + SeAttachmentStoreOp stencilStoreOp = SE_ATTACHMENT_STORE_OP_DONT_CARE); + virtual ~SwapchainAttachment(); virtual PTexture2D getTexture() override { return owner->getBackBuffer(); @@ -150,13 +131,13 @@ public: { return owner->getNumSamples(); } - virtual uint32 getSizeX() const + virtual uint32 getWidth() const { - return owner->getSizeX(); + return owner->getWidth(); } - virtual uint32 getSizeY() const + virtual uint32 getHeight() const { - return owner->getSizeY(); + return owner->getHeight(); } private: PWindow owner; diff --git a/src/Engine/Graphics/Resources.cpp b/src/Engine/Graphics/Resources.cpp index 9758ac7..8f9bb5b 100644 --- a/src/Engine/Graphics/Resources.cpp +++ b/src/Engine/Graphics/Resources.cpp @@ -30,51 +30,4 @@ void QueueOwnedResource::pipelineBarrier(SeAccessFlags srcAccess, SePipelineStag { // maybe add some checks executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage); -} - - -VertexDeclaration::VertexDeclaration() -{ -} -VertexDeclaration::~VertexDeclaration() -{ -} - -static std::mutex vertexDeclarationLock; -static Map vertexDeclarationCache; - -PVertexDeclaration VertexDeclaration::createDeclaration(PGraphics graphics, const Array& elementList) -{ - std::scoped_lock lock(vertexDeclarationLock); - uint32 key = CRC::Calculate(&elementList, sizeof(VertexElement) * elementList.size(), CRC::CRC_32()); - - auto found = vertexDeclarationCache[key]; - if(found == nullptr) - { - return found; - } - - PVertexDeclaration newDeclaration = graphics->createVertexDeclaration(elementList); - - vertexDeclarationCache[key] = newDeclaration; - return newDeclaration; -} - -RenderCommand::RenderCommand() -{ -} - -RenderCommand::~RenderCommand() -{ -} - -ComputeCommand::ComputeCommand() -{ - -} - -ComputeCommand::~ComputeCommand() -{ - -} - +} \ No newline at end of file diff --git a/src/Engine/Graphics/Resources.h b/src/Engine/Graphics/Resources.h index e952a35..5c992e7 100644 --- a/src/Engine/Graphics/Resources.h +++ b/src/Engine/Graphics/Resources.h @@ -22,14 +22,16 @@ DECLARE_REF(DescriptorSet) DECLARE_REF(Graphics) DECLARE_REF(VertexBuffer) DECLARE_REF(IndexBuffer) -class SamplerState +DECLARE_REF(GraphicsPipeline) +DECLARE_REF(ComputePipeline) +class Sampler { public: - virtual ~SamplerState() + virtual ~Sampler() { } }; -DEFINE_REF(SamplerState) +DEFINE_REF(Sampler) struct QueueFamilyMapping { @@ -80,72 +82,5 @@ protected: }; DEFINE_REF(QueueOwnedResource) -class VertexDeclaration -{ -public: - VertexDeclaration(); - virtual ~VertexDeclaration(); - - static PVertexDeclaration createDeclaration(PGraphics graphics, const Array& elementList); -private: -}; -DEFINE_REF(VertexDeclaration) -class GraphicsPipeline -{ -public: - GraphicsPipeline(OPipelineLayout layout) : layout(std::move(layout)) {} - virtual ~GraphicsPipeline(){} - PPipelineLayout getPipelineLayout() const { return layout; } -protected: - OPipelineLayout layout; -}; -DEFINE_REF(GraphicsPipeline) - -class ComputePipeline -{ -public: - ComputePipeline(OPipelineLayout layout) : layout(std::move(layout)) {} - virtual ~ComputePipeline(){} - PPipelineLayout getPipelineLayout() const { return layout; } -protected: - OPipelineLayout layout; -}; -DEFINE_REF(ComputePipeline) - -DECLARE_REF(Viewport) -class RenderCommand -{ -public: - RenderCommand(); - virtual ~RenderCommand(); - virtual bool isReady() = 0; - virtual void setViewport(Gfx::PViewport viewport) = 0; - virtual void bindPipeline(Gfx::PGraphicsPipeline pipeline) = 0; - virtual void bindDescriptor(Gfx::PDescriptorSet set) = 0; - virtual void bindDescriptor(const Array& sets) = 0; - virtual void bindVertexBuffer(const Array& buffer) = 0; - virtual void bindIndexBuffer(Gfx::PIndexBuffer indexBuffer) = 0; - virtual void pushConstants(Gfx::PPipelineLayout layout, Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size, const void* data) = 0; - virtual void draw(uint32 vertexCount, uint32 instanceCount, int32 firstVertex, uint32 firstInstance) = 0; - virtual void drawIndexed(uint32 indexCount, uint32 instanceCount, int32 firstIndex, uint32 vertexOffset, uint32 firstInstance) = 0; - virtual void dispatch(uint32 groupX, uint32 groupY, uint32 groupZ) = 0; - std::string name; -}; -DEFINE_REF(RenderCommand) -class ComputeCommand -{ -public: - ComputeCommand(); - virtual ~ComputeCommand(); - virtual bool isReady() = 0; - virtual void bindPipeline(Gfx::PComputePipeline pipeline) = 0; - virtual void bindDescriptor(Gfx::PDescriptorSet set) = 0; - virtual void bindDescriptor(const Array& sets) = 0; - virtual void pushConstants(Gfx::PPipelineLayout layout, Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size, const void* data) = 0; - virtual void dispatch(uint32 threadX, uint32 threadY, uint32 threadZ) = 0; - std::string name; -}; -DEFINE_REF(ComputeCommand) - } // namespace Gfx } // namespace Seele \ No newline at end of file diff --git a/src/Engine/Graphics/Shader.cpp b/src/Engine/Graphics/Shader.cpp index c217dca..fc592b9 100644 --- a/src/Engine/Graphics/Shader.cpp +++ b/src/Engine/Graphics/Shader.cpp @@ -140,6 +140,5 @@ void ShaderCompiler::createShaders(ShaderPermutation permutation) createInfo.entryPoint = "fragmentMain"; collection.fragmentShader = graphics->createFragmentShader(createInfo); } - collection.vertexDeclaration = graphics->createVertexDeclaration(Array()); shaders[perm] = std::move(collection); } \ No newline at end of file diff --git a/src/Engine/Graphics/Shader.h b/src/Engine/Graphics/Shader.h index 2adda51..76bd909 100644 --- a/src/Engine/Graphics/Shader.h +++ b/src/Engine/Graphics/Shader.h @@ -124,7 +124,6 @@ struct PermutationId }; struct ShaderCollection { - OVertexDeclaration vertexDeclaration; OVertexShader vertexShader; OTaskShader taskShader; OMeshShader meshShader; diff --git a/src/Engine/Graphics/StaticMeshVertexData.h b/src/Engine/Graphics/StaticMeshVertexData.h index 9729373..3a09111 100644 --- a/src/Engine/Graphics/StaticMeshVertexData.h +++ b/src/Engine/Graphics/StaticMeshVertexData.h @@ -1,5 +1,6 @@ #pragma once #include "Graphics/Initializer.h" +#include "Graphics/Command.h" #include "Math/Vector.h" #include "VertexData.h" diff --git a/src/Engine/Graphics/Texture.h b/src/Engine/Graphics/Texture.h index c1da3c6..5b1f187 100644 --- a/src/Engine/Graphics/Texture.h +++ b/src/Engine/Graphics/Texture.h @@ -5,7 +5,6 @@ namespace Seele { namespace Gfx { - // IMPORTANT!! // WHEN DERIVING FROM ANY Gfx:: BASE CLASSES WITH MULTIPLE INHERITANCE // ALWAYS PUT THE Gfx:: BASE CLASS FIRST @@ -19,17 +18,13 @@ public: virtual ~Texture(); virtual SeFormat getFormat() const = 0; - virtual uint32 getSizeX() const = 0; - virtual uint32 getSizeY() const = 0; - virtual uint32 getSizeZ() const = 0; + virtual uint32 getWidth() const = 0; + virtual uint32 getHeight() const = 0; + virtual uint32 getDepth() const = 0; virtual uint32 getNumFaces() const { return 1; } virtual SeSampleCountFlags getNumSamples() const = 0; virtual uint32 getMipLevels() const = 0; virtual void changeLayout(SeImageLayout newLayout) = 0; - virtual class Texture2D* getTexture2D() { return nullptr; } - virtual class Texture3D* getTexture3D() { return nullptr; } - virtual class TextureCube* getTextureCube() { return nullptr; } - virtual void* getNativeHandle() { return nullptr; } virtual void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array& buffer) = 0; protected: // Inherited via QueueOwnedResource @@ -46,13 +41,12 @@ public: virtual ~Texture2D(); virtual SeFormat getFormat() const = 0; - virtual uint32 getSizeX() const = 0; - virtual uint32 getSizeY() const = 0; - virtual uint32 getSizeZ() const = 0; + virtual uint32 getWidth() const = 0; + virtual uint32 getHeight() const = 0; + virtual uint32 getDepth() const = 0; virtual SeSampleCountFlags getNumSamples() const = 0; virtual uint32 getMipLevels() const = 0; virtual void changeLayout(SeImageLayout newLayout) = 0; - virtual class Texture2D* getTexture2D() { return this; } protected: //Inherited via QueueOwnedResource virtual void executeOwnershipBarrier(QueueType newOwner) = 0; @@ -68,13 +62,12 @@ public: virtual ~Texture3D(); virtual SeFormat getFormat() const = 0; - virtual uint32 getSizeX() const = 0; - virtual uint32 getSizeY() const = 0; - virtual uint32 getSizeZ() const = 0; + virtual uint32 getWidth() const = 0; + virtual uint32 getHeight() const = 0; + virtual uint32 getDepth() const = 0; virtual SeSampleCountFlags getNumSamples() const = 0; virtual uint32 getMipLevels() const = 0; virtual void changeLayout(SeImageLayout newLayout) = 0; - virtual class Texture3D* getTexture3D() { return this; } protected: //Inherited via QueueOwnedResource virtual void executeOwnershipBarrier(QueueType newOwner) = 0; @@ -90,14 +83,13 @@ public: virtual ~TextureCube(); virtual SeFormat getFormat() const = 0; - virtual uint32 getSizeX() const = 0; - virtual uint32 getSizeY() const = 0; - virtual uint32 getSizeZ() const = 0; + virtual uint32 getWidth() const = 0; + virtual uint32 getHeight() const = 0; + virtual uint32 getDepth() const = 0; virtual uint32 getNumFaces() const { return 6; } virtual SeSampleCountFlags getNumSamples() const = 0; virtual uint32 getMipLevels() const = 0; virtual void changeLayout(SeImageLayout newLayout) = 0; - virtual class TextureCube* getTextureCube() { return this; } protected: //Inherited via QueueOwnedResource virtual void executeOwnershipBarrier(QueueType newOwner) = 0; @@ -105,6 +97,5 @@ protected: SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0; }; DEFINE_REF(TextureCube) - } } \ No newline at end of file diff --git a/src/Engine/Graphics/Vulkan/Allocator.cpp b/src/Engine/Graphics/Vulkan/Allocator.cpp index 6a84289..fccde79 100644 --- a/src/Engine/Graphics/Vulkan/Allocator.cpp +++ b/src/Engine/Graphics/Vulkan/Allocator.cpp @@ -1,6 +1,7 @@ #include "Allocator.h" #include "Graphics.h" #include "Initializer.h" +#include "Resources.h" using namespace Seele::Vulkan; @@ -28,9 +29,9 @@ bool SubAllocation::isReadable() const return owner->isReadable(); } -void *SubAllocation::getMappedPointer() +void *SubAllocation::map() { - return (uint8 *)owner->getMappedPointer() + alignedOffset; + return (uint8 *)owner->map() + alignedOffset; } void SubAllocation::flushMemory() @@ -38,9 +39,9 @@ void SubAllocation::flushMemory() owner->flushMemory(); } -void SubAllocation::invalidateMemory() +void SubAllocation::invalidate() { - owner->invalidateMemory(); + owner->invalidate(); } Allocation::Allocation(PGraphics graphics, PAllocator allocator, VkDeviceSize size, uint8 memoryTypeIndex, @@ -49,23 +50,22 @@ Allocation::Allocation(PGraphics graphics, PAllocator allocator, VkDeviceSize si , allocator(allocator) , bytesAllocated(0) , bytesUsed(0) - , readable(properties & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) + , canMap((properties & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT), + , isMapped(false), , properties(properties) , memoryTypeIndex(memoryTypeIndex) { - VkMemoryAllocateInfo allocInfo = - init::MemoryAllocateInfo(); - allocInfo.allocationSize = size; - allocInfo.memoryTypeIndex = memoryTypeIndex; + VkMemoryAllocateInfo allocInfo = { + .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, + .pNext = dedicatedInfo, + .allocationSize = size, + .memoryTypeIndex = memoryTypeIndex, + }; isDedicated = dedicatedInfo != nullptr; - allocInfo.pNext = dedicatedInfo; - //std::cout << "New allocation" << std::endl; VK_CHECK(vkAllocateMemory(device, &allocInfo, nullptr, &allocatedMemory)); bytesAllocated = size; freeRanges[0] = size; - canMap = (properties & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT; - isMapped = false; } Allocation::~Allocation() @@ -97,24 +97,19 @@ OSubAllocation Allocation::getSuballocation(VkDeviceSize requestedSize, VkDevice alignedOffset /= alignment; alignedOffset *= alignment; VkDeviceSize allocatedSize = requestedSize + (alignedOffset - lower); - if (size == allocatedSize) - { - OSubAllocation alloc = new SubAllocation(this, requestedSize, lower, allocatedSize, alignedOffset); - activeAllocations.add(alloc); - freeRanges.erase(lower); - bytesUsed += allocatedSize; - return alloc; - } - else if (allocatedSize < size) + if (size <= allocatedSize) { VkDeviceSize newSize = size - allocatedSize; VkDeviceSize newLower = lower + allocatedSize; - OSubAllocation subAlloc = new SubAllocation(this, requestedSize, lower, allocatedSize, alignedOffset); - activeAllocations.add(subAlloc); + OSubAllocation alloc = new SubAllocation(this, requestedSize, lower, allocatedSize, alignedOffset); + activeAllocations.add(alloc); freeRanges.erase(lower); - freeRanges[newLower] = newSize; + if (newSize > 0) + { + freeRanges[newLower] = newSize; + } bytesUsed += allocatedSize; - return subAlloc; + return alloc; } } return nullptr; @@ -161,7 +156,7 @@ void Allocation::flushMemory() vkFlushMappedMemoryRanges(device, 1, &range); } -void Allocation::invalidateMemory() +void Allocation::invalidate() { VkMappedMemoryRange range = { .sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, @@ -232,7 +227,7 @@ OSubAllocation Allocator::allocate(const VkMemoryRequirements2 &memRequirements2 } // no suitable allocations found, allocate new block - OAllocation newAllocation = new Allocation(graphics, this, (requirements.size > MemoryBlockSize) ? requirements.size : (VkDeviceSize)MemoryBlockSize, memoryTypeIndex, properties, nullptr); + OAllocation newAllocation = new Allocation(graphics, this, (requirements.size > DEFAULT_ALLOCATION) ? requirements.size : DEFAULT_ALLOCATION, memoryTypeIndex, properties, nullptr); heaps[heapIndex].inUse += newAllocation->bytesAllocated; //std::cout << "Heap " << heapIndex << ": " << (float)heaps[heapIndex].inUse / heaps[heapIndex].maxSize << "%" << std::endl; heaps[heapIndex].allocations.add(std::move(newAllocation)); @@ -269,37 +264,37 @@ uint32 Allocator::findMemoryType(uint32 typeFilter, VkMemoryPropertyFlags proper throw std::runtime_error("error finding memory"); } -StagingBuffer::StagingBuffer(OSubAllocation allocation, VkBuffer buffer, VkDeviceSize size, VkBufferUsageFlags usage, uint8 readable) - : allocation(std::move(allocation)) +StagingBuffer::StagingBuffer(PGraphics graphics, OSubAllocation allocation, VkBuffer buffer, VkDeviceSize size) + : QueueOwnedResource(graphics->getFamilyMapping(), Gfx::QueueType::DEDICATED_TRANSFER) + , graphics(graphics) + , allocation(std::move(allocation)) , buffer(buffer) , size(size) - , usage(usage) - , readable(readable) { } StagingBuffer::~StagingBuffer() { - assert(allocation == nullptr); - // buffer went out of scope without being cleaned up + graphics->getDestructionManager()->queueBuffer( + graphics->getDedicatedTransferCommands()->getCommands(), buffer); } -void* StagingBuffer::getMappedPointer() +void* StagingBuffer::map() { - return allocation->getMappedPointer(); + return allocation->map(); } -void StagingBuffer::flushMappedMemory() +void StagingBuffer::flush() { allocation->flushMemory(); } -void StagingBuffer::invalidateMemory() +void StagingBuffer::invalidate() { - allocation->invalidateMemory(); + allocation->invalidate(); } -VkDeviceMemory StagingBuffer::getMemoryHandle() const +VkDeviceMemory StagingBuffer::getMemory() const { return allocation->getHandle(); } @@ -309,9 +304,14 @@ VkDeviceSize StagingBuffer::getOffset() const return allocation->getOffset(); } -uint64 StagingBuffer::getSize() const +void StagingBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) { - return size; + assert(false); +} +void StagingBuffer::executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, + Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) +{ + assert(false); } StagingManager::StagingManager(PGraphics graphics, PAllocator allocator) @@ -323,34 +323,23 @@ StagingManager::~StagingManager() { } -void StagingManager::clearPending() +OStagingBuffer StagingManager::create(uint64 size) { -} - -OStagingBuffer StagingManager::allocateStagingBuffer(uint64 size, VkBufferUsageFlags usage, bool readable) -{ - for (auto it = freeBuffers.begin(); it != freeBuffers.end(); ++it) - { - auto& freeBuffer = *it; - if (freeBuffer->getSize() == size && freeBuffer->isReadable() == readable && freeBuffer->getUsage() == usage) - { - //std::cout << "Reusing staging buffer" << std::endl; - activeBuffers.add(freeBuffer); - OStagingBuffer owner = std::move(freeBuffer); - freeBuffers.remove(it, false); - return std::move(owner); - } - } //std::cout << "Creating new stagingbuffer" << std::endl; - VkBuffer buffer; - VkBufferCreateInfo stagingBufferCreateInfo = init::BufferCreateInfo(usage, size); - stagingBufferCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; uint32 queueIndex = graphics->getFamilyMapping().getQueueTypeFamilyIndex(Gfx::QueueType::DEDICATED_TRANSFER); - stagingBufferCreateInfo.queueFamilyIndexCount = 1; - stagingBufferCreateInfo.pQueueFamilyIndices = &queueIndex; - VkDevice vulkanDevice = graphics->getDevice(); - - VK_CHECK(vkCreateBuffer(vulkanDevice, &stagingBufferCreateInfo, nullptr, &buffer)); + VkBufferCreateInfo stagingBufferCreateInfo = { + .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .size = size, + .usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT, + .sharingMode = VK_SHARING_MODE_EXCLUSIVE, + .queueFamilyIndexCount = 1, + .pQueueFamilyIndices = &queueIndex, + }; + + VkBuffer buffer; + VK_CHECK(vkCreateBuffer(graphics->getDevice(), &stagingBufferCreateInfo, nullptr, &buffer)); VkMemoryDedicatedRequirements dedicatedReqs = { .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS, @@ -365,31 +354,15 @@ OStagingBuffer StagingManager::allocateStagingBuffer(uint64 size, VkBufferUsageF .pNext = nullptr, .buffer = buffer, }; - vkGetBufferMemoryRequirements2(vulkanDevice, &bufferQuery, &memReqs); - - memReqs.memoryRequirements.alignment = - (16 > memReqs.memoryRequirements.alignment) ? 16 : memReqs.memoryRequirements.alignment; + vkGetBufferMemoryRequirements2(graphics->getDevice(), &bufferQuery, &memReqs); OStagingBuffer stagingBuffer = new StagingBuffer( - allocator->allocate(memReqs, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | (readable ? VK_MEMORY_PROPERTY_HOST_COHERENT_BIT : VK_MEMORY_PROPERTY_HOST_CACHED_BIT), buffer), + graphics, + allocator->allocate(memReqs, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT, buffer), buffer, - size, - usage, - readable + size ); - vkBindBufferMemory(graphics->getDevice(), buffer, stagingBuffer->getMemoryHandle(), stagingBuffer->getOffset()); - - activeBuffers.add(stagingBuffer); + vkBindBufferMemory(graphics->getDevice(), buffer, stagingBuffer->getMemory(), stagingBuffer->getOffset()); - return std::move(stagingBuffer); + return stagingBuffer; } - -void StagingManager::releaseStagingBuffer(OStagingBuffer buffer) -{ - if (buffer == nullptr) - { - return; - } - activeBuffers.remove(buffer); - freeBuffers.add(std::move(buffer)); -} \ No newline at end of file diff --git a/src/Engine/Graphics/Vulkan/Allocator.h b/src/Engine/Graphics/Vulkan/Allocator.h index 80b65d5..153b4d1 100644 --- a/src/Engine/Graphics/Vulkan/Allocator.h +++ b/src/Engine/Graphics/Vulkan/Allocator.h @@ -3,6 +3,7 @@ #include "Enums.h" #include "Containers/Map.h" #include "Containers/Array.h" +#include "Graphics/Resources.h" #include namespace Seele @@ -31,9 +32,9 @@ public: bool isReadable() const; - void *getMappedPointer(); + void *map(); void flushMemory(); - void invalidateMemory(); + void invalidate(); private: PAllocation owner; @@ -58,7 +59,7 @@ public: return allocatedMemory; } - constexpr void* getMappedPointer() + constexpr void* map() { if (!canMap) { @@ -72,13 +73,8 @@ public: return mappedPointer; } - constexpr bool isReadable() const - { - return readable; - } - void flushMemory(); - void invalidateMemory(); + void invalidate(); private: VkDevice device; @@ -92,7 +88,6 @@ private: uint8 isDedicated : 1; uint8 canMap : 1; uint8 isMapped : 1; - uint8 readable : 1; VkMemoryPropertyFlags properties; uint8 memoryTypeIndex; friend class Allocator; @@ -129,16 +124,13 @@ public: void free(PAllocation allocation); private: - enum - { - MemoryBlockSize = 16 * 1024 * 1024 // 16MB - }; + static constexpr VkDeviceSize DEFAULT_ALLOCATION = 16 * 1024 * 1024; // 16MB struct HeapInfo { VkDeviceSize maxSize = 0; VkDeviceSize inUse = 0; Array allocations; - HeapInfo() {} + HeapInfo() = default; HeapInfo(const HeapInfo& other) = delete; HeapInfo(HeapInfo&& other) = default; HeapInfo& operator=(const HeapInfo& other) = delete; @@ -150,38 +142,32 @@ private: VkPhysicalDeviceMemoryProperties memProperties; }; DEFINE_REF(Allocator) -DECLARE_REF(StagingManager) -class StagingBuffer +class StagingBuffer : public Gfx::QueueOwnedResource { public: - StagingBuffer(OSubAllocation allocation, VkBuffer buffer, VkDeviceSize size, VkBufferUsageFlags usage, uint8 readable); + StagingBuffer(PGraphics graphics, OSubAllocation allocation, VkBuffer buffer, VkDeviceSize size); ~StagingBuffer(); - void* getMappedPointer(); - void flushMappedMemory(); - void invalidateMemory(); + void* map(); + void flush(); + void invalidate(); constexpr VkBuffer getHandle() const { return buffer; } - VkDeviceMemory getMemoryHandle() const; + VkDeviceMemory getMemory() const; VkDeviceSize getOffset() const; - uint64 getSize() const; - constexpr bool isReadable() const + constexpr uint64 getSize() const { - return readable; + return size; } - - constexpr VkBufferUsageFlags getUsage() const - { - return usage; - } - private: + virtual void executeOwnershipBarrier(Gfx::QueueType newOwner) override; + virtual void executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, + Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) override; OSubAllocation allocation; + PGraphics graphics; VkBuffer buffer; VkDeviceSize size; - VkBufferUsageFlags usage; - uint8 readable; }; DEFINE_REF(StagingBuffer) @@ -190,15 +176,11 @@ class StagingManager public: StagingManager(PGraphics graphics, PAllocator allocator); ~StagingManager(); - OStagingBuffer allocateStagingBuffer(uint64 size, VkBufferUsageFlags usageFlags = VK_BUFFER_USAGE_TRANSFER_SRC_BIT, bool bCPURead = false); - void releaseStagingBuffer(OStagingBuffer buffer); - void clearPending(); + OStagingBuffer create(uint64 size); private: PGraphics graphics; PAllocator allocator; - Array freeBuffers; - Array activeBuffers; }; DEFINE_REF(StagingManager) } // namespace Vulkan diff --git a/src/Engine/Graphics/Vulkan/Buffer.cpp b/src/Engine/Graphics/Vulkan/Buffer.cpp index a0d95f3..e7f1d4f 100644 --- a/src/Engine/Graphics/Vulkan/Buffer.cpp +++ b/src/Engine/Graphics/Vulkan/Buffer.cpp @@ -32,23 +32,28 @@ Buffer::Buffer(PGraphics graphics, uint64 size, VkBufferUsageFlags usage, Gfx::Q } usage |= VK_BUFFER_USAGE_TRANSFER_DST_BIT; usage |= VK_BUFFER_USAGE_TRANSFER_SRC_BIT; - VkBufferCreateInfo info = - init::BufferCreateInfo( - usage, - size); - info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; uint32 queueFamilyIndex = graphics->getFamilyMapping().getQueueTypeFamilyIndex(queueType); - info.pQueueFamilyIndices = &queueFamilyIndex; - info.queueFamilyIndexCount = 1; - VkBufferMemoryRequirementsInfo2 bufferReqInfo; - bufferReqInfo.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2; - bufferReqInfo.pNext = nullptr; - VkMemoryDedicatedRequirements dedicatedRequirements; - dedicatedRequirements.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS; - dedicatedRequirements.pNext = nullptr; - VkMemoryRequirements2 memRequirements; - memRequirements.sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2; - memRequirements.pNext = &dedicatedRequirements; + VkBufferCreateInfo info = { + .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, + .pNext = nullptr, + .size = size, + .usage = usage, + .sharingMode = VK_SHARING_MODE_EXCLUSIVE, + .queueFamilyIndexCount = 1, + .pQueueFamilyIndices = &queueFamilyIndex, + }; + VkBufferMemoryRequirementsInfo2 bufferReqInfo = { + .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2, + .pNext = nullptr, + }; + VkMemoryDedicatedRequirements dedicatedRequirements = { + .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS, + .pNext = nullptr, + }; + VkMemoryRequirements2 memRequirements = { + .sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2, + .pNext = &dedicatedRequirements, + }; for (uint32 i = 0; i < numBuffers; ++i) { VK_CHECK(vkCreateBuffer(graphics->getDevice(), &info, nullptr, &buffers[i].buffer)); @@ -158,12 +163,12 @@ void Buffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlag vkCmdPipelineBarrier(commandBuffer->getHandle(), srcStage, dstStage, 0, 0, nullptr, numBuffers, dynamicBarriers, 0, nullptr); } -void * Buffer::lock(bool writeOnly) +void * Buffer::map(bool writeOnly) { - return lockRegion(0, size, writeOnly); + return mapRegion(0, size, writeOnly); } -void * Buffer::lockRegion(uint64 regionOffset, uint64 regionSize, bool writeOnly) +void * Buffer::mapRegion(uint64 regionOffset, uint64 regionSize, bool writeOnly) { void *data = nullptr; @@ -189,8 +194,8 @@ void * Buffer::lockRegion(uint64 regionOffset, uint64 regionSize, bool writeOnly if (writeOnly) { //requestOwnershipTransfer(Gfx::QueueType::DEDICATED_TRANSFER); - OStagingBuffer stagingBuffer = graphics->getStagingManager()->allocateStagingBuffer(regionSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT); - data = stagingBuffer->getMappedPointer(); + OStagingBuffer stagingBuffer = graphics->getStagingManager()->create(regionSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT); + data = stagingBuffer->map(); pending.stagingBuffer = std::move(stagingBuffer); } else @@ -212,7 +217,7 @@ void * Buffer::lockRegion(uint64 regionOffset, uint64 regionSize, bool writeOnly barrier.size = size; vkCmdPipelineBarrier(handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 1, &barrier, 0, nullptr); - OStagingBuffer stagingBuffer = graphics->getStagingManager()->allocateStagingBuffer(size, VK_BUFFER_USAGE_TRANSFER_DST_BIT, true); + OStagingBuffer stagingBuffer = graphics->getStagingManager()->create(size, VK_BUFFER_USAGE_TRANSFER_DST_BIT, true); VkBufferCopy regions; regions.size = size; @@ -223,9 +228,9 @@ void * Buffer::lockRegion(uint64 regionOffset, uint64 regionSize, bool writeOnly graphics->getQueueCommands(owner)->submitCommands(); vkQueueWaitIdle(graphics->getQueueCommands(owner)->getQueue()->getHandle()); - stagingBuffer->getMappedPointer(); // this maps the memory if not mapped already - stagingBuffer->flushMappedMemory(); - data = stagingBuffer->getMappedPointer(); + stagingBuffer->map(); // this maps the memory if not mapped already + stagingBuffer->flush(); + data = stagingBuffer->map(); pending.stagingBuffer = std::move(stagingBuffer); @@ -236,13 +241,13 @@ void * Buffer::lockRegion(uint64 regionOffset, uint64 regionSize, bool writeOnly return data; } -void Buffer::unlock() +void Buffer::unmap() { auto found = pendingBuffers.find(this); if (found != pendingBuffers.end()) { PendingBuffer& pending = found->second; - pending.stagingBuffer->flushMappedMemory(); + pending.stagingBuffer->flush(); if (pending.writeOnly) { PStagingBuffer stagingBuffer = pending.stagingBuffer; @@ -257,7 +262,7 @@ void Buffer::unlock() graphics->getQueueCommands(owner)->submitCommands(); } //requestOwnershipTransfer(pending.prevQueue); - graphics->getStagingManager()->releaseStagingBuffer(std::move(pending.stagingBuffer)); + graphics->getStagingManager()->release(std::move(pending.stagingBuffer)); pendingBuffers.erase(this); } } @@ -269,19 +274,19 @@ UniformBuffer::UniformBuffer(PGraphics graphics, const UniformBufferCreateInfo & { if(createInfo.dynamic) { - dedicatedStagingBuffer = graphics->getStagingManager()->allocateStagingBuffer(createInfo.sourceData.size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT); + dedicatedStagingBuffer = graphics->getStagingManager()->create(createInfo.sourceData.size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT); } if (createInfo.sourceData.data != nullptr) { - void *data = lock(); + void *data = map(); std::memcpy(data, createInfo.sourceData.data, createInfo.sourceData.size); - unlock(); + unmap(); } } UniformBuffer::~UniformBuffer() { - graphics->getStagingManager()->releaseStagingBuffer(std::move(dedicatedStagingBuffer)); + graphics->getStagingManager()->release(std::move(dedicatedStagingBuffer)); } bool UniformBuffer::updateContents(const DataSource &sourceData) @@ -291,25 +296,25 @@ bool UniformBuffer::updateContents(const DataSource &sourceData) // no update was performed, skip return false; } - void* data = lock(); + void* data = map(); std::memcpy(data, sourceData.data, sourceData.size); - unlock(); + unmap(); return true; } -void* UniformBuffer::lock(bool writeOnly) +void* UniformBuffer::map(bool writeOnly) { if(dedicatedStagingBuffer != nullptr) { - return dedicatedStagingBuffer->getMappedPointer(); + return dedicatedStagingBuffer->map(); } - return Vulkan::Buffer::lock(writeOnly); + return Vulkan::Buffer::map(writeOnly); } -void UniformBuffer::unlock() +void UniformBuffer::unmap() { if(dedicatedStagingBuffer != nullptr) { - dedicatedStagingBuffer->flushMappedMemory(); + dedicatedStagingBuffer->flush(); PCmdBuffer cmdBuffer = graphics->getQueueCommands(currentOwner)->getCommands(); VkCommandBuffer cmdHandle = cmdBuffer->getHandle(); @@ -321,7 +326,7 @@ void UniformBuffer::unlock() } else { - Vulkan::Buffer::unlock(); + Vulkan::Buffer::unmap(); } } @@ -358,19 +363,19 @@ ShaderBuffer::ShaderBuffer(PGraphics graphics, const ShaderBufferCreateInfo &sou { if(sourceData.dynamic) { - dedicatedStagingBuffer = graphics->getStagingManager()->allocateStagingBuffer(sourceData.sourceData.size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT); + dedicatedStagingBuffer = graphics->getStagingManager()->create(sourceData.sourceData.size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT); } if (sourceData.sourceData.data != nullptr) { - void *data = lock(); + void *data = map(); std::memcpy(data, sourceData.sourceData.data, sourceData.sourceData.size); - unlock(); + unmap(); } } ShaderBuffer::~ShaderBuffer() { - graphics->getStagingManager()->releaseStagingBuffer(std::move(dedicatedStagingBuffer)); + graphics->getStagingManager()->release(std::move(dedicatedStagingBuffer)); } bool ShaderBuffer::updateContents(const DataSource &sourceData) @@ -378,25 +383,25 @@ bool ShaderBuffer::updateContents(const DataSource &sourceData) assert(sourceData.size <= getSize()); Gfx::ShaderBuffer::updateContents(sourceData); //We always want to update, as the contents could be different on the GPU - void* data = lock(); + void* data = map(); std::memcpy(data, sourceData.data, sourceData.size); - unlock(); + unmap(); return true; } -void* ShaderBuffer::lock(bool writeOnly) +void* ShaderBuffer::map(bool writeOnly) { if(dedicatedStagingBuffer != nullptr) { - return dedicatedStagingBuffer->getMappedPointer(); + return dedicatedStagingBuffer->map(); } - return Vulkan::Buffer::lock(writeOnly); + return Vulkan::Buffer::map(writeOnly); } -void ShaderBuffer::unlock() +void ShaderBuffer::unmap() { if(dedicatedStagingBuffer != nullptr) { - dedicatedStagingBuffer->flushMappedMemory(); + dedicatedStagingBuffer->flush(); PCmdBuffer cmdBuffer = graphics->getQueueCommands(currentOwner)->getCommands(); VkCommandBuffer cmdHandle = cmdBuffer->getHandle(); @@ -408,7 +413,7 @@ void ShaderBuffer::unlock() } else { - Vulkan::Buffer::unlock(); + Vulkan::Buffer::unmap(); } } @@ -444,9 +449,9 @@ VertexBuffer::VertexBuffer(PGraphics graphics, const VertexBufferCreateInfo &sou { if (sourceData.sourceData.data != nullptr) { - void *data = lock(); + void *data = map(); std::memcpy(data, sourceData.sourceData.data, sourceData.sourceData.size); - unlock(); + unmap(); } } @@ -456,17 +461,17 @@ VertexBuffer::~VertexBuffer() void VertexBuffer::updateRegion(DataSource update) { - void* data = lockRegion(update.offset, update.size); + void* data = mapRegion(update.offset, update.size); std::memcpy(data, update.data, update.size); - unlock(); + unmap(); } void VertexBuffer::download(Array& buffer) { - void* data = lock(false); + void* data = map(false); buffer.resize(size); std::memcpy(buffer.data(), data, size); - unlock(); + unmap(); } void VertexBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner) @@ -501,9 +506,9 @@ IndexBuffer::IndexBuffer(PGraphics graphics, const IndexBufferCreateInfo &source { if (sourceData.sourceData.data != nullptr) { - void *data = lock(); + void *data = map(); std::memcpy(data, sourceData.sourceData.data, sourceData.sourceData.size); - unlock(); + unmap(); } } @@ -513,10 +518,10 @@ IndexBuffer::~IndexBuffer() void IndexBuffer::download(Array& buffer) { - void* data = lock(false); + void* data = map(false); buffer.resize(size); std::memcpy(buffer.data(), data, size); - unlock(); + unmap(); } void IndexBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner) diff --git a/src/Engine/Graphics/Vulkan/Buffer.h b/src/Engine/Graphics/Vulkan/Buffer.h index a701648..b65f8d2 100644 --- a/src/Engine/Graphics/Vulkan/Buffer.h +++ b/src/Engine/Graphics/Vulkan/Buffer.h @@ -25,9 +25,9 @@ public: { currentBuffer = (currentBuffer + 1) % numBuffers; } - virtual void *lock(bool writeOnly = true); - virtual void *lockRegion(uint64 regionOffset, uint64 regionSize, bool writeOnly = true); - virtual void unlock(); + virtual void *map(bool writeOnly = true); + virtual void *mapRegion(uint64 regionOffset, uint64 regionSize, bool writeOnly = true); + virtual void unmap(); protected: struct BufferAllocation @@ -61,8 +61,8 @@ public: virtual ~UniformBuffer(); virtual bool updateContents(const DataSource &sourceData); - virtual void* lock(bool writeOnly = true) override; - virtual void unlock() override; + virtual void* map(bool writeOnly = true) override; + virtual void unmap() override; protected: // Inherited via Vulkan::Buffer virtual VkAccessFlags getSourceAccessMask(); @@ -85,8 +85,8 @@ public: virtual ~ShaderBuffer(); virtual bool updateContents(const DataSource &sourceData); - virtual void* lock(bool writeOnly = true) override; - virtual void unlock() override; + virtual void* map(bool writeOnly = true) override; + virtual void unmap() override; protected: // Inherited via Vulkan::Buffer virtual VkAccessFlags getSourceAccessMask(); diff --git a/src/Engine/Graphics/Vulkan/CMakeLists.txt b/src/Engine/Graphics/Vulkan/CMakeLists.txt index 9e71b87..0b17a4e 100644 --- a/src/Engine/Graphics/Vulkan/CMakeLists.txt +++ b/src/Engine/Graphics/Vulkan/CMakeLists.txt @@ -4,10 +4,10 @@ target_sources(Engine Allocator.cpp Buffer.h Buffer.cpp - CommandBuffer.h - CommandBuffer.cpp - DescriptorSets.h - DescriptorSets.cpp + Command.h + Command.cpp + Descriptor.h + Descriptor.cpp Enums.h Enums.cpp Framebuffer.h @@ -38,7 +38,7 @@ target_sources(Engine FILES Allocator.h Buffer.h - CommandBuffer.h + Command.h DescriptorSets.h Enums.h Framebuffer.h diff --git a/src/Engine/Graphics/Vulkan/CommandBuffer.cpp b/src/Engine/Graphics/Vulkan/Command.cpp similarity index 71% rename from src/Engine/Graphics/Vulkan/CommandBuffer.cpp rename to src/Engine/Graphics/Vulkan/Command.cpp index 51646ad..3ee840b 100644 --- a/src/Engine/Graphics/Vulkan/CommandBuffer.cpp +++ b/src/Engine/Graphics/Vulkan/Command.cpp @@ -14,87 +14,87 @@ using namespace Seele; using namespace Seele::Vulkan; -CmdBuffer::CmdBuffer(PGraphics graphics, VkCommandPool cmdPool, PCommandBufferManager manager) +Command::Command(PGraphics graphics, VkCommandPool cmdPool, PCommandBufferManager manager) : graphics(graphics) , manager(manager) , owner(cmdPool) { - VkCommandBufferAllocateInfo allocInfo = - init::CommandBufferAllocateInfo(cmdPool, - VK_COMMAND_BUFFER_LEVEL_PRIMARY, - 1); - std::scoped_lock lock(handleLock); + VkCommandBufferAllocateInfo allocInfo = { + .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, + .pNext = nullptr, + .commandPool = owner, + .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY, + .commandBufferCount = 1, + }; VK_CHECK(vkAllocateCommandBuffers(graphics->getDevice(), &allocInfo, &handle)) fence = new Fence(graphics); - state = State::ReadyBegin; + state = State::Init; } -CmdBuffer::~CmdBuffer() +Command::~Command() { - std::scoped_lock lock(handleLock); vkFreeCommandBuffers(graphics->getDevice(), owner, 1, &handle); waitSemaphores.clear(); } -void CmdBuffer::begin() +void Command::begin() { - VkCommandBufferBeginInfo beginInfo = - init::CommandBufferBeginInfo(); - beginInfo.pInheritanceInfo = nullptr; - std::scoped_lock lock(handleLock); + VkCommandBufferBeginInfo beginInfo = { + .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, + .pNext = nullptr, + .flags = 0, + .pInheritanceInfo = nullptr, + }; VK_CHECK(vkBeginCommandBuffer(handle, &beginInfo)); - state = State::InsideBegin; + state = State::Begin; } -void CmdBuffer::end() +void Command::end() { - std::scoped_lock lock(handleLock); VK_CHECK(vkEndCommandBuffer(handle)); - state = State::Ended; + state = State::End; } -void CmdBuffer::beginRenderPass(PRenderPass renderPass, PFramebuffer framebuffer) +void Command::beginRenderPass(PRenderPass renderPass, PFramebuffer framebuffer) { - assert(state == State::InsideBegin); - std::scoped_lock lock(handleLock); + assert(state == State::Begin); - VkRenderPassBeginInfo beginInfo = - init::RenderPassBeginInfo(); - beginInfo.clearValueCount = (uint32)renderPass->getClearValueCount(); - beginInfo.pClearValues = renderPass->getClearValues(); - beginInfo.renderArea = renderPass->getRenderArea(); - beginInfo.renderPass = renderPass->getHandle(); - beginInfo.framebuffer = framebuffer->getHandle(); + VkRenderPassBeginInfo beginInfo = { + .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, + .pNext = nullptr, + .renderPass = renderPass->getHandle(), + .framebuffer = framebuffer->getHandle(), + .renderArea = renderPass->getRenderArea(), + .clearValueCount = (uint32)renderPass->getClearValueCount(), + .pClearValues = renderPass->getClearValues(), + }; vkCmdBeginRenderPass(handle, &beginInfo, renderPass->getSubpassContents()); - state = State::RenderPassActive; + state = State::RenderPass; } -void CmdBuffer::endRenderPass() +void Command::endRenderPass() { - std::scoped_lock lock(handleLock); vkCmdEndRenderPass(handle); - state = State::InsideBegin; + state = State::Begin; } -void CmdBuffer::executeCommands(const Array& commands) +void Command::executeCommands(const Array& commands) { - assert(state == State::RenderPassActive); + assert(state == State::RenderPass); if(commands.size() == 0) { //std::cout << "No commands provided" << std::endl; return; } - std::scoped_lock lock(handleLock); Array cmdBuffers(commands.size()); for (uint32 i = 0; i < commands.size(); ++i) { auto command = commands[i].cast(); command->end(); executingRenders.add(command); - for(auto descriptor : command->boundDescriptors) + for(auto& descriptor : command->boundDescriptors) { - descriptor->free(); boundDescriptors.add(descriptor); } cmdBuffers[i] = command->getHandle(); @@ -102,9 +102,8 @@ void CmdBuffer::executeCommands(const Array& commands) vkCmdExecuteCommands(handle, (uint32)cmdBuffers.size(), cmdBuffers.data()); } -void CmdBuffer::executeCommands(const Array& commands) +void Command::executeCommands(const Array& commands) { - std::scoped_lock lock(handleLock); if(commands.size() == 0) { return; @@ -115,9 +114,8 @@ void CmdBuffer::executeCommands(const Array& commands) auto command = commands[i].cast(); command->end(); executingComputes.add(command); - for(auto descriptor : command->boundDescriptors) + for(auto& descriptor : command->boundDescriptors) { - descriptor->free(); boundDescriptors.add(descriptor); } cmdBuffers[i] = command->getHandle(); @@ -125,65 +123,58 @@ void CmdBuffer::executeCommands(const Array& commands) vkCmdExecuteCommands(handle, (uint32)cmdBuffers.size(), cmdBuffers.data()); } -void CmdBuffer::addWaitSemaphore(VkPipelineStageFlags flags, PSemaphore semaphore) +void Command::waitForSemaphore(VkPipelineStageFlags flags, PSemaphore semaphore) { - std::scoped_lock lock(handleLock); waitSemaphores.add(semaphore); waitFlags.add(flags); } -void CmdBuffer::refreshFence() +void Command::checkFence() { - std::scoped_lock lock(handleLock); - if (state == State::Submitted) + assert(state == State::Submit || !fence->isSignaled()); + if (fence->isSignaled()) { - if (fence->isSignaled()) + vkResetCommandBuffer(handle, VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT); + fence->reset(); + for(auto& command : executingComputes) { - vkResetCommandBuffer(handle, VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT); - fence->reset(); - for(auto command : executingComputes) - { - command->reset(); - } - executingComputes.clear(); - for(auto command : executingRenders) - { - command->reset(); - } - executingRenders.clear(); - for(auto descriptor : boundDescriptors) - { - descriptor->unbind(); - } - boundDescriptors.clear(); - graphics->getDestructionManager()->notifyCmdComplete(this); - state = State::ReadyBegin; + command->reset(); } - } - else - { - assert(!fence->isSignaled()); + executingComputes.clear(); + for(auto& command : executingRenders) + { + command->reset(); + } + executingRenders.clear(); + for(auto& descriptor : boundDescriptors) + { + descriptor->unbind(); + } + boundDescriptors.clear(); + graphics->getDestructionManager()->notifyCmdComplete(this); + state = State::Init; } } -void CmdBuffer::waitForCommand(uint32 timeout) + +void Command::waitForCommand(uint32 timeout) { manager->submitCommands(); - if (state == State::InsideBegin) + if (state == State::Begin) { // is already done return; } fence->wait(timeout); - refreshFence(); + checkFence(); } -PFence CmdBuffer::getFence() +PFence Command::getFence() { return fence; } -PCommandBufferManager CmdBuffer::getManager() +PCommandBufferManager Command::getManager() { return manager; } @@ -192,10 +183,13 @@ RenderCommand::RenderCommand(PGraphics graphics, VkCommandPool cmdPool) : graphics(graphics) , owner(cmdPool) { - VkCommandBufferAllocateInfo allocInfo = - init::CommandBufferAllocateInfo(cmdPool, - VK_COMMAND_BUFFER_LEVEL_SECONDARY, - 1); + VkCommandBufferAllocateInfo allocInfo = { + .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, + .pNext = nullptr, + .commandPool = owner, + .level = VK_COMMAND_BUFFER_LEVEL_SECONDARY, + .commandBufferCount = 1, + }; VK_CHECK(vkAllocateCommandBuffers(graphics->getDevice(), &allocInfo, &handle)); } @@ -242,7 +236,7 @@ void RenderCommand::setViewport(Gfx::PViewport viewport) { assert(threadId == std::this_thread::get_id()); VkViewport vp = viewport.cast()->getHandle(); - VkRect2D scissors = init::Rect2D(viewport->getSizeX(), viewport->getSizeY(), viewport->getOffsetX(), viewport->getOffsetY()); + VkRect2D scissors = init::Rect2D(viewport->getWidth(), viewport->getHeight(), viewport->getOffsetX(), viewport->getOffsetY()); vkCmdSetViewport(handle, 0, 1, &vp); vkCmdSetScissor(handle, 0, 1, &scissors); } @@ -422,7 +416,7 @@ void ComputeCommand::dispatch(uint32 threadX, uint32 threadY, uint32 threadZ) vkCmdDispatch(handle, threadX, threadY, threadZ); } -CommandBufferManager::CommandBufferManager(PGraphics graphics, PQueue queue) +CommandPool::CommandPool(PGraphics graphics, PQueue queue) : graphics(graphics), queue(queue), queueFamilyIndex(queue->getFamilyIndex()) { VkCommandPoolCreateInfo info = @@ -432,28 +426,26 @@ CommandBufferManager::CommandBufferManager(PGraphics graphics, PQueue queue) VK_CHECK(vkCreateCommandPool(graphics->getDevice(), &info, nullptr, &commandPool)); - { - std::scoped_lock lock(allocatedBufferLock); - allocatedBuffers.add(new CmdBuffer(graphics, commandPool, this)); - } + allocatedBuffers.add(new Command(graphics, commandPool, this)); + - activeCmdBuffer = allocatedBuffers.back(); - activeCmdBuffer->begin(); + command = allocatedBuffers.back(); + command->begin(); } -CommandBufferManager::~CommandBufferManager() +CommandPool::~CommandPool() { vkDestroyCommandPool(graphics->getDevice(), commandPool, nullptr); graphics = nullptr; queue = nullptr; } -PCmdBuffer CommandBufferManager::getCommands() +PCmdBuffer CommandPool::getCommands() { - return activeCmdBuffer; + return command; } -PRenderCommand CommandBufferManager::createRenderCommand(PRenderPass renderPass, PFramebuffer framebuffer, const std::string& name) +PRenderCommand CommandPool::createRenderCommand(PRenderPass renderPass, PFramebuffer framebuffer, const std::string& name) { std::scoped_lock lck(allocatedRenderLock); for (uint32 i = 0; i < allocatedRenderCommands.size(); ++i) @@ -473,7 +465,7 @@ PRenderCommand CommandBufferManager::createRenderCommand(PRenderPass renderPass, return result; } -PComputeCommand CommandBufferManager::createComputeCommand(const std::string& name) +PComputeCommand CommandPool::createComputeCommand(const std::string& name) { std::scoped_lock lck(allocatedComputeLock); for (uint32 i = 0; i < allocatedComputeCommands.size(); ++i) @@ -482,53 +474,53 @@ PComputeCommand CommandBufferManager::createComputeCommand(const std::string& na if (cmdBuffer->isReady()) { cmdBuffer->name = name; - cmdBuffer->begin(activeCmdBuffer); + cmdBuffer->begin(command); return cmdBuffer; } } allocatedComputeCommands.add(new ComputeCommand(graphics, commandPool)); PComputeCommand result = allocatedComputeCommands.back(); result->name = name; - result->begin(activeCmdBuffer); + result->begin(command); return result; } -void CommandBufferManager::submitCommands(PSemaphore signalSemaphore) +void CommandPool::submitCommands(PSemaphore signalSemaphore) { - if (activeCmdBuffer->state == CmdBuffer::State::InsideBegin || activeCmdBuffer->state == CmdBuffer::State::RenderPassActive) + if (command->state == Command::State::Begin || command->state == Command::State::RenderPass) { - if (activeCmdBuffer->state == CmdBuffer::State::RenderPassActive) + if (command->state == Command::State::RenderPass) { std::cout << "End of renderpass forced" << std::endl; - activeCmdBuffer->endRenderPass(); + command->endRenderPass(); } - activeCmdBuffer->end(); + command->end(); if (signalSemaphore != nullptr) { - queue->submitCommandBuffer(activeCmdBuffer, signalSemaphore->getHandle()); + queue->submitCommandBuffer(command, signalSemaphore->getHandle()); } else { - queue->submitCommandBuffer(activeCmdBuffer); + queue->submitCommandBuffer(command); } } - std::scoped_lock lock(allocatedBufferLock); + std::scoped_lock map(allocatedBufferLock); for (uint32 i = 0; i < allocatedBuffers.size(); ++i) { PCmdBuffer cmdBuffer = allocatedBuffers[i]; - cmdBuffer->refreshFence(); - if (cmdBuffer->state == CmdBuffer::State::ReadyBegin) + cmdBuffer->checkFence(); + if (cmdBuffer->state == Command::State::Init) { - activeCmdBuffer = cmdBuffer; - activeCmdBuffer->begin(); + command = cmdBuffer; + command->begin(); return; } else { - assert(cmdBuffer->state == CmdBuffer::State::Submitted); + assert(cmdBuffer->state == Command::State::Submit); } } - allocatedBuffers.add(new CmdBuffer(graphics, commandPool, this)); - activeCmdBuffer = allocatedBuffers.back(); - activeCmdBuffer->begin(); + allocatedBuffers.add(new Command(graphics, commandPool, this)); + command = allocatedBuffers.back(); + command->begin(); } diff --git a/src/Engine/Graphics/Vulkan/CommandBuffer.h b/src/Engine/Graphics/Vulkan/Command.h similarity index 82% rename from src/Engine/Graphics/Vulkan/CommandBuffer.h rename to src/Engine/Graphics/Vulkan/Command.h index dbb263b..857c7b2 100644 --- a/src/Engine/Graphics/Vulkan/CommandBuffer.h +++ b/src/Engine/Graphics/Vulkan/Command.h @@ -13,13 +13,13 @@ DECLARE_REF(Framebuffer) DECLARE_REF(RenderCommand) DECLARE_REF(ComputeCommand) DECLARE_REF(DescriptorSet) -DECLARE_REF(CommandBufferManager) -class CmdBuffer +DECLARE_REF(CommandPool) +class Command { public: - CmdBuffer(PGraphics graphics, VkCommandPool cmdPool, PCommandBufferManager manager); - virtual ~CmdBuffer(); - inline VkCommandBuffer getHandle() + Command(PGraphics graphics, VkCommandPool cmdPool, PCommandBufferManager manager); + virtual ~Command(); + constexpr VkCommandBuffer getHandle() { return handle; } @@ -30,18 +30,18 @@ public: void endRenderPass(); void executeCommands(const Array& secondaryCommands); void executeCommands(const Array& secondaryCommands); - void addWaitSemaphore(VkPipelineStageFlags stages, PSemaphore waitSemaphore); - void refreshFence(); + void waitForSemaphore(VkPipelineStageFlags stages, PSemaphore waitSemaphore); + void checkFence(); void waitForCommand(uint32 timeToWait = 1000000u); PFence getFence(); PCommandBufferManager getManager(); enum State { - ReadyBegin, - InsideBegin, - RenderPassActive, - Ended, - Submitted, + Init, + Begin, + RenderPass, + End, + Submit, }; private: @@ -51,7 +51,6 @@ private: State state; VkViewport currentViewport; VkRect2D currentScissor; - std::mutex handleLock; VkCommandBuffer handle; VkCommandPool owner; Array waitSemaphores; @@ -60,10 +59,10 @@ private: Array executingComputes; Array boundDescriptors; friend class RenderCommand; - friend class CommandBufferManager; + friend class CommandPool; friend class Queue; }; -DEFINE_REF(CmdBuffer) +DEFINE_REF(Command) DECLARE_REF(GraphicsPipeline) DECLARE_REF(ComputePipeline) @@ -72,7 +71,7 @@ class RenderCommand : public Gfx::RenderCommand public: RenderCommand(PGraphics graphics, VkCommandPool cmdPool); virtual ~RenderCommand(); - inline VkCommandBuffer getHandle() + constexpr VkCommandBuffer getHandle() { return handle; } @@ -100,7 +99,7 @@ private: std::thread::id threadId; VkCommandBuffer handle; VkCommandPool owner; - friend class CmdBuffer; + friend class Command; }; DEFINE_REF(RenderCommand) @@ -132,22 +131,22 @@ private: std::thread::id threadId; VkCommandBuffer handle; VkCommandPool owner; - friend class CmdBuffer; + friend class Command; }; DEFINE_REF(ComputeCommand) -class CommandBufferManager +class CommandPool { public: - CommandBufferManager(PGraphics graphics, PQueue queue); - virtual ~CommandBufferManager(); - inline PQueue getQueue() const + CommandPool(PGraphics graphics, PQueue queue); + virtual ~CommandPool(); + constexpr PQueue getQueue() const { return queue; } - PCmdBuffer getCommands(); + PCommand getCommands(); PRenderCommand createRenderCommand(PRenderPass renderPass, PFramebuffer framebuffer, const std::string& name); PComputeCommand createComputeCommand(const std::string& name); - VkCommandPool getPoolHandle() const + constexpr VkCommandPool getHandle() const { return commandPool; } @@ -158,14 +157,11 @@ private: VkCommandPool commandPool; PQueue queue; uint32 queueFamilyIndex; - PCmdBuffer activeCmdBuffer; - std::mutex allocatedBufferLock; + PCommand command; Array allocatedBuffers; - std::mutex allocatedRenderLock; - std::mutex allocatedComputeLock; Array allocatedRenderCommands; Array allocatedComputeCommands; }; -DEFINE_REF(CommandBufferManager) +DEFINE_REF(CommandPool) } // namespace Vulkan } // namespace Seele \ No newline at end of file diff --git a/src/Engine/Graphics/Vulkan/DescriptorSets.cpp b/src/Engine/Graphics/Vulkan/Descriptor.cpp similarity index 98% rename from src/Engine/Graphics/Vulkan/DescriptorSets.cpp rename to src/Engine/Graphics/Vulkan/Descriptor.cpp index 0553d6e..a0ac50f 100644 --- a/src/Engine/Graphics/Vulkan/DescriptorSets.cpp +++ b/src/Engine/Graphics/Vulkan/Descriptor.cpp @@ -153,8 +153,8 @@ void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PShaderBuffer shaderBuff void DescriptorSet::updateSampler(uint32_t binding, Gfx::PSamplerState samplerState) { - PSamplerState vulkanSampler = samplerState.cast(); - SamplerState* cachedSampler = reinterpret_cast(cachedData[binding]); + PSamplerState vulkanSampler = samplerState.cast(); + Sampler* cachedSampler = reinterpret_cast(cachedData[binding]); if(vulkanSampler.getHandle() == cachedSampler) { return; @@ -188,7 +188,7 @@ void DescriptorSet::updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx:: cast(vulkanTexture->getLayout())); if (samplerState != nullptr) { - PSamplerState vulkanSampler = samplerState.cast(); + PSamplerState vulkanSampler = samplerState.cast(); imageInfo.sampler = vulkanSampler->sampler; } imageInfos.add(imageInfo); diff --git a/src/Engine/Graphics/Vulkan/DescriptorSets.h b/src/Engine/Graphics/Vulkan/Descriptor.h similarity index 99% rename from src/Engine/Graphics/Vulkan/DescriptorSets.h rename to src/Engine/Graphics/Vulkan/Descriptor.h index f2b0b58..0c1c153 100644 --- a/src/Engine/Graphics/Vulkan/DescriptorSets.h +++ b/src/Engine/Graphics/Vulkan/Descriptor.h @@ -120,7 +120,7 @@ private: bool currentlyBound; bool currentlyInUse; friend class DescriptorAllocator; - friend class CmdBuffer; + friend class Command; friend class RenderCommand; friend class ComputeCommand; }; diff --git a/src/Engine/Graphics/Vulkan/Framebuffer.cpp b/src/Engine/Graphics/Vulkan/Framebuffer.cpp index a7d83c9..d2e77d5 100644 --- a/src/Engine/Graphics/Vulkan/Framebuffer.cpp +++ b/src/Engine/Graphics/Vulkan/Framebuffer.cpp @@ -23,24 +23,24 @@ Framebuffer::Framebuffer(PGraphics graphics, PRenderPass renderPass, Gfx::PRende PTexture2D vkInputAttachment = inputAttachment->getTexture().cast(); attachments.add(vkInputAttachment->getView()); description.inputAttachments[description.numInputAttachments++] = vkInputAttachment->getView(); - sizeX = std::max(sizeX, vkInputAttachment->getSizeX()); - sizeY = std::max(sizeY, vkInputAttachment->getSizeY()); + sizeX = std::max(sizeX, vkInputAttachment->getWidth()); + sizeY = std::max(sizeY, vkInputAttachment->getHeight()); } for (auto colorAttachment : layout->colorAttachments) { PTexture2D vkColorAttachment = colorAttachment->getTexture().cast(); attachments.add(vkColorAttachment->getView()); description.colorAttachments[description.numColorAttachments++] = vkColorAttachment->getView(); - sizeX = std::max(sizeX, vkColorAttachment->getSizeX()); - sizeY = std::max(sizeY, vkColorAttachment->getSizeY()); + sizeX = std::max(sizeX, vkColorAttachment->getWidth()); + sizeY = std::max(sizeY, vkColorAttachment->getHeight()); } if (layout->depthAttachment != nullptr) { PTexture2D vkDepthAttachment = layout->depthAttachment->getTexture().cast(); attachments.add(vkDepthAttachment->getView()); description.depthAttachment = vkDepthAttachment->getView(); - sizeX = std::max(sizeX, vkDepthAttachment->getSizeX()); - sizeY = std::max(sizeY, vkDepthAttachment->getSizeY()); + sizeX = std::max(sizeX, vkDepthAttachment->getWidth()); + sizeY = std::max(sizeY, vkDepthAttachment->getHeight()); } VkFramebufferCreateInfo createInfo = init::FramebufferCreateInfo( diff --git a/src/Engine/Graphics/Vulkan/Graphics.cpp b/src/Engine/Graphics/Vulkan/Graphics.cpp index e20420a..bc3a460 100644 --- a/src/Engine/Graphics/Vulkan/Graphics.cpp +++ b/src/Engine/Graphics/Vulkan/Graphics.cpp @@ -4,7 +4,7 @@ #include "Buffer.h" #include "Graphics/Enums.h" #include "PipelineCache.h" -#include "CommandBuffer.h" +#include "Command.h" #include "Initializer.h" #include "RenderTarget.h" #include "RenderPass.h" @@ -241,77 +241,11 @@ Gfx::OPipelineLayout Graphics::createPipelineLayout(Gfx::PPipelineLayout baseLay return new PipelineLayout(this, baseLayout); } -void Graphics::copyTexture(Gfx::PTexture srcTexture, Gfx::PTexture dstTexture) -{ - Texture2D* src = (Texture2D*)srcTexture->getTexture2D(); - Texture2D* dst = (Texture2D*)dstTexture->getTexture2D(); - TextureHandle* srcHandle = (TextureHandle*)src->getNativeHandle(); - TextureHandle* dstHandle = (TextureHandle*)dst->getNativeHandle(); - Gfx::SeImageLayout srcLayout = srcHandle->getLayout(); - Gfx::SeImageLayout dstLayout = dstHandle->getLayout(); - Gfx::QueueType dstOwner = dstHandle->currentOwner; - src->changeLayout(Gfx::SE_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); - dst->changeLayout(Gfx::SE_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); - dstTexture->transferOwnership(srcHandle->currentOwner); - PCmdBuffer cmdBuffer = getQueueCommands(srcHandle->currentOwner)->getCommands(); - if(srcHandle->getAspect() != dstHandle->getAspect()) - { - /*VkMemoryRequirements imageRequirements; - vkGetImageMemoryRequirements(handle, srcHandle->getImage(), &imageRequirements); - PShaderBuffer tempBuffer = createShaderBuffer(); - VkBufferImageCopy bufferImageCopy; - bufferImageCopy.bufferOffset = 0; - bufferImageCopy.bufferRowLength = srcTexture->getSizeX(); - bufferImageCopy.bufferImageHeight = srcTexture->getSizeY(); - bufferImageCopy.imageExtent.width = srcTexture->getSizeX(); - bufferImageCopy.imageExtent.height = srcTexture->getSizeY(); - bufferImageCopy.imageExtent.depth = 1; - bufferImageCopy.imageOffset.x = 0; - bufferImageCopy.imageOffset.y = 0; - bufferImageCopy.imageOffset.z = 0; - bufferImageCopy.imageSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; - bufferImageCopy.imageSubresource.baseArrayLayer = 0; - bufferImageCopy.imageSubresource.layerCount = 1; - bufferImageCopy.imageSubresource.mipLevel = 0; - - vkCmdCopyImageToBuffer(cmdBuffer->getHandle(), srcHandle->getImage(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, tempBufferAllocation->getHandle(), 1, &bufferImageCopy); - - bufferImageCopy.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - - vkCmdCopyBufferToImage(cmdBuffer->getHandle(), tempBufferAllocation->getHandle(), dstHandle->getImage(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &bufferImageCopy); - delete tempBufferAllocation;*/ - throw new std::logic_error("Not yet implemented!"); - } - else if (src->getSizeX() != dst->getSizeX() - || src->getSizeY() != dst->getSizeY()) - { - throw new std::logic_error("Not yet implemented!"); - } - else - { - VkImageCopy copy; - std::memset(©, 0, sizeof(VkImageCopy)); - copy.extent.width = srcTexture->getSizeX(); - copy.extent.height = srcTexture->getSizeY(); - copy.extent.depth = 1; - copy.srcSubresource.aspectMask = srcHandle->getAspect(); - copy.srcSubresource.layerCount = 1; - copy.dstSubresource.aspectMask = dstHandle->getAspect(); - copy.dstSubresource.layerCount = 1; - vkCmdCopyImage(cmdBuffer->getHandle(), - srcHandle->getImage(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - dstHandle->getImage(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - 1, ©); - src->changeLayout(srcLayout); - dst->changeLayout(dstLayout); - dstTexture->transferOwnership(dstOwner); - } -} - void Graphics::vkCmdDrawMeshTasksEXT(VkCommandBuffer handle, uint32 groupX, uint32 groupY, uint32 groupZ) { cmdDrawMeshTasks(handle, groupX, groupY, groupZ); } + PCommandBufferManager Graphics::getQueueCommands(Gfx::QueueType queueType) { switch (queueType) @@ -332,7 +266,7 @@ PCommandBufferManager Graphics::getGraphicsCommands() { if(graphicsCommands == nullptr) { - graphicsCommands = new CommandBufferManager(this, graphicsQueue); + graphicsCommands = new CommandPool(this, graphicsQueue); } return graphicsCommands; } @@ -340,7 +274,7 @@ PCommandBufferManager Graphics::getComputeCommands() { if(computeCommands == nullptr) { - computeCommands = new CommandBufferManager(this, computeQueue); + computeCommands = new CommandPool(this, computeQueue); } return computeCommands; } @@ -348,7 +282,7 @@ PCommandBufferManager Graphics::getTransferCommands() { if(transferCommands == nullptr) { - transferCommands = new CommandBufferManager(this, transferQueue); + transferCommands = new CommandPool(this, transferQueue); } return transferCommands; } @@ -356,7 +290,7 @@ PCommandBufferManager Graphics::getDedicatedTransferCommands() { if(dedicatedTransferCommands == nullptr) { - dedicatedTransferCommands = new CommandBufferManager(this, dedicatedTransferQueue != nullptr ? dedicatedTransferQueue : transferQueue); + dedicatedTransferCommands = new CommandPool(this, dedicatedTransferQueue != nullptr ? dedicatedTransferQueue : transferQueue); } return dedicatedTransferCommands; } diff --git a/src/Engine/Graphics/Vulkan/Graphics.h b/src/Engine/Graphics/Vulkan/Graphics.h index ce925ae..68d1cfb 100644 --- a/src/Engine/Graphics/Vulkan/Graphics.h +++ b/src/Engine/Graphics/Vulkan/Graphics.h @@ -9,15 +9,9 @@ namespace Vulkan DECLARE_REF(Allocator) DECLARE_REF(StagingManager) DECLARE_REF(DestructionManager) -DECLARE_REF(CommandBufferManager) +DECLARE_REF(CommandPool) DECLARE_REF(Queue) -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: @@ -60,7 +54,6 @@ public: virtual Gfx::PRenderCommand createRenderCommand(const std::string& name) override; virtual Gfx::PComputeCommand createComputeCommand(const std::string& name) override; - virtual Gfx::OVertexDeclaration createVertexDeclaration(const Array& element) override; virtual Gfx::OVertexShader createVertexShader(const ShaderCreateInfo& createInfo) override; virtual Gfx::OFragmentShader createFragmentShader(const ShaderCreateInfo& createInfo) override; virtual Gfx::OComputeShader createComputeShader(const ShaderCreateInfo& createInfo) override; @@ -69,7 +62,7 @@ public: virtual Gfx::PGraphicsPipeline createGraphicsPipeline(Gfx::LegacyPipelineCreateInfo createInfo) override; virtual Gfx::PGraphicsPipeline createGraphicsPipeline(Gfx::MeshPipelineCreateInfo createInfo) override; virtual Gfx::PComputePipeline createComputePipeline(Gfx::ComputePipelineCreateInfo createInfo) override; - virtual Gfx::OSamplerState createSamplerState(const SamplerCreateInfo& createInfo) override; + virtual Gfx::OSampler createSamplerState(const SamplerCreateInfo& createInfo) override; virtual Gfx::ODescriptorLayout createDescriptorLayout(const std::string& name = "") override; virtual Gfx::OPipelineLayout createPipelineLayout(Gfx::PPipelineLayout baseLayout = nullptr) override; @@ -93,9 +86,6 @@ protected: OQueue transferQueue; OQueue dedicatedTransferQueue; OPipelineCache pipelineCache; - std::mutex renderPassLock; - PRenderPass activeRenderPass; - PFramebuffer activeFramebuffer; thread_local static OCommandBufferManager graphicsCommands; thread_local static OCommandBufferManager computeCommands; thread_local static OCommandBufferManager transferCommands; @@ -103,7 +93,6 @@ protected: VkPhysicalDeviceProperties props; VkPhysicalDeviceFeatures features; VkDebugReportCallbackEXT callback; - std::mutex viewportLock; Array viewports; std::mutex allocatedFrameBufferLock; Map allocatedFramebuffers; diff --git a/src/Engine/Graphics/Vulkan/Queue.cpp b/src/Engine/Graphics/Vulkan/Queue.cpp index 690e566..6b9b7f8 100644 --- a/src/Engine/Graphics/Vulkan/Queue.cpp +++ b/src/Engine/Graphics/Vulkan/Queue.cpp @@ -22,7 +22,7 @@ Queue::~Queue() void Queue::submitCommandBuffer(PCmdBuffer cmdBuffer, uint32 numSignalSemaphores, VkSemaphore *signalSemaphores) { std::scoped_lock lck(queueLock); - assert(cmdBuffer->state == CmdBuffer::State::Ended); + assert(cmdBuffer->state == Command::State::End); PFence fence = cmdBuffer->fence; assert(!fence->isSignaled()); @@ -48,7 +48,7 @@ void Queue::submitCommandBuffer(PCmdBuffer cmdBuffer, uint32 numSignalSemaphores submitInfo.pWaitDstStageMask = cmdBuffer->waitFlags.data(); } VK_CHECK(vkQueueSubmit(queue, 1, &submitInfo, fence->getHandle())); - cmdBuffer->state = CmdBuffer::State::Submitted; + cmdBuffer->state = Command::State::Submit; cmdBuffer->waitFlags.clear(); cmdBuffer->waitSemaphores.clear(); @@ -57,7 +57,7 @@ void Queue::submitCommandBuffer(PCmdBuffer cmdBuffer, uint32 numSignalSemaphores fence->wait(200 * 1000ull); } - cmdBuffer->refreshFence(); + cmdBuffer->checkFence(); graphics->getStagingManager()->clearPending(); } \ No newline at end of file diff --git a/src/Engine/Graphics/Vulkan/Queue.h b/src/Engine/Graphics/Vulkan/Queue.h index 50a100f..77eaab1 100644 --- a/src/Engine/Graphics/Vulkan/Queue.h +++ b/src/Engine/Graphics/Vulkan/Queue.h @@ -5,7 +5,7 @@ namespace Seele { namespace Vulkan { -DECLARE_REF(CmdBuffer) +DECLARE_REF(Command) DECLARE_REF(Graphics) class Queue { diff --git a/src/Engine/Graphics/Vulkan/RenderPass.cpp b/src/Engine/Graphics/Vulkan/RenderPass.cpp index cdd8aa1..fba98d7 100644 --- a/src/Engine/Graphics/Vulkan/RenderPass.cpp +++ b/src/Engine/Graphics/Vulkan/RenderPass.cpp @@ -12,8 +12,8 @@ RenderPass::RenderPass(PGraphics graphics, Gfx::ORenderTargetLayout _layout, Gfx : Gfx::RenderPass(std::move(_layout)) , graphics(graphics) { - renderArea.extent.width = viewport->getSizeX(); - renderArea.extent.height = viewport->getSizeY(); + renderArea.extent.width = viewport->getWidth(); + renderArea.extent.height = viewport->getHeight(); renderArea.offset.x = viewport->getOffsetX(); renderArea.offset.y = viewport->getOffsetY(); subpassContents = VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS; diff --git a/src/Engine/Graphics/Vulkan/RenderTarget.cpp b/src/Engine/Graphics/Vulkan/RenderTarget.cpp index a609b8e..e338b5f 100644 --- a/src/Engine/Graphics/Vulkan/RenderTarget.cpp +++ b/src/Engine/Graphics/Vulkan/RenderTarget.cpp @@ -195,7 +195,7 @@ void Window::advanceBackBuffer() &range); backBufferImages[currentImageIndex]->changeLayout(Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); - graphics->getGraphicsCommands()->getCommands()->addWaitSemaphore(VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, imageAcquiredSemaphore); + graphics->getGraphicsCommands()->getCommands()->waitForSemaphore(VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, imageAcquiredSemaphore); graphics->getGraphicsCommands()->submitCommands(); } @@ -264,9 +264,10 @@ void Window::createSwapchain() throw new std::logic_error("Trying to buffer more than the maximum number of frames"); } - VkExtent2D extent; - extent.width = getSizeX(); - extent.height = getSizeY(); + VkExtent2D extent = { + .width = getWidth(), + .height = getHeight(), + }; VkSwapchainCreateInfoKHR swapchainInfo = init::SwapchainCreateInfo( surface, @@ -289,8 +290,8 @@ void Window::createSwapchain() TextureCreateInfo backBufferCreateInfo; - backBufferCreateInfo.width = getSizeX(); - backBufferCreateInfo.height = getSizeY(); + backBufferCreateInfo.width = getWidth(); + backBufferCreateInfo.height = getHeight(); backBufferCreateInfo.usage = Gfx::SE_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; backBufferCreateInfo.sourceData.owner = Gfx::QueueType::GRAPHICS; backBufferCreateInfo.format = cast(surfaceFormat.format); @@ -304,8 +305,8 @@ void Window::createSwapchain() std::memset(&clearColor, 0, sizeof(VkClearColorValue)); backBufferImages[i]->changeLayout(Gfx::SE_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); VkImageSubresourceRange range = init::ImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT); - PCmdBuffer cmdBuffer = graphics->getGraphicsCommands()->getCommands(); - vkCmdClearColorImage(cmdBuffer->getHandle(), backBufferImages[i]->getHandle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearColor, 1, &range); + PCommand command = graphics->getGraphicsCommands()->getCommands(); + vkCmdClearColorImage(command->getHandle(), backBufferImages[i]->getHandle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearColor, 1, &range); backBufferImages[i]->changeLayout(Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); } graphics->getGraphicsCommands()->submitCommands(); diff --git a/src/Engine/Graphics/Vulkan/RenderTarget.h b/src/Engine/Graphics/Vulkan/RenderTarget.h index 190efcc..e4c4b84 100644 --- a/src/Engine/Graphics/Vulkan/RenderTarget.h +++ b/src/Engine/Graphics/Vulkan/RenderTarget.h @@ -8,7 +8,6 @@ namespace Seele { namespace Vulkan { - class Window : public Gfx::Window { public: diff --git a/src/Engine/Graphics/Vulkan/Resources.cpp b/src/Engine/Graphics/Vulkan/Resources.cpp index 3266f08..4ac302c 100644 --- a/src/Engine/Graphics/Vulkan/Resources.cpp +++ b/src/Engine/Graphics/Vulkan/Resources.cpp @@ -9,13 +9,26 @@ using namespace Seele::Vulkan; Semaphore::Semaphore(PGraphics graphics) : graphics(graphics) { - VkSemaphoreCreateInfo info = - init::SemaphoreCreateInfo(); + VkSemaphoreCreateInfo info = { + .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + }; VK_CHECK(vkCreateSemaphore(graphics->getDevice(), &info, nullptr, &handle)); } Semaphore::~Semaphore() { + uint64 value = 0; + VkSemaphoreWaitInfo waitInfo = { + .sType = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO, + .pNext = nullptr, + .flags = 0, + .semaphoreCount = 1, + .pSemaphores = &handle, + .pValues = &value, + }; + VK_CHECK(vkWaitSemaphores(graphics->getDevice(), &waitInfo, 10000)); vkDestroySemaphore(graphics->getDevice(), handle, nullptr); } @@ -23,8 +36,11 @@ Fence::Fence(PGraphics graphics) : graphics(graphics) , signaled(false) { - VkFenceCreateInfo info = - init::FenceCreateInfo(0); + VkFenceCreateInfo info = { + .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, + .pNext = nullptr, + .flags = 0 + }; VK_CHECK(vkCreateFence(graphics->getDevice(), &info, nullptr, &fence)); } @@ -40,17 +56,15 @@ bool Fence::isSignaled() return true; } VkResult res = vkGetFenceStatus(graphics->getDevice(), fence); - switch (res) + if (res == VK_SUCCESS) { - case VK_SUCCESS: signaled = true; - return signaled; - case VK_NOT_READY: - break; - default: - break; + return true; + } + if (res == VK_NOT_READY) + { + return false; } - return false; } void Fence::reset() @@ -65,17 +79,14 @@ void Fence::reset() void Fence::wait(uint32 timeout) { VkFence fences[] = {fence}; - VkResult r = vkWaitForFences(graphics->getDevice(), 1, fences, true, timeout * 1000ull); - switch (r) + VkResult res = vkWaitForFences(graphics->getDevice(), 1, fences, true, timeout); + if (res == VK_SUCCESS) { - case VK_SUCCESS: signaled = true; - break; - case VK_TIMEOUT: - break; - default: - VK_CHECK(r); - break; + } + if (res != VK_NOT_READY) + { + VK_CHECK(res); } } @@ -88,22 +99,27 @@ DestructionManager::~DestructionManager() { } -void DestructionManager::queueBuffer(PCmdBuffer cmd, VkBuffer buffer) +void DestructionManager::queueBuffer(PCommand cmd, VkBuffer buffer) { buffers[cmd].add(buffer); } -void DestructionManager::queueImage(PCmdBuffer cmd, VkImage image) +void DestructionManager::queueImage(PCommand cmd, VkImage image) { images[cmd].add(image); } -void DestructionManager::queueImageView(PCmdBuffer cmd, VkImageView image) +void DestructionManager::queueImageView(PCommand cmd, VkImageView image) { views[cmd].add(image); } -void DestructionManager::notifyCmdComplete(PCmdBuffer cmdbuffer) +void DestructionManager::queueSemaphore(PCommand cmd, VkSemaphore sem) +{ + sems[cmd].add(sem); +} + +void DestructionManager::notifyCmdComplete(PCommand cmdbuffer) { for(auto buf : buffers[cmdbuffer]) { @@ -117,16 +133,12 @@ void DestructionManager::notifyCmdComplete(PCmdBuffer cmdbuffer) { vkDestroyImage(graphics->getDevice(), img, nullptr); } + for (auto sem : sems[cmdbuffer]) + { + vkDestroySemaphore(graphics->getDevice(), sem, nullptr); + } buffers[cmdbuffer].clear(); images[cmdbuffer].clear(); views[cmdbuffer].clear(); -} - -VertexDeclaration::VertexDeclaration(const Array& elementList) - : elementList(elementList) -{ -} - -VertexDeclaration::~VertexDeclaration() -{ + sems[cmdbuffer].clear(); } diff --git a/src/Engine/Graphics/Vulkan/Resources.h b/src/Engine/Graphics/Vulkan/Resources.h index 8a5bcef..b9d1e05 100644 --- a/src/Engine/Graphics/Vulkan/Resources.h +++ b/src/Engine/Graphics/Vulkan/Resources.h @@ -1,6 +1,5 @@ #pragma once #include -#include #include "Containers/List.h" #include "Graphics/Resources.h" #include "Allocator.h" @@ -9,10 +8,9 @@ namespace Seele { namespace Vulkan { - DECLARE_REF(DescriptorAllocator) -DECLARE_REF(CommandBufferManager) -DECLARE_REF(CmdBuffer) +DECLARE_REF(CommandPool) +DECLARE_REF(Command) DECLARE_REF(Graphics) DECLARE_REF(SubAllocation) class Semaphore @@ -20,11 +18,10 @@ class Semaphore public: Semaphore(PGraphics graphics); virtual ~Semaphore(); - inline VkSemaphore getHandle() const + constexpr VkSemaphore getHandle() const { return handle; } - private: VkSemaphore handle; PGraphics graphics; @@ -38,7 +35,7 @@ public: ~Fence(); bool isSignaled(); void reset(); - inline VkFence getHandle() const + constexpr VkFence getHandle() const { return fence; } @@ -60,35 +57,26 @@ class DestructionManager public: DestructionManager(PGraphics graphics); ~DestructionManager(); - void queueBuffer(PCmdBuffer cmd, VkBuffer buffer); - void queueImage(PCmdBuffer cmd, VkImage image); - void queueImageView(PCmdBuffer cmd, VkImageView view); - void notifyCmdComplete(PCmdBuffer cmdbuffer); + void queueBuffer(PCommand cmd, VkBuffer buffer); + void queueImage(PCommand cmd, VkImage image); + void queueImageView(PCommand cmd, VkImageView view); + void queueSemaphore(PCommand cmd, VkSemaphore sem); + void notifyCmdComplete(PCommand cmdbuffer); private: PGraphics graphics; - Map> buffers; - Map> images; - Map> views; + Map> buffers; + Map> images; + Map> views; + Map> sems; }; DEFINE_REF(DestructionManager) -class VertexDeclaration : public Gfx::VertexDeclaration -{ -public: - Array elementList; - - VertexDeclaration(const Array& elementList); - virtual ~VertexDeclaration(); -private: -}; -DEFINE_REF(VertexDeclaration) - -class SamplerState : public Gfx::SamplerState +class Sampler : public Gfx::Sampler { public: VkSampler sampler; }; -DEFINE_REF(SamplerState) +DEFINE_REF(Sampler) } // namespace Vulkan } // namespace Seele diff --git a/src/Engine/Graphics/Vulkan/Texture.cpp b/src/Engine/Graphics/Vulkan/Texture.cpp index 5548a23..f4f5632 100644 --- a/src/Engine/Graphics/Vulkan/Texture.cpp +++ b/src/Engine/Graphics/Vulkan/Texture.cpp @@ -110,10 +110,10 @@ TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType, if(sourceData.size > 0) { changeLayout(Gfx::SE_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); - OStagingBuffer staging = graphics->getStagingManager()->allocateStagingBuffer(sourceData.size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT); - void* data = staging->getMappedPointer(); + OStagingBuffer staging = graphics->getStagingManager()->create(sourceData.size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT); + void* data = staging->map(); std::memcpy(data, sourceData.data, sourceData.size); - staging->flushMappedMemory(); + staging->flush(); PCommandBufferManager cmdBufferManager = graphics->getQueueCommands(currentOwner); VkBufferImageCopy region; @@ -134,7 +134,7 @@ TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType, // When loading a texture from a file, we will almost always use it as a texture map for fragment shaders changeLayout(Gfx::SE_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); - graphics->getStagingManager()->releaseStagingBuffer(std::move(staging)); + graphics->getStagingManager()->release(std::move(staging)); } else if(usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) { @@ -209,7 +209,7 @@ void TextureHandle::download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Ar { uint64 imageSize = sizeX * sizeY * sizeZ * Gfx::getFormatInfo(format).blockSize; - OStagingBuffer stagingbuffer = graphics->getStagingManager()->allocateStagingBuffer(imageSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT, true); + OStagingBuffer stagingbuffer = graphics->getStagingManager()->create(imageSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT, true); auto prevlayout = layout; changeLayout(Gfx::SE_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); PCmdBuffer cmdBuffer = graphics->getQueueCommands(currentOwner)->getCommands(); @@ -230,9 +230,9 @@ void TextureHandle::download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Ar vkCmdCopyImageToBuffer(cmdBuffer->getHandle(), image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, stagingbuffer->getHandle(), 1, ®ion); changeLayout(prevlayout); buffer.resize(stagingbuffer->getSize()); - void* data = stagingbuffer->getMappedPointer(); + void* data = stagingbuffer->map(); std::memcpy(buffer.data(), data, buffer.size()); - graphics->getStagingManager()->releaseStagingBuffer(std::move(stagingbuffer)); + graphics->getStagingManager()->release(std::move(stagingbuffer)); } void TextureHandle::executeOwnershipBarrier(Gfx::QueueType newOwner) diff --git a/src/Engine/Graphics/Vulkan/Texture.h b/src/Engine/Graphics/Vulkan/Texture.h index bd3ba1e..f5a86d8 100644 --- a/src/Engine/Graphics/Vulkan/Texture.h +++ b/src/Engine/Graphics/Vulkan/Texture.h @@ -97,15 +97,15 @@ 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 + virtual uint32 getWidth() const override { return textureHandle->sizeX; } - virtual uint32 getSizeY() const override + virtual uint32 getHeight() const override { return textureHandle->sizeY; } - virtual uint32 getSizeZ() const override + virtual uint32 getDepth() const override { return textureHandle->sizeZ; } @@ -153,15 +153,15 @@ 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 + virtual uint32 getWidth() const override { return textureHandle->sizeX; } - virtual uint32 getSizeY() const override + virtual uint32 getHeight() const override { return textureHandle->sizeY; } - virtual uint32 getSizeZ() const override + virtual uint32 getDepth() const override { return textureHandle->sizeZ; } @@ -209,15 +209,15 @@ 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 + virtual uint32 getWidth() const override { return textureHandle->sizeX; } - virtual uint32 getSizeY() const override + virtual uint32 getHeight() const override { return textureHandle->sizeY; } - virtual uint32 getSizeZ() const override + virtual uint32 getDepth() const override { return textureHandle->sizeZ; }