More refactoring
This commit is contained in:
@@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -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<uint8> 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<uint8> 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<uint8> contents;
|
||||
uint32 numElements;
|
||||
uint32 stride;
|
||||
};
|
||||
DEFINE_REF(ShaderBuffer)
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
#include "Command.h"
|
||||
|
||||
using namespace Seele;
|
||||
using namespace Seele::Gfx;
|
||||
|
||||
|
||||
RenderCommand::RenderCommand()
|
||||
{
|
||||
}
|
||||
|
||||
RenderCommand::~RenderCommand()
|
||||
{
|
||||
}
|
||||
|
||||
ComputeCommand::ComputeCommand()
|
||||
{
|
||||
}
|
||||
|
||||
ComputeCommand::~ComputeCommand()
|
||||
{
|
||||
}
|
||||
@@ -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<Gfx::PDescriptorSet>& sets) = 0;
|
||||
virtual void bindVertexBuffer(const Array<PVertexBuffer>& 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<Gfx::PDescriptorSet>& 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)
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
@@ -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<PTexture> 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<DescriptorBinding>& getBindings() const { return descriptorBindings; }
|
||||
constexpr const Array<DescriptorBinding>& getBindings() const { return descriptorBindings; }
|
||||
constexpr uint32 getSetIndex() const { return setIndex; }
|
||||
constexpr void setSetIndex(uint32 _setIndex) { setIndex = _setIndex; }
|
||||
|
||||
protected:
|
||||
Array<DescriptorBinding> 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);
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
using namespace Seele;
|
||||
using namespace Seele::Gfx;
|
||||
|
||||
|
||||
FormatCompatibilityInfo Gfx::getFormatInfo(SeFormat format)
|
||||
{
|
||||
switch(format) {
|
||||
|
||||
@@ -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<VertexElement>& 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;
|
||||
|
||||
@@ -57,14 +57,13 @@ struct DataSource
|
||||
struct TextureCreateInfo
|
||||
{
|
||||
DataSource sourceData = DataSource();
|
||||
Gfx::SeFormat format = Gfx::SE_FORMAT_R32G32B32A32_SFLOAT;
|
||||
uint32 width = 1;
|
||||
uint32 height = 1;
|
||||
uint32 depth = 1;
|
||||
bool bArray = false;
|
||||
uint32 arrayLayers = 1;
|
||||
uint32 mipLevels = 1;
|
||||
uint32 arrayLayers = 1;
|
||||
uint32 samples = 1;
|
||||
Gfx::SeFormat format = Gfx::SE_FORMAT_R32G32B32A32_SFLOAT;
|
||||
Gfx::SeImageUsageFlagBits usage = Gfx::SE_IMAGE_USAGE_SAMPLED_BIT;
|
||||
};
|
||||
struct SamplerCreateInfo
|
||||
@@ -106,7 +105,6 @@ struct UniformBufferCreateInfo
|
||||
struct ShaderBufferCreateInfo
|
||||
{
|
||||
DataSource sourceData = DataSource();
|
||||
uint32 stride;
|
||||
uint8 dynamic = 0;
|
||||
};
|
||||
struct ShaderCreateInfo
|
||||
@@ -124,47 +122,37 @@ namespace Gfx
|
||||
struct SePushConstantRange
|
||||
{
|
||||
SeShaderStageFlags stageFlags;
|
||||
uint32_t offset;
|
||||
uint32_t size;
|
||||
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<VertexElement>);
|
||||
struct RasterizationState
|
||||
{
|
||||
uint8 depthClampEnable : 1 = 0;
|
||||
uint8 rasterizerDiscardEnable : 1 = 0;
|
||||
uint8 depthBiasEnable : 1 = 0;
|
||||
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;
|
||||
SePolygonMode polygonMode;
|
||||
SeCullModeFlags cullMode;
|
||||
SeFrontFace frontFace;
|
||||
};
|
||||
struct MultisampleState
|
||||
{
|
||||
uint32 samples = 1;
|
||||
SeSampleCountFlags samples = 1;
|
||||
uint32 sampleShadingEnable = 0;
|
||||
float minSampleShading = 1;
|
||||
uint8 sampleShadingEnable : 1 = 0;
|
||||
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;
|
||||
@@ -172,12 +160,9 @@ struct DepthStencilState
|
||||
};
|
||||
struct ColorBlendState
|
||||
{
|
||||
uint8 logicOpEnable : 1;
|
||||
SeLogicOp logicOp = Gfx::SE_LOGIC_OP_OR;
|
||||
uint32 attachmentCount;
|
||||
struct BlendAttachment
|
||||
{
|
||||
uint8 blendEnable = 0;
|
||||
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;
|
||||
@@ -185,10 +170,14 @@ struct ColorBlendState
|
||||
SeBlendFactor dstAlphaBlendFactor = Gfx::SE_BLEND_FACTOR_SRC_ALPHA;
|
||||
SeBlendOp alphaBlendOp = Gfx::SE_BLEND_OP_ADD;
|
||||
SeColorComponentFlags colorWriteMask = 0;
|
||||
} blendAttachments[16];
|
||||
float blendConstants[4];
|
||||
};
|
||||
uint32 logicOpEnable;
|
||||
SeLogicOp logicOp = Gfx::SE_LOGIC_OP_OR;
|
||||
uint32 attachmentCount;
|
||||
StaticArray<BlendAttachment, 16> blendAttachments;
|
||||
StaticArray<float, 4> blendConstants;
|
||||
};
|
||||
DECLARE_REF(VertexDeclaration)
|
||||
|
||||
DECLARE_REF(VertexShader)
|
||||
DECLARE_REF(TaskShader)
|
||||
DECLARE_REF(MeshShader)
|
||||
@@ -198,7 +187,6 @@ DECLARE_REF(RenderPass)
|
||||
DECLARE_REF(PipelineLayout)
|
||||
struct LegacyPipelineCreateInfo
|
||||
{
|
||||
PVertexDeclaration vertexDeclaration;
|
||||
SePrimitiveTopology topology;
|
||||
PVertexShader vertexShader;
|
||||
PFragmentShader fragmentShader;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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<const char*, const char*>&)
|
||||
|
||||
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));
|
||||
|
||||
@@ -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<float>(viewport->getSizeX()), static_cast<float>(viewport->getSizeY())),
|
||||
.screenDimensions = Vector2(static_cast<float>(viewport->getWidth()), static_cast<float>(viewport->getHeight())),
|
||||
};
|
||||
DataSource uniformUpdate = {
|
||||
.size = sizeof(ViewParameter),
|
||||
|
||||
@@ -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<float>(viewport->getSizeX()), static_cast<float>(viewport->getSizeY()));
|
||||
viewParams.screenDimensions = Vector2(static_cast<float>(viewport->getWidth()), static_cast<float>(viewport->getHeight()));
|
||||
uniformUpdate.size = sizeof(ViewParameter);
|
||||
uniformUpdate.data = (uint8*)&viewParams;
|
||||
viewParamsBuffer->updateContents(uniformUpdate);
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
@@ -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<PRenderTargetAttachment> colorAttachments, PRenderTargetAttachment depthAttachment)
|
||||
: inputAttachments()
|
||||
, colorAttachments(colorAttachments)
|
||||
, depthAttachment(depthAttachment)
|
||||
, width(depthAttachment->getTexture()->getSizeX())
|
||||
, height(depthAttachment->getTexture()->getSizeY())
|
||||
{
|
||||
}
|
||||
RenderTargetLayout::RenderTargetLayout(Array<PRenderTargetAttachment> inputAttachments, Array<PRenderTargetAttachment> 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<PRenderTargetAttachment> colorAttachments, PRenderTargetAttachment depthAttachment)
|
||||
: inputAttachments()
|
||||
, colorAttachments(colorAttachments)
|
||||
, depthAttachment(depthAttachment)
|
||||
, width(depthAttachment->getTexture()->getWidth())
|
||||
, height(depthAttachment->getTexture()->getHeight())
|
||||
{
|
||||
}
|
||||
RenderTargetLayout::RenderTargetLayout(Array<PRenderTargetAttachment> inputAttachments, Array<PRenderTargetAttachment> colorAttachments, PRenderTargetAttachment depthAttachment)
|
||||
: inputAttachments(inputAttachments)
|
||||
, colorAttachments(colorAttachments)
|
||||
, depthAttachment(depthAttachment)
|
||||
, width(depthAttachment->getTexture()->getWidth())
|
||||
, height(depthAttachment->getTexture()->getHeight())
|
||||
{
|
||||
}
|
||||
@@ -6,7 +6,6 @@ namespace Seele
|
||||
{
|
||||
namespace Gfx
|
||||
{
|
||||
|
||||
class Window
|
||||
{
|
||||
public:
|
||||
@@ -22,19 +21,19 @@ public:
|
||||
virtual void setScrollCallback(std::function<void(double, double)> callback) = 0;
|
||||
virtual void setFileCallback(std::function<void(int, const char**)> callback) = 0;
|
||||
virtual void setCloseCallback(std::function<void()> 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;
|
||||
@@ -74,19 +73,8 @@ public:
|
||||
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()
|
||||
{
|
||||
}
|
||||
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; }
|
||||
@@ -129,15 +117,8 @@ public:
|
||||
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;
|
||||
}
|
||||
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;
|
||||
|
||||
@@ -31,50 +31,3 @@ 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<uint32, PVertexDeclaration> vertexDeclarationCache;
|
||||
|
||||
PVertexDeclaration VertexDeclaration::createDeclaration(PGraphics graphics, const Array<VertexElement>& 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()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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<VertexElement>& 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<Gfx::PDescriptorSet>& sets) = 0;
|
||||
virtual void bindVertexBuffer(const Array<PVertexBuffer>& 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<Gfx::PDescriptorSet>& 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
|
||||
@@ -140,6 +140,5 @@ void ShaderCompiler::createShaders(ShaderPermutation permutation)
|
||||
createInfo.entryPoint = "fragmentMain";
|
||||
collection.fragmentShader = graphics->createFragmentShader(createInfo);
|
||||
}
|
||||
collection.vertexDeclaration = graphics->createVertexDeclaration(Array<VertexElement>());
|
||||
shaders[perm] = std::move(collection);
|
||||
}
|
||||
@@ -124,7 +124,6 @@ struct PermutationId
|
||||
};
|
||||
struct ShaderCollection
|
||||
{
|
||||
OVertexDeclaration vertexDeclaration;
|
||||
OVertexShader vertexShader;
|
||||
OTaskShader taskShader;
|
||||
OMeshShader meshShader;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
#include "Graphics/Initializer.h"
|
||||
#include "Graphics/Command.h"
|
||||
#include "Math/Vector.h"
|
||||
#include "VertexData.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<uint8>& 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)
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
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();
|
||||
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,
|
||||
};
|
||||
|
||||
VK_CHECK(vkCreateBuffer(vulkanDevice, &stagingBufferCreateInfo, nullptr, &buffer));
|
||||
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());
|
||||
vkBindBufferMemory(graphics->getDevice(), buffer, stagingBuffer->getMemory(), stagingBuffer->getOffset());
|
||||
|
||||
activeBuffers.add(stagingBuffer);
|
||||
|
||||
return std::move(stagingBuffer);
|
||||
}
|
||||
|
||||
void StagingManager::releaseStagingBuffer(OStagingBuffer buffer)
|
||||
{
|
||||
if (buffer == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
activeBuffers.remove(buffer);
|
||||
freeBuffers.add(std::move(buffer));
|
||||
return stagingBuffer;
|
||||
}
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "Enums.h"
|
||||
#include "Containers/Map.h"
|
||||
#include "Containers/Array.h"
|
||||
#include "Graphics/Resources.h"
|
||||
#include <mutex>
|
||||
|
||||
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<OAllocation> 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<OStagingBuffer> freeBuffers;
|
||||
Array<PStagingBuffer> activeBuffers;
|
||||
};
|
||||
DEFINE_REF(StagingManager)
|
||||
} // namespace Vulkan
|
||||
|
||||
@@ -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<uint8>& 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<uint8>& 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)
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
+88
-96
@@ -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<Gfx::PRenderCommand>& commands)
|
||||
void Command::executeCommands(const Array<Gfx::PRenderCommand>& 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<VkCommandBuffer> cmdBuffers(commands.size());
|
||||
for (uint32 i = 0; i < commands.size(); ++i)
|
||||
{
|
||||
auto command = commands[i].cast<RenderCommand>();
|
||||
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<Gfx::PRenderCommand>& commands)
|
||||
vkCmdExecuteCommands(handle, (uint32)cmdBuffers.size(), cmdBuffers.data());
|
||||
}
|
||||
|
||||
void CmdBuffer::executeCommands(const Array<Gfx::PComputeCommand>& commands)
|
||||
void Command::executeCommands(const Array<Gfx::PComputeCommand>& commands)
|
||||
{
|
||||
std::scoped_lock lock(handleLock);
|
||||
if(commands.size() == 0)
|
||||
{
|
||||
return;
|
||||
@@ -115,9 +114,8 @@ void CmdBuffer::executeCommands(const Array<Gfx::PComputeCommand>& commands)
|
||||
auto command = commands[i].cast<ComputeCommand>();
|
||||
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<Gfx::PComputeCommand>& 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())
|
||||
{
|
||||
vkResetCommandBuffer(handle, VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT);
|
||||
fence->reset();
|
||||
for(auto command : executingComputes)
|
||||
for(auto& command : executingComputes)
|
||||
{
|
||||
command->reset();
|
||||
}
|
||||
executingComputes.clear();
|
||||
for(auto command : executingRenders)
|
||||
for(auto& command : executingRenders)
|
||||
{
|
||||
command->reset();
|
||||
}
|
||||
executingRenders.clear();
|
||||
for(auto descriptor : boundDescriptors)
|
||||
for(auto& descriptor : boundDescriptors)
|
||||
{
|
||||
descriptor->unbind();
|
||||
}
|
||||
boundDescriptors.clear();
|
||||
graphics->getDestructionManager()->notifyCmdComplete(this);
|
||||
state = State::ReadyBegin;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(!fence->isSignaled());
|
||||
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<Viewport>()->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();
|
||||
}
|
||||
@@ -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<Gfx::PRenderCommand>& secondaryCommands);
|
||||
void executeCommands(const Array<Gfx::PComputeCommand>& 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<PSemaphore> waitSemaphores;
|
||||
@@ -60,10 +59,10 @@ private:
|
||||
Array<PComputeCommand> executingComputes;
|
||||
Array<PDescriptorSet> 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<OCmdBuffer> allocatedBuffers;
|
||||
std::mutex allocatedRenderLock;
|
||||
std::mutex allocatedComputeLock;
|
||||
Array<ORenderCommand> allocatedRenderCommands;
|
||||
Array<OComputeCommand> allocatedComputeCommands;
|
||||
};
|
||||
DEFINE_REF(CommandBufferManager)
|
||||
DEFINE_REF(CommandPool)
|
||||
} // namespace Vulkan
|
||||
} // namespace Seele
|
||||
+3
-3
@@ -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>();
|
||||
SamplerState* cachedSampler = reinterpret_cast<SamplerState*>(cachedData[binding]);
|
||||
PSamplerState vulkanSampler = samplerState.cast<Sampler>();
|
||||
Sampler* cachedSampler = reinterpret_cast<Sampler*>(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<SamplerState>();
|
||||
PSamplerState vulkanSampler = samplerState.cast<Sampler>();
|
||||
imageInfo.sampler = vulkanSampler->sampler;
|
||||
}
|
||||
imageInfos.add(imageInfo);
|
||||
+1
-1
@@ -120,7 +120,7 @@ private:
|
||||
bool currentlyBound;
|
||||
bool currentlyInUse;
|
||||
friend class DescriptorAllocator;
|
||||
friend class CmdBuffer;
|
||||
friend class Command;
|
||||
friend class RenderCommand;
|
||||
friend class ComputeCommand;
|
||||
};
|
||||
@@ -23,24 +23,24 @@ Framebuffer::Framebuffer(PGraphics graphics, PRenderPass renderPass, Gfx::PRende
|
||||
PTexture2D vkInputAttachment = inputAttachment->getTexture().cast<Texture2D>();
|
||||
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<Texture2D>();
|
||||
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<Texture2D>();
|
||||
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(
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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<Gfx::VertexElement>& 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<PViewport> viewports;
|
||||
std::mutex allocatedFrameBufferLock;
|
||||
Map<uint32, OFramebuffer> allocatedFramebuffers;
|
||||
|
||||
@@ -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();
|
||||
|
||||
}
|
||||
@@ -5,7 +5,7 @@ namespace Seele
|
||||
{
|
||||
namespace Vulkan
|
||||
{
|
||||
DECLARE_REF(CmdBuffer)
|
||||
DECLARE_REF(Command)
|
||||
DECLARE_REF(Graphics)
|
||||
class Queue
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -8,7 +8,6 @@ namespace Seele
|
||||
{
|
||||
namespace Vulkan
|
||||
{
|
||||
|
||||
class Window : public Gfx::Window
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
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<Gfx::VertexElement>& elementList)
|
||||
: elementList(elementList)
|
||||
{
|
||||
}
|
||||
|
||||
VertexDeclaration::~VertexDeclaration()
|
||||
{
|
||||
sems[cmdbuffer].clear();
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#pragma once
|
||||
#include <vulkan/vulkan.h>
|
||||
#include <functional>
|
||||
#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<PCmdBuffer, List<VkBuffer>> buffers;
|
||||
Map<PCmdBuffer, List<VkImage>> images;
|
||||
Map<PCmdBuffer, List<VkImageView>> views;
|
||||
Map<PCommand, List<VkBuffer>> buffers;
|
||||
Map<PCommand, List<VkImage>> images;
|
||||
Map<PCommand, List<VkImageView>> views;
|
||||
Map<PCommand, List<VkSemaphore>> sems;
|
||||
};
|
||||
DEFINE_REF(DestructionManager)
|
||||
|
||||
class VertexDeclaration : public Gfx::VertexDeclaration
|
||||
{
|
||||
public:
|
||||
Array<Gfx::VertexElement> elementList;
|
||||
|
||||
VertexDeclaration(const Array<Gfx::VertexElement>& elementList);
|
||||
virtual ~VertexDeclaration();
|
||||
private:
|
||||
};
|
||||
DEFINE_REF(VertexDeclaration)
|
||||
|
||||
class SamplerState : public Gfx::SamplerState
|
||||
class Sampler : public Gfx::Sampler
|
||||
{
|
||||
public:
|
||||
VkSampler sampler;
|
||||
};
|
||||
DEFINE_REF(SamplerState)
|
||||
DEFINE_REF(Sampler)
|
||||
|
||||
} // namespace Vulkan
|
||||
} // namespace Seele
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user