Formatted EVERYTHING
This commit is contained in:
@@ -3,60 +3,34 @@
|
||||
using namespace Seele;
|
||||
using namespace Seele::Gfx;
|
||||
|
||||
Buffer::Buffer(QueueFamilyMapping mapping, QueueType startQueue)
|
||||
: QueueOwnedResource(mapping, startQueue)
|
||||
{
|
||||
}
|
||||
Buffer::Buffer(QueueFamilyMapping mapping, QueueType startQueue) : QueueOwnedResource(mapping, startQueue) {}
|
||||
|
||||
Buffer::~Buffer()
|
||||
{
|
||||
}
|
||||
Buffer::~Buffer() {}
|
||||
|
||||
VertexBuffer::VertexBuffer(QueueFamilyMapping mapping, uint32 numVertices, uint32 vertexSize, QueueType startQueueType)
|
||||
: Buffer(mapping, startQueueType)
|
||||
, numVertices(numVertices)
|
||||
, vertexSize(vertexSize)
|
||||
{
|
||||
}
|
||||
VertexBuffer::~VertexBuffer()
|
||||
{
|
||||
}
|
||||
: 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()
|
||||
{
|
||||
: 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)
|
||||
{}
|
||||
UniformBuffer::UniformBuffer(QueueFamilyMapping mapping, const DataSource& sourceData) : Buffer(mapping, sourceData.owner) {}
|
||||
|
||||
UniformBuffer::~UniformBuffer()
|
||||
{
|
||||
}
|
||||
UniformBuffer::~UniformBuffer() {}
|
||||
|
||||
ShaderBuffer::ShaderBuffer(QueueFamilyMapping mapping, uint32 numElements, const DataSource& sourceData)
|
||||
: Buffer(mapping, sourceData.owner)
|
||||
, numElements(numElements)
|
||||
{
|
||||
}
|
||||
|
||||
ShaderBuffer::~ShaderBuffer()
|
||||
{
|
||||
}
|
||||
: Buffer(mapping, sourceData.owner), numElements(numElements) {}
|
||||
|
||||
ShaderBuffer::~ShaderBuffer() {}
|
||||
|
||||
@@ -1,106 +1,95 @@
|
||||
#pragma once
|
||||
#include "Resources.h"
|
||||
#include "Initializer.h"
|
||||
#include "Resources.h"
|
||||
|
||||
|
||||
namespace Seele {
|
||||
namespace Gfx {
|
||||
class Buffer : public QueueOwnedResource {
|
||||
public:
|
||||
Buffer(QueueFamilyMapping mapping, QueueType startQueueType);
|
||||
virtual ~Buffer();
|
||||
public:
|
||||
Buffer(QueueFamilyMapping mapping, QueueType startQueueType);
|
||||
virtual ~Buffer();
|
||||
|
||||
protected:
|
||||
// Inherited via QueueOwnedResource
|
||||
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
|
||||
protected:
|
||||
// Inherited via QueueOwnedResource
|
||||
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
|
||||
};
|
||||
|
||||
class VertexBuffer : public Buffer {
|
||||
public:
|
||||
VertexBuffer(QueueFamilyMapping mapping, uint32 numVertices,
|
||||
uint32 vertexSize, QueueType startQueueType);
|
||||
virtual ~VertexBuffer();
|
||||
constexpr uint32 getNumVertices() const { return numVertices; }
|
||||
// Size of one vertex in bytes
|
||||
constexpr uint32 getVertexSize() const { return vertexSize; }
|
||||
public:
|
||||
VertexBuffer(QueueFamilyMapping mapping, uint32 numVertices, uint32 vertexSize, QueueType startQueueType);
|
||||
virtual ~VertexBuffer();
|
||||
constexpr uint32 getNumVertices() const { return numVertices; }
|
||||
// Size of one vertex in bytes
|
||||
constexpr uint32 getVertexSize() const { return vertexSize; }
|
||||
|
||||
virtual void updateRegion(DataSource update) = 0;
|
||||
virtual void download(Array<uint8> &buffer) = 0;
|
||||
virtual void updateRegion(DataSource update) = 0;
|
||||
virtual void download(Array<uint8>& buffer) = 0;
|
||||
|
||||
protected:
|
||||
// Inherited via QueueOwnedResource
|
||||
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
|
||||
virtual void executePipelineBarrier(SeAccessFlags srcAccess,
|
||||
SePipelineStageFlags srcStage,
|
||||
SeAccessFlags dstAccess,
|
||||
SePipelineStageFlags dstStage) = 0;
|
||||
uint32 numVertices;
|
||||
uint32 vertexSize;
|
||||
protected:
|
||||
// Inherited via QueueOwnedResource
|
||||
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
|
||||
virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage, SeAccessFlags dstAccess,
|
||||
SePipelineStageFlags dstStage) = 0;
|
||||
uint32 numVertices;
|
||||
uint32 vertexSize;
|
||||
};
|
||||
DEFINE_REF(VertexBuffer)
|
||||
|
||||
class IndexBuffer : public Buffer {
|
||||
public:
|
||||
IndexBuffer(QueueFamilyMapping mapping, uint64 size, Gfx::SeIndexType index,
|
||||
QueueType startQueueType);
|
||||
virtual ~IndexBuffer();
|
||||
constexpr uint64 getNumIndices() const { return numIndices; }
|
||||
constexpr Gfx::SeIndexType getIndexType() const { return indexType; }
|
||||
public:
|
||||
IndexBuffer(QueueFamilyMapping mapping, uint64 size, Gfx::SeIndexType index, QueueType startQueueType);
|
||||
virtual ~IndexBuffer();
|
||||
constexpr uint64 getNumIndices() const { return numIndices; }
|
||||
constexpr Gfx::SeIndexType getIndexType() const { return indexType; }
|
||||
|
||||
virtual void download(Array<uint8> &buffer) = 0;
|
||||
virtual void download(Array<uint8>& buffer) = 0;
|
||||
|
||||
protected:
|
||||
// Inherited via QueueOwnedResource
|
||||
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
|
||||
virtual void executePipelineBarrier(SeAccessFlags srcAccess,
|
||||
SePipelineStageFlags srcStage,
|
||||
SeAccessFlags dstAccess,
|
||||
SePipelineStageFlags dstStage) = 0;
|
||||
Gfx::SeIndexType indexType;
|
||||
uint64 numIndices;
|
||||
protected:
|
||||
// Inherited via QueueOwnedResource
|
||||
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
|
||||
virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage, SeAccessFlags dstAccess,
|
||||
SePipelineStageFlags dstStage) = 0;
|
||||
Gfx::SeIndexType indexType;
|
||||
uint64 numIndices;
|
||||
};
|
||||
DEFINE_REF(IndexBuffer)
|
||||
|
||||
DECLARE_REF(UniformBuffer)
|
||||
class UniformBuffer : public Buffer {
|
||||
public:
|
||||
UniformBuffer(QueueFamilyMapping mapping, const DataSource &sourceData);
|
||||
virtual ~UniformBuffer();
|
||||
public:
|
||||
UniformBuffer(QueueFamilyMapping mapping, const DataSource& sourceData);
|
||||
virtual ~UniformBuffer();
|
||||
|
||||
virtual void rotateBuffer(uint64 size) = 0;
|
||||
virtual void updateContents(const DataSource &sourceData) = 0;
|
||||
virtual void rotateBuffer(uint64 size) = 0;
|
||||
virtual void updateContents(const DataSource& sourceData) = 0;
|
||||
|
||||
protected:
|
||||
// Inherited via QueueOwnedResource
|
||||
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
|
||||
virtual void executePipelineBarrier(SeAccessFlags srcAccess,
|
||||
SePipelineStageFlags srcStage,
|
||||
SeAccessFlags dstAccess,
|
||||
SePipelineStageFlags dstStage) = 0;
|
||||
protected:
|
||||
// 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 numElements,
|
||||
const DataSource &bulkResourceData);
|
||||
virtual ~ShaderBuffer();
|
||||
virtual void rotateBuffer(uint64 size, bool preserveContents = false) = 0;
|
||||
virtual void updateContents(const ShaderBufferCreateInfo &sourceData) = 0;
|
||||
constexpr uint32 getNumElements() const { return numElements; }
|
||||
virtual void *mapRegion(uint64 offset = 0, uint64 size = -1,
|
||||
bool writeOnly = true) = 0;
|
||||
virtual void unmap() = 0;
|
||||
public:
|
||||
ShaderBuffer(QueueFamilyMapping mapping, uint32 numElements, const DataSource& bulkResourceData);
|
||||
virtual ~ShaderBuffer();
|
||||
virtual void rotateBuffer(uint64 size, bool preserveContents = false) = 0;
|
||||
virtual void updateContents(const ShaderBufferCreateInfo& sourceData) = 0;
|
||||
constexpr uint32 getNumElements() const { return numElements; }
|
||||
virtual void* mapRegion(uint64 offset = 0, uint64 size = -1, bool writeOnly = true) = 0;
|
||||
virtual void unmap() = 0;
|
||||
|
||||
virtual void clear() = 0;
|
||||
virtual void clear() = 0;
|
||||
|
||||
protected:
|
||||
// Inherited via QueueOwnedResource
|
||||
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
|
||||
virtual void executePipelineBarrier(SeAccessFlags srcAccess,
|
||||
SePipelineStageFlags srcStage,
|
||||
SeAccessFlags dstAccess,
|
||||
SePipelineStageFlags dstStage) = 0;
|
||||
protected:
|
||||
// Inherited via QueueOwnedResource
|
||||
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
|
||||
virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage, SeAccessFlags dstAccess,
|
||||
SePipelineStageFlags dstStage) = 0;
|
||||
|
||||
uint32 numElements;
|
||||
uint32 numElements;
|
||||
};
|
||||
DEFINE_REF(ShaderBuffer)
|
||||
} // namespace Gfx
|
||||
|
||||
@@ -3,19 +3,10 @@
|
||||
using namespace Seele;
|
||||
using namespace Seele::Gfx;
|
||||
|
||||
RenderCommand::RenderCommand() {}
|
||||
|
||||
RenderCommand::RenderCommand()
|
||||
{
|
||||
}
|
||||
RenderCommand::~RenderCommand() {}
|
||||
|
||||
RenderCommand::~RenderCommand()
|
||||
{
|
||||
}
|
||||
ComputeCommand::ComputeCommand() {}
|
||||
|
||||
ComputeCommand::ComputeCommand()
|
||||
{
|
||||
}
|
||||
|
||||
ComputeCommand::~ComputeCommand()
|
||||
{
|
||||
}
|
||||
ComputeCommand::~ComputeCommand() {}
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
#pragma once
|
||||
#include "Enums.h"
|
||||
#include "Descriptor.h"
|
||||
#include "Enums.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
namespace Gfx
|
||||
{
|
||||
|
||||
namespace Seele {
|
||||
namespace Gfx {
|
||||
DECLARE_REF(Viewport)
|
||||
class RenderCommand
|
||||
{
|
||||
public:
|
||||
class RenderCommand {
|
||||
public:
|
||||
RenderCommand();
|
||||
virtual ~RenderCommand();
|
||||
virtual void setViewport(Gfx::PViewport viewport) = 0;
|
||||
@@ -26,9 +24,8 @@ public:
|
||||
std::string name;
|
||||
};
|
||||
DEFINE_REF(RenderCommand)
|
||||
class ComputeCommand
|
||||
{
|
||||
public:
|
||||
class ComputeCommand {
|
||||
public:
|
||||
ComputeCommand();
|
||||
virtual ~ComputeCommand();
|
||||
virtual void bindPipeline(Gfx::PComputePipeline pipeline) = 0;
|
||||
@@ -40,5 +37,5 @@ public:
|
||||
};
|
||||
DEFINE_REF(ComputeCommand)
|
||||
|
||||
}
|
||||
}
|
||||
} // namespace Gfx
|
||||
} // namespace Seele
|
||||
@@ -1,11 +1,10 @@
|
||||
#pragma once
|
||||
#include "Math/Vector.h"
|
||||
#include "Containers/Array.h"
|
||||
#include "Math/Vector.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
struct DebugVertex
|
||||
{
|
||||
|
||||
namespace Seele {
|
||||
struct DebugVertex {
|
||||
Vector position;
|
||||
Vector color;
|
||||
};
|
||||
|
||||
@@ -6,28 +6,28 @@ using namespace Seele::Gfx;
|
||||
DescriptorLayout::DescriptorLayout(const std::string& name) : 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];
|
||||
}
|
||||
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];
|
||||
if (this != &other) {
|
||||
descriptorBindings.resize(other.descriptorBindings.size());
|
||||
for (uint32 i = 0; i < descriptorBindings.size(); ++i) {
|
||||
descriptorBindings[i] = other.descriptorBindings[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
return *this;
|
||||
}
|
||||
|
||||
DescriptorLayout::~DescriptorLayout() {}
|
||||
|
||||
void DescriptorLayout::addDescriptorBinding(DescriptorBinding binding) {
|
||||
if (descriptorBindings.size() <= binding.binding) {
|
||||
descriptorBindings.resize(binding.binding + 1);
|
||||
}
|
||||
if (descriptorBindings.size() <= binding.binding) {
|
||||
descriptorBindings.resize(binding.binding + 1);
|
||||
}
|
||||
descriptorBindings[binding.binding] = binding;
|
||||
}
|
||||
|
||||
@@ -45,27 +45,22 @@ DescriptorSet::~DescriptorSet() {}
|
||||
|
||||
PipelineLayout::PipelineLayout(const std::string& name) : name(name) {}
|
||||
|
||||
PipelineLayout::PipelineLayout(const std::string& name, PPipelineLayout baseLayout) : name(name){
|
||||
if (baseLayout != nullptr) {
|
||||
descriptorSetLayouts = baseLayout->descriptorSetLayouts;
|
||||
pushConstants = baseLayout->pushConstants;
|
||||
}
|
||||
PipelineLayout::PipelineLayout(const std::string& name, PPipelineLayout baseLayout) : name(name) {
|
||||
if (baseLayout != nullptr) {
|
||||
descriptorSetLayouts = baseLayout->descriptorSetLayouts;
|
||||
pushConstants = baseLayout->pushConstants;
|
||||
}
|
||||
}
|
||||
|
||||
PipelineLayout::~PipelineLayout() {}
|
||||
|
||||
void PipelineLayout::addDescriptorLayout(PDescriptorLayout layout) {
|
||||
descriptorSetLayouts[layout->getName()] = layout;
|
||||
}
|
||||
void PipelineLayout::addDescriptorLayout(PDescriptorLayout layout) { descriptorSetLayouts[layout->getName()] = layout; }
|
||||
|
||||
void PipelineLayout::addPushConstants(const SePushConstantRange& pushConstant) { pushConstants.add(pushConstant); }
|
||||
|
||||
void PipelineLayout::addMapping(Map<std::string, uint32> mapping)
|
||||
{
|
||||
for(const auto& [name, index] : mapping)
|
||||
{
|
||||
if(parameterMapping.contains(name))
|
||||
{
|
||||
void PipelineLayout::addMapping(Map<std::string, uint32> mapping) {
|
||||
for (const auto& [name, index] : mapping) {
|
||||
if (parameterMapping.contains(name)) {
|
||||
assert(parameterMapping[name] == index);
|
||||
}
|
||||
parameterMapping[name] = index;
|
||||
|
||||
@@ -1,55 +1,54 @@
|
||||
#pragma once
|
||||
#include "Enums.h"
|
||||
#include "Resources.h"
|
||||
#include "Initializer.h"
|
||||
#include "Resources.h"
|
||||
|
||||
|
||||
namespace Seele {
|
||||
namespace Gfx {
|
||||
struct DescriptorBinding {
|
||||
uint32 binding = 0;
|
||||
SeDescriptorType descriptorType = SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
||||
SeImageViewType textureType = SE_IMAGE_VIEW_TYPE_2D;
|
||||
uint32 descriptorCount = 1;
|
||||
SeDescriptorBindingFlags bindingFlags = 0;
|
||||
SeShaderStageFlags shaderStages = SE_SHADER_STAGE_ALL;
|
||||
Gfx::SeDescriptorAccessTypeFlags access = SE_DESCRIPTOR_ACCESS_READ_ONLY_BIT;
|
||||
uint32 binding = 0;
|
||||
SeDescriptorType descriptorType = SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
||||
SeImageViewType textureType = SE_IMAGE_VIEW_TYPE_2D;
|
||||
uint32 descriptorCount = 1;
|
||||
SeDescriptorBindingFlags bindingFlags = 0;
|
||||
SeShaderStageFlags shaderStages = SE_SHADER_STAGE_ALL;
|
||||
Gfx::SeDescriptorAccessTypeFlags access = SE_DESCRIPTOR_ACCESS_READ_ONLY_BIT;
|
||||
};
|
||||
|
||||
DECLARE_REF(DescriptorPool)
|
||||
DECLARE_REF(DescriptorSet)
|
||||
class DescriptorLayout {
|
||||
public:
|
||||
DescriptorLayout(const std::string &name);
|
||||
DescriptorLayout(const DescriptorLayout &other);
|
||||
DescriptorLayout &operator=(const DescriptorLayout &other);
|
||||
virtual ~DescriptorLayout();
|
||||
void addDescriptorBinding(DescriptorBinding binding);
|
||||
void reset();
|
||||
PDescriptorSet allocateDescriptorSet();
|
||||
virtual void create() = 0;
|
||||
constexpr const Array<DescriptorBinding> &getBindings() const {
|
||||
return descriptorBindings;
|
||||
}
|
||||
constexpr uint32 getHash() const { return hash; }
|
||||
constexpr const std::string &getName() const { return name; }
|
||||
public:
|
||||
DescriptorLayout(const std::string& name);
|
||||
DescriptorLayout(const DescriptorLayout& other);
|
||||
DescriptorLayout& operator=(const DescriptorLayout& other);
|
||||
virtual ~DescriptorLayout();
|
||||
void addDescriptorBinding(DescriptorBinding binding);
|
||||
void reset();
|
||||
PDescriptorSet allocateDescriptorSet();
|
||||
virtual void create() = 0;
|
||||
constexpr const Array<DescriptorBinding>& getBindings() const { return descriptorBindings; }
|
||||
constexpr uint32 getHash() const { return hash; }
|
||||
constexpr const std::string& getName() const { return name; }
|
||||
|
||||
protected:
|
||||
Array<DescriptorBinding> descriptorBindings;
|
||||
ODescriptorPool pool;
|
||||
std::string name;
|
||||
uint32 hash = 0;
|
||||
friend class PipelineLayout;
|
||||
friend class DescriptorPool;
|
||||
protected:
|
||||
Array<DescriptorBinding> descriptorBindings;
|
||||
ODescriptorPool pool;
|
||||
std::string name;
|
||||
uint32 hash = 0;
|
||||
friend class PipelineLayout;
|
||||
friend class DescriptorPool;
|
||||
};
|
||||
DEFINE_REF(DescriptorLayout)
|
||||
|
||||
DECLARE_REF(DescriptorSet)
|
||||
class DescriptorPool {
|
||||
public:
|
||||
DescriptorPool();
|
||||
virtual ~DescriptorPool();
|
||||
virtual PDescriptorSet allocateDescriptorSet() = 0;
|
||||
virtual void reset() = 0;
|
||||
public:
|
||||
DescriptorPool();
|
||||
virtual ~DescriptorPool();
|
||||
virtual PDescriptorSet allocateDescriptorSet() = 0;
|
||||
virtual void reset() = 0;
|
||||
};
|
||||
DEFINE_REF(DescriptorPool)
|
||||
DECLARE_REF(UniformBuffer)
|
||||
@@ -57,54 +56,47 @@ DECLARE_REF(ShaderBuffer)
|
||||
DECLARE_REF(Texture)
|
||||
DECLARE_REF(Sampler)
|
||||
class DescriptorSet {
|
||||
public:
|
||||
DescriptorSet(PDescriptorLayout layout);
|
||||
virtual ~DescriptorSet();
|
||||
virtual void writeChanges() = 0;
|
||||
virtual void updateBuffer(uint32 binding, PUniformBuffer uniformBuffer) = 0;
|
||||
virtual void updateBuffer(uint32 binding, PShaderBuffer ShaderBuffer) = 0;
|
||||
virtual void updateBuffer(uint32_t binding, uint32 index,
|
||||
Gfx::PShaderBuffer uniformBuffer) = 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;
|
||||
bool operator<(PDescriptorSet other);
|
||||
public:
|
||||
DescriptorSet(PDescriptorLayout layout);
|
||||
virtual ~DescriptorSet();
|
||||
virtual void writeChanges() = 0;
|
||||
virtual void updateBuffer(uint32 binding, PUniformBuffer uniformBuffer) = 0;
|
||||
virtual void updateBuffer(uint32 binding, PShaderBuffer ShaderBuffer) = 0;
|
||||
virtual void updateBuffer(uint32_t binding, uint32 index, Gfx::PShaderBuffer uniformBuffer) = 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;
|
||||
bool operator<(PDescriptorSet other);
|
||||
|
||||
constexpr PDescriptorLayout getLayout() const { return layout; }
|
||||
constexpr const std::string &getName() const { return layout->getName(); }
|
||||
constexpr PDescriptorLayout getLayout() const { return layout; }
|
||||
constexpr const std::string& getName() const { return layout->getName(); }
|
||||
|
||||
protected:
|
||||
PDescriptorLayout layout;
|
||||
protected:
|
||||
PDescriptorLayout layout;
|
||||
};
|
||||
DEFINE_REF(DescriptorSet)
|
||||
|
||||
DECLARE_REF(PipelineLayout)
|
||||
class PipelineLayout {
|
||||
public:
|
||||
PipelineLayout(const std::string &name);
|
||||
PipelineLayout(const std::string &name, PPipelineLayout baseLayout);
|
||||
virtual ~PipelineLayout();
|
||||
virtual void create() = 0;
|
||||
void addDescriptorLayout(PDescriptorLayout layout);
|
||||
void addPushConstants(const SePushConstantRange &pushConstants);
|
||||
constexpr uint32 getHash() const { return layoutHash; }
|
||||
constexpr const Map<std::string, PDescriptorLayout> &getLayouts() const {
|
||||
return descriptorSetLayouts;
|
||||
}
|
||||
constexpr uint32 findParameter(const std::string ¶m) const {
|
||||
return parameterMapping[param];
|
||||
}
|
||||
void addMapping(Map<std::string, uint32> mapping);
|
||||
constexpr std::string getName() const { return name; };
|
||||
public:
|
||||
PipelineLayout(const std::string& name);
|
||||
PipelineLayout(const std::string& name, PPipelineLayout baseLayout);
|
||||
virtual ~PipelineLayout();
|
||||
virtual void create() = 0;
|
||||
void addDescriptorLayout(PDescriptorLayout layout);
|
||||
void addPushConstants(const SePushConstantRange& pushConstants);
|
||||
constexpr uint32 getHash() const { return layoutHash; }
|
||||
constexpr const Map<std::string, PDescriptorLayout>& getLayouts() const { return descriptorSetLayouts; }
|
||||
constexpr uint32 findParameter(const std::string& param) const { return parameterMapping[param]; }
|
||||
void addMapping(Map<std::string, uint32> mapping);
|
||||
constexpr std::string getName() const { return name; };
|
||||
|
||||
protected:
|
||||
uint32 layoutHash = 0;
|
||||
Map<std::string, PDescriptorLayout> descriptorSetLayouts;
|
||||
Map<std::string, uint32> parameterMapping;
|
||||
Array<SePushConstantRange> pushConstants;
|
||||
std::string name;
|
||||
protected:
|
||||
uint32 layoutHash = 0;
|
||||
Map<std::string, PDescriptorLayout> descriptorSetLayouts;
|
||||
Map<std::string, uint32> parameterMapping;
|
||||
Array<SePushConstantRange> pushConstants;
|
||||
std::string name;
|
||||
};
|
||||
DEFINE_REF(PipelineLayout)
|
||||
} // namespace Gfx
|
||||
|
||||
+107
-108
@@ -4,113 +4,112 @@
|
||||
using namespace Seele;
|
||||
using namespace Seele::Gfx;
|
||||
|
||||
FormatCompatibilityInfo Gfx::getFormatInfo(SeFormat format)
|
||||
{
|
||||
switch(format) {
|
||||
case SE_FORMAT_R4G4_UNORM_PACK8:
|
||||
case SE_FORMAT_R8_UNORM:
|
||||
case SE_FORMAT_R8_SNORM:
|
||||
case SE_FORMAT_R8_USCALED:
|
||||
case SE_FORMAT_R8_SSCALED:
|
||||
case SE_FORMAT_R8_UINT:
|
||||
case SE_FORMAT_R8_SINT:
|
||||
case SE_FORMAT_R8_SRGB:
|
||||
return FormatCompatibilityInfo {
|
||||
.blockSize = 1,
|
||||
.blockExtent = UVector(1, 1, 1),
|
||||
.texelsPerBlock = 1,
|
||||
};
|
||||
case SE_FORMAT_R10X6_UNORM_PACK16:
|
||||
case SE_FORMAT_R12X4_UNORM_PACK16:
|
||||
//case SE_FORMAT_A4R4G4B4_UNORM_PACK16:
|
||||
//case SE_FORMAT_A4B4G4R4_UNORM_PACK16:
|
||||
case SE_FORMAT_R4G4B4A4_UNORM_PACK16:
|
||||
case SE_FORMAT_B4G4R4A4_UNORM_PACK16:
|
||||
case SE_FORMAT_R5G6B5_UNORM_PACK16:
|
||||
case SE_FORMAT_B5G6R5_UNORM_PACK16:
|
||||
case SE_FORMAT_R5G5B5A1_UNORM_PACK16:
|
||||
case SE_FORMAT_B5G5R5A1_UNORM_PACK16:
|
||||
case SE_FORMAT_A1R5G5B5_UNORM_PACK16:
|
||||
case SE_FORMAT_R8G8_UNORM:
|
||||
case SE_FORMAT_R8G8_SNORM:
|
||||
case SE_FORMAT_R8G8_USCALED:
|
||||
case SE_FORMAT_R8G8_SSCALED:
|
||||
case SE_FORMAT_R8G8_UINT:
|
||||
case SE_FORMAT_R8G8_SINT:
|
||||
case SE_FORMAT_R8G8_SRGB:
|
||||
case SE_FORMAT_R16_UNORM:
|
||||
case SE_FORMAT_R16_SNORM:
|
||||
case SE_FORMAT_R16_USCALED:
|
||||
case SE_FORMAT_R16_SSCALED:
|
||||
case SE_FORMAT_R16_UINT:
|
||||
case SE_FORMAT_R16_SINT:
|
||||
case SE_FORMAT_R16_SFLOAT:
|
||||
return FormatCompatibilityInfo {
|
||||
.blockSize = 2,
|
||||
.blockExtent = UVector(1, 1, 1),
|
||||
.texelsPerBlock = 1,
|
||||
};
|
||||
case SE_FORMAT_BC7_UNORM_BLOCK:
|
||||
case SE_FORMAT_BC7_SRGB_BLOCK:
|
||||
return FormatCompatibilityInfo {
|
||||
.blockSize = 16,
|
||||
.blockExtent = UVector(4, 4, 1),
|
||||
.texelsPerBlock = 16,
|
||||
};
|
||||
case SE_FORMAT_R10X6G10X6_UNORM_2PACK16:
|
||||
case SE_FORMAT_R12X4G12X4_UNORM_2PACK16:
|
||||
//case SE_FORMAT_R16G16_S10_5_NV:
|
||||
case SE_FORMAT_R8G8B8A8_UNORM:
|
||||
case SE_FORMAT_R8G8B8A8_SNORM:
|
||||
case SE_FORMAT_R8G8B8A8_USCALED:
|
||||
case SE_FORMAT_R8G8B8A8_SSCALED:
|
||||
case SE_FORMAT_R8G8B8A8_UINT:
|
||||
case SE_FORMAT_R8G8B8A8_SINT:
|
||||
case SE_FORMAT_R8G8B8A8_SRGB:
|
||||
case SE_FORMAT_B8G8R8A8_UNORM:
|
||||
case SE_FORMAT_B8G8R8A8_SNORM:
|
||||
case SE_FORMAT_B8G8R8A8_USCALED:
|
||||
case SE_FORMAT_B8G8R8A8_SSCALED:
|
||||
case SE_FORMAT_B8G8R8A8_UINT:
|
||||
case SE_FORMAT_B8G8R8A8_SINT:
|
||||
case SE_FORMAT_B8G8R8A8_SRGB:
|
||||
case SE_FORMAT_A8B8G8R8_UNORM_PACK32:
|
||||
case SE_FORMAT_A8B8G8R8_SNORM_PACK32:
|
||||
case SE_FORMAT_A8B8G8R8_USCALED_PACK32:
|
||||
case SE_FORMAT_A8B8G8R8_SSCALED_PACK32:
|
||||
case SE_FORMAT_A8B8G8R8_UINT_PACK32:
|
||||
case SE_FORMAT_A8B8G8R8_SINT_PACK32:
|
||||
case SE_FORMAT_A8B8G8R8_SRGB_PACK32:
|
||||
case SE_FORMAT_A2R10G10B10_UNORM_PACK32:
|
||||
case SE_FORMAT_A2R10G10B10_SNORM_PACK32:
|
||||
case SE_FORMAT_A2R10G10B10_USCALED_PACK32:
|
||||
case SE_FORMAT_A2R10G10B10_SSCALED_PACK32:
|
||||
case SE_FORMAT_A2R10G10B10_UINT_PACK32:
|
||||
case SE_FORMAT_A2R10G10B10_SINT_PACK32:
|
||||
case SE_FORMAT_A2B10G10R10_UNORM_PACK32:
|
||||
case SE_FORMAT_A2B10G10R10_SNORM_PACK32:
|
||||
case SE_FORMAT_A2B10G10R10_USCALED_PACK32:
|
||||
case SE_FORMAT_A2B10G10R10_SSCALED_PACK32:
|
||||
case SE_FORMAT_A2B10G10R10_UINT_PACK32:
|
||||
case SE_FORMAT_A2B10G10R10_SINT_PACK32:
|
||||
case SE_FORMAT_R16G16_UNORM:
|
||||
case SE_FORMAT_R16G16_SNORM:
|
||||
case SE_FORMAT_R16G16_USCALED:
|
||||
case SE_FORMAT_R16G16_SSCALED:
|
||||
case SE_FORMAT_R16G16_UINT:
|
||||
case SE_FORMAT_R16G16_SINT:
|
||||
case SE_FORMAT_R16G16_SFLOAT:
|
||||
case SE_FORMAT_R32_UINT:
|
||||
case SE_FORMAT_R32_SINT:
|
||||
case SE_FORMAT_R32_SFLOAT:
|
||||
case SE_FORMAT_B10G11R11_UFLOAT_PACK32:
|
||||
case SE_FORMAT_E5B9G9R9_UFLOAT_PACK32:
|
||||
return FormatCompatibilityInfo{
|
||||
.blockSize = 4,
|
||||
.blockExtent = Vector(1, 1, 1),
|
||||
.texelsPerBlock = 1,
|
||||
};
|
||||
default:
|
||||
throw new std::logic_error("not yet implemented");
|
||||
FormatCompatibilityInfo Gfx::getFormatInfo(SeFormat format) {
|
||||
switch (format) {
|
||||
case SE_FORMAT_R4G4_UNORM_PACK8:
|
||||
case SE_FORMAT_R8_UNORM:
|
||||
case SE_FORMAT_R8_SNORM:
|
||||
case SE_FORMAT_R8_USCALED:
|
||||
case SE_FORMAT_R8_SSCALED:
|
||||
case SE_FORMAT_R8_UINT:
|
||||
case SE_FORMAT_R8_SINT:
|
||||
case SE_FORMAT_R8_SRGB:
|
||||
return FormatCompatibilityInfo{
|
||||
.blockSize = 1,
|
||||
.blockExtent = UVector(1, 1, 1),
|
||||
.texelsPerBlock = 1,
|
||||
};
|
||||
case SE_FORMAT_R10X6_UNORM_PACK16:
|
||||
case SE_FORMAT_R12X4_UNORM_PACK16:
|
||||
// case SE_FORMAT_A4R4G4B4_UNORM_PACK16:
|
||||
// case SE_FORMAT_A4B4G4R4_UNORM_PACK16:
|
||||
case SE_FORMAT_R4G4B4A4_UNORM_PACK16:
|
||||
case SE_FORMAT_B4G4R4A4_UNORM_PACK16:
|
||||
case SE_FORMAT_R5G6B5_UNORM_PACK16:
|
||||
case SE_FORMAT_B5G6R5_UNORM_PACK16:
|
||||
case SE_FORMAT_R5G5B5A1_UNORM_PACK16:
|
||||
case SE_FORMAT_B5G5R5A1_UNORM_PACK16:
|
||||
case SE_FORMAT_A1R5G5B5_UNORM_PACK16:
|
||||
case SE_FORMAT_R8G8_UNORM:
|
||||
case SE_FORMAT_R8G8_SNORM:
|
||||
case SE_FORMAT_R8G8_USCALED:
|
||||
case SE_FORMAT_R8G8_SSCALED:
|
||||
case SE_FORMAT_R8G8_UINT:
|
||||
case SE_FORMAT_R8G8_SINT:
|
||||
case SE_FORMAT_R8G8_SRGB:
|
||||
case SE_FORMAT_R16_UNORM:
|
||||
case SE_FORMAT_R16_SNORM:
|
||||
case SE_FORMAT_R16_USCALED:
|
||||
case SE_FORMAT_R16_SSCALED:
|
||||
case SE_FORMAT_R16_UINT:
|
||||
case SE_FORMAT_R16_SINT:
|
||||
case SE_FORMAT_R16_SFLOAT:
|
||||
return FormatCompatibilityInfo{
|
||||
.blockSize = 2,
|
||||
.blockExtent = UVector(1, 1, 1),
|
||||
.texelsPerBlock = 1,
|
||||
};
|
||||
case SE_FORMAT_BC7_UNORM_BLOCK:
|
||||
case SE_FORMAT_BC7_SRGB_BLOCK:
|
||||
return FormatCompatibilityInfo{
|
||||
.blockSize = 16,
|
||||
.blockExtent = UVector(4, 4, 1),
|
||||
.texelsPerBlock = 16,
|
||||
};
|
||||
case SE_FORMAT_R10X6G10X6_UNORM_2PACK16:
|
||||
case SE_FORMAT_R12X4G12X4_UNORM_2PACK16:
|
||||
// case SE_FORMAT_R16G16_S10_5_NV:
|
||||
case SE_FORMAT_R8G8B8A8_UNORM:
|
||||
case SE_FORMAT_R8G8B8A8_SNORM:
|
||||
case SE_FORMAT_R8G8B8A8_USCALED:
|
||||
case SE_FORMAT_R8G8B8A8_SSCALED:
|
||||
case SE_FORMAT_R8G8B8A8_UINT:
|
||||
case SE_FORMAT_R8G8B8A8_SINT:
|
||||
case SE_FORMAT_R8G8B8A8_SRGB:
|
||||
case SE_FORMAT_B8G8R8A8_UNORM:
|
||||
case SE_FORMAT_B8G8R8A8_SNORM:
|
||||
case SE_FORMAT_B8G8R8A8_USCALED:
|
||||
case SE_FORMAT_B8G8R8A8_SSCALED:
|
||||
case SE_FORMAT_B8G8R8A8_UINT:
|
||||
case SE_FORMAT_B8G8R8A8_SINT:
|
||||
case SE_FORMAT_B8G8R8A8_SRGB:
|
||||
case SE_FORMAT_A8B8G8R8_UNORM_PACK32:
|
||||
case SE_FORMAT_A8B8G8R8_SNORM_PACK32:
|
||||
case SE_FORMAT_A8B8G8R8_USCALED_PACK32:
|
||||
case SE_FORMAT_A8B8G8R8_SSCALED_PACK32:
|
||||
case SE_FORMAT_A8B8G8R8_UINT_PACK32:
|
||||
case SE_FORMAT_A8B8G8R8_SINT_PACK32:
|
||||
case SE_FORMAT_A8B8G8R8_SRGB_PACK32:
|
||||
case SE_FORMAT_A2R10G10B10_UNORM_PACK32:
|
||||
case SE_FORMAT_A2R10G10B10_SNORM_PACK32:
|
||||
case SE_FORMAT_A2R10G10B10_USCALED_PACK32:
|
||||
case SE_FORMAT_A2R10G10B10_SSCALED_PACK32:
|
||||
case SE_FORMAT_A2R10G10B10_UINT_PACK32:
|
||||
case SE_FORMAT_A2R10G10B10_SINT_PACK32:
|
||||
case SE_FORMAT_A2B10G10R10_UNORM_PACK32:
|
||||
case SE_FORMAT_A2B10G10R10_SNORM_PACK32:
|
||||
case SE_FORMAT_A2B10G10R10_USCALED_PACK32:
|
||||
case SE_FORMAT_A2B10G10R10_SSCALED_PACK32:
|
||||
case SE_FORMAT_A2B10G10R10_UINT_PACK32:
|
||||
case SE_FORMAT_A2B10G10R10_SINT_PACK32:
|
||||
case SE_FORMAT_R16G16_UNORM:
|
||||
case SE_FORMAT_R16G16_SNORM:
|
||||
case SE_FORMAT_R16G16_USCALED:
|
||||
case SE_FORMAT_R16G16_SSCALED:
|
||||
case SE_FORMAT_R16G16_UINT:
|
||||
case SE_FORMAT_R16G16_SINT:
|
||||
case SE_FORMAT_R16G16_SFLOAT:
|
||||
case SE_FORMAT_R32_UINT:
|
||||
case SE_FORMAT_R32_SINT:
|
||||
case SE_FORMAT_R32_SFLOAT:
|
||||
case SE_FORMAT_B10G11R11_UFLOAT_PACK32:
|
||||
case SE_FORMAT_E5B9G9R9_UFLOAT_PACK32:
|
||||
return FormatCompatibilityInfo{
|
||||
.blockSize = 4,
|
||||
.blockExtent = Vector(1, 1, 1),
|
||||
.texelsPerBlock = 1,
|
||||
};
|
||||
default:
|
||||
throw new std::logic_error("not yet implemented");
|
||||
}
|
||||
}
|
||||
|
||||
+238
-327
File diff suppressed because it is too large
Load Diff
@@ -1,14 +1,9 @@
|
||||
#include "Graphics.h"
|
||||
#include "Shader.h"
|
||||
#include "Graphics.h"
|
||||
|
||||
|
||||
using namespace Seele::Gfx;
|
||||
|
||||
Graphics::Graphics()
|
||||
{
|
||||
shaderCompiler = new ShaderCompiler(this);
|
||||
}
|
||||
Graphics::Graphics() { shaderCompiler = new ShaderCompiler(this); }
|
||||
|
||||
Graphics::~Graphics()
|
||||
{
|
||||
}
|
||||
Graphics::~Graphics() {}
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
#pragma once
|
||||
#include "MinimalEngine.h"
|
||||
#include "Initializer.h"
|
||||
#include "Resources.h"
|
||||
#include "RenderTarget.h"
|
||||
#include "Containers/Array.h"
|
||||
#include "Initializer.h"
|
||||
#include "MinimalEngine.h"
|
||||
#include "RenderTarget.h"
|
||||
#include "Resources.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
namespace Gfx
|
||||
{
|
||||
|
||||
namespace Seele {
|
||||
namespace Gfx {
|
||||
DECLARE_REF(Window)
|
||||
DECLARE_REF(Viewport)
|
||||
DECLARE_REF(ShaderCompiler)
|
||||
@@ -33,25 +32,18 @@ DECLARE_REF(RenderCommand)
|
||||
DECLARE_REF(ComputeCommand)
|
||||
DECLARE_REF(BottomLevelAS)
|
||||
DECLARE_REF(TopLevelAS)
|
||||
class Graphics
|
||||
{
|
||||
public:
|
||||
class Graphics {
|
||||
public:
|
||||
Graphics();
|
||||
virtual ~Graphics();
|
||||
virtual void init(GraphicsInitializer initializer) = 0;
|
||||
|
||||
const QueueFamilyMapping getFamilyMapping() const
|
||||
{
|
||||
return queueMapping;
|
||||
}
|
||||
|
||||
PShaderCompiler getShaderCompiler()
|
||||
{
|
||||
return shaderCompiler;
|
||||
}
|
||||
|
||||
virtual OWindow createWindow(const WindowCreateInfo &createInfo) = 0;
|
||||
virtual OViewport createViewport(PWindow owner, const ViewportCreateInfo &createInfo) = 0;
|
||||
const QueueFamilyMapping getFamilyMapping() const { return queueMapping; }
|
||||
|
||||
PShaderCompiler getShaderCompiler() { return shaderCompiler; }
|
||||
|
||||
virtual OWindow createWindow(const WindowCreateInfo& createInfo) = 0;
|
||||
virtual OViewport createViewport(PWindow owner, const ViewportCreateInfo& createInfo) = 0;
|
||||
|
||||
virtual ORenderPass createRenderPass(RenderTargetLayout layout, Array<SubPassDependency> dependencies, PViewport renderArea) = 0;
|
||||
virtual void beginRenderPass(PRenderPass renderPass) = 0;
|
||||
@@ -61,17 +53,17 @@ public:
|
||||
virtual void executeCommands(Array<ORenderCommand> commands) = 0;
|
||||
virtual void executeCommands(Array<OComputeCommand> commands) = 0;
|
||||
|
||||
virtual OTexture2D createTexture2D(const TextureCreateInfo &createInfo) = 0;
|
||||
virtual OTexture3D createTexture3D(const TextureCreateInfo &createInfo) = 0;
|
||||
virtual OTextureCube createTextureCube(const TextureCreateInfo &createInfo) = 0;
|
||||
virtual OUniformBuffer createUniformBuffer(const UniformBufferCreateInfo &bulkData) = 0;
|
||||
virtual OShaderBuffer createShaderBuffer(const ShaderBufferCreateInfo &bulkData) = 0;
|
||||
virtual OVertexBuffer createVertexBuffer(const VertexBufferCreateInfo &bulkData) = 0;
|
||||
virtual OIndexBuffer createIndexBuffer(const IndexBufferCreateInfo &bulkData) = 0;
|
||||
|
||||
virtual OTexture2D createTexture2D(const TextureCreateInfo& createInfo) = 0;
|
||||
virtual OTexture3D createTexture3D(const TextureCreateInfo& createInfo) = 0;
|
||||
virtual OTextureCube createTextureCube(const TextureCreateInfo& createInfo) = 0;
|
||||
virtual OUniformBuffer createUniformBuffer(const UniformBufferCreateInfo& bulkData) = 0;
|
||||
virtual OShaderBuffer createShaderBuffer(const ShaderBufferCreateInfo& bulkData) = 0;
|
||||
virtual OVertexBuffer createVertexBuffer(const VertexBufferCreateInfo& bulkData) = 0;
|
||||
virtual OIndexBuffer createIndexBuffer(const IndexBufferCreateInfo& bulkData) = 0;
|
||||
|
||||
virtual ORenderCommand createRenderCommand(const std::string& name = "") = 0;
|
||||
virtual OComputeCommand createComputeCommand(const std::string& name = "") = 0;
|
||||
|
||||
|
||||
virtual OVertexShader createVertexShader(const ShaderCreateInfo& createInfo) = 0;
|
||||
virtual OFragmentShader createFragmentShader(const ShaderCreateInfo& createInfo) = 0;
|
||||
virtual OComputeShader createComputeShader(const ShaderCreateInfo& createInfo) = 0;
|
||||
@@ -82,8 +74,8 @@ public:
|
||||
virtual PComputePipeline createComputePipeline(ComputePipelineCreateInfo createInfo) = 0;
|
||||
virtual OSampler createSampler(const SamplerCreateInfo& createInfo) = 0;
|
||||
|
||||
virtual ODescriptorLayout createDescriptorLayout(const std::string& name = "") = 0;
|
||||
virtual OPipelineLayout createPipelineLayout(const std::string& name = "", PPipelineLayout baseLayout = nullptr) = 0;
|
||||
virtual ODescriptorLayout createDescriptorLayout(const std::string& name = "") = 0;
|
||||
virtual OPipelineLayout createPipelineLayout(const std::string& name = "", PPipelineLayout baseLayout = nullptr) = 0;
|
||||
|
||||
virtual OVertexInput createVertexInput(VertexInputStateCreateInfo createInfo) = 0;
|
||||
|
||||
@@ -94,7 +86,8 @@ public:
|
||||
// Ray Tracing
|
||||
virtual OBottomLevelAS createBottomLevelAccelerationStructure(const BottomLevelASCreateInfo& createInfo) = 0;
|
||||
virtual OTopLevelAS createTopLevelAccelerationStructure(const TopLevelASCreateInfo& createInfo) = 0;
|
||||
protected:
|
||||
|
||||
protected:
|
||||
QueueFamilyMapping queueMapping;
|
||||
OShaderCompiler shaderCompiler;
|
||||
bool meshShadingEnabled = false;
|
||||
|
||||
+223
-256
@@ -1,266 +1,233 @@
|
||||
#pragma once
|
||||
#include "Enums.h"
|
||||
#include "Containers/Map.h"
|
||||
#include "Enums.h"
|
||||
#include "Math/Math.h"
|
||||
#include "MinimalEngine.h"
|
||||
#include "MeshData.h"
|
||||
#include "MinimalEngine.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
struct GraphicsInitializer
|
||||
{
|
||||
const char* applicationName;
|
||||
const char* engineName;
|
||||
const char* windowLayoutFile;
|
||||
/**
|
||||
* layers defines the enabled Vulkan layers used in the instance,
|
||||
* if ENABLE_VALIDATION is defined, standard validation is already enabled
|
||||
* not yet implemented
|
||||
*/
|
||||
Array<const char*> layers;
|
||||
Array<const char*> instanceExtensions;
|
||||
Array<const char*> deviceExtensions;
|
||||
|
||||
void* windowHandle;
|
||||
GraphicsInitializer()
|
||||
: applicationName("SeeleEngine")
|
||||
, engineName("SeeleEngine")
|
||||
, windowLayoutFile(nullptr)
|
||||
, layers{ "VK_LAYER_LUNARG_monitor" }
|
||||
, instanceExtensions{}
|
||||
, deviceExtensions{ "VK_KHR_swapchain" }
|
||||
, windowHandle(nullptr)
|
||||
{
|
||||
}
|
||||
};
|
||||
struct WindowCreateInfo
|
||||
{
|
||||
int32 width;
|
||||
int32 height;
|
||||
const char* title;
|
||||
Gfx::SeFormat preferredFormat = Gfx::SE_FORMAT_B8G8R8A8_UNORM;
|
||||
void* windowHandle;
|
||||
};
|
||||
struct ViewportCreateInfo
|
||||
{
|
||||
URect dimensions;
|
||||
float fieldOfView = 1.222f; // 70 deg
|
||||
Gfx::SeSampleCountFlags numSamples;
|
||||
};
|
||||
// doesnt own the data, only proxy it
|
||||
struct DataSource
|
||||
{
|
||||
uint64 size = 0;
|
||||
uint64 offset = 0;
|
||||
uint8* data = nullptr;
|
||||
Gfx::QueueType owner = Gfx::QueueType::GRAPHICS;
|
||||
};
|
||||
struct TextureCreateInfo
|
||||
{
|
||||
DataSource sourceData = DataSource();
|
||||
Gfx::SeFormat format = Gfx::SE_FORMAT_R32G32B32A32_SFLOAT;
|
||||
uint32 width = 1;
|
||||
uint32 height = 1;
|
||||
uint32 depth = 1;
|
||||
uint32 mipLevels = 1;
|
||||
uint32 layers = 1;
|
||||
uint32 elements = 1;
|
||||
uint32 samples = 1;
|
||||
Gfx::SeImageUsageFlags usage = Gfx::SE_IMAGE_USAGE_SAMPLED_BIT;
|
||||
Gfx::SeMemoryPropertyFlags memoryProps = Gfx::SE_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
|
||||
std::string name;
|
||||
};
|
||||
struct SamplerCreateInfo
|
||||
{
|
||||
Gfx::SeSamplerCreateFlags flags;
|
||||
Gfx::SeFilter magFilter = Gfx::SE_FILTER_LINEAR;
|
||||
Gfx::SeFilter minFilter = Gfx::SE_FILTER_LINEAR;
|
||||
Gfx::SeSamplerMipmapMode mipmapMode = Gfx::SE_SAMPLER_MIPMAP_MODE_LINEAR;
|
||||
Gfx::SeSamplerAddressMode addressModeU = Gfx::SE_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||
Gfx::SeSamplerAddressMode addressModeV = Gfx::SE_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||
Gfx::SeSamplerAddressMode addressModeW = Gfx::SE_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||
float mipLodBias = 0.0f;
|
||||
uint32 anisotropyEnable = 0;
|
||||
float maxAnisotropy = 0.0f;
|
||||
uint32 compareEnable = 0;
|
||||
Gfx::SeCompareOp compareOp = Gfx::SE_COMPARE_OP_NEVER;
|
||||
float minLod = 0.0f;
|
||||
float maxLod = 0.0f;
|
||||
Gfx::SeBorderColor borderColor = Gfx::SE_BORDER_COLOR_FLOAT_OPAQUE_BLACK;
|
||||
uint32 unnormalizedCoordinates = 0;
|
||||
std::string name;
|
||||
};
|
||||
struct VertexBufferCreateInfo
|
||||
{
|
||||
DataSource sourceData = DataSource();
|
||||
// bytes per vertex
|
||||
uint32 vertexSize = 0;
|
||||
uint32 numVertices = 0;
|
||||
std::string name = "Unnamed";
|
||||
};
|
||||
struct IndexBufferCreateInfo
|
||||
{
|
||||
DataSource sourceData = DataSource();
|
||||
Gfx::SeIndexType indexType = Gfx::SeIndexType::SE_INDEX_TYPE_UINT16;
|
||||
std::string name = "Unnamed";
|
||||
};
|
||||
struct UniformBufferCreateInfo
|
||||
{
|
||||
DataSource sourceData = DataSource();
|
||||
uint8 dynamic = 0;
|
||||
std::string name = "Unnamed";
|
||||
};
|
||||
struct ShaderBufferCreateInfo
|
||||
{
|
||||
DataSource sourceData = DataSource();
|
||||
uint64 numElements = 1;
|
||||
uint8 dynamic = 0;
|
||||
uint8 vertexBuffer = 0;
|
||||
std::string name = "Unnamed";
|
||||
};
|
||||
DECLARE_NAME_REF(Gfx, PipelineLayout)
|
||||
struct ShaderCreateInfo
|
||||
{
|
||||
std::string name; // Debug info
|
||||
std::string mainModule;
|
||||
Array<std::string> additionalModules;
|
||||
std::string entryPoint;
|
||||
Array<Pair<const char*, const char*>> typeParameter;
|
||||
Map<const char*, const char*> defines;
|
||||
Gfx::PPipelineLayout rootSignature;
|
||||
};
|
||||
struct VertexInputBinding
|
||||
{
|
||||
uint32 binding;
|
||||
uint32 stride;
|
||||
Gfx::SeVertexInputRate inputRate;
|
||||
};
|
||||
struct VertexInputAttribute
|
||||
{
|
||||
uint32 location;
|
||||
uint32 binding;
|
||||
Gfx::SeFormat format;
|
||||
uint32 offset;
|
||||
};
|
||||
struct VertexInputStateCreateInfo
|
||||
{
|
||||
Array<VertexInputBinding> bindings;
|
||||
Array<VertexInputAttribute> attributes;
|
||||
};
|
||||
DECLARE_REF(MaterialInstance)
|
||||
namespace Gfx
|
||||
{
|
||||
struct SePushConstantRange
|
||||
{
|
||||
SeShaderStageFlags stageFlags;
|
||||
uint32 offset;
|
||||
uint32 size;
|
||||
};
|
||||
struct RasterizationState
|
||||
{
|
||||
uint32 depthClampEnable = 0;
|
||||
uint32 rasterizerDiscardEnable = 0;
|
||||
SePolygonMode polygonMode = Gfx::SE_POLYGON_MODE_FILL;
|
||||
SeCullModeFlags cullMode = Gfx::SE_CULL_MODE_BACK_BIT;
|
||||
SeFrontFace frontFace = Gfx::SE_FRONT_FACE_COUNTER_CLOCKWISE;
|
||||
uint32 depthBiasEnable = 0;
|
||||
float depthBiasConstantFactor = 0;
|
||||
float depthBiasClamp = 0;
|
||||
float depthBiasSlopeFactor = 0;
|
||||
float lineWidth = 1.0;
|
||||
};
|
||||
struct MultisampleState
|
||||
{
|
||||
SeSampleCountFlags samples = 1;
|
||||
uint32 sampleShadingEnable = 0;
|
||||
float minSampleShading = 1;
|
||||
uint8 alphaCoverageEnable = 0;
|
||||
uint8 alphaToOneEnable = 0;
|
||||
};
|
||||
struct DepthStencilState
|
||||
{
|
||||
uint32 depthTestEnable = 1;
|
||||
uint32 depthWriteEnable = 1;
|
||||
SeCompareOp depthCompareOp = Gfx::SE_COMPARE_OP_GREATER;
|
||||
uint32 depthBoundsTestEnable = 0;
|
||||
uint32 stencilTestEnable = 0;
|
||||
SeStencilOp front = Gfx::SE_STENCIL_OP_ZERO;
|
||||
SeStencilOp back = Gfx::SE_STENCIL_OP_ZERO;
|
||||
float minDepthBounds = 0.0f;
|
||||
float maxDepthBounds = 1.0f;
|
||||
};
|
||||
struct ColorBlendState
|
||||
{
|
||||
struct BlendAttachment
|
||||
{
|
||||
uint32 blendEnable = 0;
|
||||
SeBlendFactor srcColorBlendFactor = Gfx::SE_BLEND_FACTOR_SRC_ALPHA;
|
||||
SeBlendFactor dstColorBlendFactor = Gfx::SE_BLEND_FACTOR_SRC_ALPHA;
|
||||
SeBlendOp colorBlendOp = Gfx::SE_BLEND_OP_ADD;
|
||||
SeBlendFactor srcAlphaBlendFactor = Gfx::SE_BLEND_FACTOR_SRC_ALPHA;
|
||||
SeBlendFactor dstAlphaBlendFactor = Gfx::SE_BLEND_FACTOR_SRC_ALPHA;
|
||||
SeBlendOp alphaBlendOp = Gfx::SE_BLEND_OP_ADD;
|
||||
SeColorComponentFlags colorWriteMask = Gfx::SE_COLOR_COMPONENT_R_BIT | Gfx::SE_COLOR_COMPONENT_G_BIT | Gfx::SE_COLOR_COMPONENT_B_BIT | Gfx::SE_COLOR_COMPONENT_A_BIT;
|
||||
};
|
||||
uint32 logicOpEnable = 0;
|
||||
SeLogicOp logicOp = Gfx::SE_LOGIC_OP_OR;
|
||||
uint32 attachmentCount = 0;
|
||||
StaticArray<BlendAttachment, 16> blendAttachments;
|
||||
StaticArray<float, 4> blendConstants = { 1.0f, 1.0f, 1.0f, 1.0f, };
|
||||
};
|
||||
namespace Seele {
|
||||
struct GraphicsInitializer {
|
||||
const char* applicationName;
|
||||
const char* engineName;
|
||||
const char* windowLayoutFile;
|
||||
/**
|
||||
* layers defines the enabled Vulkan layers used in the instance,
|
||||
* if ENABLE_VALIDATION is defined, standard validation is already enabled
|
||||
* not yet implemented
|
||||
*/
|
||||
Array<const char*> layers;
|
||||
Array<const char*> instanceExtensions;
|
||||
Array<const char*> deviceExtensions;
|
||||
|
||||
DECLARE_REF(VertexInput)
|
||||
DECLARE_REF(VertexShader)
|
||||
DECLARE_REF(TaskShader)
|
||||
DECLARE_REF(MeshShader)
|
||||
DECLARE_REF(FragmentShader)
|
||||
DECLARE_REF(ComputeShader)
|
||||
DECLARE_REF(RenderPass)
|
||||
DECLARE_REF(PipelineLayout)
|
||||
struct LegacyPipelineCreateInfo
|
||||
{
|
||||
SePrimitiveTopology topology = Gfx::SE_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
|
||||
PVertexInput vertexInput = nullptr;
|
||||
PVertexShader vertexShader = nullptr;
|
||||
PFragmentShader fragmentShader = nullptr;
|
||||
PRenderPass renderPass = nullptr;
|
||||
PPipelineLayout pipelineLayout = nullptr;
|
||||
MultisampleState multisampleState;
|
||||
RasterizationState rasterizationState;
|
||||
DepthStencilState depthStencilState;
|
||||
ColorBlendState colorBlend;
|
||||
};
|
||||
void* windowHandle;
|
||||
GraphicsInitializer()
|
||||
: applicationName("SeeleEngine"), engineName("SeeleEngine"), windowLayoutFile(nullptr), layers{"VK_LAYER_LUNARG_monitor"},
|
||||
instanceExtensions{}, deviceExtensions{"VK_KHR_swapchain"}, windowHandle(nullptr) {}
|
||||
};
|
||||
struct WindowCreateInfo {
|
||||
int32 width;
|
||||
int32 height;
|
||||
const char* title;
|
||||
Gfx::SeFormat preferredFormat = Gfx::SE_FORMAT_B8G8R8A8_UNORM;
|
||||
void* windowHandle;
|
||||
};
|
||||
struct ViewportCreateInfo {
|
||||
URect dimensions;
|
||||
float fieldOfView = 1.222f; // 70 deg
|
||||
Gfx::SeSampleCountFlags numSamples;
|
||||
};
|
||||
// doesnt own the data, only proxy it
|
||||
struct DataSource {
|
||||
uint64 size = 0;
|
||||
uint64 offset = 0;
|
||||
uint8* data = nullptr;
|
||||
Gfx::QueueType owner = Gfx::QueueType::GRAPHICS;
|
||||
};
|
||||
struct TextureCreateInfo {
|
||||
DataSource sourceData = DataSource();
|
||||
Gfx::SeFormat format = Gfx::SE_FORMAT_R32G32B32A32_SFLOAT;
|
||||
uint32 width = 1;
|
||||
uint32 height = 1;
|
||||
uint32 depth = 1;
|
||||
uint32 mipLevels = 1;
|
||||
uint32 layers = 1;
|
||||
uint32 elements = 1;
|
||||
uint32 samples = 1;
|
||||
Gfx::SeImageUsageFlags usage = Gfx::SE_IMAGE_USAGE_SAMPLED_BIT;
|
||||
Gfx::SeMemoryPropertyFlags memoryProps = Gfx::SE_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
|
||||
std::string name;
|
||||
};
|
||||
struct SamplerCreateInfo {
|
||||
Gfx::SeSamplerCreateFlags flags;
|
||||
Gfx::SeFilter magFilter = Gfx::SE_FILTER_LINEAR;
|
||||
Gfx::SeFilter minFilter = Gfx::SE_FILTER_LINEAR;
|
||||
Gfx::SeSamplerMipmapMode mipmapMode = Gfx::SE_SAMPLER_MIPMAP_MODE_LINEAR;
|
||||
Gfx::SeSamplerAddressMode addressModeU = Gfx::SE_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||
Gfx::SeSamplerAddressMode addressModeV = Gfx::SE_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||
Gfx::SeSamplerAddressMode addressModeW = Gfx::SE_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||
float mipLodBias = 0.0f;
|
||||
uint32 anisotropyEnable = 0;
|
||||
float maxAnisotropy = 0.0f;
|
||||
uint32 compareEnable = 0;
|
||||
Gfx::SeCompareOp compareOp = Gfx::SE_COMPARE_OP_NEVER;
|
||||
float minLod = 0.0f;
|
||||
float maxLod = 0.0f;
|
||||
Gfx::SeBorderColor borderColor = Gfx::SE_BORDER_COLOR_FLOAT_OPAQUE_BLACK;
|
||||
uint32 unnormalizedCoordinates = 0;
|
||||
std::string name;
|
||||
};
|
||||
struct VertexBufferCreateInfo {
|
||||
DataSource sourceData = DataSource();
|
||||
// bytes per vertex
|
||||
uint32 vertexSize = 0;
|
||||
uint32 numVertices = 0;
|
||||
std::string name = "Unnamed";
|
||||
};
|
||||
struct IndexBufferCreateInfo {
|
||||
DataSource sourceData = DataSource();
|
||||
Gfx::SeIndexType indexType = Gfx::SeIndexType::SE_INDEX_TYPE_UINT16;
|
||||
std::string name = "Unnamed";
|
||||
};
|
||||
struct UniformBufferCreateInfo {
|
||||
DataSource sourceData = DataSource();
|
||||
uint8 dynamic = 0;
|
||||
std::string name = "Unnamed";
|
||||
};
|
||||
struct ShaderBufferCreateInfo {
|
||||
DataSource sourceData = DataSource();
|
||||
uint64 numElements = 1;
|
||||
uint8 dynamic = 0;
|
||||
uint8 vertexBuffer = 0;
|
||||
std::string name = "Unnamed";
|
||||
};
|
||||
DECLARE_NAME_REF(Gfx, PipelineLayout)
|
||||
struct ShaderCreateInfo {
|
||||
std::string name; // Debug info
|
||||
std::string mainModule;
|
||||
Array<std::string> additionalModules;
|
||||
std::string entryPoint;
|
||||
Array<Pair<const char*, const char*>> typeParameter;
|
||||
Map<const char*, const char*> defines;
|
||||
Gfx::PPipelineLayout rootSignature;
|
||||
};
|
||||
struct VertexInputBinding {
|
||||
uint32 binding;
|
||||
uint32 stride;
|
||||
Gfx::SeVertexInputRate inputRate;
|
||||
};
|
||||
struct VertexInputAttribute {
|
||||
uint32 location;
|
||||
uint32 binding;
|
||||
Gfx::SeFormat format;
|
||||
uint32 offset;
|
||||
};
|
||||
struct VertexInputStateCreateInfo {
|
||||
Array<VertexInputBinding> bindings;
|
||||
Array<VertexInputAttribute> attributes;
|
||||
};
|
||||
DECLARE_REF(MaterialInstance)
|
||||
DECLARE_REF(Mesh)
|
||||
namespace Gfx {
|
||||
struct SePushConstantRange {
|
||||
SeShaderStageFlags stageFlags;
|
||||
uint32 offset;
|
||||
uint32 size;
|
||||
};
|
||||
struct RasterizationState {
|
||||
uint32 depthClampEnable = 0;
|
||||
uint32 rasterizerDiscardEnable = 0;
|
||||
SePolygonMode polygonMode = Gfx::SE_POLYGON_MODE_FILL;
|
||||
SeCullModeFlags cullMode = Gfx::SE_CULL_MODE_BACK_BIT;
|
||||
SeFrontFace frontFace = Gfx::SE_FRONT_FACE_COUNTER_CLOCKWISE;
|
||||
uint32 depthBiasEnable = 0;
|
||||
float depthBiasConstantFactor = 0;
|
||||
float depthBiasClamp = 0;
|
||||
float depthBiasSlopeFactor = 0;
|
||||
float lineWidth = 1.0;
|
||||
};
|
||||
struct MultisampleState {
|
||||
SeSampleCountFlags samples = 1;
|
||||
uint32 sampleShadingEnable = 0;
|
||||
float minSampleShading = 1;
|
||||
uint8 alphaCoverageEnable = 0;
|
||||
uint8 alphaToOneEnable = 0;
|
||||
};
|
||||
struct DepthStencilState {
|
||||
uint32 depthTestEnable = 1;
|
||||
uint32 depthWriteEnable = 1;
|
||||
SeCompareOp depthCompareOp = Gfx::SE_COMPARE_OP_GREATER;
|
||||
uint32 depthBoundsTestEnable = 0;
|
||||
uint32 stencilTestEnable = 0;
|
||||
SeStencilOp front = Gfx::SE_STENCIL_OP_ZERO;
|
||||
SeStencilOp back = Gfx::SE_STENCIL_OP_ZERO;
|
||||
float minDepthBounds = 0.0f;
|
||||
float maxDepthBounds = 1.0f;
|
||||
};
|
||||
struct ColorBlendState {
|
||||
struct BlendAttachment {
|
||||
uint32 blendEnable = 0;
|
||||
SeBlendFactor srcColorBlendFactor = Gfx::SE_BLEND_FACTOR_SRC_ALPHA;
|
||||
SeBlendFactor dstColorBlendFactor = Gfx::SE_BLEND_FACTOR_SRC_ALPHA;
|
||||
SeBlendOp colorBlendOp = Gfx::SE_BLEND_OP_ADD;
|
||||
SeBlendFactor srcAlphaBlendFactor = Gfx::SE_BLEND_FACTOR_SRC_ALPHA;
|
||||
SeBlendFactor dstAlphaBlendFactor = Gfx::SE_BLEND_FACTOR_SRC_ALPHA;
|
||||
SeBlendOp alphaBlendOp = Gfx::SE_BLEND_OP_ADD;
|
||||
SeColorComponentFlags colorWriteMask =
|
||||
Gfx::SE_COLOR_COMPONENT_R_BIT | Gfx::SE_COLOR_COMPONENT_G_BIT | Gfx::SE_COLOR_COMPONENT_B_BIT | Gfx::SE_COLOR_COMPONENT_A_BIT;
|
||||
};
|
||||
uint32 logicOpEnable = 0;
|
||||
SeLogicOp logicOp = Gfx::SE_LOGIC_OP_OR;
|
||||
uint32 attachmentCount = 0;
|
||||
StaticArray<BlendAttachment, 16> blendAttachments;
|
||||
StaticArray<float, 4> blendConstants = {
|
||||
1.0f,
|
||||
1.0f,
|
||||
1.0f,
|
||||
1.0f,
|
||||
};
|
||||
};
|
||||
|
||||
struct MeshPipelineCreateInfo
|
||||
{
|
||||
PTaskShader taskShader = nullptr;
|
||||
PMeshShader meshShader = nullptr;
|
||||
PFragmentShader fragmentShader = nullptr;
|
||||
PRenderPass renderPass = nullptr;
|
||||
PPipelineLayout pipelineLayout = nullptr;
|
||||
MultisampleState multisampleState;
|
||||
RasterizationState rasterizationState;
|
||||
DepthStencilState depthStencilState;
|
||||
ColorBlendState colorBlend;
|
||||
};
|
||||
struct ComputePipelineCreateInfo
|
||||
{
|
||||
Gfx::PComputeShader computeShader = nullptr;
|
||||
Gfx::PPipelineLayout pipelineLayout = nullptr;
|
||||
};
|
||||
DECLARE_REF(ShaderBuffer)
|
||||
struct BottomLevelASCreateInfo
|
||||
{
|
||||
PShaderBuffer positionBuffer;
|
||||
PShaderBuffer indexBuffer;
|
||||
MeshData meshData;
|
||||
PMaterialInstance material;
|
||||
uint64 verticesOffset;
|
||||
uint64 indicesOffset;
|
||||
};
|
||||
struct TopLevelASCreateInfo
|
||||
{
|
||||
DECLARE_REF(VertexInput)
|
||||
DECLARE_REF(VertexShader)
|
||||
DECLARE_REF(TaskShader)
|
||||
DECLARE_REF(MeshShader)
|
||||
DECLARE_REF(FragmentShader)
|
||||
DECLARE_REF(ComputeShader)
|
||||
DECLARE_REF(RenderPass)
|
||||
DECLARE_REF(PipelineLayout)
|
||||
struct LegacyPipelineCreateInfo {
|
||||
SePrimitiveTopology topology = Gfx::SE_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
|
||||
PVertexInput vertexInput = nullptr;
|
||||
PVertexShader vertexShader = nullptr;
|
||||
PFragmentShader fragmentShader = nullptr;
|
||||
PRenderPass renderPass = nullptr;
|
||||
PPipelineLayout pipelineLayout = nullptr;
|
||||
MultisampleState multisampleState;
|
||||
RasterizationState rasterizationState;
|
||||
DepthStencilState depthStencilState;
|
||||
ColorBlendState colorBlend;
|
||||
};
|
||||
|
||||
};
|
||||
} // namespace Gfx
|
||||
struct MeshPipelineCreateInfo {
|
||||
PTaskShader taskShader = nullptr;
|
||||
PMeshShader meshShader = nullptr;
|
||||
PFragmentShader fragmentShader = nullptr;
|
||||
PRenderPass renderPass = nullptr;
|
||||
PPipelineLayout pipelineLayout = nullptr;
|
||||
MultisampleState multisampleState;
|
||||
RasterizationState rasterizationState;
|
||||
DepthStencilState depthStencilState;
|
||||
ColorBlendState colorBlend;
|
||||
};
|
||||
struct ComputePipelineCreateInfo {
|
||||
Gfx::PComputeShader computeShader = nullptr;
|
||||
Gfx::PPipelineLayout pipelineLayout = nullptr;
|
||||
};
|
||||
DECLARE_REF(ShaderBuffer)
|
||||
struct BottomLevelASCreateInfo {
|
||||
PMesh mesh;
|
||||
};
|
||||
struct TopLevelASCreateInfo {};
|
||||
} // namespace Gfx
|
||||
} // namespace Seele
|
||||
|
||||
@@ -1,19 +1,15 @@
|
||||
#include "Mesh.h"
|
||||
#include "Graphics/Graphics.h"
|
||||
#include "Asset/AssetRegistry.h"
|
||||
#include "Graphics/Graphics.h"
|
||||
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
Mesh::Mesh()
|
||||
{
|
||||
}
|
||||
Mesh::Mesh() {}
|
||||
|
||||
Mesh::~Mesh()
|
||||
{
|
||||
}
|
||||
Mesh::~Mesh() {}
|
||||
|
||||
void Mesh::save(ArchiveBuffer& buffer) const
|
||||
{
|
||||
void Mesh::save(ArchiveBuffer& buffer) const {
|
||||
Serialization::save(buffer, transform);
|
||||
Serialization::save(buffer, vertexData->getTypeName());
|
||||
Serialization::save(buffer, vertexCount);
|
||||
@@ -24,8 +20,7 @@ void Mesh::save(ArchiveBuffer& buffer) const
|
||||
vertexData->serializeMesh(id, vertexCount, buffer);
|
||||
}
|
||||
|
||||
void Mesh::load(ArchiveBuffer& buffer)
|
||||
{
|
||||
void Mesh::load(ArchiveBuffer& buffer) {
|
||||
std::string typeName;
|
||||
Serialization::load(buffer, transform);
|
||||
Serialization::load(buffer, typeName);
|
||||
|
||||
+13
-20
@@ -1,13 +1,12 @@
|
||||
#pragma once
|
||||
#include "Asset/MaterialInstanceAsset.h"
|
||||
#include "VertexData.h"
|
||||
#include "Graphics/Buffer.h"
|
||||
#include "VertexData.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
class Mesh
|
||||
{
|
||||
public:
|
||||
|
||||
namespace Seele {
|
||||
class Mesh {
|
||||
public:
|
||||
Mesh();
|
||||
~Mesh();
|
||||
|
||||
@@ -21,21 +20,15 @@ public:
|
||||
Array<Meshlet> meshlets;
|
||||
void save(ArchiveBuffer& buffer) const;
|
||||
void load(ArchiveBuffer& buffer);
|
||||
private:
|
||||
|
||||
private:
|
||||
};
|
||||
DEFINE_REF(Mesh)
|
||||
namespace Serialization
|
||||
{
|
||||
template<>
|
||||
void save(ArchiveBuffer& buffer, const OMesh& ptr)
|
||||
{
|
||||
ptr->save(buffer);
|
||||
}
|
||||
template<>
|
||||
void load(ArchiveBuffer& buffer, OMesh& ptr)
|
||||
{
|
||||
ptr = new Mesh();
|
||||
ptr->load(buffer);
|
||||
}
|
||||
namespace Serialization {
|
||||
template <> void save(ArchiveBuffer& buffer, const OMesh& ptr) { ptr->save(buffer); }
|
||||
template <> void load(ArchiveBuffer& buffer, OMesh& ptr) {
|
||||
ptr = new Mesh();
|
||||
ptr->load(buffer);
|
||||
}
|
||||
} // namespace Serialization
|
||||
} // namespace Seele
|
||||
@@ -1,18 +1,15 @@
|
||||
#pragma once
|
||||
#include "Math/AABB.h"
|
||||
namespace Seele
|
||||
{
|
||||
struct MeshData
|
||||
{
|
||||
namespace Seele {
|
||||
struct MeshData {
|
||||
AABB bounding;
|
||||
uint32 numMeshlets = 0;
|
||||
uint32 meshletOffset = 0;
|
||||
uint32 firstIndex = 0;
|
||||
uint32 numIndices = 0;
|
||||
};
|
||||
struct InstanceData
|
||||
{
|
||||
struct InstanceData {
|
||||
Matrix4 transformMatrix;
|
||||
Matrix4 inverseTransformMatrix;
|
||||
};
|
||||
}
|
||||
} // namespace Seele
|
||||
@@ -1,29 +1,26 @@
|
||||
#include "Meshlet.h"
|
||||
#include "Containers/Map.h"
|
||||
#include "Containers/List.h"
|
||||
#include "Containers/Map.h"
|
||||
#include "Containers/Set.h"
|
||||
#include <iostream>
|
||||
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
struct AdjacencyInfo
|
||||
{
|
||||
struct AdjacencyInfo {
|
||||
Array<uint32> trianglesPerVertex;
|
||||
Array<uint32> indexBufferOffset;
|
||||
Array<uint32> triangleData;
|
||||
};
|
||||
|
||||
void buildAdjacency(const uint32 numVerts, const Array<uint32>& indices, AdjacencyInfo& info)
|
||||
{
|
||||
void buildAdjacency(const uint32 numVerts, const Array<uint32>& indices, AdjacencyInfo& info) {
|
||||
info.trianglesPerVertex.resize(numVerts, 0);
|
||||
for (size_t i = 0; i < indices.size(); ++i)
|
||||
{
|
||||
for (size_t i = 0; i < indices.size(); ++i) {
|
||||
info.trianglesPerVertex[indices[i]]++;
|
||||
}
|
||||
uint32 triangleOffset = 0;
|
||||
info.indexBufferOffset.resize(numVerts, 0);
|
||||
for (size_t j = 0; j < numVerts; ++j)
|
||||
{
|
||||
for (size_t j = 0; j < numVerts; ++j) {
|
||||
info.indexBufferOffset[j] = triangleOffset;
|
||||
triangleOffset += info.trianglesPerVertex[j];
|
||||
}
|
||||
@@ -31,8 +28,7 @@ void buildAdjacency(const uint32 numVerts, const Array<uint32>& indices, Adjacen
|
||||
uint32 numTriangles = indices.size() / 3;
|
||||
info.triangleData.resize(triangleOffset);
|
||||
Array<uint32> offsets = info.indexBufferOffset;
|
||||
for (uint32 k = 0; k < numTriangles; ++k)
|
||||
{
|
||||
for (uint32 k = 0; k < numTriangles; ++k) {
|
||||
int a = indices[k * 3];
|
||||
int b = indices[k * 3 + 1];
|
||||
int c = indices[k * 3 + 2];
|
||||
@@ -43,21 +39,16 @@ void buildAdjacency(const uint32 numVerts, const Array<uint32>& indices, Adjacen
|
||||
}
|
||||
}
|
||||
|
||||
int32 skipDeadEnd(const Array<uint32>& liveTriCount, List<uint32>& deadEndStack, uint32& cursor)
|
||||
{
|
||||
while (!deadEndStack.empty())
|
||||
{
|
||||
int32 skipDeadEnd(const Array<uint32>& liveTriCount, List<uint32>& deadEndStack, uint32& cursor) {
|
||||
while (!deadEndStack.empty()) {
|
||||
uint32 vertIdx = deadEndStack.front();
|
||||
deadEndStack.popFront();
|
||||
if (liveTriCount[vertIdx] > 0)
|
||||
{
|
||||
if (liveTriCount[vertIdx] > 0) {
|
||||
return vertIdx;
|
||||
}
|
||||
}
|
||||
while (cursor < liveTriCount.size())
|
||||
{
|
||||
if (liveTriCount[cursor] > 0)
|
||||
{
|
||||
while (cursor < liveTriCount.size()) {
|
||||
if (liveTriCount[cursor] > 0) {
|
||||
return cursor;
|
||||
}
|
||||
++cursor;
|
||||
@@ -65,35 +56,29 @@ int32 skipDeadEnd(const Array<uint32>& liveTriCount, List<uint32>& deadEndStack,
|
||||
return -1;
|
||||
}
|
||||
|
||||
int32 getNextVertex(const uint32 cacheSize, const Array<uint32>& oneRing, const Array<uint32>& cacheTimeStamps, const uint32 timeStamp, const Array<uint32>& liveTriCount, List<uint32>& deadEndStack, uint32& cursor)
|
||||
{
|
||||
int32 getNextVertex(const uint32 cacheSize, const Array<uint32>& oneRing, const Array<uint32>& cacheTimeStamps, const uint32 timeStamp,
|
||||
const Array<uint32>& liveTriCount, List<uint32>& deadEndStack, uint32& cursor) {
|
||||
uint32 bestCandidate = std::numeric_limits<uint32>::max();
|
||||
int highestPriority = -1;
|
||||
for (const uint32& vertIdx : oneRing)
|
||||
{
|
||||
if (liveTriCount[vertIdx] > 0)
|
||||
{
|
||||
for (const uint32& vertIdx : oneRing) {
|
||||
if (liveTriCount[vertIdx] > 0) {
|
||||
int priority = 0;
|
||||
if (timeStamp - cacheTimeStamps[vertIdx] + 2 * liveTriCount[vertIdx] <= cacheSize)
|
||||
{
|
||||
if (timeStamp - cacheTimeStamps[vertIdx] + 2 * liveTriCount[vertIdx] <= cacheSize) {
|
||||
priority = timeStamp - cacheTimeStamps[vertIdx];
|
||||
}
|
||||
if (priority > highestPriority)
|
||||
{
|
||||
if (priority > highestPriority) {
|
||||
highestPriority = priority;
|
||||
bestCandidate = vertIdx;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(bestCandidate == std::numeric_limits<uint32>::max())
|
||||
{
|
||||
if (bestCandidate == std::numeric_limits<uint32>::max()) {
|
||||
bestCandidate = skipDeadEnd(liveTriCount, deadEndStack, cursor);
|
||||
}
|
||||
return bestCandidate;
|
||||
}
|
||||
|
||||
void tipsifyIndexBuffer(const Array<uint32>& indices, const uint32 numVerts, const uint32 cacheSize, Array<uint32>& outIndices)
|
||||
{
|
||||
void tipsifyIndexBuffer(const Array<uint32>& indices, const uint32 numVerts, const uint32 cacheSize, Array<uint32>& outIndices) {
|
||||
AdjacencyInfo adjacencyStruct;
|
||||
buildAdjacency(numVerts, indices, adjacencyStruct);
|
||||
|
||||
@@ -108,14 +93,12 @@ void tipsifyIndexBuffer(const Array<uint32>& indices, const uint32 numVerts, con
|
||||
int32 curVert = 0;
|
||||
uint32 timeStamp = cacheSize + 1;
|
||||
uint32 cursor = 1;
|
||||
while (curVert != -1)
|
||||
{
|
||||
while (curVert != -1) {
|
||||
Array<uint32> oneRing;
|
||||
const uint32* startTriPointer = &adjacencyStruct.triangleData[0] + adjacencyStruct.indexBufferOffset[curVert];
|
||||
const uint32* endTriPointer = startTriPointer + adjacencyStruct.trianglesPerVertex[curVert];
|
||||
|
||||
for (const uint32* it = startTriPointer; it != endTriPointer; ++it)
|
||||
{
|
||||
for (const uint32* it = startTriPointer; it != endTriPointer; ++it) {
|
||||
uint32 triangle = *it;
|
||||
|
||||
if (emittedTriangles[triangle])
|
||||
@@ -156,22 +139,17 @@ void tipsifyIndexBuffer(const Array<uint32>& indices, const uint32 numVerts, con
|
||||
}
|
||||
}
|
||||
|
||||
struct Triangle
|
||||
{
|
||||
struct Triangle {
|
||||
StaticArray<uint32, 3> indices;
|
||||
};
|
||||
|
||||
int findIndex(Meshlet ¤t, uint32 index)
|
||||
{
|
||||
for (uint32 i = 0; i < current.numVertices; ++i)
|
||||
{
|
||||
if (current.uniqueVertices[i] == index)
|
||||
{
|
||||
int findIndex(Meshlet& current, uint32 index) {
|
||||
for (uint32 i = 0; i < current.numVertices; ++i) {
|
||||
if (current.uniqueVertices[i] == index) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
if (current.numVertices == Gfx::numVerticesPerMeshlet)
|
||||
{
|
||||
if (current.numVertices == Gfx::numVerticesPerMeshlet) {
|
||||
return -1;
|
||||
}
|
||||
current.uniqueVertices[current.numVertices] = index;
|
||||
@@ -179,8 +157,7 @@ int findIndex(Meshlet ¤t, uint32 index)
|
||||
return current.numVertices++;
|
||||
}
|
||||
|
||||
void completeMeshlet(Array<Meshlet> &meshlets, Meshlet ¤t)
|
||||
{
|
||||
void completeMeshlet(Array<Meshlet>& meshlets, Meshlet& current) {
|
||||
meshlets.add(current);
|
||||
current = {
|
||||
.boundingBox = AABB(),
|
||||
@@ -189,14 +166,12 @@ void completeMeshlet(Array<Meshlet> &meshlets, Meshlet ¤t)
|
||||
};
|
||||
}
|
||||
|
||||
bool addTriangle(const Array<Vector>& positions, Meshlet ¤t, Triangle& tri)
|
||||
{
|
||||
bool addTriangle(const Array<Vector>& positions, Meshlet& current, Triangle& tri) {
|
||||
int f1 = findIndex(current, tri.indices[0]);
|
||||
int f2 = findIndex(current, tri.indices[1]);
|
||||
int f3 = findIndex(current, tri.indices[2]);
|
||||
|
||||
if (f1 == -1 || f2 == -1 || f3 == -1 || current.numPrimitives == Gfx::numPrimitivesPerMeshlet)
|
||||
{
|
||||
if (f1 == -1 || f2 == -1 || f3 == -1 || current.numPrimitives == Gfx::numPrimitivesPerMeshlet) {
|
||||
return false;
|
||||
}
|
||||
current.boundingBox.adjust(positions[tri.indices[0]]);
|
||||
@@ -209,36 +184,32 @@ bool addTriangle(const Array<Vector>& positions, Meshlet ¤t, Triangle& tri
|
||||
return true;
|
||||
}
|
||||
|
||||
void Meshlet::build(const Array<Vector> &positions, const Array<uint32> &indices, Array<Meshlet> &meshlets)
|
||||
{
|
||||
void Meshlet::build(const Array<Vector>& positions, const Array<uint32>& indices, Array<Meshlet>& meshlets) {
|
||||
Meshlet current = {
|
||||
.numVertices = 0,
|
||||
.numPrimitives = 0,
|
||||
};
|
||||
//Array<uint32> optimizedIndices = indices;
|
||||
//tipsifyIndexBuffer(indices, positions.size(), 25, optimizedIndices);
|
||||
// Array<uint32> optimizedIndices = indices;
|
||||
// tipsifyIndexBuffer(indices, positions.size(), 25, optimizedIndices);
|
||||
Array<Triangle> triangles(indices.size() / 3);
|
||||
for (size_t i = 0; i < triangles.size(); ++i)
|
||||
{
|
||||
for (size_t i = 0; i < triangles.size(); ++i) {
|
||||
triangles[i] = Triangle{
|
||||
.indices = {
|
||||
indices[i * 3 + 0],
|
||||
indices[i * 3 + 1],
|
||||
indices[i * 3 + 2],
|
||||
},
|
||||
.indices =
|
||||
{
|
||||
indices[i * 3 + 0],
|
||||
indices[i * 3 + 1],
|
||||
indices[i * 3 + 2],
|
||||
},
|
||||
};
|
||||
}
|
||||
while(!triangles.empty())
|
||||
{
|
||||
if (!addTriangle(positions, current, triangles.back()))
|
||||
{
|
||||
while (!triangles.empty()) {
|
||||
if (!addTriangle(positions, current, triangles.back())) {
|
||||
completeMeshlet(meshlets, current);
|
||||
addTriangle(positions, current, triangles.back());
|
||||
}
|
||||
triangles.pop();
|
||||
}
|
||||
if (current.numVertices > 0)
|
||||
{
|
||||
if (current.numVertices > 0) {
|
||||
completeMeshlet(meshlets, current);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
#pragma once
|
||||
#include "Math/AABB.h"
|
||||
#include "Graphics/Enums.h"
|
||||
#include "Math/AABB.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
struct Meshlet
|
||||
{
|
||||
|
||||
namespace Seele {
|
||||
struct Meshlet {
|
||||
AABB boundingBox;
|
||||
uint32 uniqueVertices[Gfx::numVerticesPerMeshlet]; // unique vertiex indices in the vertex data
|
||||
uint32 uniqueVertices[Gfx::numVerticesPerMeshlet]; // unique vertiex indices in the vertex data
|
||||
uint8 primitiveLayout[Gfx::numPrimitivesPerMeshlet * 3]; // indices into the uniqueVertices array, only uint8 needed
|
||||
uint32 numVertices;
|
||||
uint32 numPrimitives;
|
||||
|
||||
@@ -9,93 +9,93 @@
|
||||
namespace Seele {
|
||||
namespace Metal {
|
||||
DECLARE_REF(Graphics)
|
||||
class BufferAllocation : public CommandBoundResource
|
||||
{
|
||||
public:
|
||||
BufferAllocation(PGraphics graphics);
|
||||
virtual ~BufferAllocation();
|
||||
MTL::Buffer* buffer = nullptr;
|
||||
uint64 size = 0;
|
||||
class BufferAllocation : public CommandBoundResource {
|
||||
public:
|
||||
BufferAllocation(PGraphics graphics);
|
||||
virtual ~BufferAllocation();
|
||||
MTL::Buffer* buffer = nullptr;
|
||||
uint64 size = 0;
|
||||
};
|
||||
DECLARE_REF(BufferAllocation)
|
||||
class Buffer {
|
||||
public:
|
||||
Buffer(PGraphics graphics, uint64 size, void *data, bool dynamic, const std::string& name);
|
||||
virtual ~Buffer();
|
||||
MTL::Buffer *getHandle() const { return buffers[currentBuffer]->buffer; }
|
||||
PBufferAllocation getAlloc() const { return buffers[currentBuffer]; }
|
||||
uint64 getSize() const { return buffers[currentBuffer]->size; }
|
||||
void *map(bool writeOnly = true);
|
||||
void *mapRegion(uint64 regionOffset, uint64 regionSize, bool writeOnly);
|
||||
void unmap();
|
||||
public:
|
||||
Buffer(PGraphics graphics, uint64 size, void* data, bool dynamic, const std::string& name);
|
||||
virtual ~Buffer();
|
||||
MTL::Buffer* getHandle() const { return buffers[currentBuffer]->buffer; }
|
||||
PBufferAllocation getAlloc() const { return buffers[currentBuffer]; }
|
||||
uint64 getSize() const { return buffers[currentBuffer]->size; }
|
||||
void* map(bool writeOnly = true);
|
||||
void* mapRegion(uint64 regionOffset, uint64 regionSize, bool writeOnly);
|
||||
void unmap();
|
||||
|
||||
protected:
|
||||
PGraphics graphics;
|
||||
uint32 currentBuffer = 0;
|
||||
Array<OBufferAllocation> buffers;
|
||||
bool dynamic;
|
||||
std::string name;
|
||||
void rotateBuffer(uint64 size);
|
||||
void createBuffer(uint64 size, void* data);
|
||||
protected:
|
||||
PGraphics graphics;
|
||||
uint32 currentBuffer = 0;
|
||||
Array<OBufferAllocation> buffers;
|
||||
bool dynamic;
|
||||
std::string name;
|
||||
void rotateBuffer(uint64 size);
|
||||
void createBuffer(uint64 size, void* data);
|
||||
};
|
||||
DEFINE_REF(Buffer)
|
||||
|
||||
class VertexBuffer : public Gfx::VertexBuffer, public Buffer {
|
||||
public:
|
||||
VertexBuffer(PGraphics graphics, const VertexBufferCreateInfo &createInfo);
|
||||
virtual ~VertexBuffer();
|
||||
virtual void updateRegion(DataSource update) override;
|
||||
virtual void download(Array<uint8> &buffer) override;
|
||||
public:
|
||||
VertexBuffer(PGraphics graphics, const VertexBufferCreateInfo& createInfo);
|
||||
virtual ~VertexBuffer();
|
||||
virtual void updateRegion(DataSource update) override;
|
||||
virtual void download(Array<uint8>& buffer) override;
|
||||
|
||||
protected:
|
||||
// Inherited via QueueOwnedResource
|
||||
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner) override;
|
||||
virtual void executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) override;
|
||||
protected:
|
||||
// Inherited via QueueOwnedResource
|
||||
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner) override;
|
||||
virtual void executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, Gfx::SeAccessFlags dstAccess,
|
||||
Gfx::SePipelineStageFlags dstStage) override;
|
||||
};
|
||||
DEFINE_REF(VertexBuffer)
|
||||
class IndexBuffer : public Gfx::IndexBuffer, public Buffer {
|
||||
public:
|
||||
IndexBuffer(PGraphics graphics, const IndexBufferCreateInfo &createInfo);
|
||||
virtual ~IndexBuffer();
|
||||
public:
|
||||
IndexBuffer(PGraphics graphics, const IndexBufferCreateInfo& createInfo);
|
||||
virtual ~IndexBuffer();
|
||||
|
||||
virtual void download(Array<uint8> &buffer) override;
|
||||
protected:
|
||||
// Inherited via QueueOwnedResource
|
||||
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner) override;
|
||||
virtual void executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) override;
|
||||
virtual void download(Array<uint8>& buffer) override;
|
||||
|
||||
protected:
|
||||
// Inherited via QueueOwnedResource
|
||||
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner) override;
|
||||
virtual void executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, Gfx::SeAccessFlags dstAccess,
|
||||
Gfx::SePipelineStageFlags dstStage) override;
|
||||
};
|
||||
DEFINE_REF(IndexBuffer)
|
||||
DEFINE_REF(IndexBuffer)
|
||||
class UniformBuffer : public Gfx::UniformBuffer, public Buffer {
|
||||
public:
|
||||
UniformBuffer(PGraphics graphics, const UniformBufferCreateInfo &createInfo);
|
||||
virtual ~UniformBuffer();
|
||||
public:
|
||||
UniformBuffer(PGraphics graphics, const UniformBufferCreateInfo& createInfo);
|
||||
virtual ~UniformBuffer();
|
||||
|
||||
virtual bool updateContents(const DataSource &sourceData) override;
|
||||
virtual bool updateContents(const DataSource& sourceData) override;
|
||||
|
||||
protected:
|
||||
// Inherited via QueueOwnedResource
|
||||
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner) override;
|
||||
virtual void executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) override;
|
||||
protected:
|
||||
// Inherited via QueueOwnedResource
|
||||
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner) override;
|
||||
virtual void executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, Gfx::SeAccessFlags dstAccess,
|
||||
Gfx::SePipelineStageFlags dstStage) override;
|
||||
};
|
||||
DEFINE_REF(UniformBuffer)
|
||||
class ShaderBuffer : public Gfx::ShaderBuffer, public Buffer {
|
||||
public:
|
||||
ShaderBuffer(PGraphics graphics, const ShaderBufferCreateInfo &createInfo);
|
||||
virtual ~ShaderBuffer();
|
||||
virtual void rotateBuffer(uint64 size) override;
|
||||
virtual void updateContents(const ShaderBufferCreateInfo &sourceData) override;
|
||||
virtual void *mapRegion(uint64 offset, uint64 size, bool writeOnly) override;
|
||||
virtual void unmap() override;
|
||||
public:
|
||||
ShaderBuffer(PGraphics graphics, const ShaderBufferCreateInfo& createInfo);
|
||||
virtual ~ShaderBuffer();
|
||||
virtual void rotateBuffer(uint64 size) override;
|
||||
virtual void updateContents(const ShaderBufferCreateInfo& sourceData) override;
|
||||
virtual void* mapRegion(uint64 offset, uint64 size, bool writeOnly) override;
|
||||
virtual void unmap() override;
|
||||
|
||||
protected:
|
||||
// Inherited via QueueOwnedResource
|
||||
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner) override;
|
||||
virtual void executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) override;
|
||||
protected:
|
||||
// Inherited via QueueOwnedResource
|
||||
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner) override;
|
||||
virtual void executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, Gfx::SeAccessFlags dstAccess,
|
||||
Gfx::SePipelineStageFlags dstStage) override;
|
||||
};
|
||||
DEFINE_REF(ShaderBuffer)
|
||||
} // namespace Metal
|
||||
|
||||
@@ -11,49 +11,44 @@ using namespace Seele;
|
||||
using namespace Seele::Metal;
|
||||
|
||||
BufferAllocation::BufferAllocation(PGraphics graphics)
|
||||
: CommandBoundResource(graphics)
|
||||
{}
|
||||
: CommandBoundResource(graphics) {}
|
||||
|
||||
BufferAllocation::~BufferAllocation()
|
||||
{
|
||||
if(buffer != nullptr)
|
||||
{
|
||||
BufferAllocation::~BufferAllocation() {
|
||||
if (buffer != nullptr) {
|
||||
buffer->release();
|
||||
}
|
||||
}
|
||||
|
||||
Buffer::Buffer(PGraphics graphics, uint64 size, void* data, bool dynamic, const std::string& name)
|
||||
: graphics(graphics)
|
||||
, dynamic(dynamic)
|
||||
, name(name) {
|
||||
Buffer::Buffer(PGraphics graphics, uint64 size, void *data, bool dynamic,
|
||||
const std::string &name)
|
||||
: graphics(graphics), dynamic(dynamic), name(name) {
|
||||
createBuffer(size, data);
|
||||
}
|
||||
|
||||
Buffer::~Buffer() {
|
||||
for (size_t i = 0; i < buffers.size(); ++i) {
|
||||
//TODO
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
|
||||
void* Buffer::map(bool) { return getHandle()->contents(); }
|
||||
void *Buffer::map(bool) { return getHandle()->contents(); }
|
||||
|
||||
void* Buffer::mapRegion(uint64 regionOffset, uint64, bool) { return (char*)getHandle()->contents() + regionOffset; }
|
||||
void *Buffer::mapRegion(uint64 regionOffset, uint64, bool) {
|
||||
return (char *)getHandle()->contents() + regionOffset;
|
||||
}
|
||||
|
||||
void Buffer::unmap() {}
|
||||
|
||||
void Buffer::rotateBuffer(uint64 size)
|
||||
{
|
||||
void Buffer::rotateBuffer(uint64 size) {
|
||||
size = std::max(getSize(), size);
|
||||
for(size_t i = 0; i < buffers.size(); ++i)
|
||||
{
|
||||
if(buffers[i]->isCurrentlyBound())
|
||||
{
|
||||
for (size_t i = 0; i < buffers.size(); ++i) {
|
||||
if (buffers[i]->isCurrentlyBound()) {
|
||||
continue;
|
||||
}
|
||||
if(buffers[i]->size < size)
|
||||
{
|
||||
if (buffers[i]->size < size) {
|
||||
buffers[i]->buffer->release();
|
||||
buffers[i]->buffer = graphics->getDevice()->newBuffer(size, MTL::StorageModeShared);
|
||||
buffers[i]->buffer =
|
||||
graphics->getDevice()->newBuffer(size, MTL::StorageModeShared);
|
||||
buffers[i]->size = size;
|
||||
}
|
||||
currentBuffer = i;
|
||||
@@ -63,79 +58,106 @@ void Buffer::rotateBuffer(uint64 size)
|
||||
currentBuffer = buffers.size() - 1;
|
||||
}
|
||||
|
||||
void Buffer::createBuffer(uint64 size, void* data)
|
||||
{
|
||||
void Buffer::createBuffer(uint64 size, void *data) {
|
||||
buffers.add(new BufferAllocation(graphics));
|
||||
if (data != nullptr) {
|
||||
buffers.back()->buffer = graphics->getDevice()->newBuffer(data, size, MTL::StorageModeShared);
|
||||
buffers.back()->buffer =
|
||||
graphics->getDevice()->newBuffer(data, size, MTL::StorageModeShared);
|
||||
} else {
|
||||
buffers.back()->buffer = graphics->getDevice()->newBuffer(size, MTL::StorageModeShared);
|
||||
buffers.back()->buffer =
|
||||
graphics->getDevice()->newBuffer(size, MTL::StorageModeShared);
|
||||
}
|
||||
buffers.back()->buffer->setLabel(NS::String::string(name.c_str(), NS::ASCIIStringEncoding));
|
||||
buffers.back()->buffer->setLabel(
|
||||
NS::String::string(name.c_str(), NS::ASCIIStringEncoding));
|
||||
}
|
||||
|
||||
VertexBuffer::VertexBuffer(PGraphics graphics, const VertexBufferCreateInfo& createInfo)
|
||||
: Gfx::VertexBuffer(graphics->getFamilyMapping(), createInfo.numVertices, createInfo.vertexSize,
|
||||
createInfo.sourceData.owner),
|
||||
Seele::Metal::Buffer(graphics, createInfo.sourceData.size, createInfo.sourceData.data, false, createInfo.name) {}
|
||||
VertexBuffer::VertexBuffer(PGraphics graphics,
|
||||
const VertexBufferCreateInfo &createInfo)
|
||||
: Gfx::VertexBuffer(graphics->getFamilyMapping(), createInfo.numVertices,
|
||||
createInfo.vertexSize, createInfo.sourceData.owner),
|
||||
Seele::Metal::Buffer(graphics, createInfo.sourceData.size,
|
||||
createInfo.sourceData.data, false, createInfo.name) {
|
||||
}
|
||||
|
||||
VertexBuffer::~VertexBuffer() {}
|
||||
|
||||
void VertexBuffer::updateRegion(DataSource update) {
|
||||
void* data = getHandle()->contents();
|
||||
std::memcpy((char*)data + update.offset, update.data, update.size);
|
||||
void *data = getHandle()->contents();
|
||||
std::memcpy((char *)data + update.offset, update.data, update.size);
|
||||
}
|
||||
|
||||
void VertexBuffer::download(Array<uint8>& buffer) {
|
||||
void* data = getHandle()->contents();
|
||||
void VertexBuffer::download(Array<uint8> &buffer) {
|
||||
void *data = getHandle()->contents();
|
||||
buffer.resize(getSize());
|
||||
std::memcpy(buffer.data(), data, getSize());
|
||||
}
|
||||
|
||||
void VertexBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) { currentOwner = newOwner; }
|
||||
|
||||
void VertexBuffer::executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) {
|
||||
|
||||
void VertexBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) {
|
||||
currentOwner = newOwner;
|
||||
}
|
||||
|
||||
IndexBuffer::IndexBuffer(PGraphics graphics, const IndexBufferCreateInfo& createInfo)
|
||||
: Gfx::IndexBuffer(graphics->getFamilyMapping(), createInfo.sourceData.size, createInfo.indexType,
|
||||
createInfo.sourceData.owner),
|
||||
Seele::Metal::Buffer(graphics, createInfo.sourceData.size, createInfo.sourceData.data, false, createInfo.name) {}
|
||||
void VertexBuffer::executePipelineBarrier(Gfx::SeAccessFlags srcAccess,
|
||||
Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess,
|
||||
Gfx::SePipelineStageFlags dstStage) {}
|
||||
|
||||
IndexBuffer::IndexBuffer(PGraphics graphics,
|
||||
const IndexBufferCreateInfo &createInfo)
|
||||
: Gfx::IndexBuffer(graphics->getFamilyMapping(), createInfo.sourceData.size,
|
||||
createInfo.indexType, createInfo.sourceData.owner),
|
||||
Seele::Metal::Buffer(graphics, createInfo.sourceData.size,
|
||||
createInfo.sourceData.data, false, createInfo.name) {
|
||||
}
|
||||
|
||||
IndexBuffer::~IndexBuffer() {}
|
||||
|
||||
void IndexBuffer::download(Array<uint8>& buffer) {
|
||||
void* data = getHandle()->contents();
|
||||
void IndexBuffer::download(Array<uint8> &buffer) {
|
||||
void *data = getHandle()->contents();
|
||||
buffer.resize(getSize());
|
||||
std::memcpy(buffer.data(), data, getSize());
|
||||
}
|
||||
void IndexBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) { currentOwner = newOwner; }
|
||||
void IndexBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) {
|
||||
currentOwner = newOwner;
|
||||
}
|
||||
|
||||
void IndexBuffer::executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) {}
|
||||
void IndexBuffer::executePipelineBarrier(Gfx::SeAccessFlags srcAccess,
|
||||
Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess,
|
||||
Gfx::SePipelineStageFlags dstStage) {}
|
||||
|
||||
UniformBuffer::UniformBuffer(PGraphics graphics, const UniformBufferCreateInfo& createInfo)
|
||||
UniformBuffer::UniformBuffer(PGraphics graphics,
|
||||
const UniformBufferCreateInfo &createInfo)
|
||||
: Gfx::UniformBuffer(graphics->getFamilyMapping(), createInfo.sourceData),
|
||||
Seele::Metal::Buffer(graphics, createInfo.sourceData.size, createInfo.sourceData.data, createInfo.dynamic, createInfo.name) {}
|
||||
Seele::Metal::Buffer(graphics, createInfo.sourceData.size,
|
||||
createInfo.sourceData.data, createInfo.dynamic,
|
||||
createInfo.name) {}
|
||||
|
||||
UniformBuffer::~UniformBuffer() {}
|
||||
|
||||
bool UniformBuffer::updateContents(const DataSource& sourceData) {
|
||||
void* data = getHandle()->contents();
|
||||
std::memcpy((char*)data + sourceData.offset, sourceData.data, sourceData.size);
|
||||
bool UniformBuffer::updateContents(const DataSource &sourceData) {
|
||||
void *data = getHandle()->contents();
|
||||
std::memcpy((char *)data + sourceData.offset, sourceData.data,
|
||||
sourceData.size);
|
||||
return true;
|
||||
}
|
||||
|
||||
void UniformBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) { currentOwner = newOwner; }
|
||||
void UniformBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) {
|
||||
currentOwner = newOwner;
|
||||
}
|
||||
|
||||
void UniformBuffer::executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) {}
|
||||
void UniformBuffer::executePipelineBarrier(Gfx::SeAccessFlags srcAccess,
|
||||
Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess,
|
||||
Gfx::SePipelineStageFlags dstStage) {
|
||||
}
|
||||
|
||||
ShaderBuffer::ShaderBuffer(PGraphics graphics, const ShaderBufferCreateInfo& createInfo)
|
||||
: Gfx::ShaderBuffer(graphics->getFamilyMapping(), createInfo.numElements, createInfo.sourceData),
|
||||
Seele::Metal::Buffer(graphics, createInfo.sourceData.size, createInfo.sourceData.data, createInfo.dynamic, createInfo.name) {}
|
||||
ShaderBuffer::ShaderBuffer(PGraphics graphics,
|
||||
const ShaderBufferCreateInfo &createInfo)
|
||||
: Gfx::ShaderBuffer(graphics->getFamilyMapping(), createInfo.numElements,
|
||||
createInfo.sourceData),
|
||||
Seele::Metal::Buffer(graphics, createInfo.sourceData.size,
|
||||
createInfo.sourceData.data, createInfo.dynamic,
|
||||
createInfo.name) {}
|
||||
|
||||
ShaderBuffer::~ShaderBuffer() {}
|
||||
|
||||
@@ -143,29 +165,28 @@ void ShaderBuffer::rotateBuffer(uint64 size) {
|
||||
Metal::Buffer::rotateBuffer(size);
|
||||
}
|
||||
|
||||
void ShaderBuffer::updateContents(const ShaderBufferCreateInfo& createInfo) {
|
||||
void ShaderBuffer::updateContents(const ShaderBufferCreateInfo &createInfo) {
|
||||
Gfx::ShaderBuffer::updateContents(createInfo);
|
||||
if(createInfo.sourceData.data == nullptr)
|
||||
{
|
||||
if (createInfo.sourceData.data == nullptr) {
|
||||
return;
|
||||
}
|
||||
void* data = map();
|
||||
std::memcpy((char*)data + createInfo.sourceData.offset, createInfo.sourceData.data, createInfo.sourceData.size);
|
||||
void *data = map();
|
||||
std::memcpy((char *)data + createInfo.sourceData.offset,
|
||||
createInfo.sourceData.data, createInfo.sourceData.size);
|
||||
unmap();
|
||||
}
|
||||
|
||||
void* ShaderBuffer::mapRegion(uint64 offset, uint64 size, bool writeOnly)
|
||||
{
|
||||
void *ShaderBuffer::mapRegion(uint64 offset, uint64 size, bool writeOnly) {
|
||||
return Metal::Buffer::mapRegion(offset, size, writeOnly);
|
||||
}
|
||||
|
||||
void ShaderBuffer::unmap()
|
||||
{
|
||||
Metal::Buffer::unmap();
|
||||
void ShaderBuffer::unmap() { Metal::Buffer::unmap(); }
|
||||
|
||||
void ShaderBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) {
|
||||
currentOwner = newOwner;
|
||||
}
|
||||
|
||||
void ShaderBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) { currentOwner = newOwner; }
|
||||
|
||||
|
||||
void ShaderBuffer::executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) {}
|
||||
void ShaderBuffer::executePipelineBarrier(Gfx::SeAccessFlags srcAccess,
|
||||
Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess,
|
||||
Gfx::SePipelineStageFlags dstStage) {}
|
||||
|
||||
@@ -19,113 +19,109 @@ DECLARE_REF(IndexBuffer)
|
||||
DECLARE_REF(GraphicsPipeline)
|
||||
DECLARE_REF(ComputePipeline)
|
||||
class Command {
|
||||
public:
|
||||
Command(PGraphics graphics, MTL::CommandBuffer* cmdBuffer);
|
||||
~Command();
|
||||
void beginRenderPass(PRenderPass renderPass);
|
||||
void endRenderPass();
|
||||
void present(MTL::Drawable* drawable);
|
||||
void end(PEvent signal);
|
||||
void waitDeviceIdle();
|
||||
void signalEvent(PEvent event);
|
||||
void waitForEvent(PEvent event);
|
||||
MTL::RenderCommandEncoder* createRenderEncoder() { return parallelEncoder->renderCommandEncoder(); }
|
||||
MTL::BlitCommandEncoder* getBlitEncoder() {
|
||||
assert(!parallelEncoder);
|
||||
if(blitEncoder == nullptr)
|
||||
{
|
||||
blitEncoder = cmdBuffer->blitCommandEncoder();
|
||||
public:
|
||||
Command(PGraphics graphics, MTL::CommandBuffer* cmdBuffer);
|
||||
~Command();
|
||||
void beginRenderPass(PRenderPass renderPass);
|
||||
void endRenderPass();
|
||||
void present(MTL::Drawable* drawable);
|
||||
void end(PEvent signal);
|
||||
void waitDeviceIdle();
|
||||
void signalEvent(PEvent event);
|
||||
void waitForEvent(PEvent event);
|
||||
MTL::RenderCommandEncoder* createRenderEncoder() { return parallelEncoder->renderCommandEncoder(); }
|
||||
MTL::BlitCommandEncoder* getBlitEncoder() {
|
||||
assert(!parallelEncoder);
|
||||
if (blitEncoder == nullptr) {
|
||||
blitEncoder = cmdBuffer->blitCommandEncoder();
|
||||
}
|
||||
return blitEncoder;
|
||||
}
|
||||
return blitEncoder;
|
||||
}
|
||||
PEvent getCompletedEvent() const { return completed; }
|
||||
constexpr MTL::CommandBuffer* getHandle() const { return cmdBuffer; }
|
||||
PEvent getCompletedEvent() const { return completed; }
|
||||
constexpr MTL::CommandBuffer* getHandle() const { return cmdBuffer; }
|
||||
|
||||
private:
|
||||
PGraphics graphics;
|
||||
OEvent completed;
|
||||
MTL::CommandBuffer* cmdBuffer;
|
||||
MTL::ParallelRenderCommandEncoder* parallelEncoder = nullptr;
|
||||
MTL::BlitCommandEncoder* blitEncoder = nullptr;
|
||||
private:
|
||||
PGraphics graphics;
|
||||
OEvent completed;
|
||||
MTL::CommandBuffer* cmdBuffer;
|
||||
MTL::ParallelRenderCommandEncoder* parallelEncoder = nullptr;
|
||||
MTL::BlitCommandEncoder* blitEncoder = nullptr;
|
||||
};
|
||||
DEFINE_REF(Command)
|
||||
class RenderCommand : public Gfx::RenderCommand {
|
||||
public:
|
||||
RenderCommand(MTL::RenderCommandEncoder* encode, const std::string& name);
|
||||
virtual ~RenderCommand();
|
||||
void end();
|
||||
virtual void setViewport(Gfx::PViewport viewport) override;
|
||||
virtual void bindPipeline(Gfx::PGraphicsPipeline pipeline) override;
|
||||
virtual void bindDescriptor(Gfx::PDescriptorSet descriptorSet, Array<uint32> dynamicOffsets) override;
|
||||
virtual void bindDescriptor(const Array<Gfx::PDescriptorSet>& descriptorSets, Array<uint32> dynamicOffsets) override;
|
||||
virtual void bindVertexBuffer(const Array<Gfx::PVertexBuffer>& buffers) override;
|
||||
virtual void bindIndexBuffer(Gfx::PIndexBuffer indexBuffer) override;
|
||||
virtual void pushConstants(Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size,
|
||||
const void* data) override;
|
||||
virtual void draw(uint32 vertexCount, uint32 instanceCount, int32 firstVertex, uint32 firstInstance) override;
|
||||
virtual void drawIndexed(uint32 indexCount, uint32 instanceCount, int32 firstIndex, uint32 vertexOffset,
|
||||
uint32 firstInstance) override;
|
||||
virtual void drawMesh(uint32 groupX, uint32 groupY, uint32 groupZ) override;
|
||||
virtual void drawMeshIndirect(Gfx::PShaderBuffer buffer, uint64 offset, uint32 drawCount, uint32 stride) override;
|
||||
public:
|
||||
RenderCommand(MTL::RenderCommandEncoder* encode, const std::string& name);
|
||||
virtual ~RenderCommand();
|
||||
void end();
|
||||
virtual void setViewport(Gfx::PViewport viewport) override;
|
||||
virtual void bindPipeline(Gfx::PGraphicsPipeline pipeline) override;
|
||||
virtual void bindDescriptor(Gfx::PDescriptorSet descriptorSet, Array<uint32> dynamicOffsets) override;
|
||||
virtual void bindDescriptor(const Array<Gfx::PDescriptorSet>& descriptorSets, Array<uint32> dynamicOffsets) override;
|
||||
virtual void bindVertexBuffer(const Array<Gfx::PVertexBuffer>& buffers) override;
|
||||
virtual void bindIndexBuffer(Gfx::PIndexBuffer indexBuffer) override;
|
||||
virtual void pushConstants(Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size, const void* data) override;
|
||||
virtual void draw(uint32 vertexCount, uint32 instanceCount, int32 firstVertex, uint32 firstInstance) override;
|
||||
virtual void drawIndexed(uint32 indexCount, uint32 instanceCount, int32 firstIndex, uint32 vertexOffset, uint32 firstInstance) override;
|
||||
virtual void drawMesh(uint32 groupX, uint32 groupY, uint32 groupZ) override;
|
||||
virtual void drawMeshIndirect(Gfx::PShaderBuffer buffer, uint64 offset, uint32 drawCount, uint32 stride) override;
|
||||
|
||||
private:
|
||||
private:
|
||||
PGraphicsPipeline boundPipeline;
|
||||
PIndexBuffer boundIndexBuffer;
|
||||
MTL::Buffer* argumentBuffer;
|
||||
MTL::RenderCommandEncoder* encoder;
|
||||
std::string name;
|
||||
MTL::RenderCommandEncoder* encoder;
|
||||
std::string name;
|
||||
};
|
||||
DEFINE_REF(RenderCommand)
|
||||
class ComputeCommand : public Gfx::ComputeCommand {
|
||||
public:
|
||||
ComputeCommand(MTL::CommandBuffer* cmdBuffer, const std::string& name);
|
||||
virtual ~ComputeCommand();
|
||||
void end();
|
||||
virtual void bindPipeline(Gfx::PComputePipeline pipeline) override;
|
||||
virtual void bindDescriptor(Gfx::PDescriptorSet set, Array<uint32> dynamicOffsets) override;
|
||||
virtual void bindDescriptor(const Array<Gfx::PDescriptorSet>& sets, Array<uint32> dynamicOffsets) override;
|
||||
virtual void pushConstants(Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size,
|
||||
const void* data) override;
|
||||
virtual void dispatch(uint32 threadX, uint32 threadY, uint32 threadZ) override;
|
||||
public:
|
||||
ComputeCommand(MTL::CommandBuffer* cmdBuffer, const std::string& name);
|
||||
virtual ~ComputeCommand();
|
||||
void end();
|
||||
virtual void bindPipeline(Gfx::PComputePipeline pipeline) override;
|
||||
virtual void bindDescriptor(Gfx::PDescriptorSet set, Array<uint32> dynamicOffsets) override;
|
||||
virtual void bindDescriptor(const Array<Gfx::PDescriptorSet>& sets, Array<uint32> dynamicOffsets) override;
|
||||
virtual void pushConstants(Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size, const void* data) override;
|
||||
virtual void dispatch(uint32 threadX, uint32 threadY, uint32 threadZ) override;
|
||||
|
||||
private:
|
||||
PComputePipeline boundPipeline;
|
||||
MTL::CommandBuffer* commandBuffer;
|
||||
MTL::ComputeCommandEncoder* encoder;
|
||||
private:
|
||||
PComputePipeline boundPipeline;
|
||||
MTL::CommandBuffer* commandBuffer;
|
||||
MTL::ComputeCommandEncoder* encoder;
|
||||
MTL::Buffer* argumentBuffer;
|
||||
std::string name;
|
||||
std::string name;
|
||||
};
|
||||
DEFINE_REF(ComputeCommand)
|
||||
class CommandQueue {
|
||||
public:
|
||||
CommandQueue(PGraphics graphics);
|
||||
~CommandQueue();
|
||||
constexpr MTL::CommandQueue* getHandle() { return queue; }
|
||||
PCommand getCommands() { return activeCommand; }
|
||||
ORenderCommand getRenderCommand(const std::string& name);
|
||||
OComputeCommand getComputeCommand(const std::string& name);
|
||||
void executeCommands(Array<Gfx::ORenderCommand> commands);
|
||||
void executeCommands(Array<Gfx::OComputeCommand> commands);
|
||||
void submitCommands(PEvent signal = nullptr);
|
||||
public:
|
||||
CommandQueue(PGraphics graphics);
|
||||
~CommandQueue();
|
||||
constexpr MTL::CommandQueue* getHandle() { return queue; }
|
||||
PCommand getCommands() { return activeCommand; }
|
||||
ORenderCommand getRenderCommand(const std::string& name);
|
||||
OComputeCommand getComputeCommand(const std::string& name);
|
||||
void executeCommands(Array<Gfx::ORenderCommand> commands);
|
||||
void executeCommands(Array<Gfx::OComputeCommand> commands);
|
||||
void submitCommands(PEvent signal = nullptr);
|
||||
|
||||
private:
|
||||
PGraphics graphics;
|
||||
MTL::CommandQueue* queue;
|
||||
OCommand activeCommand;
|
||||
Array<OCommand> pendingCommands;
|
||||
private:
|
||||
PGraphics graphics;
|
||||
MTL::CommandQueue* queue;
|
||||
OCommand activeCommand;
|
||||
Array<OCommand> pendingCommands;
|
||||
};
|
||||
class IOCommandQueue {
|
||||
public:
|
||||
IOCommandQueue(PGraphics graphics);
|
||||
~IOCommandQueue();
|
||||
constexpr MTL::IOCommandQueue* getHandle() { return queue; }
|
||||
PCommand getCommands() { return activeCommand; } // TODO
|
||||
void submitCommands(PEvent signal = nullptr);
|
||||
public:
|
||||
IOCommandQueue(PGraphics graphics);
|
||||
~IOCommandQueue();
|
||||
constexpr MTL::IOCommandQueue* getHandle() { return queue; }
|
||||
PCommand getCommands() { return activeCommand; } // TODO
|
||||
void submitCommands(PEvent signal = nullptr);
|
||||
|
||||
private:
|
||||
PGraphics graphics;
|
||||
MTL::IOCommandQueue* queue;
|
||||
OCommand activeCommand;
|
||||
private:
|
||||
PGraphics graphics;
|
||||
MTL::IOCommandQueue* queue;
|
||||
OCommand activeCommand;
|
||||
};
|
||||
DEFINE_REF(IOCommandQueue)
|
||||
} // namespace Metal
|
||||
|
||||
@@ -16,8 +16,9 @@
|
||||
using namespace Seele;
|
||||
using namespace Seele::Metal;
|
||||
|
||||
Command::Command(PGraphics graphics, MTL::CommandBuffer* cmdBuffer)
|
||||
: graphics(graphics), completed(new Event(graphics)), cmdBuffer(cmdBuffer) {}
|
||||
Command::Command(PGraphics graphics, MTL::CommandBuffer *cmdBuffer)
|
||||
: graphics(graphics), completed(new Event(graphics)), cmdBuffer(cmdBuffer) {
|
||||
}
|
||||
|
||||
Command::~Command() {}
|
||||
|
||||
@@ -27,7 +28,8 @@ void Command::beginRenderPass(PRenderPass renderPass) {
|
||||
blitEncoder = nullptr;
|
||||
}
|
||||
renderPass->updateRenderPass();
|
||||
parallelEncoder = cmdBuffer->parallelRenderCommandEncoder(renderPass->getDescriptor());
|
||||
parallelEncoder =
|
||||
cmdBuffer->parallelRenderCommandEncoder(renderPass->getDescriptor());
|
||||
}
|
||||
|
||||
void Command::endRenderPass() {
|
||||
@@ -35,7 +37,9 @@ void Command::endRenderPass() {
|
||||
parallelEncoder = nullptr;
|
||||
}
|
||||
|
||||
void Command::present(MTL::Drawable* drawable) { cmdBuffer->presentDrawable(drawable); }
|
||||
void Command::present(MTL::Drawable *drawable) {
|
||||
cmdBuffer->presentDrawable(drawable);
|
||||
}
|
||||
|
||||
void Command::end(PEvent signal) {
|
||||
assert(!parallelEncoder);
|
||||
@@ -49,11 +53,16 @@ void Command::end(PEvent signal) {
|
||||
|
||||
void Command::waitDeviceIdle() { cmdBuffer->waitUntilCompleted(); }
|
||||
|
||||
void Command::signalEvent(PEvent event) { cmdBuffer->encodeSignalEvent(event->getHandle(), 1); }
|
||||
void Command::signalEvent(PEvent event) {
|
||||
cmdBuffer->encodeSignalEvent(event->getHandle(), 1);
|
||||
}
|
||||
|
||||
void Command::waitForEvent(PEvent event) { cmdBuffer->encodeWait(event->getHandle(), 1); }
|
||||
void Command::waitForEvent(PEvent event) {
|
||||
cmdBuffer->encodeWait(event->getHandle(), 1);
|
||||
}
|
||||
|
||||
RenderCommand::RenderCommand(MTL::RenderCommandEncoder* encoder, const std::string& name)
|
||||
RenderCommand::RenderCommand(MTL::RenderCommandEncoder *encoder,
|
||||
const std::string &name)
|
||||
: encoder(encoder), name(name) {}
|
||||
|
||||
RenderCommand::~RenderCommand() {}
|
||||
@@ -79,15 +88,19 @@ void RenderCommand::bindPipeline(Gfx::PGraphicsPipeline pipeline) {
|
||||
for (auto [_, layout] : boundPipeline->getPipelineLayout()->getLayouts()) {
|
||||
argBufferSize += 3 * sizeof(uint64) * layout->getBindings().size();
|
||||
}
|
||||
argumentBuffer = boundPipeline->graphics->getDevice()->newBuffer(argBufferSize, MTL::ResourceStorageModeShared);
|
||||
argumentBuffer = boundPipeline->graphics->getDevice()->newBuffer(
|
||||
argBufferSize, MTL::ResourceStorageModeShared);
|
||||
argumentBuffer->setLabel(
|
||||
NS::String::string(boundPipeline->getPipelineLayout()->getName().c_str(), NS::ASCIIStringEncoding));
|
||||
NS::String::string(boundPipeline->getPipelineLayout()->getName().c_str(),
|
||||
NS::ASCIIStringEncoding));
|
||||
}
|
||||
|
||||
void RenderCommand::bindDescriptor(Gfx::PDescriptorSet descriptorSet, Array<uint32> offsets) {
|
||||
void RenderCommand::bindDescriptor(Gfx::PDescriptorSet descriptorSet,
|
||||
Array<uint32> offsets) {
|
||||
auto metalSet = descriptorSet.cast<DescriptorSet>();
|
||||
uint32 parameterIndex = boundPipeline->getPipelineLayout()->findParameter(descriptorSet->getLayout()->getName());
|
||||
uint64* topLevelTable = (uint64*)argumentBuffer->contents();
|
||||
uint32 parameterIndex = boundPipeline->getPipelineLayout()->findParameter(
|
||||
descriptorSet->getLayout()->getName());
|
||||
uint64 *topLevelTable = (uint64 *)argumentBuffer->contents();
|
||||
topLevelTable[parameterIndex] = metalSet->getBuffer()->gpuAddress();
|
||||
auto bindings = metalSet->getLayout()->getBindings();
|
||||
encoder->useResource(metalSet->getBuffer(), MTL::ResourceUsageRead);
|
||||
@@ -117,15 +130,17 @@ void RenderCommand::bindDescriptor(Gfx::PDescriptorSet descriptorSet, Array<uint
|
||||
}
|
||||
}
|
||||
|
||||
void RenderCommand::bindDescriptor(const Array<Gfx::PDescriptorSet>& descriptorSets, Array<uint32> offsets) {
|
||||
void RenderCommand::bindDescriptor(
|
||||
const Array<Gfx::PDescriptorSet> &descriptorSets, Array<uint32> offsets) {
|
||||
for (auto set : descriptorSets) {
|
||||
bindDescriptor(set, offsets);
|
||||
}
|
||||
}
|
||||
void RenderCommand::bindVertexBuffer(const Array<Gfx::PVertexBuffer>& buffers) {
|
||||
void RenderCommand::bindVertexBuffer(const Array<Gfx::PVertexBuffer> &buffers) {
|
||||
uint32 i = 0;
|
||||
for (auto buffer : buffers) {
|
||||
encoder->setVertexBuffer(buffer.cast<VertexBuffer>()->getHandle(), 0, METAL_VERTEXBUFFER_OFFSET + i++);
|
||||
encoder->setVertexBuffer(buffer.cast<VertexBuffer>()->getHandle(), 0,
|
||||
METAL_VERTEXBUFFER_OFFSET + i++);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,24 +148,29 @@ void RenderCommand::bindIndexBuffer(Gfx::PIndexBuffer gfxIndexBuffer) {
|
||||
boundIndexBuffer = gfxIndexBuffer.cast<IndexBuffer>();
|
||||
}
|
||||
|
||||
void RenderCommand::pushConstants(Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size,
|
||||
const void* data) {
|
||||
void RenderCommand::pushConstants(Gfx::SeShaderStageFlags stage, uint32 offset,
|
||||
uint32 size, const void *data) {
|
||||
if (stage & Gfx::SE_SHADER_STAGE_VERTEX_BIT) {
|
||||
encoder->setVertexBytes((char*)data + offset, size, 0);
|
||||
encoder->setVertexBytes((char *)data + offset, size, 0);
|
||||
}
|
||||
if (stage & Gfx::SE_SHADER_STAGE_FRAGMENT_BIT) {
|
||||
encoder->setFragmentBytes((char*)data + offset, size, 0);
|
||||
encoder->setFragmentBytes((char *)data + offset, size, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void RenderCommand::draw(uint32 vertexCount, uint32 instanceCount, int32 firstVertex, uint32 firstInstance) {
|
||||
encoder->drawPrimitives(boundPipeline->getPrimitive(), firstVertex, vertexCount, instanceCount, firstInstance);
|
||||
void RenderCommand::draw(uint32 vertexCount, uint32 instanceCount,
|
||||
int32 firstVertex, uint32 firstInstance) {
|
||||
encoder->drawPrimitives(boundPipeline->getPrimitive(), firstVertex,
|
||||
vertexCount, instanceCount, firstInstance);
|
||||
}
|
||||
|
||||
void RenderCommand::drawIndexed(uint32 indexCount, uint32 instanceCount, int32 firstIndex, uint32 vertexOffset,
|
||||
void RenderCommand::drawIndexed(uint32 indexCount, uint32 instanceCount,
|
||||
int32 firstIndex, uint32 vertexOffset,
|
||||
uint32 firstInstance) {
|
||||
encoder->drawIndexedPrimitives(boundPipeline->getPrimitive(), indexCount, cast(boundIndexBuffer->getIndexType()),
|
||||
boundIndexBuffer->getHandle(), firstIndex, instanceCount, vertexOffset, firstInstance);
|
||||
encoder->drawIndexedPrimitives(boundPipeline->getPrimitive(), indexCount,
|
||||
cast(boundIndexBuffer->getIndexType()),
|
||||
boundIndexBuffer->getHandle(), firstIndex,
|
||||
instanceCount, vertexOffset, firstInstance);
|
||||
}
|
||||
|
||||
void RenderCommand::drawMesh(uint32 groupX, uint32 groupY, uint32 groupZ) {
|
||||
@@ -159,15 +179,19 @@ void RenderCommand::drawMesh(uint32 groupX, uint32 groupY, uint32 groupZ) {
|
||||
encoder->setFragmentBuffer(argumentBuffer, 0, 2);
|
||||
encoder->setMeshBuffer(argumentBuffer, 0, 2);
|
||||
encoder->setObjectBuffer(argumentBuffer, 0, 2);
|
||||
encoder->drawMeshThreadgroups(MTL::Size(groupX, groupY, groupZ), MTL::Size(128, 1, 1), MTL::Size(32, 1, 1));
|
||||
encoder->drawMeshThreadgroups(MTL::Size(groupX, groupY, groupZ),
|
||||
MTL::Size(128, 1, 1), MTL::Size(32, 1, 1));
|
||||
}
|
||||
|
||||
void RenderCommand::drawMeshIndirect(Gfx::PShaderBuffer buffer, uint64 offset, uint32 drawCount, uint32 stride) {
|
||||
//encoder->drawMeshThreadgroups()
|
||||
void RenderCommand::drawMeshIndirect(Gfx::PShaderBuffer buffer, uint64 offset,
|
||||
uint32 drawCount, uint32 stride) {
|
||||
// encoder->drawMeshThreadgroups()
|
||||
}
|
||||
|
||||
ComputeCommand::ComputeCommand(MTL::CommandBuffer* cmdBuffer, const std::string& name)
|
||||
: commandBuffer(cmdBuffer), encoder(cmdBuffer->computeCommandEncoder()), name(name) {}
|
||||
ComputeCommand::ComputeCommand(MTL::CommandBuffer *cmdBuffer,
|
||||
const std::string &name)
|
||||
: commandBuffer(cmdBuffer), encoder(cmdBuffer->computeCommandEncoder()),
|
||||
name(name) {}
|
||||
|
||||
ComputeCommand::~ComputeCommand() {}
|
||||
|
||||
@@ -180,16 +204,21 @@ void ComputeCommand::bindPipeline(Gfx::PComputePipeline pipeline) {
|
||||
boundPipeline = pipeline.cast<ComputePipeline>();
|
||||
encoder->setComputePipelineState(boundPipeline->getHandle());
|
||||
argumentBuffer = boundPipeline->graphics->getDevice()->newBuffer(
|
||||
sizeof(uint64) * (boundPipeline->getPipelineLayout()->getLayouts().size() + 1), MTL::ResourceStorageModeShared);
|
||||
sizeof(uint64) *
|
||||
(boundPipeline->getPipelineLayout()->getLayouts().size() + 1),
|
||||
MTL::ResourceStorageModeShared);
|
||||
argumentBuffer->setLabel(
|
||||
NS::String::string(pipeline->getPipelineLayout()->getName().c_str(), NS::ASCIIStringEncoding));
|
||||
NS::String::string(pipeline->getPipelineLayout()->getName().c_str(),
|
||||
NS::ASCIIStringEncoding));
|
||||
}
|
||||
|
||||
void ComputeCommand::bindDescriptor(Gfx::PDescriptorSet set, Array<uint32> offsets) {
|
||||
void ComputeCommand::bindDescriptor(Gfx::PDescriptorSet set,
|
||||
Array<uint32> offsets) {
|
||||
auto metalSet = set.cast<DescriptorSet>();
|
||||
metalSet->bind();
|
||||
uint32 parameterIndex = boundPipeline->getPipelineLayout()->findParameter(set->getLayout()->getName());
|
||||
uint64* topLevelTable = (uint64*)argumentBuffer->contents();
|
||||
uint32 parameterIndex = boundPipeline->getPipelineLayout()->findParameter(
|
||||
set->getLayout()->getName());
|
||||
uint64 *topLevelTable = (uint64 *)argumentBuffer->contents();
|
||||
topLevelTable[parameterIndex] = metalSet->getBuffer()->gpuAddress();
|
||||
auto bindings = metalSet->getLayout()->getBindings();
|
||||
encoder->useResource(metalSet->getBuffer(), MTL::ResourceUsageRead);
|
||||
@@ -219,42 +248,45 @@ void ComputeCommand::bindDescriptor(Gfx::PDescriptorSet set, Array<uint32> offse
|
||||
}
|
||||
}
|
||||
|
||||
void ComputeCommand::bindDescriptor(const Array<Gfx::PDescriptorSet>& sets, Array<uint32> offsets) {
|
||||
for (auto& set : sets) {
|
||||
void ComputeCommand::bindDescriptor(const Array<Gfx::PDescriptorSet> &sets,
|
||||
Array<uint32> offsets) {
|
||||
for (auto &set : sets) {
|
||||
bindDescriptor(set, offsets);
|
||||
}
|
||||
}
|
||||
|
||||
void ComputeCommand::pushConstants(Gfx::SeShaderStageFlags, uint32 offset, uint32 size,
|
||||
const void* data) {
|
||||
encoder->setBytes((char*)data + offset, size, 0);
|
||||
void ComputeCommand::pushConstants(Gfx::SeShaderStageFlags, uint32 offset,
|
||||
uint32 size, const void *data) {
|
||||
encoder->setBytes((char *)data + offset, size, 0);
|
||||
}
|
||||
|
||||
void ComputeCommand::dispatch(uint32 threadX, uint32 threadY, uint32 threadZ) {
|
||||
// TODO
|
||||
encoder->setBuffer(argumentBuffer, 0, 2);
|
||||
encoder->dispatchThreadgroups(MTL::Size(threadX, threadY, threadZ), MTL::Size(32, 32, 1));
|
||||
encoder->dispatchThreadgroups(MTL::Size(threadX, threadY, threadZ),
|
||||
MTL::Size(32, 32, 1));
|
||||
}
|
||||
|
||||
CommandQueue::CommandQueue(PGraphics graphics) : graphics(graphics) {
|
||||
queue = graphics->getDevice()->newCommandQueue();
|
||||
MTL::CommandBufferDescriptor* descriptor = MTL::CommandBufferDescriptor::alloc()->init();
|
||||
MTL::CommandBufferDescriptor *descriptor =
|
||||
MTL::CommandBufferDescriptor::alloc()->init();
|
||||
activeCommand = new Command(graphics, queue->commandBuffer(descriptor));
|
||||
descriptor->release();
|
||||
}
|
||||
|
||||
CommandQueue::~CommandQueue() { queue->release(); }
|
||||
|
||||
ORenderCommand CommandQueue::getRenderCommand(const std::string& name) {
|
||||
ORenderCommand CommandQueue::getRenderCommand(const std::string &name) {
|
||||
return new RenderCommand(activeCommand->createRenderEncoder(), name);
|
||||
}
|
||||
|
||||
OComputeCommand CommandQueue::getComputeCommand(const std::string& name) {
|
||||
OComputeCommand CommandQueue::getComputeCommand(const std::string &name) {
|
||||
return new ComputeCommand(queue->commandBuffer(), name);
|
||||
}
|
||||
|
||||
void CommandQueue::executeCommands(Array<Gfx::ORenderCommand> commands) {
|
||||
for (auto& command : commands) {
|
||||
for (auto &command : commands) {
|
||||
auto metalCmd = Gfx::PRenderCommand(command).cast<RenderCommand>();
|
||||
metalCmd->end();
|
||||
}
|
||||
@@ -262,33 +294,38 @@ void CommandQueue::executeCommands(Array<Gfx::ORenderCommand> commands) {
|
||||
|
||||
void CommandQueue::executeCommands(Array<Gfx::OComputeCommand> commands) {
|
||||
submitCommands();
|
||||
for (auto& command : commands) {
|
||||
for (auto &command : commands) {
|
||||
auto metalCmd = Gfx::PComputeCommand(command).cast<ComputeCommand>();
|
||||
metalCmd->end();
|
||||
}
|
||||
}
|
||||
|
||||
void CommandQueue::submitCommands(PEvent signalSemaphore) {
|
||||
activeCommand->getHandle()->addCompletedHandler(MTL::CommandBufferHandler([&](MTL::CommandBuffer* cmdBuffer) {
|
||||
for (auto it = pendingCommands.begin(); it != pendingCommands.end(); it++) {
|
||||
if ((*it)->getHandle() == cmdBuffer) {
|
||||
pendingCommands.remove(it);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}));
|
||||
activeCommand->getHandle()->addCompletedHandler(
|
||||
MTL::CommandBufferHandler([&](MTL::CommandBuffer *cmdBuffer) {
|
||||
for (auto it = pendingCommands.begin(); it != pendingCommands.end();
|
||||
it++) {
|
||||
if ((*it)->getHandle() == cmdBuffer) {
|
||||
pendingCommands.remove(it);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}));
|
||||
activeCommand->end(signalSemaphore);
|
||||
activeCommand->waitDeviceIdle();
|
||||
PEvent prevCmdEvent = activeCommand->getCompletedEvent();
|
||||
pendingCommands.add(std::move(activeCommand));
|
||||
MTL::CommandBufferDescriptor* descriptor = MTL::CommandBufferDescriptor::alloc()->init();
|
||||
descriptor->setErrorOptions(MTL::CommandBufferErrorOptionEncoderExecutionStatus);
|
||||
MTL::CommandBufferDescriptor *descriptor =
|
||||
MTL::CommandBufferDescriptor::alloc()->init();
|
||||
descriptor->setErrorOptions(
|
||||
MTL::CommandBufferErrorOptionEncoderExecutionStatus);
|
||||
activeCommand = new Command(graphics, queue->commandBuffer(descriptor));
|
||||
activeCommand->waitForEvent(prevCmdEvent);
|
||||
}
|
||||
|
||||
IOCommandQueue::IOCommandQueue(PGraphics graphics) : graphics(graphics) {
|
||||
MTL::IOCommandQueueDescriptor* desc = MTL::IOCommandQueueDescriptor::alloc()->init();
|
||||
MTL::IOCommandQueueDescriptor *desc =
|
||||
MTL::IOCommandQueueDescriptor::alloc()->init();
|
||||
desc->setType(MTL::IOCommandQueueTypeConcurrent);
|
||||
desc->setPriority(MTL::IOPriorityNormal);
|
||||
queue = graphics->getDevice()->newIOCommandQueue(desc, nullptr);
|
||||
|
||||
@@ -9,75 +9,69 @@ namespace Seele {
|
||||
namespace Metal {
|
||||
DECLARE_REF(Graphics)
|
||||
class DescriptorLayout : public Gfx::DescriptorLayout {
|
||||
public:
|
||||
DescriptorLayout(PGraphics graphics, const std::string &name);
|
||||
virtual ~DescriptorLayout();
|
||||
virtual void create() override;
|
||||
public:
|
||||
DescriptorLayout(PGraphics graphics, const std::string& name);
|
||||
virtual ~DescriptorLayout();
|
||||
virtual void create() override;
|
||||
|
||||
private:
|
||||
PGraphics graphics;
|
||||
private:
|
||||
PGraphics graphics;
|
||||
};
|
||||
DEFINE_REF(DescriptorLayout)
|
||||
|
||||
DECLARE_REF(DescriptorSet)
|
||||
class DescriptorPool : public Gfx::DescriptorPool {
|
||||
public:
|
||||
DescriptorPool(PGraphics graphics, PDescriptorLayout layout);
|
||||
virtual ~DescriptorPool();
|
||||
virtual Gfx::PDescriptorSet allocateDescriptorSet() override;
|
||||
virtual void reset() override;
|
||||
constexpr PDescriptorLayout getLayout() const { return layout; }
|
||||
public:
|
||||
DescriptorPool(PGraphics graphics, PDescriptorLayout layout);
|
||||
virtual ~DescriptorPool();
|
||||
virtual Gfx::PDescriptorSet allocateDescriptorSet() override;
|
||||
virtual void reset() override;
|
||||
constexpr PDescriptorLayout getLayout() const { return layout; }
|
||||
|
||||
private:
|
||||
PGraphics graphics;
|
||||
PDescriptorLayout layout;
|
||||
Array<ODescriptorSet> allocatedSets;
|
||||
private:
|
||||
PGraphics graphics;
|
||||
PDescriptorLayout layout;
|
||||
Array<ODescriptorSet> allocatedSets;
|
||||
};
|
||||
DEFINE_REF(DescriptorPool)
|
||||
|
||||
class DescriptorSet : public Gfx::DescriptorSet, public CommandBoundResource {
|
||||
public:
|
||||
DescriptorSet(PGraphics graphics, PDescriptorPool owner);
|
||||
virtual ~DescriptorSet();
|
||||
virtual void writeChanges() override;
|
||||
virtual void updateBuffer(uint32_t binding,
|
||||
Gfx::PUniformBuffer uniformBuffer) override;
|
||||
virtual void updateBuffer(uint32_t binding, Gfx::PShaderBuffer uniformBuffer) override;
|
||||
virtual void updateBuffer(uint32_t binding, uint32 index, Gfx::PShaderBuffer uniformBuffer) override;
|
||||
virtual void updateSampler(uint32_t binding, Gfx::PSampler samplerState) override;
|
||||
virtual void updateTexture(uint32_t binding, Gfx::PTexture texture,
|
||||
Gfx::PSampler sampler = nullptr) override;
|
||||
virtual void updateTextureArray(uint32_t binding,
|
||||
Array<Gfx::PTexture> texture) override;
|
||||
public:
|
||||
DescriptorSet(PGraphics graphics, PDescriptorPool owner);
|
||||
virtual ~DescriptorSet();
|
||||
virtual void writeChanges() override;
|
||||
virtual void updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBuffer) override;
|
||||
virtual void updateBuffer(uint32_t binding, Gfx::PShaderBuffer uniformBuffer) override;
|
||||
virtual void updateBuffer(uint32_t binding, uint32 index, Gfx::PShaderBuffer uniformBuffer) override;
|
||||
virtual void updateSampler(uint32_t binding, Gfx::PSampler samplerState) override;
|
||||
virtual void updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::PSampler sampler = nullptr) override;
|
||||
virtual void updateTextureArray(uint32_t binding, Array<Gfx::PTexture> texture) override;
|
||||
|
||||
constexpr bool isCurrentlyInUse() const { return currentlyInUse; }
|
||||
constexpr void allocate() { currentlyInUse = true; }
|
||||
constexpr void free() { currentlyInUse = false; }
|
||||
constexpr bool isCurrentlyInUse() const { return currentlyInUse; }
|
||||
constexpr void allocate() { currentlyInUse = true; }
|
||||
constexpr void free() { currentlyInUse = false; }
|
||||
|
||||
constexpr MTL::Buffer *getBuffer() const { return buffer; }
|
||||
constexpr const Array<MTL::Resource *> &getBoundResources() const {
|
||||
return boundResources;
|
||||
}
|
||||
constexpr MTL::Buffer* getBuffer() const { return buffer; }
|
||||
constexpr const Array<MTL::Resource*>& getBoundResources() const { return boundResources; }
|
||||
|
||||
private:
|
||||
PGraphics graphics;
|
||||
PDescriptorPool owner;
|
||||
MTL::Buffer *buffer = nullptr;
|
||||
uint64 *argumentBuffer = nullptr;
|
||||
Array<MTL::Resource *> boundResources;
|
||||
bool currentlyInUse;
|
||||
private:
|
||||
PGraphics graphics;
|
||||
PDescriptorPool owner;
|
||||
MTL::Buffer* buffer = nullptr;
|
||||
uint64* argumentBuffer = nullptr;
|
||||
Array<MTL::Resource*> boundResources;
|
||||
bool currentlyInUse;
|
||||
};
|
||||
DEFINE_REF(DescriptorSet)
|
||||
|
||||
class PipelineLayout : public Gfx::PipelineLayout {
|
||||
public:
|
||||
PipelineLayout(PGraphics graphics, const std::string &name,
|
||||
Gfx::PPipelineLayout baseLayout);
|
||||
virtual ~PipelineLayout();
|
||||
virtual void create() override;
|
||||
public:
|
||||
PipelineLayout(PGraphics graphics, const std::string& name, Gfx::PPipelineLayout baseLayout);
|
||||
virtual ~PipelineLayout();
|
||||
virtual void create() override;
|
||||
|
||||
private:
|
||||
PGraphics graphics;
|
||||
private:
|
||||
PGraphics graphics;
|
||||
};
|
||||
DEFINE_REF(PipelineLayout)
|
||||
} // namespace Metal
|
||||
|
||||
@@ -94,11 +94,8 @@ void DescriptorSet::updateBuffer(uint32_t binding,
|
||||
boundResources[binding] = metalBuffer->getHandle();
|
||||
}
|
||||
|
||||
void DescriptorSet::updateBuffer(uint32_t binding, uint32 index, Gfx::PShaderBuffer uniformBuffer)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void DescriptorSet::updateBuffer(uint32_t binding, uint32 index,
|
||||
Gfx::PShaderBuffer uniformBuffer) {}
|
||||
|
||||
void DescriptorSet::updateSampler(uint32_t binding,
|
||||
Gfx::PSampler samplerState) {
|
||||
|
||||
@@ -3,11 +3,9 @@
|
||||
#include "Metal/MTLStageInputOutputDescriptor.hpp"
|
||||
#include "Resources.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
namespace Metal
|
||||
{
|
||||
constexpr uint64 METAL_VERTEXBUFFER_OFFSET = 6;// something about metal vertex fetch
|
||||
namespace Seele {
|
||||
namespace Metal {
|
||||
constexpr uint64 METAL_VERTEXBUFFER_OFFSET = 6; // something about metal vertex fetch
|
||||
constexpr uint64 METAL_VERTEXATTRIBUTE_OFFSET = 11;
|
||||
|
||||
MTL::PixelFormat cast(Gfx::SeFormat format);
|
||||
@@ -32,5 +30,5 @@ MTL::PrimitiveTopologyClass cast(Gfx::SePrimitiveTopology topology);
|
||||
Gfx::SePrimitiveTopology cast(MTL::PrimitiveTopologyClass topology);
|
||||
MTL::IndexType cast(Gfx::SeIndexType indexType);
|
||||
Gfx::SeIndexType cast(MTL::IndexType indexType);
|
||||
}
|
||||
}
|
||||
} // namespace Metal
|
||||
} // namespace Seele
|
||||
@@ -767,7 +767,8 @@ Gfx::SeSamplerAddressMode Seele::Metal::cast(MTL::SamplerAddressMode mode) {
|
||||
}
|
||||
}
|
||||
|
||||
MTL::PrimitiveTopologyClass Seele::Metal::cast(Gfx::SePrimitiveTopology topology) {
|
||||
MTL::PrimitiveTopologyClass
|
||||
Seele::Metal::cast(Gfx::SePrimitiveTopology topology) {
|
||||
switch (topology) {
|
||||
case Gfx::SE_PRIMITIVE_TOPOLOGY_POINT_LIST:
|
||||
return MTL::PrimitiveTopologyClassPoint;
|
||||
|
||||
@@ -1,25 +1,24 @@
|
||||
#pragma once
|
||||
#include "Metal/Metal.hpp"
|
||||
#include "Graphics/Graphics.h"
|
||||
#include "Metal/Metal.hpp"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
namespace Metal
|
||||
{
|
||||
|
||||
namespace Seele {
|
||||
namespace Metal {
|
||||
DECLARE_REF(CommandQueue)
|
||||
DECLARE_REF(IOCommandQueue)
|
||||
DECLARE_REF(PipelineCache)
|
||||
class Graphics : public Gfx::Graphics
|
||||
{
|
||||
public:
|
||||
class Graphics : public Gfx::Graphics {
|
||||
public:
|
||||
Graphics();
|
||||
virtual ~Graphics();
|
||||
virtual void init(GraphicsInitializer initializer) override;
|
||||
|
||||
virtual Gfx::OWindow createWindow(const WindowCreateInfo &createInfo) override;
|
||||
virtual Gfx::OViewport createViewport(Gfx::PWindow owner, const ViewportCreateInfo &createInfo) override;
|
||||
|
||||
virtual Gfx::ORenderPass createRenderPass(Gfx::RenderTargetLayout layout, Array<Gfx::SubPassDependency> dependencies, Gfx::PViewport renderArea) override;
|
||||
virtual Gfx::OWindow createWindow(const WindowCreateInfo& createInfo) override;
|
||||
virtual Gfx::OViewport createViewport(Gfx::PWindow owner, const ViewportCreateInfo& createInfo) override;
|
||||
|
||||
virtual Gfx::ORenderPass createRenderPass(Gfx::RenderTargetLayout layout, Array<Gfx::SubPassDependency> dependencies,
|
||||
Gfx::PViewport renderArea) override;
|
||||
virtual void beginRenderPass(Gfx::PRenderPass renderPass) override;
|
||||
virtual void endRenderPass() override;
|
||||
virtual void waitDeviceIdle() override;
|
||||
@@ -27,17 +26,17 @@ public:
|
||||
virtual void executeCommands(Array<Gfx::ORenderCommand> commands) override;
|
||||
virtual void executeCommands(Array<Gfx::OComputeCommand> commands) override;
|
||||
|
||||
virtual Gfx::OTexture2D createTexture2D(const TextureCreateInfo &createInfo) override;
|
||||
virtual Gfx::OTexture3D createTexture3D(const TextureCreateInfo &createInfo) override;
|
||||
virtual Gfx::OTextureCube createTextureCube(const TextureCreateInfo &createInfo) override;
|
||||
virtual Gfx::OUniformBuffer createUniformBuffer(const UniformBufferCreateInfo &bulkData) override;
|
||||
virtual Gfx::OShaderBuffer createShaderBuffer(const ShaderBufferCreateInfo &bulkData) override;
|
||||
virtual Gfx::OVertexBuffer createVertexBuffer(const VertexBufferCreateInfo &bulkData) override;
|
||||
virtual Gfx::OIndexBuffer createIndexBuffer(const IndexBufferCreateInfo &bulkData) override;
|
||||
|
||||
virtual Gfx::OTexture2D createTexture2D(const TextureCreateInfo& createInfo) override;
|
||||
virtual Gfx::OTexture3D createTexture3D(const TextureCreateInfo& createInfo) override;
|
||||
virtual Gfx::OTextureCube createTextureCube(const TextureCreateInfo& createInfo) override;
|
||||
virtual Gfx::OUniformBuffer createUniformBuffer(const UniformBufferCreateInfo& bulkData) override;
|
||||
virtual Gfx::OShaderBuffer createShaderBuffer(const ShaderBufferCreateInfo& bulkData) override;
|
||||
virtual Gfx::OVertexBuffer createVertexBuffer(const VertexBufferCreateInfo& bulkData) override;
|
||||
virtual Gfx::OIndexBuffer createIndexBuffer(const IndexBufferCreateInfo& bulkData) override;
|
||||
|
||||
virtual Gfx::ORenderCommand createRenderCommand(const std::string& name = "") override;
|
||||
virtual Gfx::OComputeCommand createComputeCommand(const std::string& name = "") 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;
|
||||
@@ -48,22 +47,23 @@ public:
|
||||
virtual Gfx::PComputePipeline createComputePipeline(Gfx::ComputePipelineCreateInfo createInfo) override;
|
||||
virtual Gfx::OSampler createSampler(const SamplerCreateInfo& createInfo) override;
|
||||
|
||||
virtual Gfx::ODescriptorLayout createDescriptorLayout(const std::string& name = "") override;
|
||||
virtual Gfx::OPipelineLayout createPipelineLayout(const std::string& name = "", Gfx::PPipelineLayout baseLayout = nullptr) override;
|
||||
virtual Gfx::ODescriptorLayout createDescriptorLayout(const std::string& name = "") override;
|
||||
virtual Gfx::OPipelineLayout createPipelineLayout(const std::string& name = "", Gfx::PPipelineLayout baseLayout = nullptr) override;
|
||||
|
||||
virtual Gfx::OVertexInput createVertexInput(VertexInputStateCreateInfo createInfo) override;
|
||||
|
||||
virtual void resolveTexture(Gfx::PTexture source, Gfx::PTexture destination) override;
|
||||
|
||||
|
||||
MTL::Device* getDevice() const { return device; }
|
||||
PCommandQueue getQueue() const { return queue; }
|
||||
PIOCommandQueue getIOQueue() const { return ioQueue; }
|
||||
protected:
|
||||
|
||||
protected:
|
||||
MTL::Device* device;
|
||||
OCommandQueue queue;
|
||||
OIOCommandQueue ioQueue;
|
||||
OPipelineCache cache;
|
||||
};
|
||||
DEFINE_REF(Graphics)
|
||||
} // namespace Metal
|
||||
} // namespace Metal
|
||||
} // namespace Seele
|
||||
|
||||
@@ -1,31 +1,25 @@
|
||||
#include "Graphics.h"
|
||||
#include "Buffer.h"
|
||||
#include "Command.h"
|
||||
#include "Graphics/Initializer.h"
|
||||
#include "Graphics/Metal/Descriptor.h"
|
||||
#include "Graphics/Metal/Pipeline.h"
|
||||
#include "Graphics/Metal/PipelineCache.h"
|
||||
#include "Graphics/Metal/Resources.h"
|
||||
#include "Shader.h"
|
||||
#include "RenderPass.h"
|
||||
#include "Resources.h"
|
||||
#include "Command.h"
|
||||
#include "Shader.h"
|
||||
#include "Window.h"
|
||||
#include "Buffer.h"
|
||||
|
||||
|
||||
using namespace Seele;
|
||||
using namespace Seele::Metal;
|
||||
|
||||
Graphics::Graphics()
|
||||
{
|
||||
|
||||
}
|
||||
Graphics::Graphics() {}
|
||||
|
||||
Graphics::~Graphics()
|
||||
{
|
||||
|
||||
}
|
||||
Graphics::~Graphics() {}
|
||||
|
||||
void Graphics::init(GraphicsInitializer)
|
||||
{
|
||||
void Graphics::init(GraphicsInitializer) {
|
||||
glfwInit();
|
||||
device = MTL::CreateSystemDefaultDevice();
|
||||
queue = new CommandQueue(this);
|
||||
@@ -34,164 +28,149 @@ void Graphics::init(GraphicsInitializer)
|
||||
meshShadingEnabled = false;
|
||||
}
|
||||
|
||||
Gfx::OWindow Graphics::createWindow(const WindowCreateInfo &createInfo)
|
||||
{
|
||||
Gfx::OWindow Graphics::createWindow(const WindowCreateInfo &createInfo) {
|
||||
return new Window(this, createInfo);
|
||||
}
|
||||
|
||||
Gfx::OViewport Graphics::createViewport(Gfx::PWindow owner, const ViewportCreateInfo &createInfo)
|
||||
{
|
||||
Gfx::OViewport Graphics::createViewport(Gfx::PWindow owner,
|
||||
const ViewportCreateInfo &createInfo) {
|
||||
return new Viewport(owner, createInfo);
|
||||
}
|
||||
|
||||
Gfx::ORenderPass Graphics::createRenderPass(Gfx::RenderTargetLayout layout, Array<Gfx::SubPassDependency> dependencies, Gfx::PViewport renderArea)
|
||||
{
|
||||
Gfx::ORenderPass
|
||||
Graphics::createRenderPass(Gfx::RenderTargetLayout layout,
|
||||
Array<Gfx::SubPassDependency> dependencies,
|
||||
Gfx::PViewport renderArea) {
|
||||
return new RenderPass(this, layout, dependencies, renderArea);
|
||||
}
|
||||
|
||||
void Graphics::beginRenderPass(Gfx::PRenderPass renderPass)
|
||||
{
|
||||
void Graphics::beginRenderPass(Gfx::PRenderPass renderPass) {
|
||||
queue->getCommands()->beginRenderPass(renderPass.cast<RenderPass>());
|
||||
}
|
||||
|
||||
void Graphics::endRenderPass()
|
||||
{
|
||||
queue->getCommands()->endRenderPass();
|
||||
}
|
||||
void Graphics::endRenderPass() { queue->getCommands()->endRenderPass(); }
|
||||
|
||||
void Graphics::waitDeviceIdle()
|
||||
{
|
||||
queue->getCommands()->waitDeviceIdle();
|
||||
}
|
||||
void Graphics::waitDeviceIdle() { queue->getCommands()->waitDeviceIdle(); }
|
||||
|
||||
void Graphics::executeCommands(Array<Gfx::ORenderCommand> commands)
|
||||
{
|
||||
queue->executeCommands(std::move(commands));
|
||||
}
|
||||
|
||||
void Graphics::executeCommands(Array<Gfx::OComputeCommand> commands)
|
||||
{
|
||||
void Graphics::executeCommands(Array<Gfx::ORenderCommand> commands) {
|
||||
queue->executeCommands(std::move(commands));
|
||||
}
|
||||
|
||||
Gfx::OTexture2D Graphics::createTexture2D(const TextureCreateInfo &createInfo)
|
||||
{
|
||||
void Graphics::executeCommands(Array<Gfx::OComputeCommand> commands) {
|
||||
queue->executeCommands(std::move(commands));
|
||||
}
|
||||
|
||||
Gfx::OTexture2D Graphics::createTexture2D(const TextureCreateInfo &createInfo) {
|
||||
return new Texture2D(this, createInfo);
|
||||
}
|
||||
|
||||
Gfx::OTexture3D Graphics::createTexture3D(const TextureCreateInfo &createInfo)
|
||||
{
|
||||
|
||||
Gfx::OTexture3D Graphics::createTexture3D(const TextureCreateInfo &createInfo) {
|
||||
|
||||
return new Texture3D(this, createInfo);
|
||||
}
|
||||
|
||||
Gfx::OTextureCube Graphics::createTextureCube(const TextureCreateInfo &createInfo)
|
||||
{
|
||||
Gfx::OTextureCube
|
||||
Graphics::createTextureCube(const TextureCreateInfo &createInfo) {
|
||||
return new TextureCube(this, createInfo);
|
||||
}
|
||||
|
||||
Gfx::OUniformBuffer Graphics::createUniformBuffer(const UniformBufferCreateInfo &bulkData)
|
||||
{
|
||||
Gfx::OUniformBuffer
|
||||
Graphics::createUniformBuffer(const UniformBufferCreateInfo &bulkData) {
|
||||
return new UniformBuffer(this, bulkData);
|
||||
}
|
||||
|
||||
Gfx::OShaderBuffer Graphics::createShaderBuffer(const ShaderBufferCreateInfo &bulkData)
|
||||
{
|
||||
Gfx::OShaderBuffer
|
||||
Graphics::createShaderBuffer(const ShaderBufferCreateInfo &bulkData) {
|
||||
return new ShaderBuffer(this, bulkData);
|
||||
}
|
||||
|
||||
Gfx::OVertexBuffer Graphics::createVertexBuffer(const VertexBufferCreateInfo &bulkData)
|
||||
{
|
||||
Gfx::OVertexBuffer
|
||||
Graphics::createVertexBuffer(const VertexBufferCreateInfo &bulkData) {
|
||||
return new VertexBuffer(this, bulkData);
|
||||
}
|
||||
|
||||
Gfx::OIndexBuffer Graphics::createIndexBuffer(const IndexBufferCreateInfo &bulkData)
|
||||
{
|
||||
Gfx::OIndexBuffer
|
||||
Graphics::createIndexBuffer(const IndexBufferCreateInfo &bulkData) {
|
||||
return new IndexBuffer(this, bulkData);
|
||||
}
|
||||
|
||||
Gfx::ORenderCommand Graphics::createRenderCommand(const std::string& name)
|
||||
{
|
||||
Gfx::ORenderCommand Graphics::createRenderCommand(const std::string &name) {
|
||||
return queue->getRenderCommand(name);
|
||||
}
|
||||
|
||||
Gfx::OComputeCommand Graphics::createComputeCommand(const std::string& name)
|
||||
{
|
||||
Gfx::OComputeCommand Graphics::createComputeCommand(const std::string &name) {
|
||||
return queue->getComputeCommand(name);
|
||||
}
|
||||
|
||||
Gfx::OVertexShader Graphics::createVertexShader(const ShaderCreateInfo& createInfo)
|
||||
{
|
||||
Gfx::OVertexShader
|
||||
Graphics::createVertexShader(const ShaderCreateInfo &createInfo) {
|
||||
OVertexShader result = new VertexShader(this);
|
||||
result->create(createInfo);
|
||||
return result;
|
||||
}
|
||||
|
||||
Gfx::OFragmentShader Graphics::createFragmentShader(const ShaderCreateInfo& createInfo)
|
||||
{
|
||||
Gfx::OFragmentShader
|
||||
Graphics::createFragmentShader(const ShaderCreateInfo &createInfo) {
|
||||
OFragmentShader result = new FragmentShader(this);
|
||||
result->create(createInfo);
|
||||
return result;
|
||||
}
|
||||
|
||||
Gfx::OComputeShader Graphics::createComputeShader(const ShaderCreateInfo& createInfo)
|
||||
{
|
||||
Gfx::OComputeShader
|
||||
Graphics::createComputeShader(const ShaderCreateInfo &createInfo) {
|
||||
OComputeShader result = new ComputeShader(this);
|
||||
result->create(createInfo);
|
||||
return result;
|
||||
}
|
||||
|
||||
Gfx::OMeshShader Graphics::createMeshShader(const ShaderCreateInfo& createInfo)
|
||||
{
|
||||
Gfx::OMeshShader
|
||||
Graphics::createMeshShader(const ShaderCreateInfo &createInfo) {
|
||||
OMeshShader result = new MeshShader(this);
|
||||
result->create(createInfo);
|
||||
return result;
|
||||
}
|
||||
|
||||
Gfx::OTaskShader Graphics::createTaskShader(const ShaderCreateInfo& createInfo)
|
||||
{
|
||||
Gfx::OTaskShader
|
||||
Graphics::createTaskShader(const ShaderCreateInfo &createInfo) {
|
||||
OTaskShader result = new TaskShader(this);
|
||||
result->create(createInfo);
|
||||
return result;
|
||||
}
|
||||
|
||||
Gfx::PGraphicsPipeline Graphics::createGraphicsPipeline(Gfx::LegacyPipelineCreateInfo createInfo)
|
||||
{
|
||||
Gfx::PGraphicsPipeline
|
||||
Graphics::createGraphicsPipeline(Gfx::LegacyPipelineCreateInfo createInfo) {
|
||||
return cache->createPipeline(std::move(createInfo));
|
||||
}
|
||||
|
||||
Gfx::PGraphicsPipeline Graphics::createGraphicsPipeline(Gfx::MeshPipelineCreateInfo createInfo)
|
||||
{
|
||||
Gfx::PGraphicsPipeline
|
||||
Graphics::createGraphicsPipeline(Gfx::MeshPipelineCreateInfo createInfo) {
|
||||
return cache->createPipeline(std::move(createInfo));
|
||||
}
|
||||
|
||||
Gfx::PComputePipeline Graphics::createComputePipeline(Gfx::ComputePipelineCreateInfo createInfo)
|
||||
{
|
||||
Gfx::PComputePipeline
|
||||
Graphics::createComputePipeline(Gfx::ComputePipelineCreateInfo createInfo) {
|
||||
return cache->createPipeline(std::move(createInfo));
|
||||
}
|
||||
|
||||
Gfx::OSampler Graphics::createSampler(const SamplerCreateInfo& createInfo)
|
||||
{
|
||||
Gfx::OSampler Graphics::createSampler(const SamplerCreateInfo &createInfo) {
|
||||
return new Sampler(this, createInfo);
|
||||
}
|
||||
|
||||
Gfx::ODescriptorLayout Graphics::createDescriptorLayout(const std::string& name)
|
||||
{
|
||||
Gfx::ODescriptorLayout
|
||||
Graphics::createDescriptorLayout(const std::string &name) {
|
||||
return new DescriptorLayout(this, name);
|
||||
}
|
||||
|
||||
Gfx::OPipelineLayout Graphics::createPipelineLayout(const std::string& name, Gfx::PPipelineLayout baseLayout)
|
||||
{
|
||||
Gfx::OPipelineLayout
|
||||
Graphics::createPipelineLayout(const std::string &name,
|
||||
Gfx::PPipelineLayout baseLayout) {
|
||||
return new PipelineLayout(this, name, baseLayout);
|
||||
}
|
||||
|
||||
Gfx::OVertexInput Graphics::createVertexInput(VertexInputStateCreateInfo createInfo)
|
||||
{
|
||||
Gfx::OVertexInput
|
||||
Graphics::createVertexInput(VertexInputStateCreateInfo createInfo) {
|
||||
return new VertexInput(createInfo);
|
||||
}
|
||||
|
||||
void Graphics::resolveTexture(Gfx::PTexture source, Gfx::PTexture destination)
|
||||
{
|
||||
void Graphics::resolveTexture(Gfx::PTexture source, Gfx::PTexture destination) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -7,33 +7,35 @@
|
||||
namespace Seele {
|
||||
namespace Metal {
|
||||
class VertexInput : public Gfx::VertexInput {
|
||||
public:
|
||||
VertexInput(VertexInputStateCreateInfo createInfo);
|
||||
virtual ~VertexInput();
|
||||
public:
|
||||
VertexInput(VertexInputStateCreateInfo createInfo);
|
||||
virtual ~VertexInput();
|
||||
};
|
||||
DECLARE_REF(PipelineLayout)
|
||||
DECLARE_REF(Graphics)
|
||||
class GraphicsPipeline : public Gfx::GraphicsPipeline {
|
||||
public:
|
||||
GraphicsPipeline(PGraphics graphics, MTL::PrimitiveType primitive, MTL::RenderPipelineState* pipeline, Gfx::PPipelineLayout createInfo);
|
||||
virtual ~GraphicsPipeline();
|
||||
constexpr MTL::RenderPipelineState* getHandle() const { return state; }
|
||||
constexpr MTL::PrimitiveType getPrimitive() const { return primitiveType; }
|
||||
PGraphics graphics;
|
||||
MTL::RenderPipelineState* state;
|
||||
MTL::PrimitiveType primitiveType;
|
||||
private:
|
||||
public:
|
||||
GraphicsPipeline(PGraphics graphics, MTL::PrimitiveType primitive, MTL::RenderPipelineState* pipeline, Gfx::PPipelineLayout createInfo);
|
||||
virtual ~GraphicsPipeline();
|
||||
constexpr MTL::RenderPipelineState* getHandle() const { return state; }
|
||||
constexpr MTL::PrimitiveType getPrimitive() const { return primitiveType; }
|
||||
PGraphics graphics;
|
||||
MTL::RenderPipelineState* state;
|
||||
MTL::PrimitiveType primitiveType;
|
||||
|
||||
private:
|
||||
};
|
||||
DEFINE_REF(GraphicsPipeline)
|
||||
class ComputePipeline : public Gfx::ComputePipeline {
|
||||
public:
|
||||
ComputePipeline(PGraphics graphics, MTL::ComputePipelineState* pipeline, Gfx::PPipelineLayout);
|
||||
virtual ~ComputePipeline();
|
||||
constexpr MTL::ComputePipelineState* getHandle() const { return state; }
|
||||
public:
|
||||
ComputePipeline(PGraphics graphics, MTL::ComputePipelineState* pipeline, Gfx::PPipelineLayout);
|
||||
virtual ~ComputePipeline();
|
||||
constexpr MTL::ComputePipelineState* getHandle() const { return state; }
|
||||
|
||||
PGraphics graphics;
|
||||
private:
|
||||
MTL::ComputePipelineState* state;
|
||||
PGraphics graphics;
|
||||
|
||||
private:
|
||||
MTL::ComputePipelineState* state;
|
||||
};
|
||||
DEFINE_REF(ComputePipeline)
|
||||
} // namespace Metal
|
||||
|
||||
@@ -7,17 +7,22 @@
|
||||
using namespace Seele;
|
||||
using namespace Seele::Metal;
|
||||
|
||||
VertexInput::VertexInput(VertexInputStateCreateInfo createInfo) : Gfx::VertexInput(createInfo) {}
|
||||
VertexInput::VertexInput(VertexInputStateCreateInfo createInfo)
|
||||
: Gfx::VertexInput(createInfo) {}
|
||||
|
||||
VertexInput::~VertexInput() {}
|
||||
|
||||
GraphicsPipeline::GraphicsPipeline(PGraphics graphics, MTL::PrimitiveType primitive, MTL::RenderPipelineState* pipeline,
|
||||
GraphicsPipeline::GraphicsPipeline(PGraphics graphics,
|
||||
MTL::PrimitiveType primitive,
|
||||
MTL::RenderPipelineState *pipeline,
|
||||
Gfx::PPipelineLayout layout)
|
||||
: Gfx::GraphicsPipeline(layout), graphics(graphics), state(pipeline), primitiveType(primitive) {}
|
||||
: Gfx::GraphicsPipeline(layout), graphics(graphics), state(pipeline),
|
||||
primitiveType(primitive) {}
|
||||
|
||||
GraphicsPipeline::~GraphicsPipeline() {}
|
||||
|
||||
ComputePipeline::ComputePipeline(PGraphics graphics, MTL::ComputePipelineState* pipeline,
|
||||
ComputePipeline::ComputePipeline(PGraphics graphics,
|
||||
MTL::ComputePipelineState *pipeline,
|
||||
Gfx::PPipelineLayout layout)
|
||||
: Gfx::ComputePipeline(layout), graphics(graphics), state(pipeline) {}
|
||||
|
||||
|
||||
@@ -4,20 +4,20 @@
|
||||
|
||||
namespace Seele {
|
||||
namespace Metal {
|
||||
class PipelineCache
|
||||
{
|
||||
public:
|
||||
PipelineCache(PGraphics graphics, const std::string& cacheFilePath);
|
||||
~PipelineCache();
|
||||
PGraphicsPipeline createPipeline(Gfx::LegacyPipelineCreateInfo createInfo);
|
||||
PGraphicsPipeline createPipeline(Gfx::MeshPipelineCreateInfo createInfo);
|
||||
PComputePipeline createPipeline(Gfx::ComputePipelineCreateInfo createInfo);
|
||||
private:
|
||||
PGraphics graphics;
|
||||
Map<uint32, OGraphicsPipeline> graphicsPipelines;
|
||||
Map<uint32, OComputePipeline> computePipelines;
|
||||
std::string cacheFile;
|
||||
class PipelineCache {
|
||||
public:
|
||||
PipelineCache(PGraphics graphics, const std::string& cacheFilePath);
|
||||
~PipelineCache();
|
||||
PGraphicsPipeline createPipeline(Gfx::LegacyPipelineCreateInfo createInfo);
|
||||
PGraphicsPipeline createPipeline(Gfx::MeshPipelineCreateInfo createInfo);
|
||||
PComputePipeline createPipeline(Gfx::ComputePipelineCreateInfo createInfo);
|
||||
|
||||
private:
|
||||
PGraphics graphics;
|
||||
Map<uint32, OGraphicsPipeline> graphicsPipelines;
|
||||
Map<uint32, OComputePipeline> computePipelines;
|
||||
std::string cacheFile;
|
||||
};
|
||||
DEFINE_REF(PipelineCache)
|
||||
}
|
||||
}
|
||||
} // namespace Metal
|
||||
} // namespace Seele
|
||||
@@ -19,22 +19,30 @@
|
||||
using namespace Seele;
|
||||
using namespace Seele::Metal;
|
||||
|
||||
PipelineCache::PipelineCache(PGraphics graphics, const std::string& name) : graphics(graphics), cacheFile(name) {}
|
||||
PipelineCache::PipelineCache(PGraphics graphics, const std::string &name)
|
||||
: graphics(graphics), cacheFile(name) {}
|
||||
|
||||
PipelineCache::~PipelineCache() {}
|
||||
|
||||
PGraphicsPipeline PipelineCache::createPipeline(Gfx::LegacyPipelineCreateInfo createInfo) {
|
||||
PPipelineLayout layout = Gfx::PPipelineLayout(createInfo.pipelineLayout).cast<PipelineLayout>();
|
||||
PGraphicsPipeline
|
||||
PipelineCache::createPipeline(Gfx::LegacyPipelineCreateInfo createInfo) {
|
||||
PPipelineLayout layout =
|
||||
Gfx::PPipelineLayout(createInfo.pipelineLayout).cast<PipelineLayout>();
|
||||
|
||||
MTL::RenderPipelineDescriptor* pipelineDescriptor = MTL::RenderPipelineDescriptor::alloc()->init();
|
||||
MTL::RenderPipelineDescriptor *pipelineDescriptor =
|
||||
MTL::RenderPipelineDescriptor::alloc()->init();
|
||||
|
||||
MTL::VertexDescriptor* vertexDescriptor = pipelineDescriptor->vertexDescriptor()->init();
|
||||
MTL::VertexAttributeDescriptorArray* attributes = vertexDescriptor->attributes()->init();
|
||||
MTL::VertexDescriptor *vertexDescriptor =
|
||||
pipelineDescriptor->vertexDescriptor()->init();
|
||||
MTL::VertexAttributeDescriptorArray *attributes =
|
||||
vertexDescriptor->attributes()->init();
|
||||
if (createInfo.vertexInput != nullptr) {
|
||||
const auto& vertexInfo = createInfo.vertexInput->getInfo();
|
||||
const auto &vertexInfo = createInfo.vertexInput->getInfo();
|
||||
for (size_t attr = 0; attr < vertexInfo.attributes.size(); ++attr) {
|
||||
MTL::VertexAttributeDescriptor* attribute = attributes->object(attr + METAL_VERTEXATTRIBUTE_OFFSET)->init();
|
||||
attribute->setBufferIndex(vertexInfo.attributes[attr].binding + METAL_VERTEXBUFFER_OFFSET);
|
||||
MTL::VertexAttributeDescriptor *attribute =
|
||||
attributes->object(attr + METAL_VERTEXATTRIBUTE_OFFSET)->init();
|
||||
attribute->setBufferIndex(vertexInfo.attributes[attr].binding +
|
||||
METAL_VERTEXBUFFER_OFFSET);
|
||||
switch (vertexInfo.attributes[attr].format) {
|
||||
case Gfx::SE_FORMAT_R32G32B32_SFLOAT:
|
||||
attribute->setFormat(MTL::VertexFormatFloat3);
|
||||
@@ -45,9 +53,11 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::LegacyPipelineCreateInfo cr
|
||||
attribute->setOffset(vertexInfo.attributes[attr].offset);
|
||||
}
|
||||
|
||||
MTL::VertexBufferLayoutDescriptorArray* bufferLayout = vertexDescriptor->layouts()->init();
|
||||
MTL::VertexBufferLayoutDescriptorArray *bufferLayout =
|
||||
vertexDescriptor->layouts()->init();
|
||||
for (size_t binding = 0; binding < vertexInfo.bindings.size(); ++binding) {
|
||||
MTL::VertexBufferLayoutDescriptor* buffer = bufferLayout->object(binding + METAL_VERTEXBUFFER_OFFSET)->init();
|
||||
MTL::VertexBufferLayoutDescriptor *buffer =
|
||||
bufferLayout->object(binding + METAL_VERTEXBUFFER_OFFSET)->init();
|
||||
buffer->setStride(vertexInfo.bindings[binding].stride);
|
||||
buffer->setStepRate(1);
|
||||
switch (vertexInfo.bindings[binding].inputRate) {
|
||||
@@ -62,19 +72,28 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::LegacyPipelineCreateInfo cr
|
||||
}
|
||||
pipelineDescriptor->setVertexDescriptor(vertexDescriptor);
|
||||
|
||||
pipelineDescriptor->setVertexFunction(createInfo.vertexShader.cast<VertexShader>()->getFunction());
|
||||
pipelineDescriptor->setVertexFunction(
|
||||
createInfo.vertexShader.cast<VertexShader>()->getFunction());
|
||||
if (createInfo.fragmentShader != nullptr) {
|
||||
pipelineDescriptor->setFragmentFunction(createInfo.fragmentShader.cast<FragmentShader>()->getFunction());
|
||||
pipelineDescriptor->setFragmentFunction(
|
||||
createInfo.fragmentShader.cast<FragmentShader>()->getFunction());
|
||||
}
|
||||
pipelineDescriptor->setInputPrimitiveTopology(cast(createInfo.topology));
|
||||
if (createInfo.renderPass->getLayout().depthAttachment.getTexture() != nullptr) {
|
||||
if (createInfo.renderPass->getLayout().depthAttachment.getTexture() !=
|
||||
nullptr) {
|
||||
pipelineDescriptor->setDepthAttachmentPixelFormat(
|
||||
cast(createInfo.renderPass->getLayout().depthAttachment.getTexture().cast<Texture2D>()->getFormat()));
|
||||
cast(createInfo.renderPass->getLayout()
|
||||
.depthAttachment.getTexture()
|
||||
.cast<Texture2D>()
|
||||
->getFormat()));
|
||||
}
|
||||
pipelineDescriptor->setAlphaToCoverageEnabled(createInfo.multisampleState.alphaCoverageEnable);
|
||||
pipelineDescriptor->setAlphaToOneEnabled(createInfo.multisampleState.alphaToOneEnable);
|
||||
pipelineDescriptor->setAlphaToCoverageEnabled(
|
||||
createInfo.multisampleState.alphaCoverageEnable);
|
||||
pipelineDescriptor->setAlphaToOneEnabled(
|
||||
createInfo.multisampleState.alphaToOneEnable);
|
||||
pipelineDescriptor->setRasterSampleCount(createInfo.multisampleState.samples);
|
||||
pipelineDescriptor->setRasterizationEnabled(!createInfo.rasterizationState.rasterizerDiscardEnable);
|
||||
pipelineDescriptor->setRasterizationEnabled(
|
||||
!createInfo.rasterizationState.rasterizerDiscardEnable);
|
||||
|
||||
uint32 hash = pipelineDescriptor->hash();
|
||||
|
||||
@@ -117,12 +136,14 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::LegacyPipelineCreateInfo cr
|
||||
type = MTL::PrimitiveTypeTriangle;
|
||||
break;
|
||||
}
|
||||
NS::Error* error;
|
||||
graphicsPipelines[hash] =
|
||||
new GraphicsPipeline(graphics, type, graphics->getDevice()->newRenderPipelineState(pipelineDescriptor, &error),
|
||||
std::move(createInfo.pipelineLayout));
|
||||
NS::Error *error;
|
||||
graphicsPipelines[hash] = new GraphicsPipeline(
|
||||
graphics, type,
|
||||
graphics->getDevice()->newRenderPipelineState(pipelineDescriptor, &error),
|
||||
std::move(createInfo.pipelineLayout));
|
||||
if (error) {
|
||||
std::cout << error->localizedDescription()->cString(NS::ASCIIStringEncoding) << std::endl;
|
||||
std::cout << error->localizedDescription()->cString(NS::ASCIIStringEncoding)
|
||||
<< std::endl;
|
||||
assert(false);
|
||||
}
|
||||
|
||||
@@ -130,51 +151,67 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::LegacyPipelineCreateInfo cr
|
||||
return graphicsPipelines[hash];
|
||||
}
|
||||
|
||||
PGraphicsPipeline PipelineCache::createPipeline(Gfx::MeshPipelineCreateInfo createInfo) {
|
||||
MTL::MeshRenderPipelineDescriptor* pipelineDescriptor = MTL::MeshRenderPipelineDescriptor::alloc()->init();
|
||||
PGraphicsPipeline
|
||||
PipelineCache::createPipeline(Gfx::MeshPipelineCreateInfo createInfo) {
|
||||
MTL::MeshRenderPipelineDescriptor *pipelineDescriptor =
|
||||
MTL::MeshRenderPipelineDescriptor::alloc()->init();
|
||||
|
||||
pipelineDescriptor->setMeshFunction(createInfo.meshShader.cast<MeshShader>()->getFunction());
|
||||
pipelineDescriptor->setMeshFunction(
|
||||
createInfo.meshShader.cast<MeshShader>()->getFunction());
|
||||
if (createInfo.taskShader != nullptr) {
|
||||
pipelineDescriptor->setObjectFunction(createInfo.taskShader.cast<TaskShader>()->getFunction());
|
||||
pipelineDescriptor->setObjectFunction(
|
||||
createInfo.taskShader.cast<TaskShader>()->getFunction());
|
||||
}
|
||||
if (createInfo.fragmentShader != nullptr) {
|
||||
pipelineDescriptor->setFragmentFunction(createInfo.fragmentShader.cast<FragmentShader>()->getFunction());
|
||||
pipelineDescriptor->setFragmentFunction(
|
||||
createInfo.fragmentShader.cast<FragmentShader>()->getFunction());
|
||||
}
|
||||
if (createInfo.renderPass->getLayout().depthAttachment.getTexture() != nullptr) {
|
||||
if (createInfo.renderPass->getLayout().depthAttachment.getTexture() !=
|
||||
nullptr) {
|
||||
pipelineDescriptor->setDepthAttachmentPixelFormat(
|
||||
cast(createInfo.renderPass->getLayout().depthAttachment.getTexture().cast<Texture2D>()->getFormat()));
|
||||
cast(createInfo.renderPass->getLayout()
|
||||
.depthAttachment.getTexture()
|
||||
.cast<Texture2D>()
|
||||
->getFormat()));
|
||||
}
|
||||
pipelineDescriptor->setAlphaToCoverageEnabled(createInfo.multisampleState.alphaCoverageEnable);
|
||||
pipelineDescriptor->setAlphaToOneEnabled(createInfo.multisampleState.alphaToOneEnable);
|
||||
pipelineDescriptor->setAlphaToCoverageEnabled(
|
||||
createInfo.multisampleState.alphaCoverageEnable);
|
||||
pipelineDescriptor->setAlphaToOneEnabled(
|
||||
createInfo.multisampleState.alphaToOneEnable);
|
||||
pipelineDescriptor->setRasterSampleCount(createInfo.multisampleState.samples);
|
||||
pipelineDescriptor->setRasterizationEnabled(!createInfo.rasterizationState.rasterizerDiscardEnable);
|
||||
pipelineDescriptor->setRasterizationEnabled(
|
||||
!createInfo.rasterizationState.rasterizerDiscardEnable);
|
||||
|
||||
uint32 hash = pipelineDescriptor->hash();
|
||||
|
||||
if (graphicsPipelines.contains(hash)) {
|
||||
return graphicsPipelines[hash];
|
||||
}
|
||||
NS::Error* error = nullptr;
|
||||
NS::Error *error = nullptr;
|
||||
MTL::AutoreleasedRenderPipelineReflection reflection;
|
||||
graphicsPipelines[hash] = new GraphicsPipeline(
|
||||
graphics, MTL::PrimitiveTypeTriangle,
|
||||
graphics->getDevice()->newRenderPipelineState(pipelineDescriptor, MTL::PipelineOptionNone, &reflection, &error),
|
||||
graphics->getDevice()->newRenderPipelineState(
|
||||
pipelineDescriptor, MTL::PipelineOptionNone, &reflection, &error),
|
||||
std::move(createInfo.pipelineLayout));
|
||||
|
||||
pipelineDescriptor->release();
|
||||
return graphicsPipelines[hash];
|
||||
}
|
||||
|
||||
PComputePipeline PipelineCache::createPipeline(Gfx::ComputePipelineCreateInfo createInfo) {
|
||||
PComputePipeline
|
||||
PipelineCache::createPipeline(Gfx::ComputePipelineCreateInfo createInfo) {
|
||||
PComputeShader shader = createInfo.computeShader.cast<ComputeShader>();
|
||||
uint32 hash = shader->getShaderHash();
|
||||
if (computePipelines.contains(hash)) {
|
||||
return computePipelines[hash];
|
||||
}
|
||||
|
||||
NS::Error* error;
|
||||
NS::Error *error;
|
||||
computePipelines[hash] =
|
||||
new ComputePipeline(graphics, graphics->getDevice()->newComputePipelineState(shader->getFunction(), &error),
|
||||
new ComputePipeline(graphics,
|
||||
graphics->getDevice()->newComputePipelineState(
|
||||
shader->getFunction(), &error),
|
||||
std::move(createInfo.pipelineLayout));
|
||||
assert(!error);
|
||||
return computePipelines[hash];
|
||||
|
||||
@@ -2,22 +2,17 @@
|
||||
#include "Graphics/RenderTarget.h"
|
||||
#include "Resources.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
namespace Metal
|
||||
{
|
||||
namespace Seele {
|
||||
namespace Metal {
|
||||
DECLARE_REF(Graphics)
|
||||
class RenderPass : public Gfx::RenderPass
|
||||
{
|
||||
public:
|
||||
class RenderPass : public Gfx::RenderPass {
|
||||
public:
|
||||
RenderPass(PGraphics graphics, Gfx::RenderTargetLayout layout, Array<Gfx::SubPassDependency> dependencies, Gfx::PViewport viewport);
|
||||
virtual ~RenderPass();
|
||||
void updateRenderPass();
|
||||
MTL::RenderPassDescriptor* getDescriptor() const
|
||||
{
|
||||
return renderPass;
|
||||
}
|
||||
private:
|
||||
MTL::RenderPassDescriptor* getDescriptor() const { return renderPass; }
|
||||
|
||||
private:
|
||||
PGraphics graphics;
|
||||
Gfx::PViewport viewport;
|
||||
MTL::RenderPassDescriptor* renderPass;
|
||||
|
||||
@@ -7,9 +7,11 @@
|
||||
using namespace Seele;
|
||||
using namespace Seele::Metal;
|
||||
|
||||
RenderPass::RenderPass(PGraphics graphics, Gfx::RenderTargetLayout layout, Array<Gfx::SubPassDependency> dependencies,
|
||||
RenderPass::RenderPass(PGraphics graphics, Gfx::RenderTargetLayout layout,
|
||||
Array<Gfx::SubPassDependency> dependencies,
|
||||
Gfx::PViewport viewport)
|
||||
: Gfx::RenderPass(layout, dependencies), graphics(graphics), viewport(viewport) {
|
||||
: Gfx::RenderPass(layout, dependencies), graphics(graphics),
|
||||
viewport(viewport) {
|
||||
renderPass = MTL::RenderPassDescriptor::renderPassDescriptor();
|
||||
renderPass->setRenderTargetArrayLength(1);
|
||||
renderPass->setRenderTargetWidth(viewport->getWidth());
|
||||
@@ -17,18 +19,21 @@ RenderPass::RenderPass(PGraphics graphics, Gfx::RenderTargetLayout layout, Array
|
||||
renderPass->setDefaultRasterSampleCount(viewport->getSamples());
|
||||
|
||||
for (size_t i = 0; i < layout.colorAttachments.size(); ++i) {
|
||||
const auto& color = layout.colorAttachments[i];
|
||||
MTL::RenderPassColorAttachmentDescriptor* desc = renderPass->colorAttachments()->object(i);
|
||||
desc->setClearColor(MTL::ClearColor(color.clear.color.float32[0], color.clear.color.float32[1],
|
||||
color.clear.color.float32[2], color.clear.color.float32[3]));
|
||||
const auto &color = layout.colorAttachments[i];
|
||||
MTL::RenderPassColorAttachmentDescriptor *desc =
|
||||
renderPass->colorAttachments()->object(i);
|
||||
desc->setClearColor(MTL::ClearColor(
|
||||
color.clear.color.float32[0], color.clear.color.float32[1],
|
||||
color.clear.color.float32[2], color.clear.color.float32[3]));
|
||||
desc->setLoadAction(cast(color.getLoadOp()));
|
||||
desc->setStoreAction(cast(color.getStoreOp()));
|
||||
desc->setLevel(0);
|
||||
if (!layout.resolveAttachments.empty()) {
|
||||
const auto& resolve = layout.resolveAttachments[i];
|
||||
const auto &resolve = layout.resolveAttachments[i];
|
||||
desc->setResolveLevel(0);
|
||||
desc->setStoreAction(MTL::StoreActionStoreAndMultisampleResolve);
|
||||
desc->setResolveTexture(resolve.getTexture().cast<TextureBase>()->getTexture());
|
||||
desc->setResolveTexture(
|
||||
resolve.getTexture().cast<TextureBase>()->getTexture());
|
||||
}
|
||||
}
|
||||
if (layout.depthAttachment.getTexture() != nullptr) {
|
||||
@@ -38,7 +43,9 @@ RenderPass::RenderPass(PGraphics graphics, Gfx::RenderTargetLayout layout, Array
|
||||
depth->setStoreAction(cast(layout.depthAttachment.getStoreOp()));
|
||||
|
||||
if (layout.depthResolveAttachment.getTexture() != nullptr) {
|
||||
depth->setResolveTexture(layout.depthResolveAttachment.getTexture().cast<TextureBase>()->getTexture());
|
||||
depth->setResolveTexture(layout.depthResolveAttachment.getTexture()
|
||||
.cast<TextureBase>()
|
||||
->getTexture());
|
||||
depth->setStoreAction(MTL::StoreActionStoreAndMultisampleResolve);
|
||||
}
|
||||
}
|
||||
@@ -48,12 +55,13 @@ RenderPass::~RenderPass() {}
|
||||
|
||||
void RenderPass::updateRenderPass() {
|
||||
for (size_t i = 0; i < layout.colorAttachments.size(); ++i) {
|
||||
const auto& color = layout.colorAttachments[i];
|
||||
const auto &color = layout.colorAttachments[i];
|
||||
auto desc = renderPass->colorAttachments()->object(i);
|
||||
desc->setTexture(color.getTexture().cast<TextureBase>()->getTexture());
|
||||
}
|
||||
if (layout.depthAttachment.getTexture() != nullptr) {
|
||||
auto depth = renderPass->depthAttachment();
|
||||
depth->setTexture(layout.depthAttachment.getTexture().cast<TextureBase>()->getTexture());
|
||||
depth->setTexture(
|
||||
layout.depthAttachment.getTexture().cast<TextureBase>()->getTexture());
|
||||
}
|
||||
}
|
||||
@@ -10,58 +10,51 @@
|
||||
namespace Seele {
|
||||
namespace Metal {
|
||||
DECLARE_REF(Graphics);
|
||||
class CommandBoundResource
|
||||
{
|
||||
public:
|
||||
CommandBoundResource(PGraphics graphics)
|
||||
: graphics(graphics)
|
||||
{
|
||||
}
|
||||
virtual ~CommandBoundResource()
|
||||
{
|
||||
class CommandBoundResource {
|
||||
public:
|
||||
CommandBoundResource(PGraphics graphics) : graphics(graphics) {}
|
||||
virtual ~CommandBoundResource() {
|
||||
if (isCurrentlyBound())
|
||||
abort();
|
||||
}
|
||||
constexpr bool isCurrentlyBound() const { return bindCount > 0; }
|
||||
constexpr void bind() { bindCount++; }
|
||||
constexpr void unbind() { bindCount--; }
|
||||
protected:
|
||||
|
||||
protected:
|
||||
PGraphics graphics;
|
||||
uint64 bindCount = 0;
|
||||
};
|
||||
DEFINE_REF(CommandBoundResource)
|
||||
|
||||
class Fence {
|
||||
public:
|
||||
Fence(PGraphics graphics);
|
||||
~Fence();
|
||||
MTL::Fence *getHandle() const { return handle; }
|
||||
public:
|
||||
Fence(PGraphics graphics);
|
||||
~Fence();
|
||||
MTL::Fence* getHandle() const { return handle; }
|
||||
|
||||
private:
|
||||
MTL::Fence *handle;
|
||||
private:
|
||||
MTL::Fence* handle;
|
||||
};
|
||||
DEFINE_REF(Fence);
|
||||
class Event {
|
||||
public:
|
||||
Event(PGraphics graphics);
|
||||
~Event();
|
||||
MTL::Event *getHandle() const { return handle; }
|
||||
public:
|
||||
Event(PGraphics graphics);
|
||||
~Event();
|
||||
MTL::Event* getHandle() const { return handle; }
|
||||
|
||||
private:
|
||||
MTL::Event *handle;
|
||||
private:
|
||||
MTL::Event* handle;
|
||||
};
|
||||
DEFINE_REF(Event)
|
||||
class Sampler : public Gfx::Sampler
|
||||
{
|
||||
public:
|
||||
Sampler(PGraphics graphics, const SamplerCreateInfo& createInfo);
|
||||
virtual ~Sampler();
|
||||
MTL::SamplerState* getHandle() const
|
||||
{
|
||||
return sampler;
|
||||
}
|
||||
private:
|
||||
MTL::SamplerState* sampler;
|
||||
class Sampler : public Gfx::Sampler {
|
||||
public:
|
||||
Sampler(PGraphics graphics, const SamplerCreateInfo& createInfo);
|
||||
virtual ~Sampler();
|
||||
MTL::SamplerState* getHandle() const { return sampler; }
|
||||
|
||||
private:
|
||||
MTL::SamplerState* sampler;
|
||||
};
|
||||
DEFINE_REF(Sampler)
|
||||
} // namespace Metal
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
#include "Resources.h"
|
||||
#include "Enums.h"
|
||||
#include "Graphics.h"
|
||||
#include "Metal/MTLSampler.hpp"
|
||||
#include "Enums.h"
|
||||
|
||||
|
||||
using namespace Seele;
|
||||
using namespace Seele::Metal;
|
||||
@@ -14,9 +15,8 @@ Event::Event(PGraphics graphics) : handle(graphics->getDevice()->newEvent()) {}
|
||||
|
||||
Event::~Event() { handle->release(); }
|
||||
|
||||
Sampler::Sampler(PGraphics graphics, const SamplerCreateInfo& createInfo)
|
||||
{
|
||||
MTL::SamplerDescriptor* desc = MTL::SamplerDescriptor::alloc()->init();
|
||||
Sampler::Sampler(PGraphics graphics, const SamplerCreateInfo &createInfo) {
|
||||
MTL::SamplerDescriptor *desc = MTL::SamplerDescriptor::alloc()->init();
|
||||
desc->setBorderColor(cast(createInfo.borderColor));
|
||||
desc->setCompareFunction(cast(createInfo.compareOp));
|
||||
desc->setLodAverage(createInfo.mipLodBias);
|
||||
@@ -35,7 +35,4 @@ Sampler::Sampler(PGraphics graphics, const SamplerCreateInfo& createInfo)
|
||||
desc->release();
|
||||
}
|
||||
|
||||
Sampler::~Sampler()
|
||||
{
|
||||
sampler->release();
|
||||
}
|
||||
Sampler::~Sampler() { sampler->release(); }
|
||||
@@ -7,32 +7,32 @@ namespace Seele {
|
||||
namespace Metal {
|
||||
|
||||
class Shader {
|
||||
public:
|
||||
Shader(PGraphics graphics, Gfx::SeShaderStageFlags stage);
|
||||
virtual ~Shader();
|
||||
public:
|
||||
Shader(PGraphics graphics, Gfx::SeShaderStageFlags stage);
|
||||
virtual ~Shader();
|
||||
|
||||
void create(const ShaderCreateInfo &createInfo);
|
||||
void create(const ShaderCreateInfo& createInfo);
|
||||
|
||||
constexpr MTL::Function *getFunction() const { return function; }
|
||||
constexpr const char *getEntryPointName() const {
|
||||
// SLang renames all entry points to main, so we dont need that
|
||||
return "main"; // entryPointName.c_str();
|
||||
}
|
||||
uint32 getShaderHash() const;
|
||||
constexpr MTL::Function* getFunction() const { return function; }
|
||||
constexpr const char* getEntryPointName() const {
|
||||
// SLang renames all entry points to main, so we dont need that
|
||||
return "main"; // entryPointName.c_str();
|
||||
}
|
||||
uint32 getShaderHash() const;
|
||||
|
||||
private:
|
||||
Gfx::SeShaderStageFlags stage;
|
||||
PGraphics graphics;
|
||||
MTL::Library* library;
|
||||
MTL::Function *function;
|
||||
uint32 hash;
|
||||
private:
|
||||
Gfx::SeShaderStageFlags stage;
|
||||
PGraphics graphics;
|
||||
MTL::Library* library;
|
||||
MTL::Function* function;
|
||||
uint32 hash;
|
||||
};
|
||||
DEFINE_REF(Shader)
|
||||
|
||||
template <typename Base, Gfx::SeShaderStageFlags flags> class ShaderBase : public Base, public Shader {
|
||||
public:
|
||||
ShaderBase(PGraphics graphics) : Shader(graphics, flags) {}
|
||||
virtual ~ShaderBase() {}
|
||||
public:
|
||||
ShaderBase(PGraphics graphics) : Shader(graphics, flags) {}
|
||||
virtual ~ShaderBase() {}
|
||||
};
|
||||
using VertexShader = ShaderBase<Gfx::VertexShader, Gfx::SE_SHADER_STAGE_VERTEX_BIT>;
|
||||
using FragmentShader = ShaderBase<Gfx::FragmentShader, Gfx::SE_SHADER_STAGE_FRAGMENT_BIT>;
|
||||
|
||||
@@ -29,7 +29,7 @@ void Shader::create(const ShaderCreateInfo &createInfo) {
|
||||
Map<std::string, uint32> paramMapping;
|
||||
Slang::ComPtr<slang::IBlob> kernelBlob =
|
||||
generateShader(createInfo, SLANG_METAL, paramMapping);
|
||||
std::cout << (char*)kernelBlob->getBufferPointer() << std::endl;
|
||||
std::cout << (char *)kernelBlob->getBufferPointer() << std::endl;
|
||||
hash = CRC::Calculate(kernelBlob->getBufferPointer(),
|
||||
kernelBlob->getBufferSize(), CRC::CRC_32());
|
||||
NS::Error *error;
|
||||
@@ -43,8 +43,8 @@ void Shader::create(const ShaderCreateInfo &createInfo) {
|
||||
std::cout << error->localizedDescription()->cString(NS::ASCIIStringEncoding)
|
||||
<< std::endl;
|
||||
}
|
||||
function =
|
||||
library->newFunction(NS::String::string(createInfo.entryPoint.c_str(), NS::ASCIIStringEncoding));
|
||||
function = library->newFunction(NS::String::string(
|
||||
createInfo.entryPoint.c_str(), NS::ASCIIStringEncoding));
|
||||
if (!function) {
|
||||
assert(false);
|
||||
}
|
||||
|
||||
@@ -1,62 +1,33 @@
|
||||
#pragma once
|
||||
#include "Graphics/Texture.h"
|
||||
#include "Graphics.h"
|
||||
#include "Graphics/Texture.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
namespace Metal
|
||||
{
|
||||
class TextureBase
|
||||
{
|
||||
public:
|
||||
TextureBase(PGraphics graphics, MTL::TextureType type, const TextureCreateInfo& createInfo, Gfx::QueueType& owner, MTL::Texture* existingImage = nullptr);
|
||||
|
||||
namespace Seele {
|
||||
namespace Metal {
|
||||
class TextureBase {
|
||||
public:
|
||||
TextureBase(PGraphics graphics, MTL::TextureType type, const TextureCreateInfo& createInfo, Gfx::QueueType& owner,
|
||||
MTL::Texture* existingImage = nullptr);
|
||||
virtual ~TextureBase();
|
||||
uint32 getWidth() const
|
||||
{
|
||||
return width;
|
||||
}
|
||||
uint32 getHeight() const
|
||||
{
|
||||
return height;
|
||||
}
|
||||
uint32 getDepth() const
|
||||
{
|
||||
return depth;
|
||||
}
|
||||
constexpr MTL::Texture* getTexture() const
|
||||
{
|
||||
return texture;
|
||||
}
|
||||
constexpr Gfx::SeImageLayout getLayout() const
|
||||
{
|
||||
return layout;
|
||||
}
|
||||
void setLayout(Gfx::SeImageLayout val)
|
||||
{
|
||||
layout = val;
|
||||
}
|
||||
constexpr Gfx::SeFormat getFormat() const
|
||||
{
|
||||
return format;
|
||||
}
|
||||
constexpr Gfx::SeSampleCountFlags getNumSamples() const
|
||||
{
|
||||
return samples;
|
||||
}
|
||||
constexpr uint32 getMipLevels() const
|
||||
{
|
||||
return mipLevels;
|
||||
}
|
||||
uint32 getWidth() const { return width; }
|
||||
uint32 getHeight() const { return height; }
|
||||
uint32 getDepth() const { return depth; }
|
||||
constexpr MTL::Texture* getTexture() const { return texture; }
|
||||
constexpr Gfx::SeImageLayout getLayout() const { return layout; }
|
||||
void setLayout(Gfx::SeImageLayout val) { layout = val; }
|
||||
constexpr Gfx::SeFormat getFormat() const { return format; }
|
||||
constexpr Gfx::SeSampleCountFlags getNumSamples() const { return samples; }
|
||||
constexpr uint32 getMipLevels() const { return mipLevels; }
|
||||
void executeOwnershipBarrier(Gfx::QueueType newOwner) { currentOwner = newOwner; }
|
||||
void executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage);
|
||||
void changeLayout(Gfx::SeImageLayout newLayout,
|
||||
Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage);
|
||||
void executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, Gfx::SeAccessFlags dstAccess,
|
||||
Gfx::SePipelineStageFlags dstStage);
|
||||
void changeLayout(Gfx::SeImageLayout newLayout, Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage);
|
||||
void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer);
|
||||
|
||||
protected:
|
||||
//Updates via reference
|
||||
protected:
|
||||
// Updates via reference
|
||||
Gfx::QueueType& currentOwner;
|
||||
PGraphics graphics;
|
||||
uint32 width;
|
||||
@@ -75,128 +46,68 @@ protected:
|
||||
friend class Graphics;
|
||||
};
|
||||
DEFINE_REF(TextureBase)
|
||||
class Texture2D : public Gfx::Texture2D, public TextureBase
|
||||
{
|
||||
public:
|
||||
class Texture2D : public Gfx::Texture2D, public TextureBase {
|
||||
public:
|
||||
Texture2D(PGraphics graphics, const TextureCreateInfo& createInfo, MTL::Texture* exisitingTexture = nullptr);
|
||||
virtual ~Texture2D();
|
||||
virtual uint32 getWidth() const override
|
||||
{
|
||||
return width;
|
||||
}
|
||||
virtual uint32 getHeight() const override
|
||||
{
|
||||
return height;
|
||||
}
|
||||
virtual uint32 getDepth() const override
|
||||
{
|
||||
return depth;
|
||||
}
|
||||
virtual Gfx::SeFormat getFormat() const override
|
||||
{
|
||||
return format;
|
||||
}
|
||||
virtual Gfx::SeSampleCountFlags getNumSamples() const override
|
||||
{
|
||||
return samples;
|
||||
}
|
||||
virtual uint32 getMipLevels() const override
|
||||
{
|
||||
return mipLevels;
|
||||
}
|
||||
virtual void changeLayout(Gfx::SeImageLayout newLayout,
|
||||
Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) override;
|
||||
virtual uint32 getWidth() const override { return width; }
|
||||
virtual uint32 getHeight() const override { return height; }
|
||||
virtual uint32 getDepth() const override { return depth; }
|
||||
virtual Gfx::SeFormat getFormat() const override { return format; }
|
||||
virtual Gfx::SeSampleCountFlags getNumSamples() const override { return samples; }
|
||||
virtual uint32 getMipLevels() const override { return mipLevels; }
|
||||
virtual void changeLayout(Gfx::SeImageLayout newLayout, Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) override;
|
||||
virtual void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer) override;
|
||||
|
||||
protected:
|
||||
protected:
|
||||
// Inherited via QueueOwnedResource
|
||||
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner) override;
|
||||
virtual void executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) override;
|
||||
virtual void executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, Gfx::SeAccessFlags dstAccess,
|
||||
Gfx::SePipelineStageFlags dstStage) override;
|
||||
};
|
||||
DEFINE_REF(Texture2D)
|
||||
class Texture3D : public Gfx::Texture3D, public TextureBase
|
||||
{
|
||||
public:
|
||||
class Texture3D : public Gfx::Texture3D, public TextureBase {
|
||||
public:
|
||||
Texture3D(PGraphics graphics, const TextureCreateInfo& createInfo);
|
||||
virtual ~Texture3D();
|
||||
virtual uint32 getWidth() const override
|
||||
{
|
||||
return width;
|
||||
}
|
||||
virtual uint32 getHeight() const override
|
||||
{
|
||||
return height;
|
||||
}
|
||||
virtual uint32 getDepth() const override
|
||||
{
|
||||
return depth;
|
||||
}
|
||||
virtual Gfx::SeFormat getFormat() const override
|
||||
{
|
||||
return format;
|
||||
}
|
||||
virtual Gfx::SeSampleCountFlags getNumSamples() const override
|
||||
{
|
||||
return samples;
|
||||
}
|
||||
virtual uint32 getMipLevels() const override
|
||||
{
|
||||
return mipLevels;
|
||||
}
|
||||
virtual void changeLayout(Gfx::SeImageLayout newLayout,
|
||||
Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) override;
|
||||
virtual uint32 getWidth() const override { return width; }
|
||||
virtual uint32 getHeight() const override { return height; }
|
||||
virtual uint32 getDepth() const override { return depth; }
|
||||
virtual Gfx::SeFormat getFormat() const override { return format; }
|
||||
virtual Gfx::SeSampleCountFlags getNumSamples() const override { return samples; }
|
||||
virtual uint32 getMipLevels() const override { return mipLevels; }
|
||||
virtual void changeLayout(Gfx::SeImageLayout newLayout, Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) override;
|
||||
virtual void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer) override;
|
||||
|
||||
protected:
|
||||
protected:
|
||||
// Inherited via QueueOwnedResource
|
||||
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner) override;
|
||||
virtual void executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) override;
|
||||
|
||||
virtual void executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, Gfx::SeAccessFlags dstAccess,
|
||||
Gfx::SePipelineStageFlags dstStage) override;
|
||||
};
|
||||
DEFINE_REF(Texture3D)
|
||||
class TextureCube : public Gfx::TextureCube, TextureBase
|
||||
{
|
||||
public:
|
||||
class TextureCube : public Gfx::TextureCube, TextureBase {
|
||||
public:
|
||||
TextureCube(PGraphics graphics, const TextureCreateInfo& createInfo);
|
||||
virtual ~TextureCube();
|
||||
virtual uint32 getWidth() const override
|
||||
{
|
||||
return width;
|
||||
}
|
||||
virtual uint32 getHeight() const override
|
||||
{
|
||||
return height;
|
||||
}
|
||||
virtual uint32 getDepth() const override
|
||||
{
|
||||
return depth;
|
||||
}
|
||||
virtual Gfx::SeFormat getFormat() const override
|
||||
{
|
||||
return format;
|
||||
}
|
||||
virtual Gfx::SeSampleCountFlags getNumSamples() const override
|
||||
{
|
||||
return samples;
|
||||
}
|
||||
virtual uint32 getMipLevels() const override
|
||||
{
|
||||
return mipLevels;
|
||||
}
|
||||
virtual void changeLayout(Gfx::SeImageLayout newLayout,
|
||||
Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) override;
|
||||
virtual uint32 getWidth() const override { return width; }
|
||||
virtual uint32 getHeight() const override { return height; }
|
||||
virtual uint32 getDepth() const override { return depth; }
|
||||
virtual Gfx::SeFormat getFormat() const override { return format; }
|
||||
virtual Gfx::SeSampleCountFlags getNumSamples() const override { return samples; }
|
||||
virtual uint32 getMipLevels() const override { return mipLevels; }
|
||||
virtual void changeLayout(Gfx::SeImageLayout newLayout, Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) override;
|
||||
virtual void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer) override;
|
||||
protected:
|
||||
|
||||
protected:
|
||||
// Inherited via QueueOwnedResource
|
||||
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner) override;
|
||||
virtual void executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) override;
|
||||
virtual void executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, Gfx::SeAccessFlags dstAccess,
|
||||
Gfx::SePipelineStageFlags dstStage) override;
|
||||
};
|
||||
DEFINE_REF(TextureCube)
|
||||
}
|
||||
}
|
||||
} // namespace Metal
|
||||
} // namespace Seele
|
||||
@@ -21,18 +21,16 @@ TextureBase::TextureBase(PGraphics graphics, MTL::TextureType type,
|
||||
ownsImage(existingImage == nullptr) {
|
||||
if (existingImage == nullptr) {
|
||||
MTL::TextureUsage mtlUsage = 0;
|
||||
if(usage & Gfx::SE_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT || usage & Gfx::SE_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)
|
||||
{
|
||||
mtlUsage |= MTL::TextureUsageRenderTarget;
|
||||
if (usage & Gfx::SE_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT ||
|
||||
usage & Gfx::SE_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) {
|
||||
mtlUsage |= MTL::TextureUsageRenderTarget;
|
||||
}
|
||||
if(usage & Gfx::SE_IMAGE_USAGE_SAMPLED_BIT)
|
||||
{
|
||||
mtlUsage |= MTL::TextureUsageShaderRead;
|
||||
if (usage & Gfx::SE_IMAGE_USAGE_SAMPLED_BIT) {
|
||||
mtlUsage |= MTL::TextureUsageShaderRead;
|
||||
}
|
||||
if (usage & Gfx::SE_IMAGE_USAGE_STORAGE_BIT) {
|
||||
mtlUsage |= MTL::TextureUsageShaderWrite;
|
||||
}
|
||||
if(usage & Gfx::SE_IMAGE_USAGE_STORAGE_BIT)
|
||||
{
|
||||
mtlUsage |= MTL::TextureUsageShaderWrite;
|
||||
}
|
||||
MTL::TextureDescriptor *descriptor =
|
||||
MTL::TextureDescriptor::alloc()->init();
|
||||
descriptor->setPixelFormat(cast(format));
|
||||
@@ -44,16 +42,17 @@ TextureBase::TextureBase(PGraphics graphics, MTL::TextureType type,
|
||||
descriptor->setTextureType(type);
|
||||
descriptor->setSampleCount(samples);
|
||||
descriptor->setUsage(mtlUsage);
|
||||
|
||||
|
||||
texture = graphics->getDevice()->newTexture(descriptor);
|
||||
|
||||
descriptor->release();
|
||||
}
|
||||
// if(createInfo.sourceData.data != nullptr)
|
||||
// {
|
||||
// MTL::Region region(0, 0, 0, width, height, depth);
|
||||
// texture->replaceRegion(region, 0, createInfo.sourceData.data, createInfo.sourceData.size / (depth * height));
|
||||
// }
|
||||
// if(createInfo.sourceData.data != nullptr)
|
||||
// {
|
||||
// MTL::Region region(0, 0, 0, width, height, depth);
|
||||
// texture->replaceRegion(region, 0, createInfo.sourceData.data,
|
||||
// createInfo.sourceData.size / (depth * height));
|
||||
// }
|
||||
}
|
||||
|
||||
TextureBase::~TextureBase() {
|
||||
@@ -71,8 +70,7 @@ void TextureBase::changeLayout(Gfx::SeImageLayout, Gfx::SeAccessFlags,
|
||||
Gfx::SePipelineStageFlags, Gfx::SeAccessFlags,
|
||||
Gfx::SePipelineStageFlags) {}
|
||||
|
||||
void TextureBase::download(uint32, uint32, uint32, Array<uint8>&)
|
||||
{}
|
||||
void TextureBase::download(uint32, uint32, uint32, Array<uint8> &) {}
|
||||
|
||||
Texture2D::Texture2D(PGraphics graphics, const TextureCreateInfo &createInfo,
|
||||
MTL::Texture *exisitingTexture)
|
||||
@@ -86,93 +84,95 @@ Texture2D::Texture2D(PGraphics graphics, const TextureCreateInfo &createInfo,
|
||||
: MTL::TextureType2D),
|
||||
createInfo, Gfx::Texture2D::currentOwner, exisitingTexture) {}
|
||||
|
||||
Texture2D::~Texture2D()
|
||||
{
|
||||
Texture2D::~Texture2D() {}
|
||||
|
||||
void Texture2D::changeLayout(Gfx::SeImageLayout newLayout,
|
||||
Gfx::SeAccessFlags srcAccess,
|
||||
Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess,
|
||||
Gfx::SePipelineStageFlags dstStage) {
|
||||
TextureBase::changeLayout(newLayout, srcAccess, srcStage, dstAccess,
|
||||
dstStage);
|
||||
}
|
||||
|
||||
void Texture2D::changeLayout(Gfx::SeImageLayout newLayout,
|
||||
Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage)
|
||||
{
|
||||
TextureBase::changeLayout(newLayout, srcAccess, srcStage, dstAccess, dstStage);
|
||||
void Texture2D::download(uint32 mipLevel, uint32 arrayLayer, uint32 face,
|
||||
Array<uint8> &buffer) {
|
||||
TextureBase::download(mipLevel, arrayLayer, face, buffer);
|
||||
}
|
||||
|
||||
void Texture2D::download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer)
|
||||
{
|
||||
TextureBase::download(mipLevel, arrayLayer, face, buffer);
|
||||
void Texture2D::executeOwnershipBarrier(Gfx::QueueType newOwner) {
|
||||
TextureBase::executeOwnershipBarrier(newOwner);
|
||||
}
|
||||
|
||||
void Texture2D::executeOwnershipBarrier(Gfx::QueueType newOwner)
|
||||
{
|
||||
TextureBase::executeOwnershipBarrier(newOwner);
|
||||
void Texture2D::executePipelineBarrier(Gfx::SeAccessFlags srcAccess,
|
||||
Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess,
|
||||
Gfx::SePipelineStageFlags dstStage) {
|
||||
TextureBase::executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
|
||||
}
|
||||
|
||||
void Texture2D::executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage)
|
||||
{
|
||||
TextureBase::executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
|
||||
Texture3D::Texture3D(PGraphics graphics, const TextureCreateInfo &createInfo)
|
||||
: Gfx::Texture3D(graphics->getFamilyMapping(), createInfo.sourceData.owner),
|
||||
TextureBase(graphics, MTL::TextureType3D, createInfo,
|
||||
Gfx::Texture3D::currentOwner) {}
|
||||
|
||||
Texture3D::~Texture3D() {}
|
||||
|
||||
void Texture3D::changeLayout(Gfx::SeImageLayout newLayout,
|
||||
Gfx::SeAccessFlags srcAccess,
|
||||
Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess,
|
||||
Gfx::SePipelineStageFlags dstStage) {
|
||||
TextureBase::changeLayout(newLayout, srcAccess, srcStage, dstAccess,
|
||||
dstStage);
|
||||
}
|
||||
|
||||
Texture3D::Texture3D(PGraphics graphics, const TextureCreateInfo& createInfo)
|
||||
: Gfx::Texture3D(graphics->getFamilyMapping(), createInfo.sourceData.owner)
|
||||
, TextureBase(graphics, MTL::TextureType3D, createInfo, Gfx::Texture3D::currentOwner) {}
|
||||
|
||||
|
||||
Texture3D::~Texture3D()
|
||||
{
|
||||
void Texture3D::download(uint32 mipLevel, uint32 arrayLayer, uint32 face,
|
||||
Array<uint8> &buffer) {
|
||||
TextureBase::download(mipLevel, arrayLayer, face, buffer);
|
||||
}
|
||||
void Texture3D::executeOwnershipBarrier(Gfx::QueueType newOwner) {
|
||||
TextureBase::executeOwnershipBarrier(newOwner);
|
||||
}
|
||||
|
||||
void Texture3D::changeLayout(Gfx::SeImageLayout newLayout,
|
||||
Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage)
|
||||
{
|
||||
TextureBase::changeLayout(newLayout, srcAccess, srcStage, dstAccess, dstStage);
|
||||
void Texture3D::executePipelineBarrier(Gfx::SeAccessFlags srcAccess,
|
||||
Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess,
|
||||
Gfx::SePipelineStageFlags dstStage) {
|
||||
TextureBase::executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
|
||||
}
|
||||
|
||||
void Texture3D::download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer)
|
||||
{
|
||||
TextureBase::download(mipLevel, arrayLayer, face, buffer);
|
||||
}
|
||||
void Texture3D::executeOwnershipBarrier(Gfx::QueueType newOwner)
|
||||
{
|
||||
TextureBase::executeOwnershipBarrier(newOwner);
|
||||
TextureCube::TextureCube(PGraphics graphics,
|
||||
const TextureCreateInfo &createInfo)
|
||||
: Gfx::TextureCube(graphics->getFamilyMapping(),
|
||||
createInfo.sourceData.owner),
|
||||
TextureBase(graphics,
|
||||
createInfo.elements > 1 ? MTL::TextureTypeCubeArray
|
||||
: MTL::TextureTypeCube,
|
||||
createInfo, Gfx::TextureCube::currentOwner) {}
|
||||
|
||||
TextureCube::~TextureCube() {}
|
||||
|
||||
void TextureCube::changeLayout(Gfx::SeImageLayout newLayout,
|
||||
Gfx::SeAccessFlags srcAccess,
|
||||
Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess,
|
||||
Gfx::SePipelineStageFlags dstStage) {
|
||||
TextureBase::changeLayout(newLayout, srcAccess, srcStage, dstAccess,
|
||||
dstStage);
|
||||
}
|
||||
|
||||
void Texture3D::executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage)
|
||||
{
|
||||
TextureBase::executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
|
||||
void TextureCube::download(uint32 mipLevel, uint32 arrayLayer, uint32 face,
|
||||
Array<uint8> &buffer) {
|
||||
TextureBase::download(mipLevel, arrayLayer, face, buffer);
|
||||
}
|
||||
void TextureCube::executeOwnershipBarrier(Gfx::QueueType newOwner) {
|
||||
TextureBase::executeOwnershipBarrier(newOwner);
|
||||
}
|
||||
|
||||
TextureCube::TextureCube(PGraphics graphics, const TextureCreateInfo& createInfo)
|
||||
: Gfx::TextureCube(graphics->getFamilyMapping(), createInfo.sourceData.owner)
|
||||
, TextureBase(graphics, createInfo.elements > 1 ? MTL::TextureTypeCubeArray : MTL::TextureTypeCube,
|
||||
createInfo, Gfx::TextureCube::currentOwner)
|
||||
{
|
||||
}
|
||||
|
||||
TextureCube::~TextureCube()
|
||||
{
|
||||
}
|
||||
|
||||
void TextureCube::changeLayout(Gfx::SeImageLayout newLayout,
|
||||
Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage)
|
||||
{
|
||||
TextureBase::changeLayout(newLayout, srcAccess, srcStage, dstAccess, dstStage);
|
||||
}
|
||||
|
||||
void TextureCube::download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer)
|
||||
{
|
||||
TextureBase::download(mipLevel, arrayLayer, face, buffer);
|
||||
}
|
||||
void TextureCube::executeOwnershipBarrier(Gfx::QueueType newOwner)
|
||||
{
|
||||
TextureBase::executeOwnershipBarrier(newOwner);
|
||||
}
|
||||
|
||||
void TextureCube::executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage)
|
||||
{
|
||||
TextureBase::executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
|
||||
void TextureCube::executePipelineBarrier(Gfx::SeAccessFlags srcAccess,
|
||||
Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess,
|
||||
Gfx::SePipelineStageFlags dstStage) {
|
||||
TextureBase::executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
|
||||
}
|
||||
|
||||
@@ -17,60 +17,60 @@
|
||||
namespace Seele {
|
||||
namespace Metal {
|
||||
class Window : public Gfx::Window {
|
||||
public:
|
||||
Window(PGraphics graphics, const WindowCreateInfo& createInfo);
|
||||
virtual ~Window();
|
||||
virtual void pollInput() override;
|
||||
virtual void beginFrame() override;
|
||||
virtual void endFrame() override;
|
||||
virtual Gfx::PTexture2D getBackBuffer() const override;
|
||||
virtual void onWindowCloseEvent() override;
|
||||
virtual void setKeyCallback(std::function<void(KeyCode, InputAction, KeyModifier)> callback) override;
|
||||
virtual void setMouseMoveCallback(std::function<void(double, double)> callback) override;
|
||||
virtual void setMouseButtonCallback(std::function<void(MouseButton, InputAction, KeyModifier)> callback) override;
|
||||
virtual void setScrollCallback(std::function<void(double, double)> callback) override;
|
||||
virtual void setFileCallback(std::function<void(int, const char**)> callback) override;
|
||||
virtual void setCloseCallback(std::function<void()> callback) override;
|
||||
virtual void setResizeCallback(std::function<void(uint32, uint32)> callback) override;
|
||||
public:
|
||||
Window(PGraphics graphics, const WindowCreateInfo& createInfo);
|
||||
virtual ~Window();
|
||||
virtual void pollInput() override;
|
||||
virtual void beginFrame() override;
|
||||
virtual void endFrame() override;
|
||||
virtual Gfx::PTexture2D getBackBuffer() const override;
|
||||
virtual void onWindowCloseEvent() override;
|
||||
virtual void setKeyCallback(std::function<void(KeyCode, InputAction, KeyModifier)> callback) override;
|
||||
virtual void setMouseMoveCallback(std::function<void(double, double)> callback) override;
|
||||
virtual void setMouseButtonCallback(std::function<void(MouseButton, InputAction, KeyModifier)> callback) override;
|
||||
virtual void setScrollCallback(std::function<void(double, double)> callback) override;
|
||||
virtual void setFileCallback(std::function<void(int, const char**)> callback) override;
|
||||
virtual void setCloseCallback(std::function<void()> callback) override;
|
||||
virtual void setResizeCallback(std::function<void(uint32, uint32)> callback) override;
|
||||
|
||||
void keyPress(KeyCode code, InputAction action, KeyModifier modifier);
|
||||
void mouseMove(double x, double y);
|
||||
void mouseButton(MouseButton button, InputAction action, KeyModifier modifier);
|
||||
void scroll(double x, double y);
|
||||
void fileDrop(int num, const char** files);
|
||||
void close();
|
||||
void resize(int width, int height);
|
||||
void keyPress(KeyCode code, InputAction action, KeyModifier modifier);
|
||||
void mouseMove(double x, double y);
|
||||
void mouseButton(MouseButton button, InputAction action, KeyModifier modifier);
|
||||
void scroll(double x, double y);
|
||||
void fileDrop(int num, const char** files);
|
||||
void close();
|
||||
void resize(int width, int height);
|
||||
|
||||
private:
|
||||
void createBackBuffer();
|
||||
private:
|
||||
void createBackBuffer();
|
||||
|
||||
PGraphics graphics;
|
||||
WindowCreateInfo preferences;
|
||||
GLFWwindow* windowHandle;
|
||||
NSWindow* metalWindow;
|
||||
CAMetalLayer* metalLayer;
|
||||
CA::MetalDrawable* drawable;
|
||||
OTexture2D backBuffer;
|
||||
PGraphics graphics;
|
||||
WindowCreateInfo preferences;
|
||||
GLFWwindow* windowHandle;
|
||||
NSWindow* metalWindow;
|
||||
CAMetalLayer* metalLayer;
|
||||
CA::MetalDrawable* drawable;
|
||||
OTexture2D backBuffer;
|
||||
|
||||
std::function<void(KeyCode, InputAction, KeyModifier)> keyCallback;
|
||||
std::function<void(double, double)> mouseMoveCallback;
|
||||
std::function<void(MouseButton, InputAction, KeyModifier)> mouseButtonCallback;
|
||||
std::function<void(double, double)> scrollCallback;
|
||||
std::function<void(int, const char**)> fileCallback;
|
||||
std::function<void()> closeCallback;
|
||||
std::function<void(uint32, uint32)> resizeCallback;
|
||||
std::function<void(KeyCode, InputAction, KeyModifier)> keyCallback;
|
||||
std::function<void(double, double)> mouseMoveCallback;
|
||||
std::function<void(MouseButton, InputAction, KeyModifier)> mouseButtonCallback;
|
||||
std::function<void(double, double)> scrollCallback;
|
||||
std::function<void(int, const char**)> fileCallback;
|
||||
std::function<void()> closeCallback;
|
||||
std::function<void(uint32, uint32)> resizeCallback;
|
||||
};
|
||||
DEFINE_REF(Window);
|
||||
class Viewport : public Gfx::Viewport {
|
||||
public:
|
||||
Viewport(PWindow owner, const ViewportCreateInfo& createInfo);
|
||||
virtual ~Viewport();
|
||||
constexpr MTL::Viewport getHandle() const { return viewport; }
|
||||
virtual void resize(uint32 newX, uint32 newY);
|
||||
virtual void move(uint32 newOffset, uint32 newOffsetY);
|
||||
public:
|
||||
Viewport(PWindow owner, const ViewportCreateInfo& createInfo);
|
||||
virtual ~Viewport();
|
||||
constexpr MTL::Viewport getHandle() const { return viewport; }
|
||||
virtual void resize(uint32 newX, uint32 newY);
|
||||
virtual void move(uint32 newOffset, uint32 newOffsetY);
|
||||
|
||||
private:
|
||||
MTL::Viewport viewport;
|
||||
private:
|
||||
MTL::Viewport viewport;
|
||||
};
|
||||
} // namespace Metal
|
||||
} // namespace Seele
|
||||
|
||||
@@ -20,51 +20,58 @@ double Gfx::getCurrentFrameDelta() { return currentFrameDelta; }
|
||||
uint32 currentFrameIndex = 0;
|
||||
uint32 Gfx::getCurrentFrameIndex() { return currentFrameIndex; }
|
||||
|
||||
void glfwKeyCallback(GLFWwindow* handle, int key, int, int action, int modifier) {
|
||||
void glfwKeyCallback(GLFWwindow *handle, int key, int, int action,
|
||||
int modifier) {
|
||||
if (key == -1) {
|
||||
return;
|
||||
}
|
||||
Window* window = (Window*)glfwGetWindowUserPointer(handle);
|
||||
Window *window = (Window *)glfwGetWindowUserPointer(handle);
|
||||
window->keyPress((KeyCode)key, (InputAction)action, (KeyModifier)modifier);
|
||||
}
|
||||
|
||||
void glfwMouseMoveCallback(GLFWwindow* handle, double xpos, double ypos) {
|
||||
Window* window = (Window*)glfwGetWindowUserPointer(handle);
|
||||
void glfwMouseMoveCallback(GLFWwindow *handle, double xpos, double ypos) {
|
||||
Window *window = (Window *)glfwGetWindowUserPointer(handle);
|
||||
window->mouseMove(xpos, ypos);
|
||||
}
|
||||
|
||||
void glfwMouseButtonCallback(GLFWwindow* handle, int button, int action, int modifier) {
|
||||
Window* window = (Window*)glfwGetWindowUserPointer(handle);
|
||||
window->mouseButton((MouseButton)button, (InputAction)action, (KeyModifier)modifier);
|
||||
void glfwMouseButtonCallback(GLFWwindow *handle, int button, int action,
|
||||
int modifier) {
|
||||
Window *window = (Window *)glfwGetWindowUserPointer(handle);
|
||||
window->mouseButton((MouseButton)button, (InputAction)action,
|
||||
(KeyModifier)modifier);
|
||||
}
|
||||
|
||||
void glfwScrollCallback(GLFWwindow* handle, double xoffset, double yoffset) {
|
||||
Window* window = (Window*)glfwGetWindowUserPointer(handle);
|
||||
void glfwScrollCallback(GLFWwindow *handle, double xoffset, double yoffset) {
|
||||
Window *window = (Window *)glfwGetWindowUserPointer(handle);
|
||||
window->scroll(xoffset, yoffset);
|
||||
}
|
||||
|
||||
void glfwFileCallback(GLFWwindow* handle, int count, const char** paths) {
|
||||
Window* window = (Window*)glfwGetWindowUserPointer(handle);
|
||||
void glfwFileCallback(GLFWwindow *handle, int count, const char **paths) {
|
||||
Window *window = (Window *)glfwGetWindowUserPointer(handle);
|
||||
window->fileDrop(count, paths);
|
||||
}
|
||||
|
||||
void glfwCloseCallback(GLFWwindow* handle) {
|
||||
Window* window = (Window*)glfwGetWindowUserPointer(handle);
|
||||
void glfwCloseCallback(GLFWwindow *handle) {
|
||||
Window *window = (Window *)glfwGetWindowUserPointer(handle);
|
||||
window->close();
|
||||
}
|
||||
|
||||
void glfwFramebufferResizeCallback(GLFWwindow* handle, int width, int height) {
|
||||
Window* window = (Window*)glfwGetWindowUserPointer(handle);
|
||||
void glfwFramebufferResizeCallback(GLFWwindow *handle, int width, int height) {
|
||||
Window *window = (Window *)glfwGetWindowUserPointer(handle);
|
||||
window->resize(width, height);
|
||||
}
|
||||
|
||||
Window::Window(PGraphics graphics, const WindowCreateInfo& createInfo) : graphics(graphics), preferences(createInfo) {
|
||||
glfwSetErrorCallback([](int, const char* description) { std::cout << description << std::endl; });
|
||||
Window::Window(PGraphics graphics, const WindowCreateInfo &createInfo)
|
||||
: graphics(graphics), preferences(createInfo) {
|
||||
glfwSetErrorCallback([](int, const char *description) {
|
||||
std::cout << description << std::endl;
|
||||
});
|
||||
float xscale = 1, yscale = 1;
|
||||
glfwGetMonitorContentScale(glfwGetPrimaryMonitor(), &xscale, &yscale);
|
||||
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
||||
GLFWwindow* handle =
|
||||
glfwCreateWindow(createInfo.width / xscale, createInfo.height / yscale, createInfo.title, nullptr, nullptr);
|
||||
GLFWwindow *handle =
|
||||
glfwCreateWindow(createInfo.width / xscale, createInfo.height / yscale,
|
||||
createInfo.title, nullptr, nullptr);
|
||||
windowHandle = handle;
|
||||
glfwSetWindowUserPointer(handle, this);
|
||||
|
||||
@@ -89,12 +96,14 @@ Window::Window(PGraphics graphics, const WindowCreateInfo& createInfo) : graphic
|
||||
metalWindow.contentView.wantsLayer = YES;
|
||||
}
|
||||
|
||||
Window::~Window() { glfwDestroyWindow(static_cast<GLFWwindow*>(windowHandle)); }
|
||||
Window::~Window() {
|
||||
glfwDestroyWindow(static_cast<GLFWwindow *>(windowHandle));
|
||||
}
|
||||
|
||||
void Window::pollInput() { glfwPollEvents(); }
|
||||
|
||||
void Window::beginFrame() {
|
||||
drawable = (__bridge CA::MetalDrawable*)[metalLayer nextDrawable];
|
||||
drawable = (__bridge CA::MetalDrawable *)[metalLayer nextDrawable];
|
||||
createBackBuffer();
|
||||
}
|
||||
|
||||
@@ -108,33 +117,51 @@ void Window::onWindowCloseEvent() {}
|
||||
|
||||
Gfx::PTexture2D Window::getBackBuffer() const { return PTexture2D(backBuffer); }
|
||||
|
||||
void Window::setKeyCallback(std::function<void(KeyCode, InputAction, KeyModifier)> callback) { keyCallback = callback; }
|
||||
void Window::setKeyCallback(
|
||||
std::function<void(KeyCode, InputAction, KeyModifier)> callback) {
|
||||
keyCallback = callback;
|
||||
}
|
||||
|
||||
void Window::setMouseMoveCallback(std::function<void(double, double)> callback) { mouseMoveCallback = callback; }
|
||||
void Window::setMouseMoveCallback(
|
||||
std::function<void(double, double)> callback) {
|
||||
mouseMoveCallback = callback;
|
||||
}
|
||||
|
||||
void Window::setMouseButtonCallback(std::function<void(MouseButton, InputAction, KeyModifier)> callback) {
|
||||
void Window::setMouseButtonCallback(
|
||||
std::function<void(MouseButton, InputAction, KeyModifier)> callback) {
|
||||
mouseButtonCallback = callback;
|
||||
}
|
||||
|
||||
void Window::setScrollCallback(std::function<void(double, double)> callback) { scrollCallback = callback; }
|
||||
void Window::setScrollCallback(std::function<void(double, double)> callback) {
|
||||
scrollCallback = callback;
|
||||
}
|
||||
|
||||
void Window::setFileCallback(std::function<void(int, const char**)> callback) { fileCallback = callback; }
|
||||
void Window::setFileCallback(std::function<void(int, const char **)> callback) {
|
||||
fileCallback = callback;
|
||||
}
|
||||
|
||||
void Window::setCloseCallback(std::function<void()> callback) { closeCallback = callback; }
|
||||
void Window::setCloseCallback(std::function<void()> callback) {
|
||||
closeCallback = callback;
|
||||
}
|
||||
|
||||
void Window::setResizeCallback(std::function<void(uint32, uint32)> callback) { resizeCallback = callback; }
|
||||
void Window::setResizeCallback(std::function<void(uint32, uint32)> callback) {
|
||||
resizeCallback = callback;
|
||||
}
|
||||
|
||||
void Window::keyPress(KeyCode code, InputAction action, KeyModifier modifier) { keyCallback(code, action, modifier); }
|
||||
void Window::keyPress(KeyCode code, InputAction action, KeyModifier modifier) {
|
||||
keyCallback(code, action, modifier);
|
||||
}
|
||||
|
||||
void Window::mouseMove(double x, double y) { mouseMoveCallback(x, y); }
|
||||
|
||||
void Window::mouseButton(MouseButton button, InputAction action, KeyModifier modifier) {
|
||||
void Window::mouseButton(MouseButton button, InputAction action,
|
||||
KeyModifier modifier) {
|
||||
mouseButtonCallback(button, action, modifier);
|
||||
}
|
||||
|
||||
void Window::scroll(double x, double y) { scrollCallback(x, y); }
|
||||
|
||||
void Window::fileDrop(int num, const char** files) { fileCallback(num, files); }
|
||||
void Window::fileDrop(int num, const char **files) { fileCallback(num, files); }
|
||||
|
||||
void Window::close() { closeCallback(); }
|
||||
|
||||
@@ -149,28 +176,31 @@ void Window::resize(int width, int height) {
|
||||
framebufferWidth = width;
|
||||
framebufferHeight = height;
|
||||
// Deallocate the textures if they have been created
|
||||
drawable = (__bridge CA::MetalDrawable*)[[metalLayer nextDrawable] autorelease];
|
||||
drawable =
|
||||
(__bridge CA::MetalDrawable *)[[metalLayer nextDrawable] autorelease];
|
||||
createBackBuffer();
|
||||
resizeCallback(width, height);
|
||||
}
|
||||
|
||||
void Window::createBackBuffer() {
|
||||
MTL::Texture* buf = drawable->texture();
|
||||
backBuffer = new Texture2D(graphics,
|
||||
TextureCreateInfo{
|
||||
.width = static_cast<uint32>(buf->width()),
|
||||
.height = static_cast<uint32>(buf->height()),
|
||||
.depth = static_cast<uint32>(buf->depth()),
|
||||
.elements = static_cast<uint32>(buf->arrayLength()),
|
||||
.mipLevels = static_cast<uint32>(buf->mipmapLevelCount()),
|
||||
.format = cast(buf->pixelFormat()),
|
||||
.usage = MTL::TextureUsageRenderTarget,
|
||||
.samples = static_cast<uint32>(buf->sampleCount()),
|
||||
},
|
||||
buf);
|
||||
MTL::Texture *buf = drawable->texture();
|
||||
backBuffer = new Texture2D(
|
||||
graphics,
|
||||
TextureCreateInfo{
|
||||
.width = static_cast<uint32>(buf->width()),
|
||||
.height = static_cast<uint32>(buf->height()),
|
||||
.depth = static_cast<uint32>(buf->depth()),
|
||||
.elements = static_cast<uint32>(buf->arrayLength()),
|
||||
.mipLevels = static_cast<uint32>(buf->mipmapLevelCount()),
|
||||
.format = cast(buf->pixelFormat()),
|
||||
.usage = MTL::TextureUsageRenderTarget,
|
||||
.samples = static_cast<uint32>(buf->sampleCount()),
|
||||
},
|
||||
buf);
|
||||
}
|
||||
|
||||
Viewport::Viewport(PWindow owner, const ViewportCreateInfo& createInfo) : Gfx::Viewport(owner, createInfo) {
|
||||
Viewport::Viewport(PWindow owner, const ViewportCreateInfo &createInfo)
|
||||
: Gfx::Viewport(owner, createInfo) {
|
||||
viewport.width = sizeX;
|
||||
viewport.height = sizeY;
|
||||
viewport.originX = offsetX;
|
||||
|
||||
@@ -3,39 +3,18 @@
|
||||
using namespace Seele;
|
||||
using namespace Seele::Gfx;
|
||||
|
||||
VertexInput::VertexInput(VertexInputStateCreateInfo createInfo)
|
||||
: createInfo(createInfo)
|
||||
{
|
||||
}
|
||||
VertexInput::VertexInput(VertexInputStateCreateInfo createInfo) : createInfo(createInfo) {}
|
||||
|
||||
VertexInput::~VertexInput()
|
||||
{
|
||||
}
|
||||
VertexInput::~VertexInput() {}
|
||||
|
||||
GraphicsPipeline::GraphicsPipeline(PPipelineLayout layout)
|
||||
: layout(layout)
|
||||
{
|
||||
}
|
||||
GraphicsPipeline::GraphicsPipeline(PPipelineLayout layout) : layout(layout) {}
|
||||
|
||||
GraphicsPipeline::~GraphicsPipeline()
|
||||
{
|
||||
}
|
||||
GraphicsPipeline::~GraphicsPipeline() {}
|
||||
|
||||
PPipelineLayout GraphicsPipeline::getPipelineLayout() const
|
||||
{
|
||||
return layout;
|
||||
}
|
||||
PPipelineLayout GraphicsPipeline::getPipelineLayout() const { return layout; }
|
||||
|
||||
ComputePipeline::ComputePipeline(PPipelineLayout layout)
|
||||
: layout(layout)
|
||||
{
|
||||
}
|
||||
ComputePipeline::ComputePipeline(PPipelineLayout layout) : layout(layout) {}
|
||||
|
||||
ComputePipeline::~ComputePipeline()
|
||||
{
|
||||
}
|
||||
ComputePipeline::~ComputePipeline() {}
|
||||
|
||||
PPipelineLayout ComputePipeline::getPipelineLayout() const
|
||||
{
|
||||
return layout;
|
||||
}
|
||||
PPipelineLayout ComputePipeline::getPipelineLayout() const { return layout; }
|
||||
|
||||
@@ -1,40 +1,39 @@
|
||||
#pragma once
|
||||
#include "Enums.h"
|
||||
#include "Descriptor.h"
|
||||
#include "Enums.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
namespace Gfx
|
||||
{
|
||||
class VertexInput
|
||||
{
|
||||
public:
|
||||
|
||||
namespace Seele {
|
||||
namespace Gfx {
|
||||
class VertexInput {
|
||||
public:
|
||||
VertexInput(VertexInputStateCreateInfo createInfo);
|
||||
virtual ~VertexInput();
|
||||
const VertexInputStateCreateInfo& getInfo() const { return createInfo; }
|
||||
private:
|
||||
|
||||
private:
|
||||
VertexInputStateCreateInfo createInfo;
|
||||
};
|
||||
class GraphicsPipeline
|
||||
{
|
||||
public:
|
||||
class GraphicsPipeline {
|
||||
public:
|
||||
GraphicsPipeline(PPipelineLayout layout);
|
||||
virtual ~GraphicsPipeline();
|
||||
PPipelineLayout getPipelineLayout() const;
|
||||
protected:
|
||||
|
||||
protected:
|
||||
PPipelineLayout layout;
|
||||
};
|
||||
DEFINE_REF(GraphicsPipeline)
|
||||
|
||||
class ComputePipeline
|
||||
{
|
||||
public:
|
||||
class ComputePipeline {
|
||||
public:
|
||||
ComputePipeline(PPipelineLayout layout);
|
||||
virtual ~ComputePipeline();
|
||||
PPipelineLayout getPipelineLayout() const;
|
||||
protected:
|
||||
|
||||
protected:
|
||||
PPipelineLayout layout;
|
||||
};
|
||||
DEFINE_REF(ComputePipeline)
|
||||
}
|
||||
}
|
||||
} // namespace Gfx
|
||||
} // namespace Seele
|
||||
|
||||
@@ -2,14 +2,10 @@
|
||||
|
||||
using namespace Seele::Gfx;
|
||||
|
||||
BottomLevelAS::BottomLevelAS()
|
||||
{}
|
||||
BottomLevelAS::BottomLevelAS() {}
|
||||
|
||||
BottomLevelAS::~BottomLevelAS()
|
||||
{}
|
||||
BottomLevelAS::~BottomLevelAS() {}
|
||||
|
||||
TopLevelAS::TopLevelAS()
|
||||
{}
|
||||
TopLevelAS::TopLevelAS() {}
|
||||
|
||||
TopLevelAS::~TopLevelAS()
|
||||
{}
|
||||
TopLevelAS::~TopLevelAS() {}
|
||||
@@ -1,25 +1,23 @@
|
||||
#pragma once
|
||||
#include "Resources.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
namespace Gfx
|
||||
{
|
||||
class BottomLevelAS
|
||||
{
|
||||
public:
|
||||
namespace Seele {
|
||||
namespace Gfx {
|
||||
class BottomLevelAS {
|
||||
public:
|
||||
BottomLevelAS();
|
||||
~BottomLevelAS();
|
||||
private:
|
||||
|
||||
private:
|
||||
};
|
||||
DEFINE_REF(BottomLevelAS)
|
||||
class TopLevelAS
|
||||
{
|
||||
public:
|
||||
class TopLevelAS {
|
||||
public:
|
||||
TopLevelAS();
|
||||
~TopLevelAS();
|
||||
private:
|
||||
|
||||
private:
|
||||
};
|
||||
DEFINE_REF(TopLevelAS)
|
||||
}
|
||||
}
|
||||
} // namespace Gfx
|
||||
} // namespace Seele
|
||||
@@ -1,26 +1,25 @@
|
||||
#include "BasePass.h"
|
||||
#include "Actor/CameraActor.h"
|
||||
#include "Component/Camera.h"
|
||||
#include "Component/Mesh.h"
|
||||
#include "Graphics/Command.h"
|
||||
#include "Graphics/Descriptor.h"
|
||||
#include "Graphics/Enums.h"
|
||||
#include "Graphics/Graphics.h"
|
||||
#include "Graphics/Initializer.h"
|
||||
#include "Graphics/Shader.h"
|
||||
#include "Window/Window.h"
|
||||
#include "Component/Camera.h"
|
||||
#include "Component/Mesh.h"
|
||||
#include "Actor/CameraActor.h"
|
||||
#include "Graphics/StaticMeshVertexData.h"
|
||||
#include "Material/MaterialInstance.h"
|
||||
#include "Math/Vector.h"
|
||||
#include "RenderGraph.h"
|
||||
#include "Material/MaterialInstance.h"
|
||||
#include "Graphics/Descriptor.h"
|
||||
#include "Graphics/Command.h"
|
||||
#include "Graphics/StaticMeshVertexData.h"
|
||||
#include "Window/Window.h"
|
||||
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
extern bool useViewCulling;
|
||||
|
||||
BasePass::BasePass(Gfx::PGraphics graphics, PScene scene)
|
||||
: RenderPass(graphics, scene)
|
||||
{
|
||||
BasePass::BasePass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics, scene) {
|
||||
basePassLayout = graphics->createPipelineLayout("BasePassLayout");
|
||||
|
||||
basePassLayout->addDescriptorLayout(viewParamsLayout);
|
||||
@@ -28,9 +27,15 @@ BasePass::BasePass(Gfx::PGraphics graphics, PScene scene)
|
||||
|
||||
lightCullingLayout = graphics->createDescriptorLayout("pLightCullingData");
|
||||
// oLightIndexList
|
||||
lightCullingLayout->addDescriptorBinding(Gfx::DescriptorBinding{ .binding = 0, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER, });
|
||||
lightCullingLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.binding = 0,
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
});
|
||||
// oLightGrid
|
||||
lightCullingLayout->addDescriptorBinding(Gfx::DescriptorBinding{ .binding = 1, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_IMAGE, });
|
||||
lightCullingLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.binding = 1,
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_IMAGE,
|
||||
});
|
||||
lightCullingLayout->create();
|
||||
|
||||
basePassLayout->addDescriptorLayout(lightCullingLayout);
|
||||
@@ -38,44 +43,38 @@ BasePass::BasePass(Gfx::PGraphics graphics, PScene scene)
|
||||
.stageFlags = Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_VERTEX_BIT,
|
||||
.offset = 0,
|
||||
.size = sizeof(VertexData::DrawCallOffsets),
|
||||
});
|
||||
});
|
||||
|
||||
if (graphics->supportMeshShading())
|
||||
{
|
||||
graphics->getShaderCompiler()->registerRenderPass("BasePass", Gfx::PassConfig {
|
||||
.baseLayout = basePassLayout,
|
||||
.taskFile = "DrawListTask",
|
||||
.mainFile = "DrawListMesh",
|
||||
.fragmentFile = "BasePass",
|
||||
.hasFragmentShader = true,
|
||||
.useMeshShading = true,
|
||||
.hasTaskShader = true,
|
||||
.useMaterial = true,
|
||||
.useVisibility = false,
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
graphics->getShaderCompiler()->registerRenderPass("BasePass", Gfx::PassConfig {
|
||||
.baseLayout = basePassLayout,
|
||||
.taskFile = "",
|
||||
.mainFile = "LegacyPass",
|
||||
.fragmentFile = "BasePass",
|
||||
.hasFragmentShader = true,
|
||||
.useMeshShading = false,
|
||||
.hasTaskShader = false,
|
||||
.useMaterial = true,
|
||||
.useVisibility = false,
|
||||
});
|
||||
if (graphics->supportMeshShading()) {
|
||||
graphics->getShaderCompiler()->registerRenderPass("BasePass", Gfx::PassConfig{
|
||||
.baseLayout = basePassLayout,
|
||||
.taskFile = "DrawListTask",
|
||||
.mainFile = "DrawListMesh",
|
||||
.fragmentFile = "BasePass",
|
||||
.hasFragmentShader = true,
|
||||
.useMeshShading = true,
|
||||
.hasTaskShader = true,
|
||||
.useMaterial = true,
|
||||
.useVisibility = false,
|
||||
});
|
||||
} else {
|
||||
graphics->getShaderCompiler()->registerRenderPass("BasePass", Gfx::PassConfig{
|
||||
.baseLayout = basePassLayout,
|
||||
.taskFile = "",
|
||||
.mainFile = "LegacyPass",
|
||||
.fragmentFile = "BasePass",
|
||||
.hasFragmentShader = true,
|
||||
.useMeshShading = false,
|
||||
.hasTaskShader = false,
|
||||
.useMaterial = true,
|
||||
.useVisibility = false,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
BasePass::~BasePass()
|
||||
{
|
||||
}
|
||||
BasePass::~BasePass() {}
|
||||
|
||||
void BasePass::beginFrame(const Component::Camera& cam)
|
||||
{
|
||||
void BasePass::beginFrame(const Component::Camera& cam) {
|
||||
RenderPass::beginFrame(cam);
|
||||
|
||||
lightCullingLayout->reset();
|
||||
@@ -83,8 +82,7 @@ void BasePass::beginFrame(const Component::Camera& cam)
|
||||
transparentCulling = lightCullingLayout->allocateDescriptorSet();
|
||||
}
|
||||
|
||||
void BasePass::render()
|
||||
{
|
||||
void BasePass::render() {
|
||||
opaqueCulling->updateBuffer(0, oLightIndexList);
|
||||
opaqueCulling->updateTexture(1, oLightGrid);
|
||||
transparentCulling->updateBuffer(0, tLightIndexList);
|
||||
@@ -97,14 +95,12 @@ void BasePass::render()
|
||||
|
||||
Gfx::ShaderPermutation permutation = graphics->getShaderCompiler()->getTemplate("BasePass");
|
||||
permutation.setViewCulling(useViewCulling);
|
||||
for (VertexData* vertexData : VertexData::getList())
|
||||
{
|
||||
for (VertexData* vertexData : VertexData::getList()) {
|
||||
vertexData->getInstanceDataSet()->updateBuffer(6, cullingBuffer);
|
||||
vertexData->getInstanceDataSet()->writeChanges();
|
||||
permutation.setVertexData(vertexData->getTypeName());
|
||||
const auto& materials = vertexData->getMaterialData();
|
||||
for (const auto& materialData : materials)
|
||||
{
|
||||
for (const auto& materialData : materials) {
|
||||
// material not used for any active meshes, skip
|
||||
if (materialData.instances.size() == 0)
|
||||
continue;
|
||||
@@ -124,43 +120,46 @@ void BasePass::render()
|
||||
|
||||
const Gfx::ShaderCollection* collection = graphics->getShaderCompiler()->findShaders(id);
|
||||
assert(collection != nullptr);
|
||||
if (graphics->supportMeshShading())
|
||||
{
|
||||
if (graphics->supportMeshShading()) {
|
||||
Gfx::MeshPipelineCreateInfo pipelineInfo = {
|
||||
.taskShader = collection->taskShader,
|
||||
.meshShader = collection->meshShader,
|
||||
.fragmentShader = collection->fragmentShader,
|
||||
.renderPass = renderPass,
|
||||
.pipelineLayout = collection->pipelineLayout,
|
||||
.multisampleState = {
|
||||
.samples = viewport->getSamples(),
|
||||
},
|
||||
.depthStencilState = {
|
||||
.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER_OR_EQUAL,
|
||||
},
|
||||
.colorBlend = {
|
||||
.attachmentCount = 1,
|
||||
},
|
||||
.multisampleState =
|
||||
{
|
||||
.samples = viewport->getSamples(),
|
||||
},
|
||||
.depthStencilState =
|
||||
{
|
||||
.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER_OR_EQUAL,
|
||||
},
|
||||
.colorBlend =
|
||||
{
|
||||
.attachmentCount = 1,
|
||||
},
|
||||
};
|
||||
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
|
||||
command->bindPipeline(pipeline);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
Gfx::LegacyPipelineCreateInfo pipelineInfo = {
|
||||
.vertexShader = collection->vertexShader,
|
||||
.fragmentShader = collection->fragmentShader,
|
||||
.renderPass = renderPass,
|
||||
.pipelineLayout = collection->pipelineLayout,
|
||||
.multisampleState = {
|
||||
.samples = viewport->getSamples(),
|
||||
},
|
||||
.depthStencilState = {
|
||||
.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER_OR_EQUAL,
|
||||
},
|
||||
.colorBlend = {
|
||||
.attachmentCount = 1,
|
||||
},
|
||||
.multisampleState =
|
||||
{
|
||||
.samples = viewport->getSamples(),
|
||||
},
|
||||
.depthStencilState =
|
||||
{
|
||||
.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER_OR_EQUAL,
|
||||
},
|
||||
.colorBlend =
|
||||
{
|
||||
.attachmentCount = 1,
|
||||
},
|
||||
};
|
||||
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
|
||||
command->bindPipeline(pipeline);
|
||||
@@ -170,21 +169,18 @@ void BasePass::render()
|
||||
command->bindDescriptor(vertexData->getInstanceDataSet());
|
||||
command->bindDescriptor(scene->getLightEnvironment()->getDescriptorSet());
|
||||
command->bindDescriptor(opaqueCulling);
|
||||
for (const auto& drawCall : materialData.instances)
|
||||
{
|
||||
for (const auto& drawCall : materialData.instances) {
|
||||
command->bindDescriptor(drawCall.materialInstance->getDescriptorSet());
|
||||
command->pushConstants(Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_VERTEX_BIT, 0, sizeof(VertexData::DrawCallOffsets), &drawCall.offsets);
|
||||
if (graphics->supportMeshShading())
|
||||
{
|
||||
command->pushConstants(Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_VERTEX_BIT, 0,
|
||||
sizeof(VertexData::DrawCallOffsets), &drawCall.offsets);
|
||||
if (graphics->supportMeshShading()) {
|
||||
command->drawMesh(drawCall.instanceMeshData.size(), 1, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
command->bindIndexBuffer(vertexData->getIndexBuffer());
|
||||
for (const auto& meshData : drawCall.instanceMeshData)
|
||||
{
|
||||
for (const auto& meshData : drawCall.instanceMeshData) {
|
||||
// all meshlets of a mesh share the same indices offset
|
||||
command->drawIndexed(meshData.numIndices, 1, meshData.firstIndex, vertexData->getIndicesOffset(meshData.meshletOffset), 0);
|
||||
command->drawIndexed(meshData.numIndices, 1, meshData.firstIndex,
|
||||
vertexData->getIndicesOffset(meshData.meshletOffset), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -195,14 +191,14 @@ void BasePass::render()
|
||||
graphics->executeCommands(std::move(commands));
|
||||
graphics->endRenderPass();
|
||||
// Sync color write with next pass/swapchain present
|
||||
//colorAttachment.getTexture()->pipelineBarrier(
|
||||
// colorAttachment.getTexture()->pipelineBarrier(
|
||||
// Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
// Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||
// Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
// Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
|
||||
//);
|
||||
// Sync depth with next pass/next frame
|
||||
//depthAttachment.getTexture()->pipelineBarrier(
|
||||
// depthAttachment.getTexture()->pipelineBarrier(
|
||||
// Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
// Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
||||
// Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT,
|
||||
@@ -210,20 +206,15 @@ void BasePass::render()
|
||||
//);
|
||||
}
|
||||
|
||||
void BasePass::endFrame()
|
||||
{
|
||||
}
|
||||
void BasePass::endFrame() {}
|
||||
|
||||
void BasePass::publishOutputs()
|
||||
{
|
||||
colorAttachment = Gfx::RenderTargetAttachment(viewport,
|
||||
Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
Gfx::SE_ATTACHMENT_LOAD_OP_CLEAR, Gfx::SE_ATTACHMENT_STORE_OP_STORE);
|
||||
void BasePass::publishOutputs() {
|
||||
colorAttachment = Gfx::RenderTargetAttachment(viewport, Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
Gfx::SE_ATTACHMENT_LOAD_OP_CLEAR, Gfx::SE_ATTACHMENT_STORE_OP_STORE);
|
||||
resources->registerRenderPassOutput("BASEPASS_COLOR", colorAttachment);
|
||||
}
|
||||
|
||||
void BasePass::createRenderPass()
|
||||
{
|
||||
void BasePass::createRenderPass() {
|
||||
cullingBuffer = resources->requestBuffer("CULLINGBUFFER");
|
||||
|
||||
depthAttachment = resources->requestRenderTarget("DEPTHPREPASS_DEPTH");
|
||||
@@ -231,7 +222,7 @@ void BasePass::createRenderPass()
|
||||
depthAttachment.setInitialLayout(Gfx::SE_IMAGE_LAYOUT_GENERAL);
|
||||
depthAttachment.setFinalLayout(Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
|
||||
Gfx::RenderTargetLayout layout = Gfx::RenderTargetLayout{
|
||||
.colorAttachments = { colorAttachment },
|
||||
.colorAttachments = {colorAttachment},
|
||||
.depthAttachment = depthAttachment,
|
||||
};
|
||||
Array<Gfx::SubPassDependency> dependency = {
|
||||
@@ -240,16 +231,20 @@ void BasePass::createRenderPass()
|
||||
.dstSubpass = 0,
|
||||
.srcStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
||||
.dstStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
|
||||
.srcAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
.dstAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
.srcAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
|
||||
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
.dstAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
|
||||
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
},
|
||||
{
|
||||
.srcSubpass = 0,
|
||||
.dstSubpass = ~0U,
|
||||
.srcStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
||||
.dstStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
|
||||
.srcAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
.dstAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
.srcAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
|
||||
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
.dstAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
|
||||
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
},
|
||||
};
|
||||
renderPass = graphics->createRenderPass(std::move(layout), std::move(dependency), viewport);
|
||||
|
||||
@@ -2,12 +2,10 @@
|
||||
#include "MinimalEngine.h"
|
||||
#include "RenderPass.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
namespace Seele {
|
||||
DECLARE_REF(CameraActor)
|
||||
class BasePass : public RenderPass
|
||||
{
|
||||
public:
|
||||
class BasePass : public RenderPass {
|
||||
public:
|
||||
BasePass(Gfx::PGraphics graphics, PScene scene);
|
||||
BasePass(BasePass&&) = default;
|
||||
BasePass& operator=(BasePass&&) = default;
|
||||
@@ -17,7 +15,8 @@ public:
|
||||
virtual void endFrame() override;
|
||||
virtual void publishOutputs() override;
|
||||
virtual void createRenderPass() override;
|
||||
private:
|
||||
|
||||
private:
|
||||
Gfx::RenderTargetAttachment colorAttachment;
|
||||
Gfx::RenderTargetAttachment depthAttachment;
|
||||
Gfx::RenderTargetAttachment visibilityAttachment;
|
||||
@@ -25,7 +24,7 @@ private:
|
||||
Gfx::PShaderBuffer tLightIndexList;
|
||||
Gfx::PTexture2D oLightGrid;
|
||||
Gfx::PTexture2D tLightGrid;
|
||||
|
||||
|
||||
Gfx::PDescriptorSet opaqueCulling;
|
||||
Gfx::PDescriptorSet transparentCulling;
|
||||
|
||||
|
||||
@@ -6,9 +6,7 @@ using namespace Seele;
|
||||
extern bool usePositionOnly;
|
||||
extern bool useViewCulling;
|
||||
|
||||
CachedDepthPass::CachedDepthPass(Gfx::PGraphics graphics, PScene scene)
|
||||
: RenderPass(graphics, scene)
|
||||
{
|
||||
CachedDepthPass::CachedDepthPass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics, scene) {
|
||||
depthPrepassLayout = graphics->createPipelineLayout("CachedDepthLayout");
|
||||
depthPrepassLayout->addDescriptorLayout(viewParamsLayout);
|
||||
depthPrepassLayout->addPushConstants(Gfx::SePushConstantRange{
|
||||
@@ -16,55 +14,45 @@ CachedDepthPass::CachedDepthPass(Gfx::PGraphics graphics, PScene scene)
|
||||
.offset = 0,
|
||||
.size = sizeof(VertexData::DrawCallOffsets),
|
||||
});
|
||||
if (graphics->supportMeshShading())
|
||||
{
|
||||
if (graphics->supportMeshShading()) {
|
||||
graphics->getShaderCompiler()->registerRenderPass("CachedDepthPass", Gfx::PassConfig{
|
||||
.baseLayout = depthPrepassLayout,
|
||||
.taskFile = "DrawListTask",
|
||||
.mainFile = "DrawListMesh",
|
||||
.fragmentFile = "VisibilityPass",
|
||||
.hasFragmentShader = true,
|
||||
.useMeshShading = true,
|
||||
.hasTaskShader = true,
|
||||
.useMaterial = false,
|
||||
.useVisibility = true,
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
.baseLayout = depthPrepassLayout,
|
||||
.taskFile = "DrawListTask",
|
||||
.mainFile = "DrawListMesh",
|
||||
.fragmentFile = "VisibilityPass",
|
||||
.hasFragmentShader = true,
|
||||
.useMeshShading = true,
|
||||
.hasTaskShader = true,
|
||||
.useMaterial = false,
|
||||
.useVisibility = true,
|
||||
});
|
||||
} else {
|
||||
graphics->getShaderCompiler()->registerRenderPass("CachedDepthPass", Gfx::PassConfig{
|
||||
.baseLayout = depthPrepassLayout,
|
||||
.taskFile = "",
|
||||
.mainFile = "LegacyPass",
|
||||
.fragmentFile = "VisibilityPass",
|
||||
.hasFragmentShader = true,
|
||||
.useMeshShading = false,
|
||||
.hasTaskShader = false,
|
||||
.useMaterial = false,
|
||||
.useVisibility = true,
|
||||
});
|
||||
.baseLayout = depthPrepassLayout,
|
||||
.taskFile = "",
|
||||
.mainFile = "LegacyPass",
|
||||
.fragmentFile = "VisibilityPass",
|
||||
.hasFragmentShader = true,
|
||||
.useMeshShading = false,
|
||||
.hasTaskShader = false,
|
||||
.useMaterial = false,
|
||||
.useVisibility = true,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
CachedDepthPass::~CachedDepthPass()
|
||||
{
|
||||
}
|
||||
CachedDepthPass::~CachedDepthPass() {}
|
||||
|
||||
void CachedDepthPass::beginFrame(const Component::Camera &cam)
|
||||
{
|
||||
RenderPass::beginFrame(cam);
|
||||
}
|
||||
void CachedDepthPass::beginFrame(const Component::Camera& cam) { RenderPass::beginFrame(cam); }
|
||||
|
||||
void CachedDepthPass::render()
|
||||
{
|
||||
void CachedDepthPass::render() {
|
||||
graphics->beginRenderPass(renderPass);
|
||||
Array<Gfx::ORenderCommand> commands;
|
||||
|
||||
Gfx::ShaderPermutation permutation = graphics->getShaderCompiler()->getTemplate("CachedDepthPass");
|
||||
permutation.setPositionOnly(usePositionOnly);
|
||||
permutation.setViewCulling(useViewCulling);
|
||||
for (VertexData *vertexData : VertexData::getList())
|
||||
{
|
||||
for (VertexData* vertexData : VertexData::getList()) {
|
||||
permutation.setVertexData(vertexData->getTypeName());
|
||||
vertexData->getInstanceDataSet()->updateBuffer(6, cullingBuffer);
|
||||
vertexData->getInstanceDataSet()->writeChanges();
|
||||
@@ -79,45 +67,48 @@ void CachedDepthPass::render()
|
||||
Gfx::ORenderCommand command = graphics->createRenderCommand("DepthRender");
|
||||
command->setViewport(viewport);
|
||||
|
||||
const Gfx::ShaderCollection *collection = graphics->getShaderCompiler()->findShaders(id);
|
||||
const Gfx::ShaderCollection* collection = graphics->getShaderCompiler()->findShaders(id);
|
||||
assert(collection != nullptr);
|
||||
if (graphics->supportMeshShading())
|
||||
{
|
||||
if (graphics->supportMeshShading()) {
|
||||
Gfx::MeshPipelineCreateInfo pipelineInfo = {
|
||||
.taskShader = collection->taskShader,
|
||||
.meshShader = collection->meshShader,
|
||||
.fragmentShader = collection->fragmentShader,
|
||||
.renderPass = renderPass,
|
||||
.pipelineLayout = collection->pipelineLayout,
|
||||
.multisampleState = {
|
||||
.samples = viewport->getSamples(),
|
||||
},
|
||||
.depthStencilState = {
|
||||
.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER,
|
||||
},
|
||||
.colorBlend = {
|
||||
.attachmentCount = 1,
|
||||
},
|
||||
.multisampleState =
|
||||
{
|
||||
.samples = viewport->getSamples(),
|
||||
},
|
||||
.depthStencilState =
|
||||
{
|
||||
.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER,
|
||||
},
|
||||
.colorBlend =
|
||||
{
|
||||
.attachmentCount = 1,
|
||||
},
|
||||
};
|
||||
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
|
||||
command->bindPipeline(pipeline);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
Gfx::LegacyPipelineCreateInfo pipelineInfo = {
|
||||
.vertexShader = collection->vertexShader,
|
||||
.fragmentShader = collection->fragmentShader,
|
||||
.renderPass = renderPass,
|
||||
.pipelineLayout = collection->pipelineLayout,
|
||||
.multisampleState = {
|
||||
.samples = viewport->getSamples(),
|
||||
},
|
||||
.depthStencilState = {
|
||||
.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER,
|
||||
},
|
||||
.colorBlend = {
|
||||
.attachmentCount = 1,
|
||||
},
|
||||
.multisampleState =
|
||||
{
|
||||
.samples = viewport->getSamples(),
|
||||
},
|
||||
.depthStencilState =
|
||||
{
|
||||
.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER,
|
||||
},
|
||||
.colorBlend =
|
||||
{
|
||||
.attachmentCount = 1,
|
||||
},
|
||||
};
|
||||
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
|
||||
command->bindPipeline(pipeline);
|
||||
@@ -126,27 +117,23 @@ void CachedDepthPass::render()
|
||||
command->bindDescriptor(vertexData->getVertexDataSet());
|
||||
command->bindDescriptor(vertexData->getInstanceDataSet());
|
||||
uint32 offset = 0;
|
||||
command->pushConstants(Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_VERTEX_BIT, 0, sizeof(VertexData::DrawCallOffsets), &offset);
|
||||
if (graphics->supportMeshShading())
|
||||
{
|
||||
command->pushConstants(Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_VERTEX_BIT, 0, sizeof(VertexData::DrawCallOffsets),
|
||||
&offset);
|
||||
if (graphics->supportMeshShading()) {
|
||||
command->drawMesh(vertexData->getNumInstances(), 1, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto &materials = vertexData->getMaterialData();
|
||||
for (const auto &materialData : materials)
|
||||
{
|
||||
} else {
|
||||
const auto& materials = vertexData->getMaterialData();
|
||||
for (const auto& materialData : materials) {
|
||||
// material not used for any active meshes, skip
|
||||
if (materialData.instances.size() == 0)
|
||||
continue;
|
||||
for (const auto &drawCall : materialData.instances)
|
||||
{
|
||||
for (const auto& drawCall : materialData.instances) {
|
||||
command->bindIndexBuffer(vertexData->getIndexBuffer());
|
||||
uint32 inst = drawCall.offsets.instanceOffset;
|
||||
for (const auto &meshData : drawCall.instanceMeshData)
|
||||
{
|
||||
for (const auto& meshData : drawCall.instanceMeshData) {
|
||||
// all meshlets of a mesh share the same indices offset
|
||||
command->drawIndexed(meshData.numIndices, 1, meshData.firstIndex, vertexData->getIndicesOffset(meshData.meshletOffset), inst++);
|
||||
command->drawIndexed(meshData.numIndices, 1, meshData.firstIndex,
|
||||
vertexData->getIndicesOffset(meshData.meshletOffset), inst++);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -157,25 +144,22 @@ void CachedDepthPass::render()
|
||||
graphics->executeCommands(std::move(commands));
|
||||
graphics->endRenderPass();
|
||||
// Sync depth read/write with depth pass depth read
|
||||
//depthBuffer->pipelineBarrier(
|
||||
// depthBuffer->pipelineBarrier(
|
||||
// Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
// Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
||||
// Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT,
|
||||
// Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT);
|
||||
// sync visibility write with depth pass visibility write
|
||||
//visibilityBuffer->pipelineBarrier(
|
||||
// visibilityBuffer->pipelineBarrier(
|
||||
// Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
// Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||
// Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
// Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
|
||||
}
|
||||
|
||||
void CachedDepthPass::endFrame()
|
||||
{
|
||||
}
|
||||
void CachedDepthPass::endFrame() {}
|
||||
|
||||
void CachedDepthPass::publishOutputs()
|
||||
{
|
||||
void CachedDepthPass::publishOutputs() {
|
||||
// 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
|
||||
TextureCreateInfo depthBufferInfo = {
|
||||
@@ -186,8 +170,7 @@ void CachedDepthPass::publishOutputs()
|
||||
};
|
||||
depthBuffer = graphics->createTexture2D(depthBufferInfo);
|
||||
depthAttachment =
|
||||
Gfx::RenderTargetAttachment(depthBuffer,
|
||||
Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
|
||||
Gfx::RenderTargetAttachment(depthBuffer, Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
|
||||
Gfx::SE_ATTACHMENT_LOAD_OP_CLEAR, Gfx::SE_ATTACHMENT_STORE_OP_STORE);
|
||||
resources->registerRenderPassOutput("DEPTHPREPASS_DEPTH", depthAttachment);
|
||||
|
||||
@@ -199,14 +182,12 @@ void CachedDepthPass::publishOutputs()
|
||||
};
|
||||
visibilityBuffer = graphics->createTexture2D(visibilityInfo);
|
||||
visibilityAttachment =
|
||||
Gfx::RenderTargetAttachment(visibilityBuffer,
|
||||
Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
Gfx::RenderTargetAttachment(visibilityBuffer, Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
Gfx::SE_ATTACHMENT_LOAD_OP_CLEAR, Gfx::SE_ATTACHMENT_STORE_OP_STORE);
|
||||
resources->registerRenderPassOutput("VISIBILITY", visibilityAttachment);
|
||||
}
|
||||
|
||||
void CachedDepthPass::createRenderPass()
|
||||
{
|
||||
void CachedDepthPass::createRenderPass() {
|
||||
cullingBuffer = resources->requestBuffer("CULLINGBUFFER");
|
||||
|
||||
Gfx::RenderTargetLayout layout = Gfx::RenderTargetLayout{
|
||||
@@ -219,16 +200,20 @@ void CachedDepthPass::createRenderPass()
|
||||
.dstSubpass = 0,
|
||||
.srcStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
||||
.dstStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
|
||||
.srcAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
.dstAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
.srcAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
|
||||
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
.dstAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
|
||||
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
},
|
||||
{
|
||||
.srcSubpass = 0,
|
||||
.dstSubpass = ~0U,
|
||||
.srcStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
||||
.dstStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
|
||||
.srcAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
.dstAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
.srcAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
|
||||
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
.dstAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
|
||||
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
},
|
||||
};
|
||||
renderPass = graphics->createRenderPass(std::move(layout), std::move(dependency), viewport);
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
#pragma once
|
||||
#include "RenderPass.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
class CachedDepthPass : public RenderPass
|
||||
{
|
||||
public:
|
||||
namespace Seele {
|
||||
class CachedDepthPass : public RenderPass {
|
||||
public:
|
||||
CachedDepthPass(Gfx::PGraphics graphics, PScene scene);
|
||||
CachedDepthPass(CachedDepthPass&&) = default;
|
||||
CachedDepthPass& operator=(CachedDepthPass&&) = default;
|
||||
@@ -15,14 +13,15 @@ public:
|
||||
virtual void endFrame() override;
|
||||
virtual void publishOutputs() override;
|
||||
virtual void createRenderPass() override;
|
||||
private:
|
||||
|
||||
private:
|
||||
Gfx::RenderTargetAttachment depthAttachment;
|
||||
Gfx::RenderTargetAttachment visibilityAttachment;
|
||||
Gfx::OTexture2D depthBuffer;
|
||||
Gfx::OTexture2D visibilityBuffer;
|
||||
Gfx::OPipelineLayout depthPrepassLayout;
|
||||
|
||||
|
||||
Gfx::PShaderBuffer cullingBuffer;
|
||||
};
|
||||
DEFINE_REF(CachedDepthPass)
|
||||
}
|
||||
} // namespace Seele
|
||||
@@ -1,77 +1,62 @@
|
||||
#include "DebugPass.h"
|
||||
#include "Graphics/Graphics.h"
|
||||
#include "Graphics/RenderTarget.h"
|
||||
#include "Graphics/Pipeline.h"
|
||||
#include "Graphics/RenderTarget.h"
|
||||
#include "Graphics/Shader.h"
|
||||
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
Array<DebugVertex> gDebugVertices;
|
||||
|
||||
void Seele::addDebugVertex(DebugVertex vert)
|
||||
{
|
||||
gDebugVertices.add(vert);
|
||||
}
|
||||
void Seele::addDebugVertex(DebugVertex vert) { gDebugVertices.add(vert); }
|
||||
|
||||
void Seele::addDebugVertices(Array<DebugVertex> verts)
|
||||
{
|
||||
gDebugVertices.addAll(verts);
|
||||
}
|
||||
void Seele::addDebugVertices(Array<DebugVertex> verts) { gDebugVertices.addAll(verts); }
|
||||
|
||||
DebugPass::DebugPass(Gfx::PGraphics graphics, PScene scene)
|
||||
: RenderPass(graphics, scene)
|
||||
{
|
||||
|
||||
}
|
||||
DebugPass::DebugPass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics, scene) {}
|
||||
|
||||
DebugPass::~DebugPass()
|
||||
{
|
||||
|
||||
}
|
||||
DebugPass::~DebugPass() {}
|
||||
|
||||
void DebugPass::beginFrame(const Component::Camera& cam)
|
||||
{
|
||||
void DebugPass::beginFrame(const Component::Camera& cam) {
|
||||
RenderPass::beginFrame(cam);
|
||||
|
||||
|
||||
VertexBufferCreateInfo vertexBufferInfo = {
|
||||
.sourceData = {
|
||||
.size = sizeof(DebugVertex) * gDebugVertices.size(),
|
||||
.data = (uint8*)gDebugVertices.data(),
|
||||
},
|
||||
.sourceData =
|
||||
{
|
||||
.size = sizeof(DebugVertex) * gDebugVertices.size(),
|
||||
.data = (uint8*)gDebugVertices.data(),
|
||||
},
|
||||
.vertexSize = sizeof(DebugVertex),
|
||||
.numVertices = (uint32)gDebugVertices.size(),
|
||||
.name = "DebugVertices",
|
||||
};
|
||||
debugVertices = graphics->createVertexBuffer(vertexBufferInfo);
|
||||
|
||||
}
|
||||
|
||||
void DebugPass::render()
|
||||
{
|
||||
void DebugPass::render() {
|
||||
graphics->beginRenderPass(renderPass);
|
||||
if (gDebugVertices.size() > 0)
|
||||
{
|
||||
if (gDebugVertices.size() > 0) {
|
||||
Gfx::ORenderCommand renderCommand = graphics->createRenderCommand("DebugRender");
|
||||
renderCommand->setViewport(viewport);
|
||||
renderCommand->bindPipeline(pipeline);
|
||||
renderCommand->bindDescriptor(viewParamsSet);
|
||||
renderCommand->bindVertexBuffer({ debugVertices });
|
||||
renderCommand->bindVertexBuffer({debugVertices});
|
||||
renderCommand->draw((uint32)gDebugVertices.size(), 1, 0, 0);
|
||||
Array<Gfx::ORenderCommand> commands;
|
||||
commands.add(std::move(renderCommand));
|
||||
graphics->executeCommands({ std::move(commands) });
|
||||
graphics->executeCommands({std::move(commands)});
|
||||
}
|
||||
graphics->endRenderPass();
|
||||
gDebugVertices.clear();
|
||||
// Sync color write with next pass/swapchain present
|
||||
//colorAttachment.getTexture()->pipelineBarrier(
|
||||
// colorAttachment.getTexture()->pipelineBarrier(
|
||||
// Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
// Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||
// Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
// Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
|
||||
//);
|
||||
// Sync depth with next pass/next frame
|
||||
//depthAttachment.getTexture()->pipelineBarrier(
|
||||
// depthAttachment.getTexture()->pipelineBarrier(
|
||||
// Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
// Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
||||
// Gfx::SE_ACCESS_MEMORY_WRITE_BIT,
|
||||
@@ -79,28 +64,22 @@ void DebugPass::render()
|
||||
//);
|
||||
}
|
||||
|
||||
void DebugPass::endFrame()
|
||||
{
|
||||
|
||||
}
|
||||
void DebugPass::endFrame() {}
|
||||
|
||||
void DebugPass::publishOutputs()
|
||||
{
|
||||
}
|
||||
void DebugPass::publishOutputs() {}
|
||||
|
||||
void DebugPass::createRenderPass()
|
||||
{
|
||||
void DebugPass::createRenderPass() {
|
||||
colorAttachment = resources->requestRenderTarget("BASEPASS_COLOR");
|
||||
colorAttachment.setLoadOp(Gfx::SE_ATTACHMENT_LOAD_OP_LOAD);
|
||||
colorAttachment.setInitialLayout(Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
colorAttachment.setInitialLayout(Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
|
||||
|
||||
depthAttachment = resources->requestRenderTarget("DEPTHPREPASS_DEPTH");
|
||||
depthAttachment.setLoadOp(Gfx::SE_ATTACHMENT_LOAD_OP_LOAD);
|
||||
depthAttachment.setInitialLayout(Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
|
||||
depthAttachment.setFinalLayout(Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
|
||||
Gfx::RenderTargetLayout layout = Gfx::RenderTargetLayout{
|
||||
.colorAttachments = {colorAttachment},
|
||||
.colorAttachments = {colorAttachment},
|
||||
.depthAttachment = depthAttachment,
|
||||
};
|
||||
|
||||
@@ -110,20 +89,24 @@ void DebugPass::createRenderPass()
|
||||
.dstSubpass = 0,
|
||||
.srcStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
||||
.dstStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
|
||||
.srcAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
.dstAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
.srcAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
|
||||
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
.dstAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
|
||||
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
},
|
||||
{
|
||||
.srcSubpass = 0,
|
||||
.dstSubpass = ~0U,
|
||||
.srcStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
||||
.dstStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
|
||||
.srcAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
.dstAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
.srcAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
|
||||
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
.dstAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
|
||||
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
},
|
||||
};
|
||||
renderPass = graphics->createRenderPass(std::move(layout), dependency, viewport);
|
||||
|
||||
|
||||
pipelineLayout = graphics->createPipelineLayout("DebugPassLayout");
|
||||
pipelineLayout->addDescriptorLayout(viewParamsLayout);
|
||||
|
||||
@@ -141,27 +124,22 @@ void DebugPass::createRenderPass()
|
||||
pipelineLayout->create();
|
||||
|
||||
VertexInputStateCreateInfo inputCreate = {
|
||||
.bindings = {
|
||||
VertexInputBinding {
|
||||
.binding = 0,
|
||||
.stride = sizeof(DebugVertex),
|
||||
.inputRate = Gfx::SE_VERTEX_INPUT_RATE_VERTEX,
|
||||
.bindings =
|
||||
{
|
||||
VertexInputBinding{
|
||||
.binding = 0,
|
||||
.stride = sizeof(DebugVertex),
|
||||
.inputRate = Gfx::SE_VERTEX_INPUT_RATE_VERTEX,
|
||||
},
|
||||
},
|
||||
},
|
||||
.attributes = {
|
||||
VertexInputAttribute {
|
||||
.location = 0,
|
||||
.binding = 0,
|
||||
.format = Gfx::SE_FORMAT_R32G32B32_SFLOAT,
|
||||
.offset = 0,
|
||||
},
|
||||
VertexInputAttribute {
|
||||
.location = 1,
|
||||
.binding = 0,
|
||||
.format = Gfx::SE_FORMAT_R32G32B32_SFLOAT,
|
||||
.offset = sizeof(Vector)
|
||||
}
|
||||
},
|
||||
.attributes = {VertexInputAttribute{
|
||||
.location = 0,
|
||||
.binding = 0,
|
||||
.format = Gfx::SE_FORMAT_R32G32B32_SFLOAT,
|
||||
.offset = 0,
|
||||
},
|
||||
VertexInputAttribute{
|
||||
.location = 1, .binding = 0, .format = Gfx::SE_FORMAT_R32G32B32_SFLOAT, .offset = sizeof(Vector)}},
|
||||
};
|
||||
vertexInput = graphics->createVertexInput(inputCreate);
|
||||
Gfx::LegacyPipelineCreateInfo gfxInfo;
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
#pragma once
|
||||
#include "RenderPass.h"
|
||||
#include "Scene/Scene.h"
|
||||
#include "Graphics/DebugVertex.h"
|
||||
#include "Graphics/Pipeline.h"
|
||||
#include "RenderPass.h"
|
||||
#include "Scene/Scene.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
|
||||
namespace Seele {
|
||||
DECLARE_REF(CameraActor)
|
||||
DECLARE_REF(Scene)
|
||||
DECLARE_REF(Viewport)
|
||||
class DebugPass : public RenderPass
|
||||
{
|
||||
public:
|
||||
class DebugPass : public RenderPass {
|
||||
public:
|
||||
DebugPass(Gfx::PGraphics graphics, PScene scene);
|
||||
DebugPass(DebugPass&&) = default;
|
||||
DebugPass& operator=(DebugPass&&) = default;
|
||||
@@ -21,7 +20,8 @@ public:
|
||||
virtual void endFrame() override;
|
||||
virtual void publishOutputs() override;
|
||||
virtual void createRenderPass() override;
|
||||
private:
|
||||
|
||||
private:
|
||||
Gfx::RenderTargetAttachment colorAttachment;
|
||||
Gfx::RenderTargetAttachment depthAttachment;
|
||||
Gfx::OVertexInput vertexInput;
|
||||
|
||||
@@ -6,9 +6,7 @@ using namespace Seele;
|
||||
extern bool usePositionOnly;
|
||||
extern bool useViewCulling;
|
||||
|
||||
DepthPrepass::DepthPrepass(Gfx::PGraphics graphics, PScene scene)
|
||||
: RenderPass(graphics, scene)
|
||||
{
|
||||
DepthPrepass::DepthPrepass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics, scene) {
|
||||
depthPrepassLayout = graphics->createPipelineLayout("DepthPrepassLayout");
|
||||
depthPrepassLayout->addDescriptorLayout(viewParamsLayout);
|
||||
depthPrepassLayout->addPushConstants(Gfx::SePushConstantRange{
|
||||
@@ -16,55 +14,45 @@ DepthPrepass::DepthPrepass(Gfx::PGraphics graphics, PScene scene)
|
||||
.offset = 0,
|
||||
.size = sizeof(VertexData::DrawCallOffsets),
|
||||
});
|
||||
if (graphics->supportMeshShading())
|
||||
{
|
||||
if (graphics->supportMeshShading()) {
|
||||
graphics->getShaderCompiler()->registerRenderPass("DepthPass", Gfx::PassConfig{
|
||||
.baseLayout = depthPrepassLayout,
|
||||
.taskFile = "DepthCullingTask",
|
||||
.mainFile = "DepthCullingMesh",
|
||||
.fragmentFile = "VisibilityPass",
|
||||
.hasFragmentShader = true,
|
||||
.useMeshShading = true,
|
||||
.hasTaskShader = true,
|
||||
.useMaterial = false,
|
||||
.useVisibility = true,
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
.baseLayout = depthPrepassLayout,
|
||||
.taskFile = "DepthCullingTask",
|
||||
.mainFile = "DepthCullingMesh",
|
||||
.fragmentFile = "VisibilityPass",
|
||||
.hasFragmentShader = true,
|
||||
.useMeshShading = true,
|
||||
.hasTaskShader = true,
|
||||
.useMaterial = false,
|
||||
.useVisibility = true,
|
||||
});
|
||||
} else {
|
||||
graphics->getShaderCompiler()->registerRenderPass("DepthPass", Gfx::PassConfig{
|
||||
.baseLayout = depthPrepassLayout,
|
||||
.taskFile = "",
|
||||
.mainFile = "LegacyPass",
|
||||
.fragmentFile = "VisibilityPass",
|
||||
.hasFragmentShader = true,
|
||||
.useMeshShading = false,
|
||||
.hasTaskShader = false,
|
||||
.useMaterial = false,
|
||||
.useVisibility = true,
|
||||
});
|
||||
.baseLayout = depthPrepassLayout,
|
||||
.taskFile = "",
|
||||
.mainFile = "LegacyPass",
|
||||
.fragmentFile = "VisibilityPass",
|
||||
.hasFragmentShader = true,
|
||||
.useMeshShading = false,
|
||||
.hasTaskShader = false,
|
||||
.useMaterial = false,
|
||||
.useVisibility = true,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
DepthPrepass::~DepthPrepass()
|
||||
{
|
||||
}
|
||||
DepthPrepass::~DepthPrepass() {}
|
||||
|
||||
void DepthPrepass::beginFrame(const Component::Camera &cam)
|
||||
{
|
||||
RenderPass::beginFrame(cam);
|
||||
}
|
||||
void DepthPrepass::beginFrame(const Component::Camera& cam) { RenderPass::beginFrame(cam); }
|
||||
|
||||
void DepthPrepass::render()
|
||||
{
|
||||
void DepthPrepass::render() {
|
||||
graphics->beginRenderPass(renderPass);
|
||||
Array<Gfx::ORenderCommand> commands;
|
||||
|
||||
Gfx::ShaderPermutation permutation = graphics->getShaderCompiler()->getTemplate("DepthPass");
|
||||
permutation.setPositionOnly(usePositionOnly);
|
||||
permutation.setViewCulling(useViewCulling);
|
||||
for (VertexData *vertexData : VertexData::getList())
|
||||
{
|
||||
for (VertexData* vertexData : VertexData::getList()) {
|
||||
permutation.setVertexData(vertexData->getTypeName());
|
||||
vertexData->getInstanceDataSet()->updateBuffer(6, cullingBuffer);
|
||||
vertexData->getInstanceDataSet()->writeChanges();
|
||||
@@ -78,45 +66,48 @@ void DepthPrepass::render()
|
||||
Gfx::ORenderCommand command = graphics->createRenderCommand("DepthRender");
|
||||
command->setViewport(viewport);
|
||||
|
||||
const Gfx::ShaderCollection *collection = graphics->getShaderCompiler()->findShaders(id);
|
||||
const Gfx::ShaderCollection* collection = graphics->getShaderCompiler()->findShaders(id);
|
||||
assert(collection != nullptr);
|
||||
if (graphics->supportMeshShading())
|
||||
{
|
||||
if (graphics->supportMeshShading()) {
|
||||
Gfx::MeshPipelineCreateInfo pipelineInfo = {
|
||||
.taskShader = collection->taskShader,
|
||||
.meshShader = collection->meshShader,
|
||||
.fragmentShader = collection->fragmentShader,
|
||||
.renderPass = renderPass,
|
||||
.pipelineLayout = collection->pipelineLayout,
|
||||
.multisampleState = {
|
||||
.samples = viewport->getSamples(),
|
||||
},
|
||||
.depthStencilState = {
|
||||
.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER,
|
||||
},
|
||||
.colorBlend = {
|
||||
.attachmentCount = 1,
|
||||
},
|
||||
.multisampleState =
|
||||
{
|
||||
.samples = viewport->getSamples(),
|
||||
},
|
||||
.depthStencilState =
|
||||
{
|
||||
.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER,
|
||||
},
|
||||
.colorBlend =
|
||||
{
|
||||
.attachmentCount = 1,
|
||||
},
|
||||
};
|
||||
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
|
||||
command->bindPipeline(pipeline);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
Gfx::LegacyPipelineCreateInfo pipelineInfo = {
|
||||
.vertexShader = collection->vertexShader,
|
||||
.fragmentShader = collection->fragmentShader,
|
||||
.renderPass = renderPass,
|
||||
.pipelineLayout = collection->pipelineLayout,
|
||||
.multisampleState = {
|
||||
.samples = viewport->getSamples(),
|
||||
},
|
||||
.depthStencilState = {
|
||||
.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER,
|
||||
},
|
||||
.colorBlend = {
|
||||
.attachmentCount = 1,
|
||||
},
|
||||
.multisampleState =
|
||||
{
|
||||
.samples = viewport->getSamples(),
|
||||
},
|
||||
.depthStencilState =
|
||||
{
|
||||
.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER,
|
||||
},
|
||||
.colorBlend =
|
||||
{
|
||||
.attachmentCount = 1,
|
||||
},
|
||||
};
|
||||
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
|
||||
command->bindPipeline(pipeline);
|
||||
@@ -125,27 +116,23 @@ void DepthPrepass::render()
|
||||
command->bindDescriptor(vertexData->getVertexDataSet());
|
||||
command->bindDescriptor(vertexData->getInstanceDataSet());
|
||||
uint32 offset = 0;
|
||||
command->pushConstants(Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_VERTEX_BIT, 0, sizeof(VertexData::DrawCallOffsets), &offset);
|
||||
if (graphics->supportMeshShading())
|
||||
{
|
||||
command->pushConstants(Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_VERTEX_BIT, 0, sizeof(VertexData::DrawCallOffsets),
|
||||
&offset);
|
||||
if (graphics->supportMeshShading()) {
|
||||
command->drawMesh(vertexData->getNumInstances(), 1, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto &materials = vertexData->getMaterialData();
|
||||
for (const auto &materialData : materials)
|
||||
{
|
||||
for (const auto &drawCall : materialData.instances)
|
||||
{
|
||||
} else {
|
||||
const auto& materials = vertexData->getMaterialData();
|
||||
for (const auto& materialData : materials) {
|
||||
for (const auto& drawCall : materialData.instances) {
|
||||
// material not used for any active meshes, skip
|
||||
if (materialData.instances.size() == 0)
|
||||
continue;
|
||||
command->bindIndexBuffer(vertexData->getIndexBuffer());
|
||||
uint32 inst = drawCall.offsets.instanceOffset;
|
||||
for (const auto &meshData : drawCall.instanceMeshData)
|
||||
{
|
||||
for (const auto& meshData : drawCall.instanceMeshData) {
|
||||
// all meshlets of a mesh share the same indices offset
|
||||
command->drawIndexed(meshData.numIndices, 1, meshData.firstIndex, vertexData->getIndicesOffset(meshData.meshletOffset), inst++);
|
||||
command->drawIndexed(meshData.numIndices, 1, meshData.firstIndex,
|
||||
vertexData->getIndicesOffset(meshData.meshletOffset), inst++);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -156,38 +143,27 @@ void DepthPrepass::render()
|
||||
graphics->executeCommands(std::move(commands));
|
||||
graphics->endRenderPass();
|
||||
// Sync depth read/write with compute read
|
||||
depthAttachment.getTexture()->pipelineBarrier(
|
||||
depthAttachment.getTexture()->pipelineBarrier(
|
||||
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
||||
Gfx::SE_ACCESS_SHADER_READ_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT
|
||||
);
|
||||
Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||
// Sync depth read/write with base pass read
|
||||
//depthAttachment.getTexture()->pipelineBarrier(
|
||||
// depthAttachment.getTexture()->pipelineBarrier(
|
||||
// Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
// Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
||||
// Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT,
|
||||
// Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
|
||||
//);
|
||||
// Sync visibility write with compute read
|
||||
visibilityAttachment.getTexture()->pipelineBarrier(
|
||||
Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||
Gfx::SE_ACCESS_SHADER_READ_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT
|
||||
);
|
||||
visibilityAttachment.getTexture()->pipelineBarrier(Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||
}
|
||||
|
||||
void DepthPrepass::endFrame()
|
||||
{
|
||||
}
|
||||
void DepthPrepass::endFrame() {}
|
||||
|
||||
void DepthPrepass::publishOutputs()
|
||||
{
|
||||
}
|
||||
void DepthPrepass::publishOutputs() {}
|
||||
|
||||
void DepthPrepass::createRenderPass()
|
||||
{
|
||||
void DepthPrepass::createRenderPass() {
|
||||
cullingBuffer = resources->requestBuffer("CULLINGBUFFER");
|
||||
|
||||
depthAttachment = resources->requestRenderTarget("DEPTHPREPASS_DEPTH");
|
||||
@@ -209,16 +185,20 @@ void DepthPrepass::createRenderPass()
|
||||
.dstSubpass = 0,
|
||||
.srcStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
||||
.dstStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
|
||||
.srcAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
.dstAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
.srcAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
|
||||
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
.dstAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
|
||||
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
},
|
||||
{
|
||||
.srcSubpass = 0,
|
||||
.dstSubpass = ~0U,
|
||||
.srcStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
||||
.dstStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
|
||||
.srcAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
.dstAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
.srcAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
|
||||
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
.dstAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
|
||||
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
},
|
||||
};
|
||||
renderPass = graphics->createRenderPass(std::move(layout), std::move(dependency), viewport);
|
||||
|
||||
@@ -2,11 +2,9 @@
|
||||
#include "MinimalEngine.h"
|
||||
#include "RenderPass.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
class DepthPrepass : public RenderPass
|
||||
{
|
||||
public:
|
||||
namespace Seele {
|
||||
class DepthPrepass : public RenderPass {
|
||||
public:
|
||||
DepthPrepass(Gfx::PGraphics graphics, PScene scene);
|
||||
DepthPrepass(DepthPrepass&&) = default;
|
||||
DepthPrepass& operator=(DepthPrepass&&) = default;
|
||||
@@ -16,7 +14,8 @@ public:
|
||||
virtual void endFrame() override;
|
||||
virtual void publishOutputs() override;
|
||||
virtual void createRenderPass() override;
|
||||
private:
|
||||
|
||||
private:
|
||||
Gfx::RenderTargetAttachment depthAttachment;
|
||||
Gfx::RenderTargetAttachment visibilityAttachment;
|
||||
Gfx::OPipelineLayout depthPrepassLayout;
|
||||
|
||||
@@ -1,62 +1,46 @@
|
||||
#include "LightCullingPass.h"
|
||||
#include "Graphics/Graphics.h"
|
||||
#include "Scene/Scene.h"
|
||||
#include "Actor/CameraActor.h"
|
||||
#include "Component/Camera.h"
|
||||
#include "RenderGraph.h"
|
||||
#include "Graphics/Command.h"
|
||||
#include "Graphics/Graphics.h"
|
||||
#include "RenderGraph.h"
|
||||
#include "Scene/Scene.h"
|
||||
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
extern bool useLightCulling;
|
||||
|
||||
LightCullingPass::LightCullingPass(Gfx::PGraphics graphics, PScene scene)
|
||||
: RenderPass(graphics, scene)
|
||||
{
|
||||
}
|
||||
LightCullingPass::LightCullingPass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics, scene) {}
|
||||
|
||||
LightCullingPass::~LightCullingPass()
|
||||
{
|
||||
LightCullingPass::~LightCullingPass() {}
|
||||
|
||||
}
|
||||
|
||||
void LightCullingPass::beginFrame(const Component::Camera& cam)
|
||||
{
|
||||
void LightCullingPass::beginFrame(const Component::Camera& cam) {
|
||||
RenderPass::beginFrame(cam);
|
||||
|
||||
oLightIndexCounter->pipelineBarrier(
|
||||
Gfx::SE_ACCESS_MEMORY_WRITE_BIT | Gfx::SE_ACCESS_MEMORY_READ_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||
Gfx::SE_ACCESS_MEMORY_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT
|
||||
);
|
||||
tLightIndexCounter->pipelineBarrier(
|
||||
Gfx::SE_ACCESS_MEMORY_WRITE_BIT | Gfx::SE_ACCESS_MEMORY_READ_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||
Gfx::SE_ACCESS_MEMORY_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT
|
||||
);
|
||||
oLightIndexCounter->pipelineBarrier(Gfx::SE_ACCESS_MEMORY_WRITE_BIT | Gfx::SE_ACCESS_MEMORY_READ_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, Gfx::SE_ACCESS_MEMORY_WRITE_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT);
|
||||
tLightIndexCounter->pipelineBarrier(Gfx::SE_ACCESS_MEMORY_WRITE_BIT | Gfx::SE_ACCESS_MEMORY_READ_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, Gfx::SE_ACCESS_MEMORY_WRITE_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT);
|
||||
uint32 reset = 0;
|
||||
ShaderBufferCreateInfo counterReset = {
|
||||
.sourceData = {
|
||||
.size = sizeof(uint32),
|
||||
.data = (uint8*)&reset,
|
||||
.owner = Gfx::QueueType::COMPUTE
|
||||
}
|
||||
};
|
||||
.sourceData = {.size = sizeof(uint32), .data = (uint8*)&reset, .owner = Gfx::QueueType::COMPUTE}};
|
||||
oLightIndexCounter->rotateBuffer(sizeof(uint32));
|
||||
oLightIndexCounter->updateContents(counterReset);
|
||||
tLightIndexCounter->rotateBuffer(sizeof(uint32));
|
||||
tLightIndexCounter->updateContents(counterReset);
|
||||
oLightIndexCounter->pipelineBarrier(
|
||||
Gfx::SE_ACCESS_MEMORY_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
Gfx::SE_ACCESS_MEMORY_READ_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||
tLightIndexCounter->pipelineBarrier(
|
||||
Gfx::SE_ACCESS_MEMORY_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
Gfx::SE_ACCESS_MEMORY_READ_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||
oLightIndexCounter->pipelineBarrier(Gfx::SE_ACCESS_MEMORY_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
Gfx::SE_ACCESS_MEMORY_READ_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||
tLightIndexCounter->pipelineBarrier(Gfx::SE_ACCESS_MEMORY_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
Gfx::SE_ACCESS_MEMORY_READ_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||
|
||||
cullingDescriptorLayout->reset();
|
||||
cullingDescriptorSet = cullingDescriptorLayout->allocateDescriptorSet();
|
||||
}
|
||||
|
||||
void LightCullingPass::render()
|
||||
{
|
||||
void LightCullingPass::render() {
|
||||
depthAttachment->transferOwnership(Gfx::QueueType::COMPUTE);
|
||||
cullingDescriptorSet->updateTexture(0, depthAttachment);
|
||||
cullingDescriptorSet->updateBuffer(1, oLightIndexCounter);
|
||||
@@ -67,41 +51,31 @@ void LightCullingPass::render()
|
||||
cullingDescriptorSet->updateTexture(6, Gfx::PTexture2D(tLightGrid));
|
||||
cullingDescriptorSet->writeChanges();
|
||||
Gfx::OComputeCommand computeCommand = graphics->createComputeCommand("CullingCommand");
|
||||
if (useLightCulling)
|
||||
{
|
||||
if (useLightCulling) {
|
||||
computeCommand->bindPipeline(cullingEnabledPipeline);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
computeCommand->bindPipeline(cullingPipeline);
|
||||
}
|
||||
computeCommand->bindDescriptor({ viewParamsSet, dispatchParamsSet, cullingDescriptorSet, lightEnv->getDescriptorSet() });
|
||||
computeCommand->bindDescriptor({viewParamsSet, dispatchParamsSet, cullingDescriptorSet, lightEnv->getDescriptorSet()});
|
||||
computeCommand->dispatch(dispatchParams.numThreadGroups.x, dispatchParams.numThreadGroups.y, dispatchParams.numThreadGroups.z);
|
||||
Array<Gfx::OComputeCommand> commands;
|
||||
commands.add(std::move(computeCommand));
|
||||
//std::cout << "Execute" << std::endl;
|
||||
// std::cout << "Execute" << std::endl;
|
||||
graphics->executeCommands(std::move(commands));
|
||||
|
||||
oLightIndexList->pipelineBarrier(
|
||||
Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||
Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||
tLightIndexList->pipelineBarrier(
|
||||
Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||
Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||
oLightGrid->pipelineBarrier(
|
||||
Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||
Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||
tLightGrid->pipelineBarrier(
|
||||
Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||
Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||
|
||||
oLightIndexList->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||
Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||
tLightIndexList->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||
Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||
oLightGrid->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||
tLightGrid->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||
}
|
||||
|
||||
void LightCullingPass::endFrame()
|
||||
{
|
||||
}
|
||||
void LightCullingPass::endFrame() {}
|
||||
|
||||
void LightCullingPass::publishOutputs()
|
||||
{
|
||||
void LightCullingPass::publishOutputs() {
|
||||
setupFrustums();
|
||||
uint32_t viewportWidth = viewport->getWidth();
|
||||
uint32_t viewportHeight = viewport->getHeight();
|
||||
@@ -109,14 +83,10 @@ void LightCullingPass::publishOutputs()
|
||||
dispatchParams.numThreadGroups = numThreadGroups;
|
||||
dispatchParams.numThreads = numThreadGroups * glm::uvec3(BLOCK_SIZE, BLOCK_SIZE, 1);
|
||||
dispatchParamsBuffer = graphics->createUniformBuffer(UniformBufferCreateInfo{
|
||||
.sourceData = {
|
||||
.size = sizeof(DispatchParams),
|
||||
.data = (uint8*)&dispatchParams,
|
||||
.owner = Gfx::QueueType::COMPUTE
|
||||
},
|
||||
.sourceData = {.size = sizeof(DispatchParams), .data = (uint8*)&dispatchParams, .owner = Gfx::QueueType::COMPUTE},
|
||||
.dynamic = false,
|
||||
.name = "DispatchParams",
|
||||
});
|
||||
});
|
||||
|
||||
dispatchParamsSet = dispatchParamsLayout->allocateDescriptorSet();
|
||||
dispatchParamsSet->updateBuffer(0, dispatchParamsBuffer);
|
||||
@@ -125,20 +95,29 @@ void LightCullingPass::publishOutputs()
|
||||
|
||||
cullingDescriptorLayout = graphics->createDescriptorLayout("pCullingParams");
|
||||
|
||||
//DepthTexture
|
||||
cullingDescriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{ .binding = 0, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE, });
|
||||
//o_lightIndexCounter
|
||||
cullingDescriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{ .binding = 1, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER, .access = Gfx::SE_DESCRIPTOR_ACCESS_READ_WRITE_BIT });
|
||||
//t_lightIndexCounter
|
||||
cullingDescriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{ .binding = 2, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER, .access = Gfx::SE_DESCRIPTOR_ACCESS_READ_WRITE_BIT });
|
||||
//o_lightIndexList
|
||||
cullingDescriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{ .binding = 3, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER, .access = Gfx::SE_DESCRIPTOR_ACCESS_READ_WRITE_BIT });
|
||||
//t_lightIndexList
|
||||
cullingDescriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{ .binding = 4, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER, .access = Gfx::SE_DESCRIPTOR_ACCESS_READ_WRITE_BIT });
|
||||
//o_lightGrid
|
||||
cullingDescriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{ .binding = 5, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_IMAGE, .access = Gfx::SE_DESCRIPTOR_ACCESS_READ_WRITE_BIT });
|
||||
//t_lightGrid
|
||||
cullingDescriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{ .binding = 6, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_IMAGE, .access = Gfx::SE_DESCRIPTOR_ACCESS_READ_WRITE_BIT });
|
||||
// DepthTexture
|
||||
cullingDescriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.binding = 0,
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||
});
|
||||
// o_lightIndexCounter
|
||||
cullingDescriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.binding = 1, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER, .access = Gfx::SE_DESCRIPTOR_ACCESS_READ_WRITE_BIT});
|
||||
// t_lightIndexCounter
|
||||
cullingDescriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.binding = 2, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER, .access = Gfx::SE_DESCRIPTOR_ACCESS_READ_WRITE_BIT});
|
||||
// o_lightIndexList
|
||||
cullingDescriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.binding = 3, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER, .access = Gfx::SE_DESCRIPTOR_ACCESS_READ_WRITE_BIT});
|
||||
// t_lightIndexList
|
||||
cullingDescriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.binding = 4, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER, .access = Gfx::SE_DESCRIPTOR_ACCESS_READ_WRITE_BIT});
|
||||
// o_lightGrid
|
||||
cullingDescriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.binding = 5, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_IMAGE, .access = Gfx::SE_DESCRIPTOR_ACCESS_READ_WRITE_BIT});
|
||||
// t_lightGrid
|
||||
cullingDescriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.binding = 6, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_IMAGE, .access = Gfx::SE_DESCRIPTOR_ACCESS_READ_WRITE_BIT});
|
||||
|
||||
cullingDescriptorLayout->create();
|
||||
|
||||
@@ -172,7 +151,7 @@ void LightCullingPass::publishOutputs()
|
||||
cullingEnableLayout->addDescriptorLayout(dispatchParamsLayout);
|
||||
cullingEnableLayout->addDescriptorLayout(cullingDescriptorLayout);
|
||||
cullingEnableLayout->addDescriptorLayout(lightEnv->getDescriptorLayout());
|
||||
|
||||
|
||||
ShaderCreateInfo createInfo = {
|
||||
.name = "Culling",
|
||||
.mainModule = "LightCulling",
|
||||
@@ -182,20 +161,21 @@ void LightCullingPass::publishOutputs()
|
||||
createInfo.defines["LIGHT_CULLING"] = "1";
|
||||
cullingEnabledShader = graphics->createComputeShader(createInfo);
|
||||
cullingEnableLayout->create();
|
||||
|
||||
|
||||
Gfx::ComputePipelineCreateInfo pipelineInfo;
|
||||
pipelineInfo.computeShader = cullingShader;
|
||||
pipelineInfo.pipelineLayout = std::move(cullingEnableLayout);
|
||||
cullingEnabledPipeline = graphics->createComputePipeline(std::move(pipelineInfo));
|
||||
}
|
||||
|
||||
|
||||
uint32 counterReset = 0;
|
||||
ShaderBufferCreateInfo structInfo = {
|
||||
.sourceData = {
|
||||
.size = sizeof(uint32),
|
||||
.data = (uint8*)&counterReset,
|
||||
.owner = Gfx::QueueType::COMPUTE,
|
||||
},
|
||||
.sourceData =
|
||||
{
|
||||
.size = sizeof(uint32),
|
||||
.data = (uint8*)&counterReset,
|
||||
.owner = Gfx::QueueType::COMPUTE,
|
||||
},
|
||||
.numElements = 1,
|
||||
.dynamic = true,
|
||||
.name = "oLightIndexCounter",
|
||||
@@ -204,14 +184,10 @@ void LightCullingPass::publishOutputs()
|
||||
structInfo.name = "tLightIndexCounter";
|
||||
tLightIndexCounter = graphics->createShaderBuffer(structInfo);
|
||||
structInfo = {
|
||||
.sourceData = {
|
||||
.size = (uint32)sizeof(uint32)
|
||||
* dispatchParams.numThreadGroups.x
|
||||
* dispatchParams.numThreadGroups.y
|
||||
* dispatchParams.numThreadGroups.z * 8192,
|
||||
.data = nullptr,
|
||||
.owner = Gfx::QueueType::COMPUTE
|
||||
},
|
||||
.sourceData = {.size = (uint32)sizeof(uint32) * dispatchParams.numThreadGroups.x * dispatchParams.numThreadGroups.y *
|
||||
dispatchParams.numThreadGroups.z * 8192,
|
||||
.data = nullptr,
|
||||
.owner = Gfx::QueueType::COMPUTE},
|
||||
.dynamic = false,
|
||||
.name = "oLightIndexList",
|
||||
};
|
||||
@@ -234,15 +210,9 @@ void LightCullingPass::publishOutputs()
|
||||
resources->registerTextureOutput("LIGHTCULLING_TLIGHTGRID", Gfx::PTexture2D(tLightGrid));
|
||||
}
|
||||
|
||||
void LightCullingPass::createRenderPass() { depthAttachment = resources->requestRenderTarget("DEPTHPREPASS_DEPTH").getTexture(); }
|
||||
|
||||
void LightCullingPass::createRenderPass()
|
||||
{
|
||||
depthAttachment = resources->requestRenderTarget("DEPTHPREPASS_DEPTH").getTexture();
|
||||
}
|
||||
|
||||
|
||||
void LightCullingPass::setupFrustums()
|
||||
{
|
||||
void LightCullingPass::setupFrustums() {
|
||||
uint32_t viewportWidth = viewport->getWidth();
|
||||
uint32_t viewportHeight = viewport->getHeight();
|
||||
|
||||
@@ -254,8 +224,12 @@ void LightCullingPass::setupFrustums()
|
||||
dispatchParams.numThreadGroups = numThreadGroups;
|
||||
|
||||
dispatchParamsLayout = graphics->createDescriptorLayout("pDispatchParams");
|
||||
dispatchParamsLayout->addDescriptorBinding(Gfx::DescriptorBinding{ .binding = 0, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER, });
|
||||
dispatchParamsLayout->addDescriptorBinding(Gfx::DescriptorBinding{ .binding = 1, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER, .access = Gfx::SE_DESCRIPTOR_ACCESS_WRITE_ONLY_BIT });
|
||||
dispatchParamsLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.binding = 0,
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
||||
});
|
||||
dispatchParamsLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.binding = 1, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER, .access = Gfx::SE_DESCRIPTOR_ACCESS_WRITE_ONLY_BIT});
|
||||
frustumLayout = graphics->createPipelineLayout("FrustumLayout");
|
||||
frustumLayout->addDescriptorLayout(viewParamsLayout);
|
||||
frustumLayout->addDescriptorLayout(dispatchParamsLayout);
|
||||
@@ -277,25 +251,17 @@ void LightCullingPass::setupFrustums()
|
||||
frustumPipeline = graphics->createComputePipeline(pipelineInfo);
|
||||
|
||||
Gfx::OUniformBuffer frustumDispatchParamsBuffer = graphics->createUniformBuffer(UniformBufferCreateInfo{
|
||||
.sourceData = {
|
||||
.size = sizeof(DispatchParams),
|
||||
.data = (uint8*)&dispatchParams,
|
||||
.owner = Gfx::QueueType::COMPUTE
|
||||
},
|
||||
.sourceData = {.size = sizeof(DispatchParams), .data = (uint8*)&dispatchParams, .owner = Gfx::QueueType::COMPUTE},
|
||||
.dynamic = false,
|
||||
.name = "FrustumDispatch"
|
||||
});
|
||||
.name = "FrustumDispatch"});
|
||||
|
||||
frustumBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||
.sourceData = {
|
||||
.size = sizeof(Frustum) * numThreads.x * numThreads.y * numThreads.z,
|
||||
.data = nullptr,
|
||||
.owner = Gfx::QueueType::COMPUTE
|
||||
},
|
||||
.numElements = numThreads.x * numThreads.y * numThreads.z,
|
||||
.dynamic = false,
|
||||
.name = "FrustumBuffer"
|
||||
});
|
||||
frustumBuffer = graphics->createShaderBuffer(
|
||||
ShaderBufferCreateInfo{.sourceData = {.size = sizeof(Frustum) * numThreads.x * numThreads.y * numThreads.z,
|
||||
.data = nullptr,
|
||||
.owner = Gfx::QueueType::COMPUTE},
|
||||
.numElements = numThreads.x * numThreads.y * numThreads.z,
|
||||
.dynamic = false,
|
||||
.name = "FrustumBuffer"});
|
||||
|
||||
Gfx::PDescriptorSet dispatchParamsSet = dispatchParamsLayout->allocateDescriptorSet();
|
||||
dispatchParamsSet->updateBuffer(0, frustumDispatchParamsBuffer);
|
||||
@@ -304,11 +270,11 @@ void LightCullingPass::setupFrustums()
|
||||
|
||||
Gfx::OComputeCommand command = graphics->createComputeCommand("FrustumCommand");
|
||||
command->bindPipeline(frustumPipeline);
|
||||
command->bindDescriptor({ viewParamsSet, dispatchParamsSet });
|
||||
command->bindDescriptor({viewParamsSet, dispatchParamsSet});
|
||||
command->dispatch(numThreadGroups.x, numThreadGroups.y, numThreadGroups.z);
|
||||
Array<Gfx::OComputeCommand> commands;
|
||||
commands.add(std::move(command));
|
||||
graphics->executeCommands(std::move(commands));
|
||||
frustumBuffer->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||
Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||
Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||
}
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
#pragma once
|
||||
#include "RenderPass.h"
|
||||
#include "Graphics/Shader.h"
|
||||
#include "RenderPass.h"
|
||||
#include "Scene/Scene.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
|
||||
namespace Seele {
|
||||
DECLARE_REF(CameraActor)
|
||||
DECLARE_REF(Scene)
|
||||
DECLARE_REF(Viewport)
|
||||
class LightCullingPass : public RenderPass
|
||||
{
|
||||
public:
|
||||
class LightCullingPass : public RenderPass {
|
||||
public:
|
||||
LightCullingPass(Gfx::PGraphics graphics, PScene scene);
|
||||
LightCullingPass(LightCullingPass&&) = default;
|
||||
LightCullingPass& operator=(LightCullingPass&&) = default;
|
||||
@@ -20,24 +19,22 @@ public:
|
||||
virtual void endFrame() override;
|
||||
virtual void publishOutputs() override;
|
||||
virtual void createRenderPass() override;
|
||||
private:
|
||||
|
||||
private:
|
||||
void setupFrustums();
|
||||
static constexpr uint32 BLOCK_SIZE = 32;
|
||||
static constexpr uint32 INDEX_LIGHT_ENV = 1;
|
||||
struct DispatchParams
|
||||
{
|
||||
struct DispatchParams {
|
||||
glm::uvec3 numThreadGroups;
|
||||
uint32_t pad0;
|
||||
glm::uvec3 numThreads;
|
||||
uint32_t pad1;
|
||||
} dispatchParams;
|
||||
struct Plane
|
||||
{
|
||||
struct Plane {
|
||||
Vector n;
|
||||
float d;
|
||||
};
|
||||
struct Frustum
|
||||
{
|
||||
struct Frustum {
|
||||
Plane planes[4];
|
||||
};
|
||||
|
||||
@@ -49,7 +46,7 @@ private:
|
||||
Gfx::OComputeShader frustumShader;
|
||||
Gfx::PComputePipeline frustumPipeline;
|
||||
Gfx::OPipelineLayout frustumLayout;
|
||||
|
||||
|
||||
PLightEnvironment lightEnv;
|
||||
Gfx::PTexture2D depthAttachment;
|
||||
Gfx::OShaderBuffer oLightIndexCounter;
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
#pragma once
|
||||
#include "RenderPass.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
class RayTracingPass : public RenderPass
|
||||
{
|
||||
public:
|
||||
namespace Seele {
|
||||
class RayTracingPass : public RenderPass {
|
||||
public:
|
||||
RayTracingPass(Gfx::PGraphics graphics, PScene scene);
|
||||
RayTracingPass(RayTracingPass&& other) = default;
|
||||
RayTracingPass& operator=(RayTracingPass&& other) = default;
|
||||
@@ -14,7 +12,7 @@ public:
|
||||
virtual void endFrame() override;
|
||||
virtual void publishOutputs() override;
|
||||
virtual void createRenderPass() override;
|
||||
private:
|
||||
|
||||
|
||||
private:
|
||||
};
|
||||
}
|
||||
} // namespace Seele
|
||||
@@ -1,54 +1,40 @@
|
||||
#pragma once
|
||||
#include "RenderPass.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
class RenderGraph
|
||||
{
|
||||
public:
|
||||
RenderGraph()
|
||||
{
|
||||
res = new RenderGraphResources();
|
||||
}
|
||||
void addPass(ORenderPass pass)
|
||||
{
|
||||
namespace Seele {
|
||||
class RenderGraph {
|
||||
public:
|
||||
RenderGraph() { res = new RenderGraphResources(); }
|
||||
void addPass(ORenderPass pass) {
|
||||
pass->setResources(res);
|
||||
passes.add(std::move(pass));
|
||||
passes.add(std::move(pass));
|
||||
}
|
||||
void setViewport(Gfx::PViewport viewport)
|
||||
{
|
||||
for (auto& pass : passes)
|
||||
{
|
||||
void setViewport(Gfx::PViewport viewport) {
|
||||
for (auto& pass : passes) {
|
||||
pass->setViewport(viewport);
|
||||
}
|
||||
}
|
||||
void createRenderPass()
|
||||
{
|
||||
for (auto& pass : passes)
|
||||
{
|
||||
void createRenderPass() {
|
||||
for (auto& pass : passes) {
|
||||
pass->publishOutputs();
|
||||
}
|
||||
for (auto& pass : passes)
|
||||
{
|
||||
for (auto& pass : passes) {
|
||||
pass->createRenderPass();
|
||||
}
|
||||
}
|
||||
void render(const Component::Camera& cam)
|
||||
{
|
||||
for (auto& pass : passes)
|
||||
{
|
||||
void render(const Component::Camera& cam) {
|
||||
for (auto& pass : passes) {
|
||||
pass->beginFrame(cam);
|
||||
}
|
||||
for (auto& pass : passes)
|
||||
{
|
||||
for (auto& pass : passes) {
|
||||
pass->render();
|
||||
}
|
||||
for (auto& pass : passes)
|
||||
{
|
||||
for (auto& pass : passes) {
|
||||
pass->endFrame();
|
||||
}
|
||||
}
|
||||
private:
|
||||
|
||||
private:
|
||||
PRenderGraphResources res;
|
||||
List<ORenderPass> passes;
|
||||
};
|
||||
|
||||
@@ -3,51 +3,31 @@
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
RenderGraphResources::RenderGraphResources()
|
||||
{
|
||||
|
||||
}
|
||||
RenderGraphResources::RenderGraphResources() {}
|
||||
|
||||
RenderGraphResources::~RenderGraphResources()
|
||||
{
|
||||
|
||||
}
|
||||
RenderGraphResources::~RenderGraphResources() {}
|
||||
|
||||
Gfx::RenderTargetAttachment RenderGraphResources::requestRenderTarget(const std::string& outputName)
|
||||
{
|
||||
Gfx::RenderTargetAttachment RenderGraphResources::requestRenderTarget(const std::string& outputName) {
|
||||
return registeredAttachments.at(outputName);
|
||||
}
|
||||
|
||||
Gfx::PTexture RenderGraphResources::requestTexture(const std::string& outputName)
|
||||
{
|
||||
return registeredTextures.at(outputName);
|
||||
}
|
||||
Gfx::PTexture RenderGraphResources::requestTexture(const std::string& outputName) { return registeredTextures.at(outputName); }
|
||||
|
||||
Gfx::PShaderBuffer RenderGraphResources::requestBuffer(const std::string& outputName)
|
||||
{
|
||||
return registeredBuffers.at(outputName);
|
||||
}
|
||||
Gfx::PShaderBuffer RenderGraphResources::requestBuffer(const std::string& outputName) { return registeredBuffers.at(outputName); }
|
||||
|
||||
Gfx::PUniformBuffer RenderGraphResources::requestUniform(const std::string& outputName)
|
||||
{
|
||||
return registeredUniforms.at(outputName);
|
||||
}
|
||||
Gfx::PUniformBuffer RenderGraphResources::requestUniform(const std::string& outputName) { return registeredUniforms.at(outputName); }
|
||||
|
||||
void RenderGraphResources::registerRenderPassOutput(const std::string& outputName, Gfx::RenderTargetAttachment attachment)
|
||||
{
|
||||
void RenderGraphResources::registerRenderPassOutput(const std::string& outputName, Gfx::RenderTargetAttachment attachment) {
|
||||
registeredAttachments[outputName] = attachment;
|
||||
}
|
||||
|
||||
void RenderGraphResources::registerTextureOutput(const std::string& outputName, Gfx::PTexture texture)
|
||||
{
|
||||
void RenderGraphResources::registerTextureOutput(const std::string& outputName, Gfx::PTexture texture) {
|
||||
registeredTextures[outputName] = texture;
|
||||
}
|
||||
|
||||
void RenderGraphResources::registerBufferOutput(const std::string& outputName, Gfx::PShaderBuffer buffer)
|
||||
{
|
||||
void RenderGraphResources::registerBufferOutput(const std::string& outputName, Gfx::PShaderBuffer buffer) {
|
||||
registeredBuffers[outputName] = buffer;
|
||||
}
|
||||
void RenderGraphResources::registerUniformOutput(const std::string& outputName, Gfx::PUniformBuffer buffer)
|
||||
{
|
||||
void RenderGraphResources::registerUniformOutput(const std::string& outputName, Gfx::PUniformBuffer buffer) {
|
||||
registeredUniforms[outputName] = buffer;
|
||||
}
|
||||
@@ -1,16 +1,15 @@
|
||||
#pragma once
|
||||
#include "MinimalEngine.h"
|
||||
#include "Graphics/Buffer.h"
|
||||
#include "Graphics/RenderTarget.h"
|
||||
#include "Graphics/Texture.h"
|
||||
#include "Graphics/Buffer.h"
|
||||
#include "MinimalEngine.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
|
||||
namespace Seele {
|
||||
DECLARE_REF(ViewFrame)
|
||||
|
||||
class RenderGraphResources
|
||||
{
|
||||
public:
|
||||
class RenderGraphResources {
|
||||
public:
|
||||
RenderGraphResources();
|
||||
~RenderGraphResources();
|
||||
Gfx::RenderTargetAttachment requestRenderTarget(const std::string& outputName);
|
||||
@@ -21,7 +20,8 @@ public:
|
||||
void registerTextureOutput(const std::string& outputName, Gfx::PTexture buffer);
|
||||
void registerBufferOutput(const std::string& outputName, Gfx::PShaderBuffer buffer);
|
||||
void registerUniformOutput(const std::string& outputName, Gfx::PUniformBuffer buffer);
|
||||
protected:
|
||||
|
||||
protected:
|
||||
Map<std::string, Gfx::RenderTargetAttachment> registeredAttachments;
|
||||
Map<std::string, Gfx::PTexture> registeredTextures;
|
||||
Map<std::string, Gfx::PShaderBuffer> registeredBuffers;
|
||||
|
||||
@@ -2,18 +2,19 @@
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
RenderPass::RenderPass(Gfx::PGraphics graphics, PScene scene)
|
||||
: graphics(graphics)
|
||||
, scene(scene)
|
||||
{
|
||||
RenderPass::RenderPass(Gfx::PGraphics graphics, PScene scene) : graphics(graphics), scene(scene) {
|
||||
|
||||
viewParamsLayout = graphics->createDescriptorLayout("pViewParams");
|
||||
viewParamsLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 0, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER,});
|
||||
viewParamsLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.binding = 0,
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
||||
});
|
||||
UniformBufferCreateInfo uniformInitializer = {
|
||||
.sourceData = {
|
||||
.size = sizeof(ViewParameter),
|
||||
.data = (uint8*)&viewParams,
|
||||
},
|
||||
.sourceData =
|
||||
{
|
||||
.size = sizeof(ViewParameter),
|
||||
.data = (uint8*)&viewParams,
|
||||
},
|
||||
.dynamic = true,
|
||||
.name = "viewParamsBuffer",
|
||||
};
|
||||
@@ -21,11 +22,9 @@ RenderPass::RenderPass(Gfx::PGraphics graphics, PScene scene)
|
||||
viewParamsLayout->create();
|
||||
}
|
||||
|
||||
RenderPass::~RenderPass()
|
||||
{}
|
||||
RenderPass::~RenderPass() {}
|
||||
|
||||
void RenderPass::beginFrame(const Component::Camera& cam)
|
||||
{
|
||||
void RenderPass::beginFrame(const Component::Camera& cam) {
|
||||
viewParams = {
|
||||
.viewMatrix = cam.getViewMatrix(),
|
||||
.inverseViewMatrix = glm::inverse(cam.getViewMatrix()),
|
||||
@@ -40,23 +39,14 @@ void RenderPass::beginFrame(const Component::Camera& cam)
|
||||
};
|
||||
viewParamsBuffer->rotateBuffer(sizeof(ViewParameter));
|
||||
viewParamsBuffer->updateContents(uniformUpdate);
|
||||
viewParamsBuffer->pipelineBarrier(
|
||||
Gfx::SE_ACCESS_TRANSFER_WRITE_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
Gfx::SE_ACCESS_MEMORY_READ_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_ALL_COMMANDS_BIT);
|
||||
viewParamsBuffer->pipelineBarrier(Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
Gfx::SE_ACCESS_MEMORY_READ_BIT, Gfx::SE_PIPELINE_STAGE_ALL_COMMANDS_BIT);
|
||||
viewParamsLayout->reset();
|
||||
viewParamsSet = viewParamsLayout->allocateDescriptorSet();
|
||||
viewParamsSet->updateBuffer(0, viewParamsBuffer);
|
||||
viewParamsSet->writeChanges();
|
||||
}
|
||||
|
||||
void RenderPass::setResources(PRenderGraphResources _resources)
|
||||
{
|
||||
resources = _resources;
|
||||
}
|
||||
void RenderPass::setResources(PRenderGraphResources _resources) { resources = _resources; }
|
||||
|
||||
void RenderPass::setViewport(Gfx::PViewport _viewport)
|
||||
{
|
||||
viewport = _viewport;
|
||||
}
|
||||
void RenderPass::setViewport(Gfx::PViewport _viewport) { viewport = _viewport; }
|
||||
|
||||
@@ -1,20 +1,19 @@
|
||||
#pragma once
|
||||
#include "MinimalEngine.h"
|
||||
#include "Math/Math.h"
|
||||
#include "RenderGraphResources.h"
|
||||
#include "Component/Camera.h"
|
||||
#include "Scene/Scene.h"
|
||||
#include "Material/MaterialInstance.h"
|
||||
#include "Graphics/VertexData.h"
|
||||
#include "Material/MaterialInstance.h"
|
||||
#include "Math/Math.h"
|
||||
#include "MinimalEngine.h"
|
||||
#include "RenderGraphResources.h"
|
||||
#include "Scene/Scene.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
|
||||
namespace Seele {
|
||||
DECLARE_NAME_REF(Gfx, Viewport)
|
||||
DECLARE_NAME_REF(Gfx, Graphics)
|
||||
DECLARE_NAME_REF(Gfx, RenderPass)
|
||||
class RenderPass
|
||||
{
|
||||
public:
|
||||
class RenderPass {
|
||||
public:
|
||||
RenderPass(Gfx::PGraphics graphics, PScene scene);
|
||||
RenderPass(RenderPass&&) = default;
|
||||
RenderPass& operator=(RenderPass&&) = default;
|
||||
@@ -26,9 +25,9 @@ public:
|
||||
virtual void createRenderPass() = 0;
|
||||
void setResources(PRenderGraphResources _resources);
|
||||
void setViewport(Gfx::PViewport _viewport);
|
||||
protected:
|
||||
struct ViewParameter
|
||||
{
|
||||
|
||||
protected:
|
||||
struct ViewParameter {
|
||||
Matrix4 viewMatrix;
|
||||
Matrix4 inverseViewMatrix;
|
||||
Matrix4 projectionMatrix;
|
||||
@@ -46,7 +45,7 @@ protected:
|
||||
PScene scene;
|
||||
};
|
||||
DEFINE_REF(RenderPass)
|
||||
template<typename RP>
|
||||
template <typename RP>
|
||||
concept RenderPassType = std::derived_from<RP, RenderPass>;
|
||||
|
||||
} // namespace Seele
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
#include "SkyboxRenderPass.h"
|
||||
#include "Graphics/Graphics.h"
|
||||
#include "Asset/AssetRegistry.h"
|
||||
#include "Graphics/Command.h"
|
||||
#include "Graphics/Graphics.h"
|
||||
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
SkyboxRenderPass::SkyboxRenderPass(Gfx::PGraphics graphics, PScene scene)
|
||||
: RenderPass(graphics, scene)
|
||||
{
|
||||
SkyboxRenderPass::SkyboxRenderPass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics, scene) {
|
||||
skybox = Seele::Component::Skybox{
|
||||
//.day = AssetRegistry::findTexture("FS000_Day_01")->getTexture().cast<Gfx::TextureCube>(),
|
||||
//.night = AssetRegistry::findTexture("FS000_Night_01")->getTexture().cast<Gfx::TextureCube>(),
|
||||
@@ -15,13 +14,9 @@ SkyboxRenderPass::SkyboxRenderPass(Gfx::PGraphics graphics, PScene scene)
|
||||
.blendFactor = 0,
|
||||
};
|
||||
}
|
||||
SkyboxRenderPass::~SkyboxRenderPass()
|
||||
{
|
||||
SkyboxRenderPass::~SkyboxRenderPass() {}
|
||||
|
||||
}
|
||||
|
||||
void SkyboxRenderPass::beginFrame(const Component::Camera& cam)
|
||||
{
|
||||
void SkyboxRenderPass::beginFrame(const Component::Camera& cam) {
|
||||
RenderPass::beginFrame(cam);
|
||||
|
||||
skyboxDataLayout->reset();
|
||||
@@ -30,14 +25,12 @@ void SkyboxRenderPass::beginFrame(const Component::Camera& cam)
|
||||
skyboxBuffer->updateContents(DataSource{
|
||||
.size = sizeof(SkyboxData),
|
||||
.data = (uint8*)&skyboxData,
|
||||
});
|
||||
});
|
||||
skyboxDataSet = skyboxDataLayout->allocateDescriptorSet();
|
||||
skyboxDataSet->updateBuffer(0, skyboxBuffer);
|
||||
skyboxDataSet->writeChanges();
|
||||
skyboxBuffer->pipelineBarrier(
|
||||
Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
Gfx::SE_ACCESS_MEMORY_READ_BIT, Gfx::SE_PIPELINE_STAGE_VERTEX_SHADER_BIT
|
||||
);
|
||||
skyboxBuffer->pipelineBarrier(Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT, Gfx::SE_ACCESS_MEMORY_READ_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_VERTEX_SHADER_BIT);
|
||||
textureSet = textureLayout->allocateDescriptorSet();
|
||||
textureSet->updateTexture(0, skybox.day);
|
||||
textureSet->updateTexture(1, skybox.night);
|
||||
@@ -45,16 +38,13 @@ void SkyboxRenderPass::beginFrame(const Component::Camera& cam)
|
||||
textureSet->writeChanges();
|
||||
}
|
||||
|
||||
void SkyboxRenderPass::render()
|
||||
{
|
||||
void SkyboxRenderPass::render() {
|
||||
colorAttachment.getTexture()->pipelineBarrier(
|
||||
Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||
Gfx::SE_ACCESS_COLOR_ATTACHMENT_READ_BIT, Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
|
||||
);
|
||||
Gfx::SE_ACCESS_COLOR_ATTACHMENT_READ_BIT, Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
|
||||
depthAttachment.getTexture()->pipelineBarrier(
|
||||
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
||||
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT, Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
|
||||
);
|
||||
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT, Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT);
|
||||
graphics->beginRenderPass(renderPass);
|
||||
Gfx::ORenderCommand renderCommand = graphics->createRenderCommand("SkyboxRender");
|
||||
renderCommand->setViewport(viewport);
|
||||
@@ -67,48 +57,56 @@ void SkyboxRenderPass::render()
|
||||
graphics->endRenderPass();
|
||||
}
|
||||
|
||||
void SkyboxRenderPass::endFrame()
|
||||
{
|
||||
void SkyboxRenderPass::endFrame() {}
|
||||
|
||||
}
|
||||
|
||||
void SkyboxRenderPass::publishOutputs()
|
||||
{
|
||||
void SkyboxRenderPass::publishOutputs() {
|
||||
skyboxDataLayout = graphics->createDescriptorLayout("pSkyboxData");
|
||||
skyboxDataLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 0, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER,});
|
||||
skyboxDataLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.binding = 0,
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
||||
});
|
||||
skyboxDataLayout->create();
|
||||
textureLayout = graphics->createDescriptorLayout("pSkyboxTextures");
|
||||
textureLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 0, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE,});
|
||||
textureLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 1, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE,});
|
||||
textureLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 2, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLER,});
|
||||
textureLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.binding = 0,
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||
});
|
||||
textureLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.binding = 1,
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||
});
|
||||
textureLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.binding = 2,
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLER,
|
||||
});
|
||||
textureLayout->create();
|
||||
|
||||
skyboxSampler = graphics->createSampler({});
|
||||
}
|
||||
|
||||
void SkyboxRenderPass::createRenderPass()
|
||||
{
|
||||
void SkyboxRenderPass::createRenderPass() {
|
||||
colorAttachment = resources->requestRenderTarget("BASEPASS_COLOR");
|
||||
//colorAttachment->loadOp = Gfx::SE_ATTACHMENT_LOAD_OP_LOAD;
|
||||
// colorAttachment->loadOp = Gfx::SE_ATTACHMENT_LOAD_OP_LOAD;
|
||||
depthAttachment = resources->requestRenderTarget("DEPTHPREPASS_DEPTH");
|
||||
//depthAttachment->loadOp = Gfx::SE_ATTACHMENT_LOAD_OP_LOAD;
|
||||
//Gfx::ORenderTargetLayout layout = new Gfx::RenderTargetLayout{
|
||||
// .colorAttachments = { colorAttachment },
|
||||
// .depthAttachment = depthAttachment
|
||||
//};
|
||||
//renderPass = graphics->createRenderPass(std::move(layout), viewport);
|
||||
// depthAttachment->loadOp = Gfx::SE_ATTACHMENT_LOAD_OP_LOAD;
|
||||
// Gfx::ORenderTargetLayout layout = new Gfx::RenderTargetLayout{
|
||||
// .colorAttachments = { colorAttachment },
|
||||
// .depthAttachment = depthAttachment
|
||||
// };
|
||||
// renderPass = graphics->createRenderPass(std::move(layout), viewport);
|
||||
|
||||
skyboxData.transformMatrix = Matrix4(1);
|
||||
skyboxData.fogColor = skybox.fogColor;
|
||||
skyboxData.blendFactor = skybox.blendFactor;
|
||||
|
||||
skyboxBuffer = graphics->createUniformBuffer(UniformBufferCreateInfo{
|
||||
.sourceData = {
|
||||
.size = sizeof(SkyboxData),
|
||||
.data = (uint8*)&skyboxData,
|
||||
},
|
||||
.sourceData =
|
||||
{
|
||||
.size = sizeof(SkyboxData),
|
||||
.data = (uint8*)&skyboxData,
|
||||
},
|
||||
.dynamic = true,
|
||||
});
|
||||
});
|
||||
|
||||
ShaderCreateInfo createInfo = {
|
||||
.name = "SkyboxVertex",
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
#pragma once
|
||||
#include "RenderPass.h"
|
||||
#include "Graphics/Shader.h"
|
||||
#include "Component/Skybox.h"
|
||||
#include "Graphics/Shader.h"
|
||||
#include "RenderPass.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
class SkyboxRenderPass : public RenderPass
|
||||
{
|
||||
public:
|
||||
|
||||
namespace Seele {
|
||||
class SkyboxRenderPass : public RenderPass {
|
||||
public:
|
||||
SkyboxRenderPass(Gfx::PGraphics graphics, PScene scene);
|
||||
SkyboxRenderPass(SkyboxRenderPass&&) = default;
|
||||
SkyboxRenderPass& operator=(SkyboxRenderPass&&) = default;
|
||||
@@ -17,7 +16,8 @@ public:
|
||||
virtual void endFrame() override;
|
||||
virtual void publishOutputs() override;
|
||||
virtual void createRenderPass() override;
|
||||
private:
|
||||
|
||||
private:
|
||||
Gfx::RenderTargetAttachment colorAttachment;
|
||||
Gfx::RenderTargetAttachment depthAttachment;
|
||||
Gfx::ODescriptorLayout skyboxDataLayout;
|
||||
@@ -29,8 +29,7 @@ private:
|
||||
Gfx::OPipelineLayout pipelineLayout;
|
||||
Gfx::PGraphicsPipeline pipeline;
|
||||
Gfx::OSampler skyboxSampler;
|
||||
struct SkyboxData
|
||||
{
|
||||
struct SkyboxData {
|
||||
Matrix4 transformMatrix;
|
||||
Vector fogColor;
|
||||
float blendFactor;
|
||||
|
||||
@@ -1,40 +1,32 @@
|
||||
#include "TextPass.h"
|
||||
#include "Graphics/Command.h"
|
||||
#include "Graphics/Enums.h"
|
||||
#include "RenderGraph.h"
|
||||
#include "Graphics/Graphics.h"
|
||||
#include "Graphics/RenderTarget.h"
|
||||
#include "Graphics/Command.h"
|
||||
#include "RenderGraph.h"
|
||||
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
TextPass::TextPass(Gfx::PGraphics graphics, PScene scene)
|
||||
: RenderPass(graphics, scene)
|
||||
{
|
||||
}
|
||||
TextPass::TextPass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics, scene) {}
|
||||
|
||||
TextPass::~TextPass()
|
||||
{
|
||||
|
||||
}
|
||||
TextPass::~TextPass() {}
|
||||
|
||||
void TextPass::beginFrame(const Component::Camera& cam)
|
||||
{
|
||||
void TextPass::beginFrame(const Component::Camera& cam) {
|
||||
RenderPass::beginFrame(cam);
|
||||
for(TextRender& render : texts)
|
||||
{
|
||||
for (TextRender& render : texts) {
|
||||
FontData& fd = getFontData(render.font);
|
||||
TextResources& res = textResources[render.font].add();
|
||||
Array<GlyphInstanceData> instanceData;
|
||||
float x = render.position.x;
|
||||
float y = render.position.y;
|
||||
for(uint32 c : render.text)
|
||||
{
|
||||
for (uint32 c : render.text) {
|
||||
const GlyphData& glyph = fd.glyphDataSet[fd.characterToGlyphIndex[c]];
|
||||
Vector2 bearing = glyph.bearing;
|
||||
Vector2 size = glyph.size;
|
||||
float xpos = x + bearing.x * render.scale;
|
||||
float ypos = y - (size.y - bearing.y) * render.scale;
|
||||
|
||||
|
||||
float w = size.x * render.scale;
|
||||
float h = size.y * render.scale;
|
||||
|
||||
@@ -46,10 +38,11 @@ void TextPass::beginFrame(const Component::Camera& cam)
|
||||
x += (glyph.advance >> 6) * render.scale;
|
||||
}
|
||||
res.instanceBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||
.sourceData = {
|
||||
.size = static_cast<uint32>(instanceData.size() * sizeof(GlyphInstanceData)),
|
||||
.data = reinterpret_cast<uint8*>(instanceData.data()),
|
||||
},
|
||||
.sourceData =
|
||||
{
|
||||
.size = static_cast<uint32>(instanceData.size() * sizeof(GlyphInstanceData)),
|
||||
.data = reinterpret_cast<uint8*>(instanceData.data()),
|
||||
},
|
||||
.numElements = instanceData.size(),
|
||||
});
|
||||
|
||||
@@ -68,48 +61,42 @@ void TextPass::beginFrame(const Component::Camera& cam)
|
||||
projectionBuffer->updateContents(projectionUpdate);
|
||||
generalSet->updateBuffer(1, projectionBuffer);
|
||||
generalSet->writeChanges();
|
||||
//co_return;
|
||||
// co_return;
|
||||
}
|
||||
|
||||
void TextPass::render()
|
||||
{
|
||||
void TextPass::render() {
|
||||
graphics->beginRenderPass(renderPass);
|
||||
Array<Gfx::ORenderCommand> commands;
|
||||
for(const auto& [fontAsset, res] : textResources)
|
||||
{
|
||||
for (const auto& [fontAsset, res] : textResources) {
|
||||
Gfx::ORenderCommand command = graphics->createRenderCommand("TextPassCommand");
|
||||
command->setViewport(viewport);
|
||||
command->bindPipeline(pipeline);
|
||||
for(const auto& resource : res)
|
||||
{
|
||||
for (const auto& resource : res) {
|
||||
command->bindDescriptor({generalSet, resource.textureArraySet});
|
||||
//command->bindVertexBuffer({resource.vertexBuffer});
|
||||
|
||||
command->pushConstants(Gfx::SE_SHADER_STAGE_VERTEX_BIT | Gfx::SE_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(TextData), &resource.textData);
|
||||
//command->draw(4, static_cast<uint32>(resource.vertexBuffer->getNumVertices()), 0, 0);
|
||||
// command->bindVertexBuffer({resource.vertexBuffer});
|
||||
|
||||
command->pushConstants(Gfx::SE_SHADER_STAGE_VERTEX_BIT | Gfx::SE_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(TextData),
|
||||
&resource.textData);
|
||||
// command->draw(4, static_cast<uint32>(resource.vertexBuffer->getNumVertices()), 0, 0);
|
||||
}
|
||||
commands.add(std::move(command));
|
||||
}
|
||||
graphics->executeCommands(std::move(commands));
|
||||
graphics->endRenderPass();
|
||||
textResources.clear();
|
||||
//co_return;
|
||||
// co_return;
|
||||
}
|
||||
|
||||
void TextPass::endFrame()
|
||||
{
|
||||
//co_return;
|
||||
void TextPass::endFrame() {
|
||||
// co_return;
|
||||
}
|
||||
|
||||
void TextPass::publishOutputs()
|
||||
{
|
||||
}
|
||||
void TextPass::publishOutputs() {}
|
||||
|
||||
void TextPass::createRenderPass()
|
||||
{
|
||||
void TextPass::createRenderPass() {
|
||||
renderTarget = resources->requestRenderTarget("UIPASS_COLOR");
|
||||
depthAttachment = resources->requestRenderTarget("UIPASS_DEPTH");
|
||||
|
||||
|
||||
ShaderCreateInfo createInfo = {
|
||||
.name = "TextVertex",
|
||||
.mainModule = "TextPass",
|
||||
@@ -118,22 +105,35 @@ void TextPass::createRenderPass()
|
||||
vertexShader = graphics->createVertexShader(createInfo);
|
||||
|
||||
createInfo.name = "TextFragment";
|
||||
createInfo.entryPoint = "fragmentMain";
|
||||
createInfo.entryPoint = "fragmentMain";
|
||||
fragmentShader = graphics->createFragmentShader(createInfo);
|
||||
generalLayout = graphics->createDescriptorLayout("pRender");
|
||||
generalLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 0, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER,});
|
||||
generalLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 1, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLER,});
|
||||
generalLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.binding = 0,
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
||||
});
|
||||
generalLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.binding = 1,
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLER,
|
||||
});
|
||||
generalLayout->create();
|
||||
|
||||
textureArrayLayout = graphics->createDescriptorLayout("pGlyphTextures");
|
||||
textureArrayLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 0, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE, .textureType = Gfx::SE_IMAGE_VIEW_TYPE_2D_ARRAY, .descriptorCount = 256, .bindingFlags = Gfx::SE_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT,});
|
||||
textureArrayLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.binding = 0,
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||
.textureType = Gfx::SE_IMAGE_VIEW_TYPE_2D_ARRAY,
|
||||
.descriptorCount = 256,
|
||||
.bindingFlags = Gfx::SE_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT,
|
||||
});
|
||||
textureArrayLayout->create();
|
||||
|
||||
projectionBuffer = graphics->createUniformBuffer({
|
||||
.sourceData = {
|
||||
.size = sizeof(Matrix4),
|
||||
.data = nullptr,
|
||||
},
|
||||
.sourceData =
|
||||
{
|
||||
.size = sizeof(Matrix4),
|
||||
.data = nullptr,
|
||||
},
|
||||
.dynamic = true,
|
||||
});
|
||||
|
||||
@@ -148,22 +148,17 @@ void TextPass::createRenderPass()
|
||||
generalSet->updateBuffer(0, projectionBuffer);
|
||||
generalSet->updateSampler(1, glyphSampler);
|
||||
generalSet->writeChanges();
|
||||
|
||||
|
||||
pipelineLayout = graphics->createPipelineLayout();
|
||||
pipelineLayout->addDescriptorLayout(generalLayout);
|
||||
pipelineLayout->addDescriptorLayout(textureArrayLayout);
|
||||
pipelineLayout->addPushConstants({
|
||||
.stageFlags = Gfx::SE_SHADER_STAGE_VERTEX_BIT | Gfx::SE_SHADER_STAGE_FRAGMENT_BIT,
|
||||
.offset = 0,
|
||||
.size = sizeof(TextData)});
|
||||
pipelineLayout->addPushConstants(
|
||||
{.stageFlags = Gfx::SE_SHADER_STAGE_VERTEX_BIT | Gfx::SE_SHADER_STAGE_FRAGMENT_BIT, .offset = 0, .size = sizeof(TextData)});
|
||||
pipelineLayout->create();
|
||||
|
||||
Gfx::RenderTargetLayout layout = Gfx::RenderTargetLayout{
|
||||
.colorAttachments = {renderTarget},
|
||||
.depthAttachment = depthAttachment
|
||||
};
|
||||
Gfx::RenderTargetLayout layout = Gfx::RenderTargetLayout{.colorAttachments = {renderTarget}, .depthAttachment = depthAttachment};
|
||||
renderPass = graphics->createRenderPass(std::move(layout), {}, viewport);
|
||||
|
||||
|
||||
Gfx::LegacyPipelineCreateInfo pipelineInfo;
|
||||
pipelineInfo.vertexShader = vertexShader;
|
||||
pipelineInfo.fragmentShader = fragmentShader;
|
||||
@@ -172,7 +167,8 @@ void TextPass::createRenderPass()
|
||||
pipelineInfo.rasterizationState.cullMode = Gfx::SE_CULL_MODE_NONE;
|
||||
pipelineInfo.colorBlend.attachmentCount = 1;
|
||||
pipelineInfo.colorBlend.blendAttachments[0].blendEnable = true;
|
||||
pipelineInfo.colorBlend.blendAttachments[0].colorWriteMask = Gfx::SE_COLOR_COMPONENT_R_BIT | Gfx::SE_COLOR_COMPONENT_G_BIT | Gfx::SE_COLOR_COMPONENT_B_BIT | Gfx::SE_COLOR_COMPONENT_A_BIT;
|
||||
pipelineInfo.colorBlend.blendAttachments[0].colorWriteMask =
|
||||
Gfx::SE_COLOR_COMPONENT_R_BIT | Gfx::SE_COLOR_COMPONENT_G_BIT | Gfx::SE_COLOR_COMPONENT_B_BIT | Gfx::SE_COLOR_COMPONENT_A_BIT;
|
||||
pipelineInfo.colorBlend.blendAttachments[0].srcColorBlendFactor = Gfx::SE_BLEND_FACTOR_SRC_ALPHA;
|
||||
pipelineInfo.colorBlend.blendAttachments[0].dstColorBlendFactor = Gfx::SE_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
|
||||
pipelineInfo.colorBlend.blendAttachments[0].alphaBlendOp = Gfx::SE_BLEND_OP_ADD;
|
||||
@@ -183,19 +179,16 @@ void TextPass::createRenderPass()
|
||||
|
||||
pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
|
||||
}
|
||||
TextPass::FontData& TextPass::getFontData(PFontAsset font)
|
||||
{
|
||||
if(fontData.exists(font))
|
||||
{
|
||||
TextPass::FontData& TextPass::getFontData(PFontAsset font) {
|
||||
if (fontData.exists(font)) {
|
||||
return fontData[font];
|
||||
}
|
||||
}
|
||||
const auto& fontGlyphs = font->getGlyphData();
|
||||
FontData& fd = fontData[font];
|
||||
Array<GlyphData> glyphData;
|
||||
Array<Gfx::PTexture> textures;
|
||||
glyphData.reserve(fontGlyphs.size());
|
||||
for(const auto& [key, value] : fontGlyphs)
|
||||
{
|
||||
for (const auto& [key, value] : fontGlyphs) {
|
||||
fd.characterToGlyphIndex[key] = static_cast<uint32>(glyphData.size());
|
||||
GlyphData& gd = glyphData.add();
|
||||
gd.bearing = value.bearing;
|
||||
@@ -204,7 +197,7 @@ TextPass::FontData& TextPass::getFontData(PFontAsset font)
|
||||
textures.add(font->getTexture(value.textureIndex));
|
||||
}
|
||||
fd.glyphDataSet = glyphData;
|
||||
|
||||
|
||||
textureArrayLayout->reset();
|
||||
fd.textureArraySet = textureArrayLayout->allocateDescriptorSet();
|
||||
fd.textureArraySet->updateTextureArray(0, textures);
|
||||
|
||||
@@ -1,24 +1,22 @@
|
||||
#pragma once
|
||||
#include "RenderPass.h"
|
||||
#include "UI/RenderHierarchy.h"
|
||||
#include "Asset/FontAsset.h"
|
||||
#include "Graphics/Shader.h"
|
||||
#include "RenderPass.h"
|
||||
#include "UI/RenderHierarchy.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
|
||||
namespace Seele {
|
||||
DECLARE_NAME_REF(Gfx, Texture2D)
|
||||
DECLARE_NAME_REF(Gfx, ShaderBuffer)
|
||||
struct TextRender
|
||||
{
|
||||
struct TextRender {
|
||||
std::string text;
|
||||
PFontAsset font;
|
||||
Vector4 textColor;
|
||||
Vector2 position;
|
||||
float scale;
|
||||
};
|
||||
class TextPass : public RenderPass
|
||||
{
|
||||
public:
|
||||
class TextPass : public RenderPass {
|
||||
public:
|
||||
TextPass(Gfx::PGraphics graphics, PScene scene);
|
||||
TextPass(TextPass&&) = default;
|
||||
TextPass& operator=(TextPass&&) = default;
|
||||
@@ -28,26 +26,23 @@ public:
|
||||
virtual void endFrame() override;
|
||||
virtual void publishOutputs() override;
|
||||
virtual void createRenderPass() override;
|
||||
private:
|
||||
struct GlyphData
|
||||
{
|
||||
|
||||
private:
|
||||
struct GlyphData {
|
||||
Vector2 bearing;
|
||||
Vector2 size;
|
||||
uint32 advance;
|
||||
};
|
||||
struct GlyphInstanceData
|
||||
{
|
||||
struct GlyphInstanceData {
|
||||
Vector2 position;
|
||||
Vector2 widthHeight;
|
||||
uint32 glyphIndex;
|
||||
};
|
||||
struct TextData
|
||||
{
|
||||
struct TextData {
|
||||
Vector4 textColor;
|
||||
float scale;
|
||||
};
|
||||
struct FontData
|
||||
{
|
||||
struct FontData {
|
||||
Gfx::PDescriptorSet textureArraySet;
|
||||
Array<GlyphData> glyphDataSet;
|
||||
Map<uint32, uint32> characterToGlyphIndex;
|
||||
@@ -55,8 +50,7 @@ private:
|
||||
FontData& getFontData(PFontAsset font);
|
||||
Map<PFontAsset, FontData> fontData;
|
||||
|
||||
struct TextResources
|
||||
{
|
||||
struct TextResources {
|
||||
Gfx::PShaderBuffer instanceBuffer;
|
||||
Gfx::PDescriptorSet textureArraySet;
|
||||
TextData textData;
|
||||
|
||||
@@ -1,30 +1,21 @@
|
||||
#include "UIPass.h"
|
||||
#include "Graphics/Command.h"
|
||||
#include "Graphics/Enums.h"
|
||||
#include "RenderGraph.h"
|
||||
#include "Graphics/Graphics.h"
|
||||
#include "Graphics/RenderTarget.h"
|
||||
#include "Graphics/Command.h"
|
||||
#include "RenderGraph.h"
|
||||
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
UIPass::UIPass(Gfx::PGraphics graphics, PScene scene)
|
||||
: RenderPass(graphics, scene)
|
||||
{
|
||||
}
|
||||
UIPass::UIPass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics, scene) {}
|
||||
|
||||
UIPass::~UIPass()
|
||||
{
|
||||
|
||||
}
|
||||
UIPass::~UIPass() {}
|
||||
|
||||
void UIPass::beginFrame(const Component::Camera& cam)
|
||||
{
|
||||
void UIPass::beginFrame(const Component::Camera& cam) {
|
||||
RenderPass::beginFrame(cam);
|
||||
VertexBufferCreateInfo info = {
|
||||
.sourceData = {
|
||||
.size = (uint32)(sizeof(UI::RenderElementStyle) * renderElements.size()),
|
||||
.data = (uint8*)renderElements.data()
|
||||
},
|
||||
.sourceData = {.size = (uint32)(sizeof(UI::RenderElementStyle) * renderElements.size()), .data = (uint8*)renderElements.data()},
|
||||
.vertexSize = sizeof(UI::RenderElementStyle),
|
||||
.numVertices = (uint32)renderElements.size(),
|
||||
};
|
||||
@@ -37,11 +28,10 @@ void UIPass::beginFrame(const Component::Camera& cam)
|
||||
descriptorSet->updateBuffer(2, numTexturesBuffer);
|
||||
descriptorSet->updateTextureArray(3, usedTextures);
|
||||
descriptorSet->writeChanges();
|
||||
//co_return;
|
||||
// co_return;
|
||||
}
|
||||
|
||||
void UIPass::render()
|
||||
{
|
||||
void UIPass::render() {
|
||||
graphics->beginRenderPass(renderPass);
|
||||
Gfx::ORenderCommand command = graphics->createRenderCommand("UIPassCommand");
|
||||
command->setViewport(viewport);
|
||||
@@ -53,17 +43,15 @@ void UIPass::render()
|
||||
commands.add(std::move(command));
|
||||
graphics->executeCommands(std::move(commands));
|
||||
graphics->endRenderPass();
|
||||
|
||||
//co_return;
|
||||
|
||||
// co_return;
|
||||
}
|
||||
|
||||
void UIPass::endFrame()
|
||||
{
|
||||
//co_return;
|
||||
void UIPass::endFrame() {
|
||||
// co_return;
|
||||
}
|
||||
|
||||
void UIPass::publishOutputs()
|
||||
{
|
||||
void UIPass::publishOutputs() {
|
||||
TextureCreateInfo depthBufferInfo = {
|
||||
.format = Gfx::SE_FORMAT_D32_SFLOAT,
|
||||
.width = viewport->getWidth(),
|
||||
@@ -72,10 +60,9 @@ void UIPass::publishOutputs()
|
||||
};
|
||||
|
||||
depthBuffer = graphics->createTexture2D(depthBufferInfo);
|
||||
depthAttachment =
|
||||
Gfx::RenderTargetAttachment(depthBuffer,
|
||||
Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
|
||||
Gfx::SE_ATTACHMENT_LOAD_OP_CLEAR, Gfx::SE_ATTACHMENT_STORE_OP_STORE);
|
||||
depthAttachment =
|
||||
Gfx::RenderTargetAttachment(depthBuffer, Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
|
||||
Gfx::SE_ATTACHMENT_LOAD_OP_CLEAR, Gfx::SE_ATTACHMENT_STORE_OP_STORE);
|
||||
resources->registerRenderPassOutput("UIPASS_DEPTH", depthAttachment);
|
||||
|
||||
TextureCreateInfo colorBufferInfo = {
|
||||
@@ -85,16 +72,14 @@ void UIPass::publishOutputs()
|
||||
.usage = Gfx::SE_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
|
||||
};
|
||||
colorBuffer = graphics->createTexture2D(colorBufferInfo);
|
||||
renderTarget =
|
||||
Gfx::RenderTargetAttachment(colorBuffer,
|
||||
Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
Gfx::SE_ATTACHMENT_LOAD_OP_CLEAR, Gfx::SE_ATTACHMENT_STORE_OP_STORE);
|
||||
renderTarget.clear.color = { {0.0f, 0.0f, 0.0f, 1.0f} };
|
||||
renderTarget = Gfx::RenderTargetAttachment(colorBuffer, Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, Gfx::SE_ATTACHMENT_LOAD_OP_CLEAR,
|
||||
Gfx::SE_ATTACHMENT_STORE_OP_STORE);
|
||||
renderTarget.clear.color = {{0.0f, 0.0f, 0.0f, 1.0f}};
|
||||
resources->registerRenderPassOutput("UIPASS_COLOR", renderTarget);
|
||||
}
|
||||
|
||||
void UIPass::createRenderPass()
|
||||
{
|
||||
void UIPass::createRenderPass() {
|
||||
ShaderCreateInfo createInfo = {
|
||||
.name = "UIVertex",
|
||||
.mainModule = "UIPass",
|
||||
@@ -103,32 +88,45 @@ void UIPass::createRenderPass()
|
||||
vertexShader = graphics->createVertexShader(createInfo);
|
||||
|
||||
createInfo.name = "UIFragment";
|
||||
createInfo.entryPoint = "fragmentMain";
|
||||
createInfo.entryPoint = "fragmentMain";
|
||||
fragmentShader = graphics->createFragmentShader(createInfo);
|
||||
|
||||
descriptorLayout = graphics->createDescriptorLayout("pParams");
|
||||
descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 0, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER,});
|
||||
descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 1, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLER,});
|
||||
descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 2, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER,});
|
||||
descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 3, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE, .textureType = Gfx::SE_IMAGE_VIEW_TYPE_2D_ARRAY, .descriptorCount = 256, .bindingFlags = Gfx::SE_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT | Gfx::SE_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT,});
|
||||
descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.binding = 0,
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
||||
});
|
||||
descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.binding = 1,
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLER,
|
||||
});
|
||||
descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.binding = 2,
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
||||
});
|
||||
descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.binding = 3,
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||
.textureType = Gfx::SE_IMAGE_VIEW_TYPE_2D_ARRAY,
|
||||
.descriptorCount = 256,
|
||||
.bindingFlags = Gfx::SE_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT | Gfx::SE_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT,
|
||||
});
|
||||
descriptorLayout->create();
|
||||
|
||||
Matrix4 projectionMatrix = glm::ortho(0, 1, 1, 0);
|
||||
UniformBufferCreateInfo info = {
|
||||
.sourceData = {
|
||||
.size = sizeof(Matrix4),
|
||||
.data = (uint8*)&projectionMatrix,
|
||||
},
|
||||
.sourceData =
|
||||
{
|
||||
.size = sizeof(Matrix4),
|
||||
.data = (uint8*)&projectionMatrix,
|
||||
},
|
||||
.dynamic = false,
|
||||
};
|
||||
Gfx::OUniformBuffer uniformBuffer = graphics->createUniformBuffer(info);
|
||||
Gfx::OSampler backgroundSampler = graphics->createSampler({});
|
||||
|
||||
info = {
|
||||
.sourceData = {
|
||||
.size = sizeof(uint32),
|
||||
.data = nullptr
|
||||
},
|
||||
.sourceData = {.size = sizeof(uint32), .data = nullptr},
|
||||
.dynamic = true,
|
||||
};
|
||||
|
||||
@@ -143,12 +141,9 @@ void UIPass::createRenderPass()
|
||||
pipelineLayout->addDescriptorLayout(descriptorLayout);
|
||||
pipelineLayout->create();
|
||||
|
||||
Gfx::RenderTargetLayout layout = Gfx::RenderTargetLayout{
|
||||
.colorAttachments = { renderTarget },
|
||||
.depthAttachment = depthAttachment
|
||||
};
|
||||
Gfx::RenderTargetLayout layout = Gfx::RenderTargetLayout{.colorAttachments = {renderTarget}, .depthAttachment = depthAttachment};
|
||||
renderPass = graphics->createRenderPass(std::move(layout), {}, viewport);
|
||||
|
||||
|
||||
Gfx::LegacyPipelineCreateInfo pipelineInfo;
|
||||
pipelineInfo.vertexShader = vertexShader;
|
||||
pipelineInfo.fragmentShader = fragmentShader;
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
#pragma once
|
||||
#include "Graphics/Shader.h"
|
||||
#include "RenderPass.h"
|
||||
#include "UI/RenderHierarchy.h"
|
||||
#include "Graphics/Shader.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
|
||||
namespace Seele {
|
||||
DECLARE_NAME_REF(Gfx, Texture2D)
|
||||
DECLARE_NAME_REF(Gfx, RenderTargetAttachment)
|
||||
class UIPass : public RenderPass
|
||||
{
|
||||
public:
|
||||
class UIPass : public RenderPass {
|
||||
public:
|
||||
UIPass(Gfx::PGraphics graphics, PScene scene);
|
||||
UIPass(UIPass&&) = default;
|
||||
UIPass& operator=(UIPass&&) = default;
|
||||
@@ -19,7 +18,8 @@ public:
|
||||
virtual void endFrame() override;
|
||||
virtual void publishOutputs() override;
|
||||
virtual void createRenderPass() override;
|
||||
private:
|
||||
|
||||
private:
|
||||
Gfx::RenderTargetAttachment renderTarget;
|
||||
Gfx::OTexture2D colorBuffer;
|
||||
Gfx::RenderTargetAttachment depthAttachment;
|
||||
|
||||
@@ -5,64 +5,44 @@ using namespace Seele;
|
||||
|
||||
extern bool resetVisibility;
|
||||
|
||||
VisibilityPass::VisibilityPass(Gfx::PGraphics graphics, PScene scene)
|
||||
: RenderPass(graphics, scene)
|
||||
{
|
||||
}
|
||||
VisibilityPass::VisibilityPass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics, scene) {}
|
||||
|
||||
VisibilityPass::~VisibilityPass()
|
||||
{
|
||||
VisibilityPass::~VisibilityPass() {}
|
||||
|
||||
}
|
||||
|
||||
void VisibilityPass::beginFrame(const Component::Camera& cam)
|
||||
{
|
||||
void VisibilityPass::beginFrame(const Component::Camera& cam) {
|
||||
RenderPass::beginFrame(cam);
|
||||
cullingBuffer->rotateBuffer(VertexData::getMeshletCount() * sizeof(VertexData::MeshletCullingInfo), true);
|
||||
if (resetVisibility)
|
||||
{
|
||||
if (resetVisibility) {
|
||||
Array<VertexData::MeshletCullingInfo> cullingData(VertexData::getMeshletCount());
|
||||
std::memset(cullingData.data(), 0xffff, cullingData.size() * sizeof(VertexData::MeshletCullingInfo));
|
||||
|
||||
cullingBuffer->updateContents(ShaderBufferCreateInfo{
|
||||
.sourceData = {
|
||||
.size = VertexData::getMeshletCount() * sizeof(VertexData::MeshletCullingInfo),
|
||||
.data = (uint8 *)cullingData.data(),
|
||||
},
|
||||
.numElements = VertexData::getMeshletCount()});
|
||||
cullingBuffer->pipelineBarrier(
|
||||
Gfx::SE_ACCESS_TRANSFER_WRITE_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
Gfx::SE_ACCESS_MEMORY_WRITE_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
|
||||
cullingBuffer->updateContents(
|
||||
ShaderBufferCreateInfo{.sourceData =
|
||||
{
|
||||
.size = VertexData::getMeshletCount() * sizeof(VertexData::MeshletCullingInfo),
|
||||
.data = (uint8*)cullingData.data(),
|
||||
},
|
||||
.numElements = VertexData::getMeshletCount()});
|
||||
cullingBuffer->pipelineBarrier(Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
Gfx::SE_ACCESS_MEMORY_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
|
||||
|
||||
resetVisibility = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void VisibilityPass::render()
|
||||
{
|
||||
cullingBuffer->pipelineBarrier(
|
||||
Gfx::SE_ACCESS_SHADER_READ_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_MESH_SHADER_BIT_EXT,
|
||||
Gfx::SE_ACCESS_TRANSFER_WRITE_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT
|
||||
);
|
||||
void VisibilityPass::render() {
|
||||
cullingBuffer->pipelineBarrier(Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_MESH_SHADER_BIT_EXT,
|
||||
Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT);
|
||||
cullingBuffer->clear();
|
||||
cullingBuffer->pipelineBarrier(
|
||||
Gfx::SE_ACCESS_TRANSFER_WRITE_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
Gfx::SE_ACCESS_SHADER_READ_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT
|
||||
);
|
||||
cullingBuffer->pipelineBarrier(Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||
|
||||
visibilityDescriptor->reset();
|
||||
visibilitySet = visibilityDescriptor->allocateDescriptorSet();
|
||||
visibilitySet->updateTexture(0, visibilityAttachment.getTexture());
|
||||
visibilitySet->updateBuffer(1, cullingBuffer);
|
||||
visibilitySet->writeChanges();
|
||||
|
||||
|
||||
Gfx::OComputeCommand command = graphics->createComputeCommand("VisibilityCommand");
|
||||
command->bindPipeline(visibilityPipeline);
|
||||
command->bindDescriptor({viewParamsSet, visibilitySet});
|
||||
@@ -71,33 +51,33 @@ void VisibilityPass::render()
|
||||
commands.add(std::move(command));
|
||||
graphics->executeCommands(std::move(commands));
|
||||
|
||||
cullingBuffer->pipelineBarrier(
|
||||
Gfx::SE_ACCESS_SHADER_WRITE_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||
Gfx::SE_ACCESS_SHADER_READ_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_TASK_SHADER_BIT_EXT | Gfx::SE_PIPELINE_STAGE_MESH_SHADER_BIT_EXT
|
||||
);
|
||||
cullingBuffer->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||
Gfx::SE_ACCESS_SHADER_READ_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_TASK_SHADER_BIT_EXT | Gfx::SE_PIPELINE_STAGE_MESH_SHADER_BIT_EXT);
|
||||
}
|
||||
|
||||
void VisibilityPass::endFrame()
|
||||
{
|
||||
void VisibilityPass::endFrame() {}
|
||||
|
||||
}
|
||||
|
||||
void VisibilityPass::publishOutputs()
|
||||
{
|
||||
void VisibilityPass::publishOutputs() {
|
||||
uint32_t viewportWidth = viewport->getWidth();
|
||||
uint32_t viewportHeight = viewport->getHeight();
|
||||
threadGroupSize = glm::ceil(glm::vec3(viewportWidth / (float)BLOCK_SIZE, viewportHeight / (float)BLOCK_SIZE, 1));
|
||||
visibilityDescriptor = graphics->createDescriptorLayout("pVisibilityParams");
|
||||
visibilityDescriptor->addDescriptorBinding(Gfx::DescriptorBinding{ .binding = 0, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE, });
|
||||
visibilityDescriptor->addDescriptorBinding(Gfx::DescriptorBinding{ .binding = 1, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER, .access = Gfx::SE_DESCRIPTOR_ACCESS_READ_WRITE_BIT, });
|
||||
visibilityDescriptor->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.binding = 0,
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||
});
|
||||
visibilityDescriptor->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.binding = 1,
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
.access = Gfx::SE_DESCRIPTOR_ACCESS_READ_WRITE_BIT,
|
||||
});
|
||||
visibilityDescriptor->create();
|
||||
|
||||
visibilityLayout = graphics->createPipelineLayout("VisibilityLayout");
|
||||
visibilityLayout->addDescriptorLayout(viewParamsLayout);
|
||||
visibilityLayout->addDescriptorLayout(visibilityDescriptor);
|
||||
|
||||
|
||||
ShaderCreateInfo createInfo = {
|
||||
.name = "Visibility",
|
||||
.mainModule = "VisibilityCompute",
|
||||
@@ -116,7 +96,4 @@ void VisibilityPass::publishOutputs()
|
||||
resources->registerBufferOutput("CULLINGBUFFER", cullingBuffer);
|
||||
}
|
||||
|
||||
void VisibilityPass::createRenderPass()
|
||||
{
|
||||
visibilityAttachment = resources->requestRenderTarget("VISIBILITY");
|
||||
}
|
||||
void VisibilityPass::createRenderPass() { visibilityAttachment = resources->requestRenderTarget("VISIBILITY"); }
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
#pragma once
|
||||
#include "RenderPass.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
class VisibilityPass : public RenderPass
|
||||
{
|
||||
public:
|
||||
namespace Seele {
|
||||
class VisibilityPass : public RenderPass {
|
||||
public:
|
||||
VisibilityPass(Gfx::PGraphics graphics, PScene scene);
|
||||
VisibilityPass(VisibilityPass&&) = default;
|
||||
VisibilityPass& operator=(VisibilityPass&&) = default;
|
||||
@@ -15,7 +13,8 @@ public:
|
||||
virtual void endFrame() override;
|
||||
virtual void publishOutputs() override;
|
||||
virtual void createRenderPass() override;
|
||||
private:
|
||||
|
||||
private:
|
||||
static constexpr uint32 BLOCK_SIZE = 32;
|
||||
Gfx::RenderTargetAttachment visibilityAttachment;
|
||||
Gfx::PDescriptorSet visibilitySet;
|
||||
@@ -29,4 +28,4 @@ private:
|
||||
glm::uvec3 threadGroupSize;
|
||||
};
|
||||
DEFINE_REF(VisibilityPass)
|
||||
}
|
||||
} // namespace Seele
|
||||
@@ -3,44 +3,16 @@
|
||||
using namespace Seele;
|
||||
using namespace Seele::Gfx;
|
||||
|
||||
RenderTargetAttachment::RenderTargetAttachment(PTexture2D texture,
|
||||
SeImageLayout initialLayout,
|
||||
SeImageLayout finalLayout,
|
||||
SeAttachmentLoadOp loadOp,
|
||||
SeAttachmentStoreOp storeOp,
|
||||
SeAttachmentLoadOp stencilLoadOp,
|
||||
SeAttachmentStoreOp stencilStoreOp)
|
||||
: clear()
|
||||
, componentFlags(0)
|
||||
, texture(texture)
|
||||
, initialLayout(initialLayout)
|
||||
, finalLayout(finalLayout)
|
||||
, loadOp(loadOp)
|
||||
, storeOp(storeOp)
|
||||
, stencilLoadOp(stencilLoadOp)
|
||||
, stencilStoreOp(stencilStoreOp)
|
||||
{
|
||||
}
|
||||
RenderTargetAttachment::RenderTargetAttachment(PTexture2D texture, SeImageLayout initialLayout, SeImageLayout finalLayout,
|
||||
SeAttachmentLoadOp loadOp, SeAttachmentStoreOp storeOp, SeAttachmentLoadOp stencilLoadOp,
|
||||
SeAttachmentStoreOp stencilStoreOp)
|
||||
: clear(), componentFlags(0), texture(texture), initialLayout(initialLayout), finalLayout(finalLayout), loadOp(loadOp),
|
||||
storeOp(storeOp), stencilLoadOp(stencilLoadOp), stencilStoreOp(stencilStoreOp) {}
|
||||
|
||||
RenderTargetAttachment::RenderTargetAttachment(PViewport viewport,
|
||||
SeImageLayout initialLayout,
|
||||
SeImageLayout finalLayout,
|
||||
SeAttachmentLoadOp loadOp,
|
||||
SeAttachmentStoreOp storeOp,
|
||||
SeAttachmentLoadOp stencilLoadOp,
|
||||
SeAttachmentStoreOp stencilStoreOp)
|
||||
: clear()
|
||||
, componentFlags(0)
|
||||
, viewport(viewport)
|
||||
, initialLayout(initialLayout)
|
||||
, finalLayout(finalLayout)
|
||||
, loadOp(loadOp)
|
||||
, storeOp(storeOp)
|
||||
, stencilLoadOp(stencilLoadOp)
|
||||
, stencilStoreOp(stencilStoreOp)
|
||||
{
|
||||
}
|
||||
RenderTargetAttachment::RenderTargetAttachment(PViewport viewport, SeImageLayout initialLayout, SeImageLayout finalLayout,
|
||||
SeAttachmentLoadOp loadOp, SeAttachmentStoreOp storeOp, SeAttachmentLoadOp stencilLoadOp,
|
||||
SeAttachmentStoreOp stencilStoreOp)
|
||||
: clear(), componentFlags(0), viewport(viewport), initialLayout(initialLayout), finalLayout(finalLayout), loadOp(loadOp),
|
||||
storeOp(storeOp), stencilLoadOp(stencilLoadOp), stencilStoreOp(stencilStoreOp) {}
|
||||
|
||||
RenderTargetAttachment::~RenderTargetAttachment()
|
||||
{
|
||||
}
|
||||
RenderTargetAttachment::~RenderTargetAttachment() {}
|
||||
|
||||
@@ -4,70 +4,52 @@
|
||||
#include "Texture.h"
|
||||
#include "Window.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
namespace Gfx
|
||||
{
|
||||
class RenderTargetAttachment
|
||||
{
|
||||
public:
|
||||
RenderTargetAttachment()
|
||||
{}
|
||||
RenderTargetAttachment(PTexture2D texture,
|
||||
SeImageLayout initialLayout,
|
||||
SeImageLayout finalLayout,
|
||||
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);
|
||||
namespace Seele {
|
||||
namespace Gfx {
|
||||
class RenderTargetAttachment {
|
||||
public:
|
||||
RenderTargetAttachment() {}
|
||||
RenderTargetAttachment(PTexture2D texture, SeImageLayout initialLayout, SeImageLayout finalLayout,
|
||||
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(PViewport viewport,
|
||||
SeImageLayout initialLayout,
|
||||
SeImageLayout finalLayout,
|
||||
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(PViewport viewport, SeImageLayout initialLayout, SeImageLayout finalLayout,
|
||||
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();
|
||||
PTexture2D getTexture() const
|
||||
{
|
||||
if(viewport != nullptr)
|
||||
{
|
||||
PTexture2D getTexture() const {
|
||||
if (viewport != nullptr) {
|
||||
return viewport->getOwner()->getBackBuffer();
|
||||
}
|
||||
return texture;
|
||||
}
|
||||
SeFormat getFormat() const
|
||||
{
|
||||
if(viewport != nullptr)
|
||||
{
|
||||
SeFormat getFormat() const {
|
||||
if (viewport != nullptr) {
|
||||
return viewport->getOwner()->getSwapchainFormat();
|
||||
}
|
||||
return texture->getFormat();
|
||||
}
|
||||
SeSampleCountFlags getNumSamples() const
|
||||
{
|
||||
if(viewport != nullptr)
|
||||
{
|
||||
SeSampleCountFlags getNumSamples() const {
|
||||
if (viewport != nullptr) {
|
||||
return viewport->getSamples();
|
||||
}
|
||||
return texture->getNumSamples();
|
||||
}
|
||||
uint32 getWidth() const
|
||||
{
|
||||
if(viewport != nullptr)
|
||||
{
|
||||
uint32 getWidth() const {
|
||||
if (viewport != nullptr) {
|
||||
return viewport->getWidth();
|
||||
}
|
||||
return texture->getWidth();
|
||||
return texture->getWidth();
|
||||
}
|
||||
uint32 getHeight() const
|
||||
{
|
||||
if(viewport != nullptr)
|
||||
{
|
||||
uint32 getHeight() const {
|
||||
if (viewport != nullptr) {
|
||||
return viewport->getHeight();
|
||||
}
|
||||
return texture->getHeight();
|
||||
return texture->getHeight();
|
||||
}
|
||||
constexpr SeAttachmentLoadOp getLoadOp() const { return loadOp; }
|
||||
constexpr SeAttachmentStoreOp getStoreOp() const { return storeOp; }
|
||||
@@ -81,9 +63,10 @@ public:
|
||||
constexpr void setStencilStoreOp(SeAttachmentStoreOp val) { stencilStoreOp = val; }
|
||||
constexpr void setInitialLayout(SeImageLayout val) { initialLayout = val; }
|
||||
constexpr void setFinalLayout(SeImageLayout val) { finalLayout = val; }
|
||||
SeClearValue clear = { { { 0 } } };
|
||||
SeClearValue clear = {{{0}}};
|
||||
SeColorComponentFlags componentFlags = 0;
|
||||
protected:
|
||||
|
||||
protected:
|
||||
PTexture2D texture = nullptr;
|
||||
PViewport viewport = nullptr;
|
||||
SeImageLayout initialLayout = SE_IMAGE_LAYOUT_UNDEFINED;
|
||||
@@ -94,8 +77,7 @@ protected:
|
||||
SeAttachmentStoreOp stencilStoreOp = SE_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||
};
|
||||
|
||||
struct RenderTargetLayout
|
||||
{
|
||||
struct RenderTargetLayout {
|
||||
Array<RenderTargetAttachment> inputAttachments;
|
||||
Array<RenderTargetAttachment> colorAttachments;
|
||||
Array<RenderTargetAttachment> resolveAttachments;
|
||||
@@ -103,8 +85,7 @@ struct RenderTargetLayout
|
||||
RenderTargetAttachment depthResolveAttachment;
|
||||
};
|
||||
|
||||
struct SubPassDependency
|
||||
{
|
||||
struct SubPassDependency {
|
||||
uint32 srcSubpass;
|
||||
uint32 dstSubpass;
|
||||
SePipelineStageFlags srcStage;
|
||||
@@ -113,22 +94,19 @@ struct SubPassDependency
|
||||
SeAccessFlags dstAccess;
|
||||
};
|
||||
|
||||
class RenderPass
|
||||
{
|
||||
public:
|
||||
RenderPass(RenderTargetLayout layout, Array<SubPassDependency> dependencies)
|
||||
: layout(std::move(layout))
|
||||
, dependencies(std::move(dependencies))
|
||||
{}
|
||||
class RenderPass {
|
||||
public:
|
||||
RenderPass(RenderTargetLayout layout, Array<SubPassDependency> dependencies)
|
||||
: layout(std::move(layout)), dependencies(std::move(dependencies)) {}
|
||||
virtual ~RenderPass() {}
|
||||
RenderPass(RenderPass&&) = default;
|
||||
RenderPass& operator=(RenderPass&&) = default;
|
||||
const RenderTargetLayout& getLayout() const { return layout; }
|
||||
|
||||
protected:
|
||||
protected:
|
||||
RenderTargetLayout layout;
|
||||
Array<SubPassDependency> dependencies;
|
||||
};
|
||||
DEFINE_REF(RenderPass)
|
||||
}
|
||||
}
|
||||
} // namespace Gfx
|
||||
} // namespace Seele
|
||||
@@ -1,35 +1,28 @@
|
||||
#include "Resources.h"
|
||||
#include "Graphics.h"
|
||||
#include "RenderPass/DepthPrepass.h"
|
||||
#include "RenderPass/BasePass.h"
|
||||
#include "Material/Material.h"
|
||||
#include "RenderPass/BasePass.h"
|
||||
#include "RenderPass/DepthPrepass.h"
|
||||
#include "Resources.h"
|
||||
|
||||
|
||||
using namespace Seele;
|
||||
using namespace Seele::Gfx;
|
||||
|
||||
QueueOwnedResource::QueueOwnedResource(QueueFamilyMapping mapping, QueueType startQueueType)
|
||||
: currentOwner(startQueueType)
|
||||
, mapping(mapping)
|
||||
{
|
||||
: currentOwner(startQueueType), mapping(mapping) {}
|
||||
|
||||
QueueOwnedResource::~QueueOwnedResource() {}
|
||||
|
||||
void QueueOwnedResource::transferOwnership(QueueType newOwner) {
|
||||
if (mapping.needsTransfer(currentOwner, newOwner)) {
|
||||
executeOwnershipBarrier(newOwner);
|
||||
}
|
||||
currentOwner = newOwner;
|
||||
}
|
||||
|
||||
QueueOwnedResource::~QueueOwnedResource()
|
||||
{
|
||||
void QueueOwnedResource::pipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage, SeAccessFlags dstAccess,
|
||||
SePipelineStageFlags dstStage) {
|
||||
// maybe add some checks
|
||||
executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
|
||||
}
|
||||
|
||||
void QueueOwnedResource::transferOwnership(QueueType newOwner)
|
||||
{
|
||||
if(mapping.needsTransfer(currentOwner, newOwner))
|
||||
{
|
||||
executeOwnershipBarrier(newOwner);
|
||||
}
|
||||
currentOwner = newOwner;
|
||||
}
|
||||
|
||||
void QueueOwnedResource::pipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage, SeAccessFlags dstAccess, SePipelineStageFlags dstStage)
|
||||
{
|
||||
// maybe add some checks
|
||||
executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,41 +1,34 @@
|
||||
#pragma once
|
||||
#include "Math/Math.h"
|
||||
#include "Enums.h"
|
||||
#include "Containers/Array.h"
|
||||
#include "Enums.h"
|
||||
#include "Math/Math.h"
|
||||
|
||||
|
||||
#ifndef ENABLE_VALIDATION
|
||||
#define ENABLE_VALIDATION 1
|
||||
#endif
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
namespace Seele {
|
||||
DECLARE_REF(Material)
|
||||
namespace Gfx
|
||||
{
|
||||
namespace Gfx {
|
||||
DECLARE_REF(DescriptorSet)
|
||||
DECLARE_REF(Graphics)
|
||||
DECLARE_REF(VertexBuffer)
|
||||
DECLARE_REF(IndexBuffer)
|
||||
DECLARE_REF(GraphicsPipeline)
|
||||
DECLARE_REF(ComputePipeline)
|
||||
class Sampler
|
||||
{
|
||||
public:
|
||||
virtual ~Sampler()
|
||||
{
|
||||
}
|
||||
class Sampler {
|
||||
public:
|
||||
virtual ~Sampler() {}
|
||||
};
|
||||
DEFINE_REF(Sampler)
|
||||
|
||||
struct QueueFamilyMapping
|
||||
{
|
||||
struct QueueFamilyMapping {
|
||||
uint32 graphicsFamily;
|
||||
uint32 computeFamily;
|
||||
uint32 transferFamily;
|
||||
uint32 getQueueTypeFamilyIndex(Gfx::QueueType type) const
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
uint32 getQueueTypeFamilyIndex(Gfx::QueueType type) const {
|
||||
switch (type) {
|
||||
case Gfx::QueueType::GRAPHICS:
|
||||
return graphicsFamily;
|
||||
case Gfx::QueueType::COMPUTE:
|
||||
@@ -46,28 +39,26 @@ struct QueueFamilyMapping
|
||||
return 0x7fff;
|
||||
}
|
||||
}
|
||||
bool needsTransfer(Gfx::QueueType src, Gfx::QueueType dst) const
|
||||
{
|
||||
bool needsTransfer(Gfx::QueueType src, Gfx::QueueType dst) const {
|
||||
uint32 srcIndex = getQueueTypeFamilyIndex(src);
|
||||
uint32 dstIndex = getQueueTypeFamilyIndex(dst);
|
||||
return srcIndex != dstIndex;
|
||||
}
|
||||
};
|
||||
|
||||
class QueueOwnedResource
|
||||
{
|
||||
public:
|
||||
class QueueOwnedResource {
|
||||
public:
|
||||
QueueOwnedResource(QueueFamilyMapping mapping, QueueType startQueueType);
|
||||
virtual ~QueueOwnedResource();
|
||||
|
||||
//Preliminary checks to see if the barrier should be executed at all
|
||||
// Preliminary checks to see if the barrier should be executed at all
|
||||
void transferOwnership(QueueType newOwner);
|
||||
void pipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage, SeAccessFlags dstAccess, SePipelineStageFlags dstStage);
|
||||
|
||||
protected:
|
||||
protected:
|
||||
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
|
||||
virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage,
|
||||
SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0;
|
||||
virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage, SeAccessFlags dstAccess,
|
||||
SePipelineStageFlags dstStage) = 0;
|
||||
Gfx::QueueType currentOwner;
|
||||
QueueFamilyMapping mapping;
|
||||
};
|
||||
|
||||
@@ -1,117 +1,90 @@
|
||||
#include "Shader.h"
|
||||
#include "ThreadPool.h"
|
||||
#include "Graphics/Initializer.h"
|
||||
#include "Graphics/RenderPass/DepthPrepass.h"
|
||||
#include "Graphics/RenderPass/BasePass.h"
|
||||
#include "Graphics/RenderPass/DepthPrepass.h"
|
||||
#include "ThreadPool.h"
|
||||
#include <fmt/core.h>
|
||||
|
||||
|
||||
using namespace Seele;
|
||||
using namespace Seele::Gfx;
|
||||
|
||||
ShaderCompiler::ShaderCompiler(Gfx::PGraphics graphics)
|
||||
: graphics(graphics)
|
||||
{
|
||||
}
|
||||
ShaderCompiler::ShaderCompiler(Gfx::PGraphics graphics) : graphics(graphics) {}
|
||||
|
||||
ShaderCompiler::~ShaderCompiler()
|
||||
{
|
||||
}
|
||||
ShaderCompiler::~ShaderCompiler() {}
|
||||
|
||||
const ShaderCollection *ShaderCompiler::findShaders(PermutationId id) const
|
||||
{
|
||||
return &shaders[id];
|
||||
}
|
||||
const ShaderCollection* ShaderCompiler::findShaders(PermutationId id) const { return &shaders[id]; }
|
||||
|
||||
void ShaderCompiler::registerMaterial(PMaterial material)
|
||||
{
|
||||
void ShaderCompiler::registerMaterial(PMaterial material) {
|
||||
materials[material->getName()] = material;
|
||||
compile();
|
||||
}
|
||||
|
||||
void ShaderCompiler::registerVertexData(VertexData *vd)
|
||||
{
|
||||
void ShaderCompiler::registerVertexData(VertexData* vd) {
|
||||
vertexData[vd->getTypeName()] = vd;
|
||||
compile();
|
||||
}
|
||||
|
||||
void ShaderCompiler::registerRenderPass(std::string name, PassConfig config)
|
||||
{
|
||||
void ShaderCompiler::registerRenderPass(std::string name, PassConfig config) {
|
||||
passes[name] = std::move(config);
|
||||
compile();
|
||||
}
|
||||
|
||||
ShaderPermutation ShaderCompiler::getTemplate(std::string name)
|
||||
{
|
||||
ShaderPermutation ShaderCompiler::getTemplate(std::string name) {
|
||||
std::scoped_lock lock(shadersLock);
|
||||
ShaderPermutation permutation;
|
||||
PassConfig &pass = passes[name];
|
||||
if (pass.useMeshShading)
|
||||
{
|
||||
PassConfig& pass = passes[name];
|
||||
if (pass.useMeshShading) {
|
||||
permutation.setMeshFile(pass.mainFile);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
permutation.setVertexFile(pass.mainFile);
|
||||
}
|
||||
if (pass.hasFragmentShader)
|
||||
{
|
||||
if (pass.hasFragmentShader) {
|
||||
permutation.setFragmentFile(pass.fragmentFile);
|
||||
}
|
||||
if (pass.hasTaskShader)
|
||||
{
|
||||
if (pass.hasTaskShader) {
|
||||
permutation.setTaskFile(pass.taskFile);
|
||||
}
|
||||
permutation.setVisibilityPass(pass.useVisibility);
|
||||
return permutation;
|
||||
}
|
||||
|
||||
void ShaderCompiler::compile()
|
||||
{
|
||||
void ShaderCompiler::compile() {
|
||||
List<std::function<void()>> work;
|
||||
for (const auto &[name, pass] : passes)
|
||||
{
|
||||
for (const auto &[vdName, vd] : vertexData)
|
||||
{
|
||||
if (pass.useMaterial)
|
||||
{
|
||||
for (const auto &[matName, mat] : materials)
|
||||
{
|
||||
for (int x = 0; x < 2; x++)
|
||||
{
|
||||
for (int y = 0; y < 2; y++)
|
||||
{
|
||||
work.add([=]()
|
||||
{
|
||||
ShaderPermutation permutation = getTemplate(name);
|
||||
permutation.setPositionOnly(x);
|
||||
permutation.setViewCulling(y);
|
||||
permutation.setVertexData(vd->getTypeName());
|
||||
OPipelineLayout layout = graphics->createPipelineLayout(pass.baseLayout->getName(), pass.baseLayout);
|
||||
layout->addDescriptorLayout(vd->getVertexDataLayout());
|
||||
layout->addDescriptorLayout(vd->getInstanceDataLayout());
|
||||
layout->addDescriptorLayout(mat->getDescriptorLayout());
|
||||
permutation.setMaterial(mat->getName());
|
||||
createShaders(permutation, std::move(layout)); });
|
||||
for (const auto& [name, pass] : passes) {
|
||||
for (const auto& [vdName, vd] : vertexData) {
|
||||
if (pass.useMaterial) {
|
||||
for (const auto& [matName, mat] : materials) {
|
||||
for (int x = 0; x < 2; x++) {
|
||||
for (int y = 0; y < 2; y++) {
|
||||
work.add([=]() {
|
||||
ShaderPermutation permutation = getTemplate(name);
|
||||
permutation.setPositionOnly(x);
|
||||
permutation.setViewCulling(y);
|
||||
permutation.setVertexData(vd->getTypeName());
|
||||
OPipelineLayout layout = graphics->createPipelineLayout(pass.baseLayout->getName(), pass.baseLayout);
|
||||
layout->addDescriptorLayout(vd->getVertexDataLayout());
|
||||
layout->addDescriptorLayout(vd->getInstanceDataLayout());
|
||||
layout->addDescriptorLayout(mat->getDescriptorLayout());
|
||||
permutation.setMaterial(mat->getName());
|
||||
createShaders(permutation, std::move(layout));
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int x = 0; x < 2; x++)
|
||||
{
|
||||
for (int y = 0; y < 2; y++)
|
||||
{
|
||||
work.add([=]()
|
||||
{
|
||||
ShaderPermutation permutation = getTemplate(name);
|
||||
permutation.setPositionOnly(x);
|
||||
permutation.setViewCulling(y);
|
||||
permutation.setVertexData(vd->getTypeName());
|
||||
OPipelineLayout layout = graphics->createPipelineLayout(pass.baseLayout->getName(), pass.baseLayout);
|
||||
layout->addDescriptorLayout(vd->getVertexDataLayout());
|
||||
layout->addDescriptorLayout(vd->getInstanceDataLayout());
|
||||
createShaders(permutation, std::move(layout)); });
|
||||
} else {
|
||||
for (int x = 0; x < 2; x++) {
|
||||
for (int y = 0; y < 2; y++) {
|
||||
work.add([=]() {
|
||||
ShaderPermutation permutation = getTemplate(name);
|
||||
permutation.setPositionOnly(x);
|
||||
permutation.setViewCulling(y);
|
||||
permutation.setVertexData(vd->getTypeName());
|
||||
OPipelineLayout layout = graphics->createPipelineLayout(pass.baseLayout->getName(), pass.baseLayout);
|
||||
layout->addDescriptorLayout(vd->getVertexDataLayout());
|
||||
layout->addDescriptorLayout(vd->getInstanceDataLayout());
|
||||
createShaders(permutation, std::move(layout));
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -120,8 +93,7 @@ void ShaderCompiler::compile()
|
||||
getThreadPool().runAndWait(std::move(work));
|
||||
}
|
||||
|
||||
void ShaderCompiler::createShaders(ShaderPermutation permutation, Gfx::OPipelineLayout layout)
|
||||
{
|
||||
void ShaderCompiler::createShaders(ShaderPermutation permutation, Gfx::OPipelineLayout layout) {
|
||||
PermutationId perm = PermutationId(permutation);
|
||||
{
|
||||
std::scoped_lock lock(shadersLock);
|
||||
@@ -134,30 +106,24 @@ void ShaderCompiler::createShaders(ShaderPermutation permutation, Gfx::OPipeline
|
||||
ShaderCreateInfo createInfo;
|
||||
createInfo.name = fmt::format("Material {0}", permutation.materialName);
|
||||
createInfo.rootSignature = collection.pipelineLayout;
|
||||
if (std::strlen(permutation.materialName) > 0)
|
||||
{
|
||||
if (std::strlen(permutation.materialName) > 0) {
|
||||
createInfo.additionalModules.add(permutation.materialName);
|
||||
createInfo.defines["MATERIAL_FILE_NAME"] = permutation.materialName;
|
||||
}
|
||||
if (permutation.positionOnly)
|
||||
{
|
||||
if (permutation.positionOnly) {
|
||||
createInfo.defines["POS_ONLY"] = "1";
|
||||
}
|
||||
if (permutation.viewCulling)
|
||||
{
|
||||
if (permutation.viewCulling) {
|
||||
createInfo.defines["VIEW_CULLING"] = "1";
|
||||
}
|
||||
if (permutation.visibilityPass)
|
||||
{
|
||||
if (permutation.visibilityPass) {
|
||||
createInfo.defines["VISIBILITY"] = "1";
|
||||
}
|
||||
createInfo.typeParameter.add({Pair<const char *, const char *>("IVertexData", permutation.vertexDataName)});
|
||||
createInfo.typeParameter.add({Pair<const char*, const char*>("IVertexData", permutation.vertexDataName)});
|
||||
createInfo.additionalModules.add(permutation.vertexDataName);
|
||||
|
||||
if (permutation.useMeshShading)
|
||||
{
|
||||
if (permutation.hasTaskShader)
|
||||
{
|
||||
if (permutation.useMeshShading) {
|
||||
if (permutation.hasTaskShader) {
|
||||
createInfo.mainModule = permutation.taskFile;
|
||||
createInfo.entryPoint = "taskMain";
|
||||
collection.taskShader = graphics->createTaskShader(createInfo);
|
||||
@@ -165,16 +131,13 @@ void ShaderCompiler::createShaders(ShaderPermutation permutation, Gfx::OPipeline
|
||||
createInfo.mainModule = permutation.vertexMeshFile;
|
||||
createInfo.entryPoint = "meshMain";
|
||||
collection.meshShader = graphics->createMeshShader(createInfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
createInfo.mainModule = permutation.vertexMeshFile;
|
||||
createInfo.entryPoint = "vertexMain";
|
||||
collection.vertexShader = graphics->createVertexShader(createInfo);
|
||||
}
|
||||
|
||||
if (permutation.hasFragment)
|
||||
{
|
||||
if (permutation.hasFragment) {
|
||||
createInfo.mainModule = permutation.fragmentFile;
|
||||
createInfo.entryPoint = "fragmentMain";
|
||||
collection.fragmentShader = graphics->createFragmentShader(createInfo);
|
||||
|
||||
@@ -1,58 +1,50 @@
|
||||
#pragma once
|
||||
#include "Enums.h"
|
||||
#include "CRC.h"
|
||||
#include "Enums.h"
|
||||
#include "Resources.h"
|
||||
#include "VertexData.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
namespace Gfx
|
||||
{
|
||||
|
||||
class Shader
|
||||
{};
|
||||
namespace Seele {
|
||||
namespace Gfx {
|
||||
|
||||
class Shader {};
|
||||
DEFINE_REF(Shader)
|
||||
class TaskShader
|
||||
{
|
||||
public:
|
||||
class TaskShader {
|
||||
public:
|
||||
TaskShader() {}
|
||||
virtual ~TaskShader() {}
|
||||
};
|
||||
DEFINE_REF(TaskShader)
|
||||
class MeshShader
|
||||
{
|
||||
public:
|
||||
class MeshShader {
|
||||
public:
|
||||
MeshShader() {}
|
||||
virtual ~MeshShader() {}
|
||||
};
|
||||
DEFINE_REF(MeshShader)
|
||||
class VertexShader
|
||||
{
|
||||
public:
|
||||
class VertexShader {
|
||||
public:
|
||||
VertexShader() {}
|
||||
virtual ~VertexShader() {}
|
||||
};
|
||||
DEFINE_REF(VertexShader)
|
||||
class FragmentShader
|
||||
{
|
||||
public:
|
||||
class FragmentShader {
|
||||
public:
|
||||
FragmentShader() {}
|
||||
virtual ~FragmentShader() {}
|
||||
};
|
||||
DEFINE_REF(FragmentShader)
|
||||
|
||||
class ComputeShader
|
||||
{
|
||||
public:
|
||||
class ComputeShader {
|
||||
public:
|
||||
ComputeShader() {}
|
||||
virtual ~ComputeShader() {}
|
||||
};
|
||||
DEFINE_REF(ComputeShader)
|
||||
|
||||
//Uniquely identifies a permutation of shaders
|
||||
//using the type parameters used to generate it
|
||||
struct ShaderPermutation
|
||||
{
|
||||
// Uniquely identifies a permutation of shaders
|
||||
// using the type parameters used to generate it
|
||||
struct ShaderPermutation {
|
||||
char taskFile[32];
|
||||
char vertexMeshFile[32];
|
||||
char fragmentFile[32];
|
||||
@@ -65,80 +57,50 @@ struct ShaderPermutation
|
||||
uint8 positionOnly;
|
||||
uint8 viewCulling;
|
||||
uint8 visibilityPass;
|
||||
//TODO: lightmapping etc
|
||||
ShaderPermutation()
|
||||
{
|
||||
std::memset(this, 0, sizeof(ShaderPermutation));
|
||||
}
|
||||
void setTaskFile(std::string_view name)
|
||||
{
|
||||
// TODO: lightmapping etc
|
||||
ShaderPermutation() { std::memset(this, 0, sizeof(ShaderPermutation)); }
|
||||
void setTaskFile(std::string_view name) {
|
||||
std::memset(taskFile, 0, sizeof(taskFile));
|
||||
hasTaskShader = 1;
|
||||
strncpy(taskFile, name.data(), sizeof(taskFile));
|
||||
}
|
||||
void setVertexFile(std::string_view name)
|
||||
{
|
||||
void setVertexFile(std::string_view name) {
|
||||
std::memset(vertexMeshFile, 0, sizeof(vertexMeshFile));
|
||||
useMeshShading = 0;
|
||||
strncpy(vertexMeshFile, name.data(), sizeof(vertexMeshFile));
|
||||
}
|
||||
void setMeshFile(std::string_view name)
|
||||
{
|
||||
void setMeshFile(std::string_view name) {
|
||||
std::memset(vertexMeshFile, 0, sizeof(vertexMeshFile));
|
||||
useMeshShading = 1;
|
||||
strncpy(vertexMeshFile, name.data(), sizeof(vertexMeshFile));
|
||||
}
|
||||
void setFragmentFile(std::string_view name)
|
||||
{
|
||||
void setFragmentFile(std::string_view name) {
|
||||
std::memset(fragmentFile, 0, sizeof(fragmentFile));
|
||||
hasFragment = 1;
|
||||
strncpy(fragmentFile, name.data(), sizeof(fragmentFile));
|
||||
}
|
||||
void setVertexData(std::string_view name)
|
||||
{
|
||||
void setVertexData(std::string_view name) {
|
||||
std::memset(vertexDataName, 0, sizeof(vertexDataName));
|
||||
strncpy(vertexDataName, name.data(), sizeof(vertexDataName));
|
||||
}
|
||||
void setMaterial(std::string_view name)
|
||||
{
|
||||
void setMaterial(std::string_view name) {
|
||||
std::memset(materialName, 0, sizeof(materialName));
|
||||
useMaterial = 1;
|
||||
strncpy(materialName, name.data(), sizeof(materialName));
|
||||
}
|
||||
void setPositionOnly(bool enable)
|
||||
{
|
||||
positionOnly = enable;
|
||||
}
|
||||
void setViewCulling(bool enable)
|
||||
{
|
||||
viewCulling = enable;
|
||||
}
|
||||
void setVisibilityPass(bool enable)
|
||||
{
|
||||
visibilityPass = enable;
|
||||
}
|
||||
void setPositionOnly(bool enable) { positionOnly = enable; }
|
||||
void setViewCulling(bool enable) { viewCulling = enable; }
|
||||
void setVisibilityPass(bool enable) { visibilityPass = enable; }
|
||||
};
|
||||
//Hashed ShaderPermutation for fast lookup
|
||||
struct PermutationId
|
||||
{
|
||||
// Hashed ShaderPermutation for fast lookup
|
||||
struct PermutationId {
|
||||
uint32 hash;
|
||||
PermutationId()
|
||||
: hash(0)
|
||||
{}
|
||||
PermutationId(ShaderPermutation permutation)
|
||||
: hash(CRC::Calculate(&permutation, sizeof(ShaderPermutation), CRC::CRC_32()))
|
||||
{}
|
||||
friend constexpr bool operator==(const PermutationId& lhs, const PermutationId& rhs)
|
||||
{
|
||||
return lhs.hash == rhs.hash;
|
||||
}
|
||||
friend constexpr auto operator<=>(const PermutationId& lhs, const PermutationId& rhs)
|
||||
{
|
||||
return lhs.hash <=> rhs.hash;
|
||||
}
|
||||
PermutationId() : hash(0) {}
|
||||
PermutationId(ShaderPermutation permutation) : hash(CRC::Calculate(&permutation, sizeof(ShaderPermutation), CRC::CRC_32())) {}
|
||||
friend constexpr bool operator==(const PermutationId& lhs, const PermutationId& rhs) { return lhs.hash == rhs.hash; }
|
||||
friend constexpr auto operator<=>(const PermutationId& lhs, const PermutationId& rhs) { return lhs.hash <=> rhs.hash; }
|
||||
};
|
||||
struct ShaderCollection
|
||||
{
|
||||
struct ShaderCollection {
|
||||
OPipelineLayout pipelineLayout;
|
||||
OVertexShader vertexShader;
|
||||
OTaskShader taskShader;
|
||||
@@ -146,8 +108,7 @@ struct ShaderCollection
|
||||
OFragmentShader fragmentShader;
|
||||
};
|
||||
|
||||
struct PassConfig
|
||||
{
|
||||
struct PassConfig {
|
||||
Gfx::PPipelineLayout baseLayout;
|
||||
std::string taskFile = "";
|
||||
std::string mainFile = "";
|
||||
@@ -158,9 +119,8 @@ struct PassConfig
|
||||
bool useMaterial = false;
|
||||
bool useVisibility = false;
|
||||
};
|
||||
class ShaderCompiler
|
||||
{
|
||||
public:
|
||||
class ShaderCompiler {
|
||||
public:
|
||||
ShaderCompiler(Gfx::PGraphics graphics);
|
||||
~ShaderCompiler();
|
||||
const ShaderCollection* findShaders(PermutationId id) const;
|
||||
@@ -168,7 +128,8 @@ public:
|
||||
void registerVertexData(VertexData* vertexData);
|
||||
void registerRenderPass(std::string name, PassConfig config);
|
||||
ShaderPermutation getTemplate(std::string name);
|
||||
private:
|
||||
|
||||
private:
|
||||
void compile();
|
||||
void createShaders(ShaderPermutation permutation, OPipelineLayout layout);
|
||||
std::mutex shadersLock;
|
||||
@@ -179,5 +140,5 @@ private:
|
||||
Gfx::PGraphics graphics;
|
||||
};
|
||||
DEFINE_REF(ShaderCompiler)
|
||||
}
|
||||
} // namespace Gfx
|
||||
} // namespace Seele
|
||||
|
||||
@@ -7,22 +7,16 @@ using namespace Seele;
|
||||
|
||||
extern List<VertexData*> vertexDataList;
|
||||
|
||||
StaticMeshVertexData::StaticMeshVertexData()
|
||||
{
|
||||
vertexDataList.add(this);
|
||||
}
|
||||
StaticMeshVertexData::StaticMeshVertexData() { vertexDataList.add(this); }
|
||||
|
||||
StaticMeshVertexData::~StaticMeshVertexData()
|
||||
{}
|
||||
StaticMeshVertexData::~StaticMeshVertexData() {}
|
||||
|
||||
StaticMeshVertexData* StaticMeshVertexData::getInstance()
|
||||
{
|
||||
StaticMeshVertexData* StaticMeshVertexData::getInstance() {
|
||||
static StaticMeshVertexData instance;
|
||||
return &instance;
|
||||
}
|
||||
|
||||
void StaticMeshVertexData::loadPositions(MeshId id, const Array<Vector>& data)
|
||||
{
|
||||
void StaticMeshVertexData::loadPositions(MeshId id, const Array<Vector>& data) {
|
||||
uint64 offset;
|
||||
{
|
||||
std::unique_lock l(mutex);
|
||||
@@ -33,8 +27,7 @@ void StaticMeshVertexData::loadPositions(MeshId id, const Array<Vector>& data)
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
void StaticMeshVertexData::loadTexCoords(MeshId id, uint64 index, const Array<Vector2>& data)
|
||||
{
|
||||
void StaticMeshVertexData::loadTexCoords(MeshId id, uint64 index, const Array<Vector2>& data) {
|
||||
uint64 offset;
|
||||
{
|
||||
std::unique_lock l(mutex);
|
||||
@@ -45,8 +38,7 @@ void StaticMeshVertexData::loadTexCoords(MeshId id, uint64 index, const Array<Ve
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
void StaticMeshVertexData::loadNormals(MeshId id, const Array<Vector>& data)
|
||||
{
|
||||
void StaticMeshVertexData::loadNormals(MeshId id, const Array<Vector>& data) {
|
||||
uint64 offset;
|
||||
{
|
||||
std::unique_lock l(mutex);
|
||||
@@ -57,8 +49,7 @@ void StaticMeshVertexData::loadNormals(MeshId id, const Array<Vector>& data)
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
void StaticMeshVertexData::loadTangents(MeshId id, const Array<Vector>& data)
|
||||
{
|
||||
void StaticMeshVertexData::loadTangents(MeshId id, const Array<Vector>& data) {
|
||||
uint64 offset;
|
||||
{
|
||||
std::unique_lock l(mutex);
|
||||
@@ -69,8 +60,7 @@ void StaticMeshVertexData::loadTangents(MeshId id, const Array<Vector>& data)
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
void StaticMeshVertexData::loadBiTangents(MeshId id, const Array<Vector>& data)
|
||||
{
|
||||
void StaticMeshVertexData::loadBiTangents(MeshId id, const Array<Vector>& data) {
|
||||
uint64 offset;
|
||||
{
|
||||
std::unique_lock l(mutex);
|
||||
@@ -81,8 +71,7 @@ void StaticMeshVertexData::loadBiTangents(MeshId id, const Array<Vector>& data)
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
void Seele::StaticMeshVertexData::loadColors(MeshId id, const Array<Vector>& data)
|
||||
{
|
||||
void Seele::StaticMeshVertexData::loadColors(MeshId id, const Array<Vector>& data) {
|
||||
uint64 offset;
|
||||
{
|
||||
std::unique_lock l(mutex);
|
||||
@@ -93,8 +82,7 @@ void Seele::StaticMeshVertexData::loadColors(MeshId id, const Array<Vector>& dat
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
void StaticMeshVertexData::serializeMesh(MeshId id, uint64 numVertices, ArchiveBuffer& buffer)
|
||||
{
|
||||
void StaticMeshVertexData::serializeMesh(MeshId id, uint64 numVertices, ArchiveBuffer& buffer) {
|
||||
uint64 offset;
|
||||
{
|
||||
std::unique_lock l(mutex);
|
||||
@@ -102,8 +90,7 @@ void StaticMeshVertexData::serializeMesh(MeshId id, uint64 numVertices, ArchiveB
|
||||
}
|
||||
Array<Vector> pos(numVertices);
|
||||
Array<Vector2> tex[MAX_TEXCOORDS];
|
||||
for (size_t i = 0; i < MAX_TEXCOORDS; ++i)
|
||||
{
|
||||
for (size_t i = 0; i < MAX_TEXCOORDS; ++i) {
|
||||
tex[i].resize(numVertices);
|
||||
std::memcpy(tex[i].data(), texCoordsData[i].data() + offset, numVertices * sizeof(Vector2));
|
||||
Serialization::save(buffer, tex[i]);
|
||||
@@ -124,12 +111,10 @@ void StaticMeshVertexData::serializeMesh(MeshId id, uint64 numVertices, ArchiveB
|
||||
Serialization::save(buffer, col);
|
||||
}
|
||||
|
||||
void StaticMeshVertexData::deserializeMesh(MeshId id, ArchiveBuffer& buffer)
|
||||
{
|
||||
void StaticMeshVertexData::deserializeMesh(MeshId id, ArchiveBuffer& buffer) {
|
||||
Array<Vector> pos;
|
||||
Array<Vector2> tex[MAX_TEXCOORDS];
|
||||
for (size_t i = 0; i < MAX_TEXCOORDS; ++i)
|
||||
{
|
||||
for (size_t i = 0; i < MAX_TEXCOORDS; ++i) {
|
||||
Serialization::load(buffer, tex[i]);
|
||||
loadTexCoords(id, i, tex[i]);
|
||||
}
|
||||
@@ -149,26 +134,24 @@ void StaticMeshVertexData::deserializeMesh(MeshId id, ArchiveBuffer& buffer)
|
||||
loadColors(id, col);
|
||||
}
|
||||
|
||||
void StaticMeshVertexData::init(Gfx::PGraphics _graphics)
|
||||
{
|
||||
void StaticMeshVertexData::init(Gfx::PGraphics _graphics) {
|
||||
VertexData::init(_graphics);
|
||||
descriptorLayout = _graphics->createDescriptorLayout("pVertexData");
|
||||
descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{ .binding = 0, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER });
|
||||
descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{ .binding = 1, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER });
|
||||
descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{ .binding = 2, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER });
|
||||
descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{ .binding = 3, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER });
|
||||
descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{ .binding = 4, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER });
|
||||
descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{ .binding = 5, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER, .descriptorCount = MAX_TEXCOORDS });
|
||||
descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 0, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER});
|
||||
descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 1, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER});
|
||||
descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 2, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER});
|
||||
descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 3, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER});
|
||||
descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 4, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER});
|
||||
descriptorLayout->addDescriptorBinding(
|
||||
Gfx::DescriptorBinding{.binding = 5, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER, .descriptorCount = MAX_TEXCOORDS});
|
||||
descriptorLayout->create();
|
||||
descriptorSet = descriptorLayout->allocateDescriptorSet();
|
||||
}
|
||||
|
||||
void StaticMeshVertexData::destroy()
|
||||
{
|
||||
void StaticMeshVertexData::destroy() {
|
||||
VertexData::destroy();
|
||||
positions = nullptr;
|
||||
for (size_t i = 0; i < MAX_TEXCOORDS; ++i)
|
||||
{
|
||||
for (size_t i = 0; i < MAX_TEXCOORDS; ++i) {
|
||||
texCoords[i] = nullptr;
|
||||
}
|
||||
normals = nullptr;
|
||||
@@ -178,27 +161,20 @@ void StaticMeshVertexData::destroy()
|
||||
descriptorLayout = nullptr;
|
||||
}
|
||||
|
||||
void StaticMeshVertexData::bindBuffers(Gfx::PRenderCommand)
|
||||
{
|
||||
void StaticMeshVertexData::bindBuffers(Gfx::PRenderCommand) {
|
||||
// TODO: for legacy vertex buffer binding
|
||||
}
|
||||
|
||||
Gfx::PDescriptorLayout StaticMeshVertexData::getVertexDataLayout()
|
||||
{
|
||||
return descriptorLayout;
|
||||
}
|
||||
Gfx::PDescriptorLayout StaticMeshVertexData::getVertexDataLayout() { return descriptorLayout; }
|
||||
|
||||
Gfx::PDescriptorSet StaticMeshVertexData::getVertexDataSet()
|
||||
{
|
||||
return descriptorSet;
|
||||
}
|
||||
Gfx::PDescriptorSet StaticMeshVertexData::getVertexDataSet() { return descriptorSet; }
|
||||
|
||||
void StaticMeshVertexData::resizeBuffers()
|
||||
{
|
||||
void StaticMeshVertexData::resizeBuffers() {
|
||||
ShaderBufferCreateInfo createInfo = {
|
||||
.sourceData = {
|
||||
.size = verticesAllocated * sizeof(Vector),
|
||||
},
|
||||
.sourceData =
|
||||
{
|
||||
.size = verticesAllocated * sizeof(Vector),
|
||||
},
|
||||
.numElements = verticesAllocated * 3,
|
||||
.dynamic = false,
|
||||
.vertexBuffer = 1,
|
||||
@@ -217,8 +193,7 @@ void StaticMeshVertexData::resizeBuffers()
|
||||
createInfo.sourceData.size = verticesAllocated * sizeof(Vector2);
|
||||
createInfo.name = "TexCoords";
|
||||
createInfo.numElements = verticesAllocated * 2;
|
||||
for (size_t i = 0; i < MAX_TEXCOORDS; ++i)
|
||||
{
|
||||
for (size_t i = 0; i < MAX_TEXCOORDS; ++i) {
|
||||
texCoords[i] = graphics->createShaderBuffer(createInfo);
|
||||
texCoordsData[i].resize(verticesAllocated);
|
||||
}
|
||||
@@ -230,53 +205,50 @@ void StaticMeshVertexData::resizeBuffers()
|
||||
colorData.resize(verticesAllocated);
|
||||
}
|
||||
|
||||
void StaticMeshVertexData::updateBuffers()
|
||||
{
|
||||
void StaticMeshVertexData::updateBuffers() {
|
||||
positions->updateContents(ShaderBufferCreateInfo{
|
||||
.sourceData{
|
||||
.size = positionData.size() * sizeof(Vector),
|
||||
.data = (uint8*)positionData.data(),
|
||||
},
|
||||
.numElements = positionData.size(),
|
||||
});
|
||||
for (size_t i = 0; i < MAX_TEXCOORDS; ++i)
|
||||
{
|
||||
texCoords[i]->updateContents(ShaderBufferCreateInfo {
|
||||
.sourceData = {
|
||||
.size = texCoordsData[i].size() * sizeof(Vector2),
|
||||
.data = (uint8*)texCoordsData[i].data(),
|
||||
},
|
||||
});
|
||||
for (size_t i = 0; i < MAX_TEXCOORDS; ++i) {
|
||||
texCoords[i]->updateContents(ShaderBufferCreateInfo{
|
||||
.sourceData =
|
||||
{
|
||||
.size = texCoordsData[i].size() * sizeof(Vector2),
|
||||
.data = (uint8*)texCoordsData[i].data(),
|
||||
},
|
||||
.numElements = texCoordsData[i].size(),
|
||||
});
|
||||
});
|
||||
}
|
||||
normals->updateContents(ShaderBufferCreateInfo {
|
||||
.sourceData = {
|
||||
.size = normalData.size() * sizeof(Vector),
|
||||
.data = (uint8*)normalData.data(),
|
||||
},
|
||||
normals->updateContents(ShaderBufferCreateInfo{
|
||||
.sourceData =
|
||||
{
|
||||
.size = normalData.size() * sizeof(Vector),
|
||||
.data = (uint8*)normalData.data(),
|
||||
},
|
||||
.numElements = normalData.size(),
|
||||
});
|
||||
tangents->updateContents(ShaderBufferCreateInfo {
|
||||
.sourceData = {
|
||||
.size = tangentData.size() * sizeof(Vector),
|
||||
.data = (uint8*)tangentData.data(),
|
||||
},
|
||||
.numElements = tangentData.size()
|
||||
});
|
||||
biTangents->updateContents(ShaderBufferCreateInfo {
|
||||
.sourceData = {
|
||||
.size = biTangentData.size() * sizeof(Vector),
|
||||
.data = (uint8*)biTangentData.data(),
|
||||
},
|
||||
});
|
||||
tangents->updateContents(ShaderBufferCreateInfo{.sourceData =
|
||||
{
|
||||
.size = tangentData.size() * sizeof(Vector),
|
||||
.data = (uint8*)tangentData.data(),
|
||||
},
|
||||
.numElements = tangentData.size()});
|
||||
biTangents->updateContents(ShaderBufferCreateInfo{
|
||||
.sourceData =
|
||||
{
|
||||
.size = biTangentData.size() * sizeof(Vector),
|
||||
.data = (uint8*)biTangentData.data(),
|
||||
},
|
||||
.numElements = biTangentData.size(),
|
||||
});
|
||||
colors->updateContents(ShaderBufferCreateInfo {
|
||||
.sourceData = {
|
||||
.size = colorData.size() * sizeof(Vector),
|
||||
.data = (uint8*)colorData.data()
|
||||
},
|
||||
});
|
||||
colors->updateContents(ShaderBufferCreateInfo{
|
||||
.sourceData = {.size = colorData.size() * sizeof(Vector), .data = (uint8*)colorData.data()},
|
||||
.numElements = colorData.size(),
|
||||
});
|
||||
});
|
||||
descriptorLayout->reset();
|
||||
descriptorSet = descriptorLayout->allocateDescriptorSet();
|
||||
descriptorSet->updateBuffer(0, positions);
|
||||
|
||||
@@ -1,64 +1,63 @@
|
||||
#pragma once
|
||||
#include "Graphics/Initializer.h"
|
||||
#include "Graphics/Command.h"
|
||||
#include "Graphics/Initializer.h"
|
||||
#include "Math/Vector.h"
|
||||
#include "VertexData.h"
|
||||
#include "entt/entt.hpp"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
class StaticMeshVertexData : public VertexData
|
||||
{
|
||||
public:
|
||||
struct StaticMatInstance
|
||||
{
|
||||
PMaterialInstance instance;
|
||||
Array<uint32> meshletIds;
|
||||
Gfx::OShaderBuffer culledMeshletBuffer;
|
||||
//Gfx::OShaderBuffer indirectDrawBuffer;
|
||||
};
|
||||
struct StaticMatData
|
||||
{
|
||||
PMaterial material;
|
||||
Array<StaticMatInstance> staticInstance;
|
||||
};
|
||||
|
||||
namespace Seele {
|
||||
class StaticMeshVertexData : public VertexData {
|
||||
public:
|
||||
struct StaticMatInstance {
|
||||
PMaterialInstance instance;
|
||||
Array<uint32> meshletIds;
|
||||
Gfx::OShaderBuffer culledMeshletBuffer;
|
||||
// Gfx::OShaderBuffer indirectDrawBuffer;
|
||||
};
|
||||
struct StaticMatData {
|
||||
PMaterial material;
|
||||
Array<StaticMatInstance> staticInstance;
|
||||
};
|
||||
StaticMeshVertexData();
|
||||
virtual ~StaticMeshVertexData();
|
||||
static StaticMeshVertexData* getInstance();
|
||||
void loadPositions(MeshId id, const Array<Vector>& data);
|
||||
void loadTexCoords(MeshId id, uint64 index, const Array<Vector2>& data);
|
||||
void loadNormals(MeshId id, const Array<Vector>& data);
|
||||
void loadTangents(MeshId id, const Array<Vector>& data);
|
||||
void loadBiTangents(MeshId id, const Array<Vector>& data);
|
||||
void loadColors(MeshId id, const Array<Vector>& data);
|
||||
virtual void serializeMesh(MeshId id, uint64 numVertices, ArchiveBuffer& buffer) override;
|
||||
virtual void deserializeMesh(MeshId id, ArchiveBuffer& buffer) override;
|
||||
virtual void init(Gfx::PGraphics graphics) override;
|
||||
virtual void destroy() override;
|
||||
virtual void bindBuffers(Gfx::PRenderCommand command) override;
|
||||
virtual Gfx::PDescriptorLayout getVertexDataLayout() override;
|
||||
virtual Gfx::PDescriptorSet getVertexDataSet() override;
|
||||
virtual std::string getTypeName() const override { return "StaticMeshVertexData"; }
|
||||
constexpr const Array<StaticMatData>& getStaticMeshes() const { return staticData; }
|
||||
private:
|
||||
virtual void resizeBuffers() override;
|
||||
virtual void updateBuffers() override;
|
||||
Array<StaticMatData> staticData;
|
||||
static StaticMeshVertexData* getInstance();
|
||||
void loadPositions(MeshId id, const Array<Vector>& data);
|
||||
void loadTexCoords(MeshId id, uint64 index, const Array<Vector2>& data);
|
||||
void loadNormals(MeshId id, const Array<Vector>& data);
|
||||
void loadTangents(MeshId id, const Array<Vector>& data);
|
||||
void loadBiTangents(MeshId id, const Array<Vector>& data);
|
||||
void loadColors(MeshId id, const Array<Vector>& data);
|
||||
virtual void serializeMesh(MeshId id, uint64 numVertices, ArchiveBuffer& buffer) override;
|
||||
virtual void deserializeMesh(MeshId id, ArchiveBuffer& buffer) override;
|
||||
virtual void init(Gfx::PGraphics graphics) override;
|
||||
virtual void destroy() override;
|
||||
virtual void bindBuffers(Gfx::PRenderCommand command) override;
|
||||
virtual Gfx::PDescriptorLayout getVertexDataLayout() override;
|
||||
virtual Gfx::PDescriptorSet getVertexDataSet() override;
|
||||
virtual std::string getTypeName() const override { return "StaticMeshVertexData"; }
|
||||
virtual Gfx::PShaderBuffer getPositionBuffer() const override { return positions; }
|
||||
constexpr const Array<StaticMatData>& getStaticMeshes() const { return staticData; }
|
||||
|
||||
std::mutex mutex;
|
||||
private:
|
||||
virtual void resizeBuffers() override;
|
||||
virtual void updateBuffers() override;
|
||||
Array<StaticMatData> staticData;
|
||||
|
||||
std::mutex mutex;
|
||||
Gfx::OShaderBuffer positions;
|
||||
Array<Vector> positionData;
|
||||
Array<Vector> positionData;
|
||||
Gfx::OShaderBuffer texCoords[MAX_TEXCOORDS];
|
||||
Array<Vector2> texCoordsData[MAX_TEXCOORDS];
|
||||
Array<Vector2> texCoordsData[MAX_TEXCOORDS];
|
||||
Gfx::OShaderBuffer normals;
|
||||
Array<Vector> normalData;
|
||||
Array<Vector> normalData;
|
||||
Gfx::OShaderBuffer tangents;
|
||||
Array<Vector> tangentData;
|
||||
Array<Vector> tangentData;
|
||||
Gfx::OShaderBuffer biTangents;
|
||||
Array<Vector> biTangentData;
|
||||
Gfx::OShaderBuffer colors;
|
||||
Array<Vector> colorData;
|
||||
Gfx::ODescriptorLayout descriptorLayout;
|
||||
Gfx::PDescriptorSet descriptorSet;
|
||||
Array<Vector> biTangentData;
|
||||
Gfx::OShaderBuffer colors;
|
||||
Array<Vector> colorData;
|
||||
Gfx::ODescriptorLayout descriptorLayout;
|
||||
Gfx::PDescriptorSet descriptorSet;
|
||||
};
|
||||
}
|
||||
} // namespace Seele
|
||||
|
||||
@@ -1,42 +1,21 @@
|
||||
#include "Texture.h"
|
||||
#include "Texture.h"
|
||||
|
||||
|
||||
using namespace Seele;
|
||||
using namespace Seele::Gfx;
|
||||
|
||||
Texture::Texture(QueueFamilyMapping mapping, Gfx::QueueType startQueueType) : QueueOwnedResource(mapping, startQueueType) {}
|
||||
|
||||
Texture::Texture(QueueFamilyMapping mapping, Gfx::QueueType startQueueType)
|
||||
: QueueOwnedResource(mapping, startQueueType)
|
||||
{
|
||||
}
|
||||
Texture::~Texture() {}
|
||||
|
||||
Texture::~Texture()
|
||||
{
|
||||
}
|
||||
Texture2D::Texture2D(QueueFamilyMapping mapping, Gfx::QueueType startQueueType) : Texture(mapping, startQueueType) {}
|
||||
|
||||
Texture2D::Texture2D(QueueFamilyMapping mapping, Gfx::QueueType startQueueType)
|
||||
: Texture(mapping, startQueueType)
|
||||
{
|
||||
}
|
||||
Texture2D::~Texture2D() {}
|
||||
|
||||
Texture2D::~Texture2D()
|
||||
{
|
||||
}
|
||||
Texture3D::Texture3D(QueueFamilyMapping mapping, Gfx::QueueType startQueueType) : Texture(mapping, startQueueType) {}
|
||||
|
||||
Texture3D::Texture3D(QueueFamilyMapping mapping, Gfx::QueueType startQueueType)
|
||||
: Texture(mapping, startQueueType)
|
||||
{
|
||||
}
|
||||
Texture3D::~Texture3D() {}
|
||||
|
||||
Texture3D::~Texture3D()
|
||||
{
|
||||
}
|
||||
TextureCube::TextureCube(QueueFamilyMapping mapping, Gfx::QueueType startQueueType) : Texture(mapping, startQueueType) {}
|
||||
|
||||
TextureCube::TextureCube(QueueFamilyMapping mapping, Gfx::QueueType startQueueType)
|
||||
: Texture(mapping, startQueueType)
|
||||
{
|
||||
}
|
||||
|
||||
TextureCube::~TextureCube()
|
||||
{
|
||||
}
|
||||
TextureCube::~TextureCube() {}
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
#pragma once
|
||||
#include "Resources.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
namespace Gfx
|
||||
{
|
||||
class Texture : public QueueOwnedResource
|
||||
{
|
||||
public:
|
||||
namespace Seele {
|
||||
namespace Gfx {
|
||||
class Texture : public QueueOwnedResource {
|
||||
public:
|
||||
Texture(QueueFamilyMapping mapping, QueueType startQueueType);
|
||||
virtual ~Texture();
|
||||
|
||||
@@ -18,21 +15,20 @@ public:
|
||||
virtual uint32 getNumFaces() const { return 1; }
|
||||
virtual SeSampleCountFlags getNumSamples() const = 0;
|
||||
virtual uint32 getMipLevels() const = 0;
|
||||
virtual void changeLayout(SeImageLayout newLayout,
|
||||
SeAccessFlags srcAccess, SePipelineStageFlags srcStage,
|
||||
SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0;
|
||||
virtual void changeLayout(SeImageLayout newLayout, SeAccessFlags srcAccess, SePipelineStageFlags srcStage, SeAccessFlags dstAccess,
|
||||
SePipelineStageFlags dstStage) = 0;
|
||||
virtual void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer) = 0;
|
||||
protected:
|
||||
|
||||
protected:
|
||||
// Inherited via QueueOwnedResource
|
||||
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
|
||||
virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage,
|
||||
SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0;
|
||||
virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage, SeAccessFlags dstAccess,
|
||||
SePipelineStageFlags dstStage) = 0;
|
||||
};
|
||||
DEFINE_REF(Texture)
|
||||
|
||||
class Texture2D : public Texture
|
||||
{
|
||||
public:
|
||||
class Texture2D : public Texture {
|
||||
public:
|
||||
Texture2D(QueueFamilyMapping mapping, QueueType startQueueType);
|
||||
virtual ~Texture2D();
|
||||
|
||||
@@ -42,20 +38,19 @@ public:
|
||||
virtual uint32 getDepth() const = 0;
|
||||
virtual SeSampleCountFlags getNumSamples() const = 0;
|
||||
virtual uint32 getMipLevels() const = 0;
|
||||
virtual void changeLayout(SeImageLayout newLayout,
|
||||
SeAccessFlags srcAccess, SePipelineStageFlags srcStage,
|
||||
SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0;
|
||||
protected:
|
||||
//Inherited via QueueOwnedResource
|
||||
virtual void changeLayout(SeImageLayout newLayout, SeAccessFlags srcAccess, SePipelineStageFlags srcStage, SeAccessFlags dstAccess,
|
||||
SePipelineStageFlags dstStage) = 0;
|
||||
|
||||
protected:
|
||||
// Inherited via QueueOwnedResource
|
||||
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
|
||||
virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage,
|
||||
SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0;
|
||||
virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage, SeAccessFlags dstAccess,
|
||||
SePipelineStageFlags dstStage) = 0;
|
||||
};
|
||||
DEFINE_REF(Texture2D)
|
||||
|
||||
class Texture3D : public Texture
|
||||
{
|
||||
public:
|
||||
class Texture3D : public Texture {
|
||||
public:
|
||||
Texture3D(QueueFamilyMapping mapping, QueueType startQueueType);
|
||||
virtual ~Texture3D();
|
||||
|
||||
@@ -65,20 +60,19 @@ public:
|
||||
virtual uint32 getDepth() const = 0;
|
||||
virtual SeSampleCountFlags getNumSamples() const = 0;
|
||||
virtual uint32 getMipLevels() const = 0;
|
||||
virtual void changeLayout(SeImageLayout newLayout,
|
||||
SeAccessFlags srcAccess, SePipelineStageFlags srcStage,
|
||||
SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0;
|
||||
protected:
|
||||
//Inherited via QueueOwnedResource
|
||||
virtual void changeLayout(SeImageLayout newLayout, SeAccessFlags srcAccess, SePipelineStageFlags srcStage, SeAccessFlags dstAccess,
|
||||
SePipelineStageFlags dstStage) = 0;
|
||||
|
||||
protected:
|
||||
// Inherited via QueueOwnedResource
|
||||
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
|
||||
virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage,
|
||||
SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0;
|
||||
virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage, SeAccessFlags dstAccess,
|
||||
SePipelineStageFlags dstStage) = 0;
|
||||
};
|
||||
DEFINE_REF(Texture3D)
|
||||
|
||||
class TextureCube : public Texture
|
||||
{
|
||||
public:
|
||||
class TextureCube : public Texture {
|
||||
public:
|
||||
TextureCube(QueueFamilyMapping mapping, QueueType startQueueType);
|
||||
virtual ~TextureCube();
|
||||
|
||||
@@ -89,15 +83,15 @@ public:
|
||||
virtual uint32 getNumFaces() const { return 6; }
|
||||
virtual SeSampleCountFlags getNumSamples() const = 0;
|
||||
virtual uint32 getMipLevels() const = 0;
|
||||
virtual void changeLayout(SeImageLayout newLayout,
|
||||
SeAccessFlags srcAccess, SePipelineStageFlags srcStage,
|
||||
SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0;
|
||||
protected:
|
||||
//Inherited via QueueOwnedResource
|
||||
virtual void changeLayout(SeImageLayout newLayout, SeAccessFlags srcAccess, SePipelineStageFlags srcStage, SeAccessFlags dstAccess,
|
||||
SePipelineStageFlags dstStage) = 0;
|
||||
|
||||
protected:
|
||||
// Inherited via QueueOwnedResource
|
||||
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
|
||||
virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage,
|
||||
SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0;
|
||||
virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage, SeAccessFlags dstAccess,
|
||||
SePipelineStageFlags dstStage) = 0;
|
||||
};
|
||||
DEFINE_REF(TextureCube)
|
||||
}
|
||||
}
|
||||
} // namespace Gfx
|
||||
} // namespace Seele
|
||||
+100
-142
@@ -1,13 +1,14 @@
|
||||
#include "VertexData.h"
|
||||
#include "Graphics/Enums.h"
|
||||
#include "Graphics/Initializer.h"
|
||||
#include "Material/Material.h"
|
||||
#include "Graphics/Graphics.h"
|
||||
#include "Graphics/Descriptor.h"
|
||||
#include "Graphics/Shader.h"
|
||||
#include "Graphics/Enums.h"
|
||||
#include "Graphics/Graphics.h"
|
||||
#include "Graphics/Initializer.h"
|
||||
#include "Graphics/Mesh.h"
|
||||
#include "Graphics/Shader.h"
|
||||
#include "Material/Material.h"
|
||||
#include "Material/MaterialInstance.h"
|
||||
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
constexpr static uint64 NUM_DEFAULT_ELEMENTS = 1024 * 1024;
|
||||
@@ -15,44 +16,36 @@ Map<VertexData::MeshMapping, VertexData::CullingMapping> VertexData::instanceIdM
|
||||
uint64 VertexData::instanceCount = 0;
|
||||
uint64 VertexData::meshletCount = 0;
|
||||
|
||||
void VertexData::resetMeshData()
|
||||
{
|
||||
void VertexData::resetMeshData() {
|
||||
std::unique_lock l(materialDataLock);
|
||||
for (auto &mat : materialData)
|
||||
{
|
||||
for (auto &inst : mat.instances)
|
||||
{
|
||||
for (auto& mat : materialData) {
|
||||
for (auto& inst : mat.instances) {
|
||||
inst.instanceData.clear();
|
||||
inst.instanceMeshData.clear();
|
||||
}
|
||||
if (mat.material != nullptr)
|
||||
{
|
||||
if (mat.material != nullptr) {
|
||||
mat.material->getDescriptorLayout()->reset();
|
||||
}
|
||||
}
|
||||
if (dirty)
|
||||
{
|
||||
if (dirty) {
|
||||
updateBuffers();
|
||||
dirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
void VertexData::updateMesh(entt::entity id, uint32 meshIndex, PMesh mesh, Component::Transform &transform)
|
||||
{
|
||||
void VertexData::updateMesh(entt::entity id, uint32 meshIndex, PMesh mesh, Component::Transform& transform) {
|
||||
std::unique_lock l(materialDataLock);
|
||||
PMaterialInstance referencedInstance = mesh->referencedMaterial->getHandle();
|
||||
PMaterial mat = referencedInstance->getBaseMaterial();
|
||||
if (materialData.size() <= mat->getId())
|
||||
{
|
||||
if (materialData.size() <= mat->getId()) {
|
||||
materialData.resize(mat->getId() + 1);
|
||||
}
|
||||
MaterialData &matData = materialData[mat->getId()];
|
||||
MaterialData& matData = materialData[mat->getId()];
|
||||
matData.material = mat;
|
||||
if (matData.instances.size() <= referencedInstance->getId())
|
||||
{
|
||||
if (matData.instances.size() <= referencedInstance->getId()) {
|
||||
matData.instances.resize(referencedInstance->getId() + 1);
|
||||
}
|
||||
BatchedDrawCall &matInstanceData = matData.instances[referencedInstance->getId()];
|
||||
BatchedDrawCall& matInstanceData = matData.instances[referencedInstance->getId()];
|
||||
matInstanceData.materialInstance = referencedInstance;
|
||||
|
||||
Matrix4 transformMatrix = transform.toMatrix() * mesh->transform;
|
||||
@@ -60,13 +53,12 @@ void VertexData::updateMesh(entt::entity id, uint32 meshIndex, PMesh mesh, Compo
|
||||
.transformMatrix = transformMatrix,
|
||||
.inverseTransformMatrix = glm::inverse(transformMatrix),
|
||||
});
|
||||
const auto &data = meshData[mesh->id];
|
||||
const auto& data = meshData[mesh->id];
|
||||
auto [instanceId, meshletOffset] = getCullingMapping(id, meshIndex, data.numMeshlets);
|
||||
matInstanceData.instanceMeshData.add(data);
|
||||
matInstanceData.cullingOffsets.add(meshletOffset);
|
||||
referencedInstance->updateDescriptor();
|
||||
for (size_t i = 0; i < 0; ++i)
|
||||
{
|
||||
for (size_t i = 0; i < 0; ++i) {
|
||||
auto bounding = meshlets[data.meshletOffset + i].bounding;
|
||||
StaticArray<Vector, 8> corners;
|
||||
Vector min = bounding.min; // bounding.center - bounding.radius * Vector(1, 1, 1);
|
||||
@@ -106,23 +98,19 @@ void VertexData::updateMesh(entt::entity id, uint32 meshIndex, PMesh mesh, Compo
|
||||
}
|
||||
}
|
||||
|
||||
void VertexData::createDescriptors()
|
||||
{
|
||||
void VertexData::createDescriptors() {
|
||||
std::unique_lock l(materialDataLock);
|
||||
|
||||
instanceData.clear();
|
||||
instanceMeshData.clear();
|
||||
|
||||
Array<uint32> cullingOffsets;
|
||||
for (auto &mat : materialData)
|
||||
{
|
||||
for (auto &instance : mat.instances)
|
||||
{
|
||||
for (auto& mat : materialData) {
|
||||
for (auto& instance : mat.instances) {
|
||||
instance.offsets.instanceOffset = instanceData.size();
|
||||
// instance.offsets.cullingCounterOffset = cullingOffsets.size();
|
||||
// instance.numMeshlets = 0;
|
||||
for (size_t i = 0; i < instance.instanceData.size(); ++i)
|
||||
{
|
||||
for (size_t i = 0; i < instance.instanceData.size(); ++i) {
|
||||
cullingOffsets.add(instance.cullingOffsets[i]);
|
||||
instanceData.add(instance.instanceData[i]);
|
||||
instanceMeshData.add(instance.instanceMeshData[i]);
|
||||
@@ -132,43 +120,34 @@ void VertexData::createDescriptors()
|
||||
}
|
||||
}
|
||||
cullingOffsetBuffer->rotateBuffer(cullingOffsets.size() * sizeof(uint32));
|
||||
cullingOffsetBuffer->updateContents(ShaderBufferCreateInfo{
|
||||
.sourceData = {
|
||||
.size = cullingOffsets.size() * sizeof(uint32),
|
||||
.data = (uint8 *)cullingOffsets.data(),
|
||||
},
|
||||
.numElements = cullingOffsets.size()});
|
||||
cullingOffsetBuffer->pipelineBarrier(
|
||||
Gfx::SE_ACCESS_TRANSFER_WRITE_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
Gfx::SE_ACCESS_MEMORY_READ_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
|
||||
cullingOffsetBuffer->updateContents(ShaderBufferCreateInfo{.sourceData =
|
||||
{
|
||||
.size = cullingOffsets.size() * sizeof(uint32),
|
||||
.data = (uint8*)cullingOffsets.data(),
|
||||
},
|
||||
.numElements = cullingOffsets.size()});
|
||||
cullingOffsetBuffer->pipelineBarrier(Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
Gfx::SE_ACCESS_MEMORY_READ_BIT, Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
|
||||
|
||||
instanceBuffer->rotateBuffer(instanceData.size() * sizeof(InstanceData));
|
||||
instanceBuffer->updateContents(ShaderBufferCreateInfo{
|
||||
.sourceData = {
|
||||
.size = instanceData.size() * sizeof(InstanceData),
|
||||
.data = (uint8 *)instanceData.data(),
|
||||
},
|
||||
.numElements = instanceData.size()});
|
||||
instanceBuffer->pipelineBarrier(
|
||||
Gfx::SE_ACCESS_TRANSFER_WRITE_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
Gfx::SE_ACCESS_MEMORY_READ_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
|
||||
instanceBuffer->updateContents(ShaderBufferCreateInfo{.sourceData =
|
||||
{
|
||||
.size = instanceData.size() * sizeof(InstanceData),
|
||||
.data = (uint8*)instanceData.data(),
|
||||
},
|
||||
.numElements = instanceData.size()});
|
||||
instanceBuffer->pipelineBarrier(Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT, Gfx::SE_ACCESS_MEMORY_READ_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
|
||||
|
||||
instanceMeshDataBuffer->rotateBuffer(sizeof(MeshData) * instanceMeshData.size());
|
||||
instanceMeshDataBuffer->updateContents(ShaderBufferCreateInfo{
|
||||
.sourceData = {
|
||||
.size = sizeof(MeshData) * instanceMeshData.size(),
|
||||
.data = (uint8 *)instanceMeshData.data(),
|
||||
},
|
||||
.numElements = instanceMeshData.size()});
|
||||
instanceMeshDataBuffer->pipelineBarrier(
|
||||
Gfx::SE_ACCESS_TRANSFER_WRITE_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
Gfx::SE_ACCESS_MEMORY_READ_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
|
||||
instanceMeshDataBuffer->updateContents(ShaderBufferCreateInfo{.sourceData =
|
||||
{
|
||||
.size = sizeof(MeshData) * instanceMeshData.size(),
|
||||
.data = (uint8*)instanceMeshData.data(),
|
||||
},
|
||||
.numElements = instanceMeshData.size()});
|
||||
instanceMeshDataBuffer->pipelineBarrier(Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
Gfx::SE_ACCESS_MEMORY_READ_BIT, Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
|
||||
instanceDataLayout->reset();
|
||||
descriptorSet = instanceDataLayout->allocateDescriptorSet();
|
||||
descriptorSet->updateBuffer(0, instanceBuffer);
|
||||
@@ -179,8 +158,7 @@ void VertexData::createDescriptors()
|
||||
descriptorSet->updateBuffer(5, cullingOffsetBuffer);
|
||||
}
|
||||
|
||||
void VertexData::loadMesh(MeshId id, Array<uint32> loadedIndices, Array<Meshlet> loadedMeshlets)
|
||||
{
|
||||
void VertexData::loadMesh(MeshId id, Array<uint32> loadedIndices, Array<Meshlet> loadedMeshlets) {
|
||||
assert(loadedMeshlets.size() < 2048);
|
||||
std::unique_lock l(vertexDataLock);
|
||||
meshlets.reserve(meshlets.size() + loadedMeshlets.size());
|
||||
@@ -188,9 +166,8 @@ void VertexData::loadMesh(MeshId id, Array<uint32> loadedIndices, Array<Meshlet>
|
||||
primitiveIndices.reserve(primitiveIndices.size() + loadedMeshlets.size() * Gfx::numPrimitivesPerMeshlet * 3);
|
||||
uint32 meshletOffset = meshlets.size();
|
||||
AABB meshAABB;
|
||||
for (uint32 i = 0; i < loadedMeshlets.size(); ++i)
|
||||
{
|
||||
Meshlet &m = loadedMeshlets[i];
|
||||
for (uint32 i = 0; i < loadedMeshlets.size(); ++i) {
|
||||
Meshlet& m = loadedMeshlets[i];
|
||||
meshAABB = meshAABB.combine(m.boundingBox);
|
||||
uint32 vertexOffset = vertexIndices.size();
|
||||
vertexIndices.resize(vertexOffset + m.numVertices);
|
||||
@@ -216,93 +193,75 @@ void VertexData::loadMesh(MeshId id, Array<uint32> loadedIndices, Array<Meshlet>
|
||||
.numIndices = (uint32)loadedIndices.size(),
|
||||
};
|
||||
|
||||
if (!graphics->supportMeshShading())
|
||||
{
|
||||
indices.resize(indices.size() + loadedIndices.size());
|
||||
std::memcpy(indices.data() + meshData[id].firstIndex, loadedIndices.data(), loadedIndices.size() * sizeof(uint32));
|
||||
indexBuffer = graphics->createIndexBuffer(IndexBufferCreateInfo{
|
||||
.sourceData = {
|
||||
indices.resize(indices.size() + loadedIndices.size());
|
||||
std::memcpy(indices.data() + meshData[id].firstIndex, loadedIndices.data(), loadedIndices.size() * sizeof(uint32));
|
||||
indexBuffer = graphics->createIndexBuffer(IndexBufferCreateInfo{
|
||||
.sourceData =
|
||||
{
|
||||
.size = sizeof(uint32) * indices.size(),
|
||||
.data = (uint8 *)indices.data(),
|
||||
.data = (uint8*)indices.data(),
|
||||
},
|
||||
.indexType = Gfx::SE_INDEX_TYPE_UINT32,
|
||||
.name = "IndexBuffer",
|
||||
});
|
||||
}
|
||||
meshletBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||
.sourceData = {
|
||||
.size = sizeof(MeshletDescription) * meshlets.size(),
|
||||
.data = (uint8 *)meshlets.data()},
|
||||
.numElements = meshlets.size(),
|
||||
.dynamic = false,
|
||||
.name = "MeshletBuffer"});
|
||||
.indexType = Gfx::SE_INDEX_TYPE_UINT32,
|
||||
.name = "IndexBuffer",
|
||||
});
|
||||
meshletBuffer = graphics->createShaderBuffer(
|
||||
ShaderBufferCreateInfo{.sourceData = {.size = sizeof(MeshletDescription) * meshlets.size(), .data = (uint8*)meshlets.data()},
|
||||
.numElements = meshlets.size(),
|
||||
.dynamic = false,
|
||||
.name = "MeshletBuffer"});
|
||||
|
||||
vertexIndicesBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||
.sourceData = {
|
||||
.size = sizeof(uint32) * vertexIndices.size(),
|
||||
.data = (uint8 *)vertexIndices.data(),
|
||||
},
|
||||
.numElements = vertexIndices.size(),
|
||||
.dynamic = false,
|
||||
.name = "VertexIndicesBuffer"});
|
||||
vertexIndicesBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{.sourceData =
|
||||
{
|
||||
.size = sizeof(uint32) * vertexIndices.size(),
|
||||
.data = (uint8*)vertexIndices.data(),
|
||||
},
|
||||
.numElements = vertexIndices.size(),
|
||||
.dynamic = false,
|
||||
.name = "VertexIndicesBuffer"});
|
||||
|
||||
primitiveIndicesBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||
.sourceData = {
|
||||
.size = sizeof(uint8) * primitiveIndices.size(),
|
||||
.data = (uint8 *)primitiveIndices.data(),
|
||||
},
|
||||
.sourceData =
|
||||
{
|
||||
.size = sizeof(uint8) * primitiveIndices.size(),
|
||||
.data = (uint8*)primitiveIndices.data(),
|
||||
},
|
||||
.numElements = primitiveIndices.size(),
|
||||
.dynamic = false,
|
||||
.name = "PrimitiveIndicesBuffer",
|
||||
});
|
||||
}
|
||||
|
||||
MeshId VertexData::allocateVertexData(uint64 numVertices)
|
||||
{
|
||||
MeshId VertexData::allocateVertexData(uint64 numVertices) {
|
||||
std::unique_lock l(vertexDataLock);
|
||||
MeshId res{idCounter++};
|
||||
meshOffsets[res] = head;
|
||||
meshVertexCounts[res] = numVertices;
|
||||
head += numVertices;
|
||||
if (head > verticesAllocated)
|
||||
{
|
||||
if (head > verticesAllocated) {
|
||||
verticesAllocated = std::max(head, verticesAllocated + NUM_DEFAULT_ELEMENTS);
|
||||
resizeBuffers();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
uint64 VertexData::getMeshOffset(MeshId id)
|
||||
{
|
||||
return meshOffsets[id];
|
||||
}
|
||||
uint64 VertexData::getMeshOffset(MeshId id) { return meshOffsets[id]; }
|
||||
|
||||
uint64 VertexData::getMeshVertexCount(MeshId id)
|
||||
{
|
||||
return meshVertexCounts[id];
|
||||
}
|
||||
uint64 VertexData::getMeshVertexCount(MeshId id) { return meshVertexCounts[id]; }
|
||||
|
||||
List<VertexData *> vertexDataList;
|
||||
List<VertexData*> vertexDataList;
|
||||
|
||||
List<VertexData *> VertexData::getList()
|
||||
{
|
||||
return vertexDataList;
|
||||
}
|
||||
List<VertexData*> VertexData::getList() { return vertexDataList; }
|
||||
|
||||
VertexData *VertexData::findByTypeName(std::string name)
|
||||
{
|
||||
for (auto vd : vertexDataList)
|
||||
{
|
||||
if (vd->getTypeName() == name)
|
||||
{
|
||||
VertexData* VertexData::findByTypeName(std::string name) {
|
||||
for (auto vd : vertexDataList) {
|
||||
if (vd->getTypeName() == name) {
|
||||
return vd;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void VertexData::init(Gfx::PGraphics _graphics)
|
||||
{
|
||||
void VertexData::init(Gfx::PGraphics _graphics) {
|
||||
graphics = _graphics;
|
||||
verticesAllocated = NUM_DEFAULT_ELEMENTS;
|
||||
instanceDataLayout = graphics->createDescriptorLayout("pScene");
|
||||
@@ -318,15 +277,20 @@ void VertexData::init(Gfx::PGraphics _graphics)
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
});
|
||||
// meshletData
|
||||
instanceDataLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 2, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER});
|
||||
instanceDataLayout->addDescriptorBinding(
|
||||
Gfx::DescriptorBinding{.binding = 2, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER});
|
||||
// primitiveIndices
|
||||
instanceDataLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 3, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER});
|
||||
instanceDataLayout->addDescriptorBinding(
|
||||
Gfx::DescriptorBinding{.binding = 3, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER});
|
||||
// vertexIndices
|
||||
instanceDataLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 4, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER});
|
||||
instanceDataLayout->addDescriptorBinding(
|
||||
Gfx::DescriptorBinding{.binding = 4, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER});
|
||||
// cullingOffset
|
||||
instanceDataLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 5, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER});
|
||||
instanceDataLayout->addDescriptorBinding(
|
||||
Gfx::DescriptorBinding{.binding = 5, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER});
|
||||
// cullingInfos
|
||||
instanceDataLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 6, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER});
|
||||
instanceDataLayout->addDescriptorBinding(
|
||||
Gfx::DescriptorBinding{.binding = 6, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER});
|
||||
|
||||
instanceDataLayout->create();
|
||||
|
||||
@@ -346,8 +310,7 @@ void VertexData::init(Gfx::PGraphics _graphics)
|
||||
graphics->getShaderCompiler()->registerVertexData(this);
|
||||
}
|
||||
|
||||
void VertexData::destroy()
|
||||
{
|
||||
void VertexData::destroy() {
|
||||
instanceBuffer = nullptr;
|
||||
instanceMeshDataBuffer = nullptr;
|
||||
instanceDataLayout = nullptr;
|
||||
@@ -359,18 +322,13 @@ void VertexData::destroy()
|
||||
materialData.clear();
|
||||
}
|
||||
|
||||
VertexData::CullingMapping VertexData::getCullingMapping(entt::entity id, uint32 meshIndex, uint32 numMeshlets)
|
||||
{
|
||||
VertexData::CullingMapping VertexData::getCullingMapping(entt::entity id, uint32 meshIndex, uint32 numMeshlets) {
|
||||
MeshMapping key = MeshMapping{.id = id, .meshId = meshIndex};
|
||||
if (!instanceIdMap.contains(key))
|
||||
{
|
||||
if (!instanceIdMap.contains(key)) {
|
||||
instanceIdMap[key] = CullingMapping{.instanceId = instanceCount++, .cullingOffset = uint32(meshletCount)};
|
||||
meshletCount += numMeshlets;
|
||||
}
|
||||
return instanceIdMap[key];
|
||||
}
|
||||
|
||||
VertexData::VertexData()
|
||||
: idCounter(0), head(0), verticesAllocated(0), dirty(false)
|
||||
{
|
||||
}
|
||||
VertexData::VertexData() : idCounter(0), head(0), verticesAllocated(0), dirty(false) {}
|
||||
|
||||
+105
-112
@@ -8,128 +8,121 @@
|
||||
#include "Meshlet.h"
|
||||
#include <entt/entt.hpp>
|
||||
|
||||
|
||||
constexpr uint64 MAX_TEXCOORDS = 8;
|
||||
|
||||
namespace Seele {
|
||||
DECLARE_REF(MaterialInstance)
|
||||
DECLARE_REF(Mesh)
|
||||
struct MeshId {
|
||||
uint64 id;
|
||||
std::strong_ordering operator<=>(const MeshId &other) const {
|
||||
return id <=> other.id;
|
||||
}
|
||||
bool operator==(const MeshId &other) const { return id == other.id; }
|
||||
uint64 id;
|
||||
std::strong_ordering operator<=>(const MeshId& other) const { return id <=> other.id; }
|
||||
bool operator==(const MeshId& other) const { return id == other.id; }
|
||||
};
|
||||
class VertexData {
|
||||
public:
|
||||
struct DrawCallOffsets {
|
||||
uint32 instanceOffset = 0;
|
||||
};
|
||||
public:
|
||||
struct DrawCallOffsets {
|
||||
uint32 instanceOffset = 0;
|
||||
};
|
||||
|
||||
struct MeshletCullingInfo {
|
||||
uint64_t cull[256 / 64];
|
||||
};
|
||||
struct BatchedDrawCall {
|
||||
PMaterialInstance materialInstance;
|
||||
DrawCallOffsets offsets;
|
||||
struct MeshletCullingInfo {
|
||||
uint64_t cull[256 / 64];
|
||||
};
|
||||
struct BatchedDrawCall {
|
||||
PMaterialInstance materialInstance;
|
||||
DrawCallOffsets offsets;
|
||||
Array<InstanceData> instanceData;
|
||||
Array<MeshData> instanceMeshData;
|
||||
Array<uint32> cullingOffsets;
|
||||
};
|
||||
struct MaterialData {
|
||||
PMaterial material;
|
||||
Array<BatchedDrawCall> instances;
|
||||
};
|
||||
void resetMeshData();
|
||||
void updateMesh(entt::entity id, uint32 meshIndex, PMesh mesh, Component::Transform& transform);
|
||||
void createDescriptors();
|
||||
void loadMesh(MeshId id, Array<uint32> indices, Array<Meshlet> meshlets);
|
||||
MeshId allocateVertexData(uint64 numVertices);
|
||||
uint64 getMeshOffset(MeshId id);
|
||||
uint64 getMeshVertexCount(MeshId id);
|
||||
virtual void serializeMesh(MeshId id, uint64 numVertices, ArchiveBuffer& buffer) = 0;
|
||||
virtual void deserializeMesh(MeshId id, ArchiveBuffer& buffer) = 0;
|
||||
virtual void bindBuffers(Gfx::PRenderCommand command) = 0;
|
||||
virtual Gfx::PDescriptorLayout getVertexDataLayout() = 0;
|
||||
virtual Gfx::PDescriptorSet getVertexDataSet() = 0;
|
||||
virtual std::string getTypeName() const = 0;
|
||||
virtual Gfx::PShaderBuffer getPositionBuffer() const = 0;
|
||||
Gfx::PIndexBuffer getIndexBuffer() { return indexBuffer; }
|
||||
Gfx::PDescriptorLayout getInstanceDataLayout() { return instanceDataLayout; }
|
||||
Gfx::PDescriptorSet getInstanceDataSet() { return descriptorSet; }
|
||||
const Array<MaterialData>& getMaterialData() const { return materialData; }
|
||||
const MeshData& getMeshData(MeshId id) { return meshData[id]; }
|
||||
uint64 getIndicesOffset(uint32 meshletIndex) { return meshlets[meshletIndex].indicesOffset; }
|
||||
uint64 getNumInstances() const { return instanceData.size(); }
|
||||
static List<VertexData*> getList();
|
||||
static VertexData* findByTypeName(std::string name);
|
||||
virtual void init(Gfx::PGraphics graphics);
|
||||
virtual void destroy();
|
||||
|
||||
struct CullingMapping {
|
||||
uint64 instanceId;
|
||||
uint32 cullingOffset;
|
||||
};
|
||||
static CullingMapping getCullingMapping(entt::entity id, uint32 meshIndex, uint32 numMeshlets);
|
||||
static uint64 getInstanceCount() { return instanceCount; }
|
||||
static uint64 getMeshletCount() { return meshletCount; }
|
||||
|
||||
protected:
|
||||
virtual void resizeBuffers() = 0;
|
||||
virtual void updateBuffers() = 0;
|
||||
VertexData();
|
||||
struct MeshletDescription {
|
||||
AABB bounding;
|
||||
uint32 vertexCount;
|
||||
uint32 primitiveCount;
|
||||
uint32 vertexOffset;
|
||||
uint32 primitiveOffset;
|
||||
Vector color;
|
||||
uint32 indicesOffset = 0;
|
||||
};
|
||||
std::mutex materialDataLock;
|
||||
Array<MaterialData> materialData;
|
||||
std::mutex vertexDataLock;
|
||||
Map<MeshId, MeshData> meshData;
|
||||
Map<MeshId, uint64> meshOffsets;
|
||||
Map<MeshId, uint64> meshVertexCounts;
|
||||
Array<MeshletDescription> meshlets;
|
||||
Array<uint8> primitiveIndices;
|
||||
Array<uint32> vertexIndices;
|
||||
Array<uint32> indices;
|
||||
|
||||
struct MeshMapping {
|
||||
entt::entity id;
|
||||
uint32 meshId;
|
||||
auto operator<=>(const MeshMapping& other) const = default;
|
||||
};
|
||||
static Map<MeshMapping, CullingMapping> instanceIdMap;
|
||||
static uint64 instanceCount;
|
||||
static uint64 meshletCount;
|
||||
|
||||
Gfx::PGraphics graphics;
|
||||
Gfx::ODescriptorLayout instanceDataLayout;
|
||||
// for mesh shading
|
||||
Gfx::OShaderBuffer meshletBuffer;
|
||||
Gfx::OShaderBuffer vertexIndicesBuffer;
|
||||
Gfx::OShaderBuffer primitiveIndicesBuffer;
|
||||
Gfx::OShaderBuffer cullingOffsetBuffer;
|
||||
// for legacy pipeline
|
||||
Gfx::OIndexBuffer indexBuffer;
|
||||
// Material data
|
||||
Array<InstanceData> instanceData;
|
||||
Gfx::OShaderBuffer instanceBuffer;
|
||||
Array<MeshData> instanceMeshData;
|
||||
Array<uint32> cullingOffsets;
|
||||
};
|
||||
struct MaterialData {
|
||||
PMaterial material;
|
||||
Array<BatchedDrawCall> instances;
|
||||
};
|
||||
void resetMeshData();
|
||||
void updateMesh(entt::entity id, uint32 meshIndex, PMesh mesh,
|
||||
Component::Transform &transform);
|
||||
void createDescriptors();
|
||||
void loadMesh(MeshId id, Array<uint32> indices, Array<Meshlet> meshlets);
|
||||
MeshId allocateVertexData(uint64 numVertices);
|
||||
uint64 getMeshOffset(MeshId id);
|
||||
uint64 getMeshVertexCount(MeshId id);
|
||||
virtual void serializeMesh(MeshId id, uint64 numVertices,
|
||||
ArchiveBuffer &buffer) = 0;
|
||||
virtual void deserializeMesh(MeshId id, ArchiveBuffer &buffer) = 0;
|
||||
virtual void bindBuffers(Gfx::PRenderCommand command) = 0;
|
||||
virtual Gfx::PDescriptorLayout getVertexDataLayout() = 0;
|
||||
virtual Gfx::PDescriptorSet getVertexDataSet() = 0;
|
||||
virtual std::string getTypeName() const = 0;
|
||||
Gfx::PIndexBuffer getIndexBuffer() { return indexBuffer; }
|
||||
Gfx::PDescriptorLayout getInstanceDataLayout() { return instanceDataLayout; }
|
||||
Gfx::PDescriptorSet getInstanceDataSet() { return descriptorSet; }
|
||||
const Array<MaterialData> &getMaterialData() const { return materialData; }
|
||||
const MeshData &getMeshData(MeshId id) { return meshData[id]; }
|
||||
uint64 getIndicesOffset(uint32 meshletIndex) {
|
||||
return meshlets[meshletIndex].indicesOffset;
|
||||
}
|
||||
uint64 getNumInstances() const { return instanceData.size(); }
|
||||
static List<VertexData *> getList();
|
||||
static VertexData *findByTypeName(std::string name);
|
||||
virtual void init(Gfx::PGraphics graphics);
|
||||
virtual void destroy();
|
||||
|
||||
struct CullingMapping {
|
||||
uint64 instanceId;
|
||||
uint32 cullingOffset;
|
||||
};
|
||||
static CullingMapping getCullingMapping(entt::entity id, uint32 meshIndex,
|
||||
uint32 numMeshlets);
|
||||
static uint64 getInstanceCount() { return instanceCount; }
|
||||
static uint64 getMeshletCount() { return meshletCount; }
|
||||
|
||||
protected:
|
||||
virtual void resizeBuffers() = 0;
|
||||
virtual void updateBuffers() = 0;
|
||||
VertexData();
|
||||
struct MeshletDescription {
|
||||
AABB bounding;
|
||||
uint32 vertexCount;
|
||||
uint32 primitiveCount;
|
||||
uint32 vertexOffset;
|
||||
uint32 primitiveOffset;
|
||||
Vector color;
|
||||
uint32 indicesOffset = 0;
|
||||
};
|
||||
std::mutex materialDataLock;
|
||||
Array<MaterialData> materialData;
|
||||
std::mutex vertexDataLock;
|
||||
Map<MeshId, MeshData> meshData;
|
||||
Map<MeshId, uint64> meshOffsets;
|
||||
Map<MeshId, uint64> meshVertexCounts;
|
||||
Array<MeshletDescription> meshlets;
|
||||
Array<uint8> primitiveIndices;
|
||||
Array<uint32> vertexIndices;
|
||||
Array<uint32> indices;
|
||||
|
||||
struct MeshMapping {
|
||||
entt::entity id;
|
||||
uint32 meshId;
|
||||
auto operator<=>(const MeshMapping &other) const = default;
|
||||
};
|
||||
static Map<MeshMapping, CullingMapping> instanceIdMap;
|
||||
static uint64 instanceCount;
|
||||
static uint64 meshletCount;
|
||||
|
||||
Gfx::PGraphics graphics;
|
||||
Gfx::ODescriptorLayout instanceDataLayout;
|
||||
// for mesh shading
|
||||
Gfx::OShaderBuffer meshletBuffer;
|
||||
Gfx::OShaderBuffer vertexIndicesBuffer;
|
||||
Gfx::OShaderBuffer primitiveIndicesBuffer;
|
||||
Gfx::OShaderBuffer cullingOffsetBuffer;
|
||||
// for legacy pipeline
|
||||
Gfx::OIndexBuffer indexBuffer;
|
||||
// Material data
|
||||
Array<InstanceData> instanceData;
|
||||
Gfx::OShaderBuffer instanceBuffer;
|
||||
Array<MeshData> instanceMeshData;
|
||||
Gfx::OShaderBuffer instanceMeshDataBuffer;
|
||||
Gfx::PDescriptorSet descriptorSet;
|
||||
uint64 idCounter;
|
||||
uint64 head;
|
||||
uint64 verticesAllocated;
|
||||
bool dirty;
|
||||
Gfx::OShaderBuffer instanceMeshDataBuffer;
|
||||
Gfx::PDescriptorSet descriptorSet;
|
||||
uint64 idCounter;
|
||||
uint64 head;
|
||||
uint64 verticesAllocated;
|
||||
bool dirty;
|
||||
};
|
||||
} // namespace Seele
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
|
||||
// using namespace Seele::Vulkan;
|
||||
|
||||
// SubAllocation::SubAllocation(PAllocation owner, VkDeviceSize requestedSize, VkDeviceSize allocatedOffset, VkDeviceSize allocatedSize, VkDeviceSize alignedOffset)
|
||||
// SubAllocation::SubAllocation(PAllocation owner, VkDeviceSize requestedSize, VkDeviceSize allocatedOffset, VkDeviceSize allocatedSize,
|
||||
// VkDeviceSize alignedOffset)
|
||||
// : owner(owner)
|
||||
// , requestedSize(requestedSize)
|
||||
// , allocatedOffset(allocatedOffset)
|
||||
@@ -112,10 +113,9 @@
|
||||
|
||||
// void Allocation::markFree(PSubAllocation allocation)
|
||||
// {
|
||||
// //std::cout << "Freeing " << allocation->allocatedOffset << "-" << allocation->allocatedOffset + allocation->allocatedSize << std::endl;
|
||||
// assert(activeAllocations.find(allocation) != activeAllocations.end());
|
||||
// VkDeviceSize lowerBound = allocation->allocatedOffset;
|
||||
// VkDeviceSize upperBound = allocation->allocatedOffset + allocation->allocatedSize;
|
||||
// //std::cout << "Freeing " << allocation->allocatedOffset << "-" << allocation->allocatedOffset + allocation->allocatedSize <<
|
||||
// std::endl; assert(activeAllocations.find(allocation) != activeAllocations.end()); VkDeviceSize lowerBound =
|
||||
// allocation->allocatedOffset; VkDeviceSize upperBound = allocation->allocatedOffset + allocation->allocatedSize;
|
||||
// freeRanges[lowerBound] = allocation->allocatedSize;
|
||||
// for (const auto& [lower, size] : freeRanges)
|
||||
// {
|
||||
@@ -171,7 +171,7 @@
|
||||
// for (size_t i = 0; i < memProperties.memoryHeapCount; ++i)
|
||||
// {
|
||||
// VkMemoryHeap memoryHeap = memProperties.memoryHeaps[i];
|
||||
// HeapInfo heapInfo;
|
||||
// HeapInfo heapInfo;
|
||||
// heapInfo.maxSize = memoryHeap.size;
|
||||
// //std::cout << "Creating heap " << i << " with properties " << memoryHeap.flags << " size " << memoryHeap.size << std::endl;
|
||||
// heaps.add(std::move(heapInfo));
|
||||
@@ -182,7 +182,8 @@
|
||||
// {
|
||||
// }
|
||||
|
||||
// OSubAllocation Allocator::allocate(const VkMemoryRequirements2 &memRequirements2, VkMemoryPropertyFlags properties, VkMemoryDedicatedAllocateInfo *dedicatedInfo)
|
||||
// OSubAllocation Allocator::allocate(const VkMemoryRequirements2 &memRequirements2, VkMemoryPropertyFlags properties,
|
||||
// VkMemoryDedicatedAllocateInfo *dedicatedInfo)
|
||||
// {
|
||||
// const VkMemoryRequirements &requirements = memRequirements2.memoryRequirements;
|
||||
// uint32 memoryTypeIndex = findMemoryType(requirements.memoryTypeBits, properties);
|
||||
@@ -195,10 +196,10 @@
|
||||
// {
|
||||
// OAllocation newAllocation = new Allocation(graphics, this, requirements.size, memoryTypeIndex, properties, dedicatedInfo);
|
||||
// heaps[heapIndex].inUse += newAllocation->bytesAllocated;
|
||||
// std::cout << "Heap " << heapIndex << ": " << (float)heaps[heapIndex].inUse / heaps[heapIndex].maxSize * 100 << "%" << std::endl;
|
||||
// heaps[heapIndex].allocations.add(std::move(newAllocation));
|
||||
// return heaps[heapIndex].allocations.back()->getSuballocation(requirements.size, requirements.alignment);
|
||||
// }
|
||||
// std::cout << "Heap " << heapIndex << ": " << (float)heaps[heapIndex].inUse / heaps[heapIndex].maxSize * 100 << "%" <<
|
||||
// std::endl; heaps[heapIndex].allocations.add(std::move(newAllocation)); return
|
||||
// heaps[heapIndex].allocations.back()->getSuballocation(requirements.size, requirements.alignment);
|
||||
// }
|
||||
// }
|
||||
// for (auto& alloc : heaps[heapIndex].allocations)
|
||||
// {
|
||||
@@ -213,9 +214,9 @@
|
||||
// }
|
||||
|
||||
// // no suitable allocations found, allocate new block
|
||||
// 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 * 100 << "%" << std::endl;
|
||||
// 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 * 100 << "%" << std::endl;
|
||||
// heaps[heapIndex].allocations.add(std::move(newAllocation));
|
||||
// return heaps[heapIndex].allocations.back()->getSuballocation(requirements.size, requirements.alignment);
|
||||
// }
|
||||
@@ -241,16 +242,17 @@
|
||||
// std::cout << "Heap " << heapIndex << std::endl;
|
||||
// for (uint32 alloc = 0; alloc < heaps[heapIndex].allocations.size(); ++alloc)
|
||||
// {
|
||||
// std::cout << "[" << alloc << "]: " << (float)heaps[heapIndex].allocations[alloc]->bytesUsed / heaps[heapIndex].allocations[alloc]->bytesAllocated << std::endl;
|
||||
// std::cout << "[" << alloc << "]: " << (float)heaps[heapIndex].allocations[alloc]->bytesUsed /
|
||||
// heaps[heapIndex].allocations[alloc]->bytesAllocated << std::endl;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// uint32 Allocator::findMemoryType(uint32 typeFilter, VkMemoryPropertyFlags properties)
|
||||
// {
|
||||
// for (uint32 i = 0; i < memProperties.memoryTypeCount; i++)
|
||||
// for (uint32 i = 0; i < memProperties.memoryTypeCount; i++)
|
||||
// {
|
||||
// if ((typeFilter & (1 << i)) && (memProperties.memoryTypes[i].propertyFlags & properties) == properties)
|
||||
// if ((typeFilter & (1 << i)) && (memProperties.memoryTypes[i].propertyFlags & properties) == properties)
|
||||
// {
|
||||
// return i;
|
||||
// }
|
||||
@@ -334,7 +336,7 @@
|
||||
// .queueFamilyIndexCount = 1,
|
||||
// .pQueueFamilyIndices = &queueIndex,
|
||||
// };
|
||||
|
||||
|
||||
// VkBuffer buffer;
|
||||
// VK_CHECK(vkCreateBuffer(graphics->getDevice(), &stagingBufferCreateInfo, nullptr, &buffer));
|
||||
|
||||
@@ -361,7 +363,7 @@
|
||||
// owner
|
||||
// );
|
||||
// vkBindBufferMemory(graphics->getDevice(), buffer, stagingBuffer->getMemory(), stagingBuffer->getOffset());
|
||||
|
||||
|
||||
// return stagingBuffer;
|
||||
// }
|
||||
|
||||
|
||||
@@ -16,9 +16,8 @@
|
||||
// class SubAllocation
|
||||
// {
|
||||
// public:
|
||||
// SubAllocation(PAllocation owner, VkDeviceSize requestedSize, VkDeviceSize allocatedOffset, VkDeviceSize allocatedSize, VkDeviceSize alignedOffset);
|
||||
// ~SubAllocation();
|
||||
// VkDeviceMemory getHandle() const;
|
||||
// SubAllocation(PAllocation owner, VkDeviceSize requestedSize, VkDeviceSize allocatedOffset, VkDeviceSize allocatedSize, VkDeviceSize
|
||||
// alignedOffset); ~SubAllocation(); VkDeviceMemory getHandle() const;
|
||||
|
||||
// constexpr VkDeviceSize getSize() const
|
||||
// {
|
||||
|
||||
@@ -6,579 +6,472 @@
|
||||
using namespace Seele;
|
||||
using namespace Seele::Vulkan;
|
||||
|
||||
BufferAllocation::BufferAllocation(PGraphics graphics)
|
||||
: CommandBoundResource(graphics) {}
|
||||
BufferAllocation::BufferAllocation(PGraphics graphics) : CommandBoundResource(graphics) {}
|
||||
|
||||
BufferAllocation::~BufferAllocation() {
|
||||
if (buffer != VK_NULL_HANDLE) {
|
||||
vmaDestroyBuffer(graphics->getAllocator(), buffer, allocation);
|
||||
}
|
||||
if (buffer != VK_NULL_HANDLE) {
|
||||
vmaDestroyBuffer(graphics->getAllocator(), buffer, allocation);
|
||||
}
|
||||
}
|
||||
|
||||
struct PendingBuffer {
|
||||
OBufferAllocation allocation;
|
||||
uint64 offset;
|
||||
Gfx::QueueType prevQueue;
|
||||
bool writeOnly;
|
||||
OBufferAllocation allocation;
|
||||
uint64 offset;
|
||||
Gfx::QueueType prevQueue;
|
||||
bool writeOnly;
|
||||
};
|
||||
|
||||
static Map<Vulkan::Buffer *, PendingBuffer> pendingBuffers;
|
||||
static Map<Vulkan::Buffer*, PendingBuffer> pendingBuffers;
|
||||
|
||||
Buffer::Buffer(PGraphics graphics, uint64 size, VkBufferUsageFlags usage,
|
||||
Gfx::QueueType &queueType, bool dynamic, std::string name)
|
||||
Buffer::Buffer(PGraphics graphics, uint64 size, VkBufferUsageFlags usage, Gfx::QueueType& queueType, bool dynamic, std::string name)
|
||||
: graphics(graphics), currentBuffer(0), owner(queueType),
|
||||
usage(usage | VK_BUFFER_USAGE_TRANSFER_DST_BIT |
|
||||
VK_BUFFER_USAGE_TRANSFER_SRC_BIT),
|
||||
dynamic(dynamic), name(name) {
|
||||
createBuffer(size);
|
||||
usage(usage | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT), dynamic(dynamic), name(name) {
|
||||
createBuffer(size);
|
||||
}
|
||||
|
||||
Buffer::~Buffer() {
|
||||
for (uint32 i = 0; i < buffers.size(); ++i) {
|
||||
graphics->getDestructionManager()->queueResourceForDestruction(
|
||||
std::move(buffers[i]));
|
||||
}
|
||||
for (uint32 i = 0; i < buffers.size(); ++i) {
|
||||
graphics->getDestructionManager()->queueResourceForDestruction(std::move(buffers[i]));
|
||||
}
|
||||
}
|
||||
|
||||
void Buffer::executeOwnershipBarrier(Gfx::QueueType newOwner) {
|
||||
if (getSize() == 0)
|
||||
return;
|
||||
Gfx::QueueFamilyMapping mapping = graphics->getFamilyMapping();
|
||||
VkBufferMemoryBarrier barrier = {
|
||||
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
|
||||
.pNext = nullptr,
|
||||
.srcQueueFamilyIndex = mapping.getQueueTypeFamilyIndex(owner),
|
||||
.dstQueueFamilyIndex = mapping.getQueueTypeFamilyIndex(newOwner),
|
||||
.buffer = getHandle(),
|
||||
.offset = 0,
|
||||
.size = getSize(),
|
||||
};
|
||||
PCommandPool sourcePool = graphics->getQueueCommands(owner);
|
||||
PCommandPool dstPool = nullptr;
|
||||
VkPipelineStageFlags srcStage = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
|
||||
VkPipelineStageFlags dstStage = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
|
||||
assert(barrier.srcQueueFamilyIndex != barrier.dstQueueFamilyIndex);
|
||||
if (owner == Gfx::QueueType::TRANSFER) {
|
||||
barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
srcStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
|
||||
} else if (owner == Gfx::QueueType::COMPUTE) {
|
||||
barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
|
||||
srcStage = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
|
||||
} else if (owner == Gfx::QueueType::GRAPHICS) {
|
||||
barrier.srcAccessMask = getSourceAccessMask();
|
||||
srcStage = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT;
|
||||
}
|
||||
if (newOwner == Gfx::QueueType::TRANSFER) {
|
||||
barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
|
||||
dstStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
|
||||
dstPool = graphics->getTransferCommands();
|
||||
} else if (newOwner == Gfx::QueueType::COMPUTE) {
|
||||
barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
|
||||
dstStage = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
|
||||
dstPool = graphics->getComputeCommands();
|
||||
} else if (newOwner == Gfx::QueueType::GRAPHICS) {
|
||||
barrier.dstAccessMask = getDestAccessMask();
|
||||
dstStage = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT;
|
||||
dstPool = graphics->getGraphicsCommands();
|
||||
}
|
||||
VkCommandBuffer srcCommand = sourcePool->getCommands()->getHandle();
|
||||
VkCommandBuffer dstCommand = dstPool->getCommands()->getHandle();
|
||||
vkCmdPipelineBarrier(srcCommand, srcStage, srcStage, 0, 0, nullptr, 1,
|
||||
&barrier, 0, nullptr);
|
||||
vkCmdPipelineBarrier(dstCommand, dstStage, dstStage, 0, 0, nullptr, 1,
|
||||
&barrier, 0, nullptr);
|
||||
sourcePool->submitCommands();
|
||||
}
|
||||
|
||||
void Buffer::executePipelineBarrier(VkAccessFlags srcAccess,
|
||||
VkPipelineStageFlags srcStage,
|
||||
VkAccessFlags dstAccess,
|
||||
VkPipelineStageFlags dstStage) {
|
||||
if (getSize() == 0)
|
||||
return;
|
||||
PCommand commandBuffer = graphics->getQueueCommands(owner)->getCommands();
|
||||
VkBufferMemoryBarrier barrier = {
|
||||
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
|
||||
.pNext = nullptr,
|
||||
.srcAccessMask = srcAccess,
|
||||
.dstAccessMask = dstAccess,
|
||||
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.buffer = getHandle(),
|
||||
.offset = 0,
|
||||
.size = getSize(),
|
||||
};
|
||||
vkCmdPipelineBarrier(commandBuffer->getHandle(), srcStage, dstStage, 0, 0,
|
||||
nullptr, 1, &barrier, 0, nullptr);
|
||||
}
|
||||
|
||||
void *Buffer::map(bool writeOnly) { return mapRegion(0, getSize(), writeOnly); }
|
||||
|
||||
void *Buffer::mapRegion(uint64 regionOffset, uint64 regionSize,
|
||||
bool writeOnly) {
|
||||
if (regionSize == 0)
|
||||
return nullptr;
|
||||
void *data = nullptr;
|
||||
|
||||
PendingBuffer pending;
|
||||
pending.allocation = new BufferAllocation(graphics);
|
||||
pending.allocation->size = regionSize;
|
||||
pending.writeOnly = writeOnly;
|
||||
pending.prevQueue = owner;
|
||||
pending.offset = regionOffset;
|
||||
if (writeOnly) {
|
||||
if (buffers[currentBuffer]->properties &
|
||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) {
|
||||
VK_CHECK(vmaMapMemory(graphics->getAllocator(),
|
||||
buffers[currentBuffer]->allocation, &data));
|
||||
} else {
|
||||
VkBufferCreateInfo stagingInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
.flags = 0,
|
||||
.size = regionSize,
|
||||
.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
|
||||
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
|
||||
};
|
||||
VmaAllocationCreateInfo allocInfo = {
|
||||
.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT |
|
||||
VMA_ALLOCATION_CREATE_MAPPED_BIT,
|
||||
.usage = VMA_MEMORY_USAGE_AUTO,
|
||||
.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
|
||||
};
|
||||
VK_CHECK(vmaCreateBuffer(graphics->getAllocator(), &stagingInfo,
|
||||
&allocInfo, &pending.allocation->buffer,
|
||||
&pending.allocation->allocation, nullptr));
|
||||
vmaMapMemory(graphics->getAllocator(), pending.allocation->allocation,
|
||||
&data);
|
||||
vmaSetAllocationName(graphics->getAllocator(),
|
||||
pending.allocation->allocation, "MappingStaging");
|
||||
if (getSize() == 0)
|
||||
return;
|
||||
Gfx::QueueFamilyMapping mapping = graphics->getFamilyMapping();
|
||||
VkBufferMemoryBarrier barrier = {
|
||||
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
|
||||
.pNext = nullptr,
|
||||
.srcQueueFamilyIndex = mapping.getQueueTypeFamilyIndex(owner),
|
||||
.dstQueueFamilyIndex = mapping.getQueueTypeFamilyIndex(newOwner),
|
||||
.buffer = getHandle(),
|
||||
.offset = 0,
|
||||
.size = getSize(),
|
||||
};
|
||||
PCommandPool sourcePool = graphics->getQueueCommands(owner);
|
||||
PCommandPool dstPool = nullptr;
|
||||
VkPipelineStageFlags srcStage = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
|
||||
VkPipelineStageFlags dstStage = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
|
||||
assert(barrier.srcQueueFamilyIndex != barrier.dstQueueFamilyIndex);
|
||||
if (owner == Gfx::QueueType::TRANSFER) {
|
||||
barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
srcStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
|
||||
} else if (owner == Gfx::QueueType::COMPUTE) {
|
||||
barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
|
||||
srcStage = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
|
||||
} else if (owner == Gfx::QueueType::GRAPHICS) {
|
||||
barrier.srcAccessMask = getSourceAccessMask();
|
||||
srcStage = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT;
|
||||
}
|
||||
} else {
|
||||
assert(false);
|
||||
}
|
||||
pendingBuffers[this] = std::move(pending);
|
||||
if (newOwner == Gfx::QueueType::TRANSFER) {
|
||||
barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
|
||||
dstStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
|
||||
dstPool = graphics->getTransferCommands();
|
||||
} else if (newOwner == Gfx::QueueType::COMPUTE) {
|
||||
barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
|
||||
dstStage = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
|
||||
dstPool = graphics->getComputeCommands();
|
||||
} else if (newOwner == Gfx::QueueType::GRAPHICS) {
|
||||
barrier.dstAccessMask = getDestAccessMask();
|
||||
dstStage = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT;
|
||||
dstPool = graphics->getGraphicsCommands();
|
||||
}
|
||||
VkCommandBuffer srcCommand = sourcePool->getCommands()->getHandle();
|
||||
VkCommandBuffer dstCommand = dstPool->getCommands()->getHandle();
|
||||
vkCmdPipelineBarrier(srcCommand, srcStage, srcStage, 0, 0, nullptr, 1, &barrier, 0, nullptr);
|
||||
vkCmdPipelineBarrier(dstCommand, dstStage, dstStage, 0, 0, nullptr, 1, &barrier, 0, nullptr);
|
||||
sourcePool->submitCommands();
|
||||
}
|
||||
|
||||
assert(data);
|
||||
return data;
|
||||
void Buffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess,
|
||||
VkPipelineStageFlags dstStage) {
|
||||
if (getSize() == 0)
|
||||
return;
|
||||
PCommand commandBuffer = graphics->getQueueCommands(owner)->getCommands();
|
||||
VkBufferMemoryBarrier barrier = {
|
||||
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
|
||||
.pNext = nullptr,
|
||||
.srcAccessMask = srcAccess,
|
||||
.dstAccessMask = dstAccess,
|
||||
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.buffer = getHandle(),
|
||||
.offset = 0,
|
||||
.size = getSize(),
|
||||
};
|
||||
vkCmdPipelineBarrier(commandBuffer->getHandle(), srcStage, dstStage, 0, 0, nullptr, 1, &barrier, 0, nullptr);
|
||||
}
|
||||
|
||||
void* Buffer::map(bool writeOnly) { return mapRegion(0, getSize(), writeOnly); }
|
||||
|
||||
void* Buffer::mapRegion(uint64 regionOffset, uint64 regionSize, bool writeOnly) {
|
||||
if (regionSize == 0)
|
||||
return nullptr;
|
||||
void* data = nullptr;
|
||||
|
||||
PendingBuffer pending;
|
||||
pending.allocation = new BufferAllocation(graphics);
|
||||
pending.allocation->size = regionSize;
|
||||
pending.writeOnly = writeOnly;
|
||||
pending.prevQueue = owner;
|
||||
pending.offset = regionOffset;
|
||||
if (writeOnly) {
|
||||
if (buffers[currentBuffer]->properties & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) {
|
||||
VK_CHECK(vmaMapMemory(graphics->getAllocator(), buffers[currentBuffer]->allocation, &data));
|
||||
} else {
|
||||
VkBufferCreateInfo stagingInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
.flags = 0,
|
||||
.size = regionSize,
|
||||
.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
|
||||
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
|
||||
};
|
||||
VmaAllocationCreateInfo allocInfo = {
|
||||
.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT,
|
||||
.usage = VMA_MEMORY_USAGE_AUTO,
|
||||
.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
|
||||
};
|
||||
VK_CHECK(vmaCreateBuffer(graphics->getAllocator(), &stagingInfo, &allocInfo, &pending.allocation->buffer,
|
||||
&pending.allocation->allocation, nullptr));
|
||||
vmaMapMemory(graphics->getAllocator(), pending.allocation->allocation, &data);
|
||||
vmaSetAllocationName(graphics->getAllocator(), pending.allocation->allocation, "MappingStaging");
|
||||
}
|
||||
} else {
|
||||
assert(false);
|
||||
}
|
||||
pendingBuffers[this] = std::move(pending);
|
||||
|
||||
assert(data);
|
||||
return data;
|
||||
}
|
||||
|
||||
void Buffer::unmap() {
|
||||
auto found = pendingBuffers.find(this);
|
||||
if (found != pendingBuffers.end()) {
|
||||
PendingBuffer &pending = found->value;
|
||||
if (pending.writeOnly) {
|
||||
if (buffers[currentBuffer]->properties &
|
||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) {
|
||||
vmaUnmapMemory(graphics->getAllocator(),
|
||||
buffers[currentBuffer]->allocation);
|
||||
} else {
|
||||
vmaFlushAllocation(graphics->getAllocator(),
|
||||
pending.allocation->allocation, 0, VK_WHOLE_SIZE);
|
||||
vmaUnmapMemory(graphics->getAllocator(),
|
||||
pending.allocation->allocation);
|
||||
PCommand command = graphics->getQueueCommands(owner)->getCommands();
|
||||
command->bindResource(PBufferAllocation(pending.allocation));
|
||||
VkCommandBuffer cmdHandle = command->getHandle();
|
||||
auto found = pendingBuffers.find(this);
|
||||
if (found != pendingBuffers.end()) {
|
||||
PendingBuffer& pending = found->value;
|
||||
if (pending.writeOnly) {
|
||||
if (buffers[currentBuffer]->properties & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) {
|
||||
vmaUnmapMemory(graphics->getAllocator(), buffers[currentBuffer]->allocation);
|
||||
} else {
|
||||
vmaFlushAllocation(graphics->getAllocator(), pending.allocation->allocation, 0, VK_WHOLE_SIZE);
|
||||
vmaUnmapMemory(graphics->getAllocator(), pending.allocation->allocation);
|
||||
PCommand command = graphics->getQueueCommands(owner)->getCommands();
|
||||
command->bindResource(PBufferAllocation(pending.allocation));
|
||||
VkCommandBuffer cmdHandle = command->getHandle();
|
||||
|
||||
VkBufferCopy region = {
|
||||
.srcOffset = 0,
|
||||
.dstOffset = pending.offset,
|
||||
.size = pending.allocation->size,
|
||||
};
|
||||
VkBufferMemoryBarrier barrier = {
|
||||
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
|
||||
.pNext = nullptr,
|
||||
.srcAccessMask = VK_ACCESS_MEMORY_READ_BIT,
|
||||
.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.buffer = buffers[currentBuffer]->buffer,
|
||||
.offset = 0,
|
||||
.size = buffers[currentBuffer]->size,
|
||||
};
|
||||
vkCmdPipelineBarrier(cmdHandle, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 1,
|
||||
&barrier, 0, nullptr);
|
||||
vkCmdCopyBuffer(cmdHandle, pending.allocation->buffer,
|
||||
buffers[currentBuffer]->buffer, 1, ®ion);
|
||||
barrier = {
|
||||
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
|
||||
.pNext = nullptr,
|
||||
.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||
.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT,
|
||||
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.buffer = buffers[currentBuffer]->buffer,
|
||||
.offset = 0,
|
||||
.size = buffers[currentBuffer]->size,
|
||||
};
|
||||
vkCmdPipelineBarrier(cmdHandle, VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr,
|
||||
1, &barrier, 0, nullptr);
|
||||
graphics->getDestructionManager()->queueResourceForDestruction(
|
||||
std::move(pending.allocation));
|
||||
}
|
||||
VkBufferCopy region = {
|
||||
.srcOffset = 0,
|
||||
.dstOffset = pending.offset,
|
||||
.size = pending.allocation->size,
|
||||
};
|
||||
VkBufferMemoryBarrier barrier = {
|
||||
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
|
||||
.pNext = nullptr,
|
||||
.srcAccessMask = VK_ACCESS_MEMORY_READ_BIT,
|
||||
.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.buffer = buffers[currentBuffer]->buffer,
|
||||
.offset = 0,
|
||||
.size = buffers[currentBuffer]->size,
|
||||
};
|
||||
vkCmdPipelineBarrier(cmdHandle, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 1,
|
||||
&barrier, 0, nullptr);
|
||||
vkCmdCopyBuffer(cmdHandle, pending.allocation->buffer, buffers[currentBuffer]->buffer, 1, ®ion);
|
||||
barrier = {
|
||||
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
|
||||
.pNext = nullptr,
|
||||
.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||
.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT,
|
||||
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.buffer = buffers[currentBuffer]->buffer,
|
||||
.offset = 0,
|
||||
.size = buffers[currentBuffer]->size,
|
||||
};
|
||||
vkCmdPipelineBarrier(cmdHandle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 1,
|
||||
&barrier, 0, nullptr);
|
||||
graphics->getDestructionManager()->queueResourceForDestruction(std::move(pending.allocation));
|
||||
}
|
||||
}
|
||||
pendingBuffers.erase(this);
|
||||
}
|
||||
pendingBuffers.erase(this);
|
||||
}
|
||||
}
|
||||
|
||||
void Buffer::rotateBuffer(uint64 size, bool preserveContents) {
|
||||
assert(dynamic);
|
||||
size = std::max(getSize(), size);
|
||||
for (size_t i = 0; i < buffers.size(); ++i) {
|
||||
if (buffers[i]->isCurrentlyBound()) {
|
||||
continue;
|
||||
}
|
||||
if (buffers[i]->size < size) {
|
||||
vmaDestroyBuffer(graphics->getAllocator(), buffers[i]->buffer,
|
||||
buffers[i]->allocation);
|
||||
VkBufferCreateInfo info = {
|
||||
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
.size = size,
|
||||
.usage = usage,
|
||||
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
|
||||
};
|
||||
VmaAllocationCreateInfo allocInfo = {
|
||||
.flags =
|
||||
VMA_ALLOCATION_CREATE_HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT |
|
||||
VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT,
|
||||
.usage = VMA_MEMORY_USAGE_AUTO,
|
||||
};
|
||||
VK_CHECK(vmaCreateBuffer(graphics->getAllocator(), &info, &allocInfo,
|
||||
&buffers[i]->buffer, &buffers[i]->allocation,
|
||||
&buffers[i]->info));
|
||||
vmaGetAllocationMemoryProperties(graphics->getAllocator(),
|
||||
buffers[i]->allocation,
|
||||
&buffers[i]->properties);
|
||||
if (!name.empty()) {
|
||||
VkDebugUtilsObjectNameInfoEXT nameInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT,
|
||||
.pNext = nullptr,
|
||||
.objectType = VK_OBJECT_TYPE_BUFFER,
|
||||
.objectHandle = (uint64)buffers[i]->buffer,
|
||||
.pObjectName = this->name.c_str()};
|
||||
graphics->vkSetDebugUtilsObjectNameEXT(&nameInfo);
|
||||
}
|
||||
buffers[i]->size = size;
|
||||
assert(dynamic);
|
||||
size = std::max(getSize(), size);
|
||||
for (size_t i = 0; i < buffers.size(); ++i) {
|
||||
if (buffers[i]->isCurrentlyBound()) {
|
||||
continue;
|
||||
}
|
||||
if (buffers[i]->size < size) {
|
||||
vmaDestroyBuffer(graphics->getAllocator(), buffers[i]->buffer, buffers[i]->allocation);
|
||||
VkBufferCreateInfo info = {
|
||||
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
.size = size,
|
||||
.usage = usage,
|
||||
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
|
||||
};
|
||||
VmaAllocationCreateInfo allocInfo = {
|
||||
.flags =
|
||||
VMA_ALLOCATION_CREATE_HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT,
|
||||
.usage = VMA_MEMORY_USAGE_AUTO,
|
||||
};
|
||||
VK_CHECK(vmaCreateBuffer(graphics->getAllocator(), &info, &allocInfo, &buffers[i]->buffer, &buffers[i]->allocation,
|
||||
&buffers[i]->info));
|
||||
vmaGetAllocationMemoryProperties(graphics->getAllocator(), buffers[i]->allocation, &buffers[i]->properties);
|
||||
if (!name.empty()) {
|
||||
VkDebugUtilsObjectNameInfoEXT nameInfo = {.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT,
|
||||
.pNext = nullptr,
|
||||
.objectType = VK_OBJECT_TYPE_BUFFER,
|
||||
.objectHandle = (uint64)buffers[i]->buffer,
|
||||
.pObjectName = this->name.c_str()};
|
||||
graphics->vkSetDebugUtilsObjectNameEXT(&nameInfo);
|
||||
}
|
||||
buffers[i]->size = size;
|
||||
}
|
||||
if (preserveContents) {
|
||||
copyBuffer(currentBuffer, i);
|
||||
}
|
||||
currentBuffer = i;
|
||||
return;
|
||||
}
|
||||
createBuffer(size);
|
||||
if (preserveContents) {
|
||||
copyBuffer(currentBuffer, i);
|
||||
copyBuffer(currentBuffer, buffers.size() - 1);
|
||||
}
|
||||
currentBuffer = i;
|
||||
return;
|
||||
}
|
||||
createBuffer(size);
|
||||
if (preserveContents) {
|
||||
copyBuffer(currentBuffer, buffers.size() - 1);
|
||||
}
|
||||
currentBuffer = buffers.size() - 1;
|
||||
currentBuffer = buffers.size() - 1;
|
||||
}
|
||||
|
||||
void Buffer::createBuffer(uint64 size) {
|
||||
VkBufferCreateInfo info = {
|
||||
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
.size = size,
|
||||
.usage = usage,
|
||||
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
|
||||
};
|
||||
VmaAllocationCreateInfo allocInfo = {
|
||||
.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT |
|
||||
VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT,
|
||||
.usage = VMA_MEMORY_USAGE_AUTO,
|
||||
};
|
||||
buffers.add(new BufferAllocation(graphics));
|
||||
if (size > 0) {
|
||||
VK_CHECK(vmaCreateBuffer(
|
||||
graphics->getAllocator(), &info, &allocInfo, &buffers.back()->buffer,
|
||||
&buffers.back()->allocation, &buffers.back()->info));
|
||||
buffers.back()->size = size;
|
||||
vmaGetAllocationMemoryProperties(graphics->getAllocator(),
|
||||
buffers.back()->allocation,
|
||||
&buffers.back()->properties);
|
||||
VkBufferDeviceAddressInfo addrInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_KHR,
|
||||
VkBufferCreateInfo info = {
|
||||
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
.buffer = buffers.back()->buffer,
|
||||
.size = size,
|
||||
.usage = usage,
|
||||
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
|
||||
};
|
||||
buffers.back()->deviceAddress =
|
||||
vkGetBufferDeviceAddress(graphics->getDevice(), &addrInfo);
|
||||
if (!name.empty()) {
|
||||
VkDebugUtilsObjectNameInfoEXT nameInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT,
|
||||
.pNext = nullptr,
|
||||
.objectType = VK_OBJECT_TYPE_BUFFER,
|
||||
.objectHandle = (uint64)buffers.back()->buffer,
|
||||
.pObjectName = this->name.c_str()};
|
||||
graphics->vkSetDebugUtilsObjectNameEXT(&nameInfo);
|
||||
VmaAllocationCreateInfo allocInfo = {
|
||||
.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT,
|
||||
.usage = VMA_MEMORY_USAGE_AUTO,
|
||||
};
|
||||
buffers.add(new BufferAllocation(graphics));
|
||||
if (size > 0) {
|
||||
VK_CHECK(vmaCreateBuffer(graphics->getAllocator(), &info, &allocInfo, &buffers.back()->buffer, &buffers.back()->allocation,
|
||||
&buffers.back()->info));
|
||||
buffers.back()->size = size;
|
||||
vmaGetAllocationMemoryProperties(graphics->getAllocator(), buffers.back()->allocation, &buffers.back()->properties);
|
||||
VkBufferDeviceAddressInfo addrInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_KHR,
|
||||
.pNext = nullptr,
|
||||
.buffer = buffers.back()->buffer,
|
||||
};
|
||||
buffers.back()->deviceAddress = vkGetBufferDeviceAddress(graphics->getDevice(), &addrInfo);
|
||||
if (!name.empty()) {
|
||||
VkDebugUtilsObjectNameInfoEXT nameInfo = {.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT,
|
||||
.pNext = nullptr,
|
||||
.objectType = VK_OBJECT_TYPE_BUFFER,
|
||||
.objectHandle = (uint64)buffers.back()->buffer,
|
||||
.pObjectName = this->name.c_str()};
|
||||
graphics->vkSetDebugUtilsObjectNameEXT(&nameInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Buffer::copyBuffer(uint64 src, uint64 dst) {
|
||||
if (src == dst) {
|
||||
return;
|
||||
}
|
||||
PCommand command = graphics->getQueueCommands(owner)->getCommands();
|
||||
VkBufferMemoryBarrier srcBarrier = {
|
||||
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
|
||||
.pNext = nullptr,
|
||||
.srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT,
|
||||
.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT,
|
||||
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.buffer = buffers[src]->buffer,
|
||||
.offset = 0,
|
||||
.size = buffers[src]->size,
|
||||
};
|
||||
vkCmdPipelineBarrier(command->getHandle(),
|
||||
VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 1,
|
||||
&srcBarrier, 0, nullptr);
|
||||
VkBufferCopy region = {
|
||||
.srcOffset = 0, .dstOffset = 0, .size = buffers[src]->size};
|
||||
vkCmdCopyBuffer(command->getHandle(), buffers[src]->buffer,
|
||||
buffers[dst]->buffer, 1, ®ion);
|
||||
VkBufferMemoryBarrier dstBarrier = {
|
||||
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
|
||||
.pNext = nullptr,
|
||||
.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||
.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT,
|
||||
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.buffer = buffers[dst]->buffer,
|
||||
.offset = 0,
|
||||
.size = buffers[dst]->size,
|
||||
};
|
||||
vkCmdPipelineBarrier(command->getHandle(), VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0, nullptr, 1,
|
||||
&dstBarrier, 0, nullptr);
|
||||
if (src == dst) {
|
||||
return;
|
||||
}
|
||||
PCommand command = graphics->getQueueCommands(owner)->getCommands();
|
||||
VkBufferMemoryBarrier srcBarrier = {
|
||||
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
|
||||
.pNext = nullptr,
|
||||
.srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT,
|
||||
.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT,
|
||||
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.buffer = buffers[src]->buffer,
|
||||
.offset = 0,
|
||||
.size = buffers[src]->size,
|
||||
};
|
||||
vkCmdPipelineBarrier(command->getHandle(), VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 1,
|
||||
&srcBarrier, 0, nullptr);
|
||||
VkBufferCopy region = {.srcOffset = 0, .dstOffset = 0, .size = buffers[src]->size};
|
||||
vkCmdCopyBuffer(command->getHandle(), buffers[src]->buffer, buffers[dst]->buffer, 1, ®ion);
|
||||
VkBufferMemoryBarrier dstBarrier = {
|
||||
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
|
||||
.pNext = nullptr,
|
||||
.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||
.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT,
|
||||
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.buffer = buffers[dst]->buffer,
|
||||
.offset = 0,
|
||||
.size = buffers[dst]->size,
|
||||
};
|
||||
vkCmdPipelineBarrier(command->getHandle(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0, nullptr, 1,
|
||||
&dstBarrier, 0, nullptr);
|
||||
}
|
||||
|
||||
UniformBuffer::UniformBuffer(PGraphics graphics,
|
||||
const UniformBufferCreateInfo &createInfo)
|
||||
UniformBuffer::UniformBuffer(PGraphics graphics, const UniformBufferCreateInfo& createInfo)
|
||||
: Gfx::UniformBuffer(graphics->getFamilyMapping(), createInfo.sourceData),
|
||||
Vulkan::Buffer(graphics, createInfo.sourceData.size,
|
||||
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, currentOwner,
|
||||
createInfo.dynamic, createInfo.name) {
|
||||
if (getSize() > 0 && createInfo.sourceData.data != nullptr) {
|
||||
void *data = map();
|
||||
std::memcpy(data, createInfo.sourceData.data, createInfo.sourceData.size);
|
||||
unmap();
|
||||
}
|
||||
Vulkan::Buffer(graphics, createInfo.sourceData.size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, currentOwner, createInfo.dynamic,
|
||||
createInfo.name) {
|
||||
if (getSize() > 0 && createInfo.sourceData.data != nullptr) {
|
||||
void* data = map();
|
||||
std::memcpy(data, createInfo.sourceData.data, createInfo.sourceData.size);
|
||||
unmap();
|
||||
}
|
||||
}
|
||||
|
||||
UniformBuffer::~UniformBuffer() {}
|
||||
|
||||
void UniformBuffer::updateContents(const DataSource &sourceData) {
|
||||
void *data = map();
|
||||
std::memcpy(data, sourceData.data, sourceData.size);
|
||||
unmap();
|
||||
}
|
||||
|
||||
void UniformBuffer::rotateBuffer(uint64 size) {
|
||||
Vulkan::Buffer::rotateBuffer(size);
|
||||
}
|
||||
|
||||
void UniformBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner) {
|
||||
Gfx::QueueOwnedResource::transferOwnership(newOwner);
|
||||
}
|
||||
|
||||
void UniformBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) {
|
||||
Vulkan::Buffer::executeOwnershipBarrier(newOwner);
|
||||
}
|
||||
|
||||
void UniformBuffer::executePipelineBarrier(VkAccessFlags srcAccess,
|
||||
VkPipelineStageFlags srcStage,
|
||||
VkAccessFlags dstAccess,
|
||||
VkPipelineStageFlags dstStage) {
|
||||
Vulkan::Buffer::executePipelineBarrier(srcAccess, srcStage, dstAccess,
|
||||
dstStage);
|
||||
}
|
||||
|
||||
VkAccessFlags UniformBuffer::getSourceAccessMask() {
|
||||
return VK_ACCESS_MEMORY_WRITE_BIT;
|
||||
}
|
||||
|
||||
VkAccessFlags UniformBuffer::getDestAccessMask() {
|
||||
return VK_ACCESS_UNIFORM_READ_BIT;
|
||||
}
|
||||
|
||||
ShaderBuffer::ShaderBuffer(PGraphics graphics,
|
||||
const ShaderBufferCreateInfo &sourceData)
|
||||
: Gfx::ShaderBuffer(graphics->getFamilyMapping(), sourceData.numElements,
|
||||
sourceData.sourceData),
|
||||
Vulkan::Buffer(
|
||||
graphics, sourceData.sourceData.size,
|
||||
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
|
||||
(sourceData.vertexBuffer
|
||||
? VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR |
|
||||
VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT
|
||||
: 0),
|
||||
currentOwner, sourceData.dynamic, sourceData.name) {
|
||||
if (getSize() > 0 && sourceData.sourceData.data != nullptr) {
|
||||
void *data = map();
|
||||
std::memcpy(data, sourceData.sourceData.data, sourceData.sourceData.size);
|
||||
void UniformBuffer::updateContents(const DataSource& sourceData) {
|
||||
void* data = map();
|
||||
std::memcpy(data, sourceData.data, sourceData.size);
|
||||
unmap();
|
||||
}
|
||||
}
|
||||
|
||||
void UniformBuffer::rotateBuffer(uint64 size) { Vulkan::Buffer::rotateBuffer(size); }
|
||||
|
||||
void UniformBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner) { Gfx::QueueOwnedResource::transferOwnership(newOwner); }
|
||||
|
||||
void UniformBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) { Vulkan::Buffer::executeOwnershipBarrier(newOwner); }
|
||||
|
||||
void UniformBuffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess,
|
||||
VkPipelineStageFlags dstStage) {
|
||||
Vulkan::Buffer::executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
|
||||
}
|
||||
|
||||
VkAccessFlags UniformBuffer::getSourceAccessMask() { return VK_ACCESS_MEMORY_WRITE_BIT; }
|
||||
|
||||
VkAccessFlags UniformBuffer::getDestAccessMask() { return VK_ACCESS_UNIFORM_READ_BIT; }
|
||||
|
||||
ShaderBuffer::ShaderBuffer(PGraphics graphics, const ShaderBufferCreateInfo& sourceData)
|
||||
: Gfx::ShaderBuffer(graphics->getFamilyMapping(), sourceData.numElements, sourceData.sourceData),
|
||||
Vulkan::Buffer(graphics, sourceData.sourceData.size,
|
||||
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
|
||||
(sourceData.vertexBuffer ? VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR |
|
||||
VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT
|
||||
: 0),
|
||||
currentOwner, sourceData.dynamic, sourceData.name) {
|
||||
if (getSize() > 0 && sourceData.sourceData.data != nullptr) {
|
||||
void* data = map();
|
||||
std::memcpy(data, sourceData.sourceData.data, sourceData.sourceData.size);
|
||||
unmap();
|
||||
}
|
||||
}
|
||||
|
||||
ShaderBuffer::~ShaderBuffer() {}
|
||||
|
||||
void ShaderBuffer::updateContents(const ShaderBufferCreateInfo &createInfo) {
|
||||
if (createInfo.sourceData.data == nullptr) {
|
||||
return;
|
||||
}
|
||||
// We always want to update, as the contents could be different on the GPU
|
||||
void *data = map();
|
||||
std::memcpy((char *)data + createInfo.sourceData.offset,
|
||||
createInfo.sourceData.data, createInfo.sourceData.size);
|
||||
unmap();
|
||||
void ShaderBuffer::updateContents(const ShaderBufferCreateInfo& createInfo) {
|
||||
if (createInfo.sourceData.data == nullptr) {
|
||||
return;
|
||||
}
|
||||
// We always want to update, as the contents could be different on the GPU
|
||||
void* data = map();
|
||||
std::memcpy((char*)data + createInfo.sourceData.offset, createInfo.sourceData.data, createInfo.sourceData.size);
|
||||
unmap();
|
||||
}
|
||||
|
||||
void Seele::Vulkan::ShaderBuffer::rotateBuffer(uint64 size,
|
||||
bool preserveContents) {
|
||||
assert(dynamic);
|
||||
Vulkan::Buffer::rotateBuffer(size, preserveContents);
|
||||
void Seele::Vulkan::ShaderBuffer::rotateBuffer(uint64 size, bool preserveContents) {
|
||||
assert(dynamic);
|
||||
Vulkan::Buffer::rotateBuffer(size, preserveContents);
|
||||
}
|
||||
|
||||
void *ShaderBuffer::mapRegion(uint64 offset, uint64 size, bool writeOnly) {
|
||||
return Vulkan::Buffer::mapRegion(offset, size, writeOnly);
|
||||
}
|
||||
void* ShaderBuffer::mapRegion(uint64 offset, uint64 size, bool writeOnly) { return Vulkan::Buffer::mapRegion(offset, size, writeOnly); }
|
||||
|
||||
void ShaderBuffer::unmap() { Vulkan::Buffer::unmap(); }
|
||||
|
||||
void ShaderBuffer::clear() {
|
||||
vkCmdFillBuffer(graphics->getQueueCommands(owner)->getCommands()->getHandle(),
|
||||
Vulkan::Buffer::getHandle(), 0, VK_WHOLE_SIZE, 0);
|
||||
vkCmdFillBuffer(graphics->getQueueCommands(owner)->getCommands()->getHandle(), Vulkan::Buffer::getHandle(), 0, VK_WHOLE_SIZE, 0);
|
||||
}
|
||||
|
||||
void ShaderBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner) {
|
||||
Gfx::QueueOwnedResource::transferOwnership(newOwner);
|
||||
}
|
||||
void ShaderBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner) { Gfx::QueueOwnedResource::transferOwnership(newOwner); }
|
||||
|
||||
void ShaderBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) {
|
||||
Vulkan::Buffer::executeOwnershipBarrier(newOwner);
|
||||
}
|
||||
void ShaderBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) { Vulkan::Buffer::executeOwnershipBarrier(newOwner); }
|
||||
|
||||
void ShaderBuffer::executePipelineBarrier(VkAccessFlags srcAccess,
|
||||
VkPipelineStageFlags srcStage,
|
||||
VkAccessFlags dstAccess,
|
||||
void ShaderBuffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess,
|
||||
VkPipelineStageFlags dstStage) {
|
||||
Vulkan::Buffer::executePipelineBarrier(srcAccess, srcStage, dstAccess,
|
||||
dstStage);
|
||||
Vulkan::Buffer::executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
|
||||
}
|
||||
|
||||
VkAccessFlags ShaderBuffer::getSourceAccessMask() {
|
||||
return VK_ACCESS_MEMORY_WRITE_BIT;
|
||||
}
|
||||
VkAccessFlags ShaderBuffer::getSourceAccessMask() { return VK_ACCESS_MEMORY_WRITE_BIT; }
|
||||
|
||||
VkAccessFlags ShaderBuffer::getDestAccessMask() {
|
||||
return VK_ACCESS_MEMORY_READ_BIT;
|
||||
}
|
||||
VkAccessFlags ShaderBuffer::getDestAccessMask() { return VK_ACCESS_MEMORY_READ_BIT; }
|
||||
|
||||
VertexBuffer::VertexBuffer(PGraphics graphics,
|
||||
const VertexBufferCreateInfo &sourceData)
|
||||
: Gfx::VertexBuffer(graphics->getFamilyMapping(), sourceData.numVertices,
|
||||
sourceData.vertexSize, sourceData.sourceData.owner),
|
||||
Vulkan::Buffer(graphics, sourceData.sourceData.size,
|
||||
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, currentOwner, false,
|
||||
sourceData.name) {
|
||||
if (sourceData.sourceData.data != nullptr) {
|
||||
void *data = map();
|
||||
std::memcpy(data, sourceData.sourceData.data, sourceData.sourceData.size);
|
||||
unmap();
|
||||
}
|
||||
VertexBuffer::VertexBuffer(PGraphics graphics, const VertexBufferCreateInfo& sourceData)
|
||||
: Gfx::VertexBuffer(graphics->getFamilyMapping(), sourceData.numVertices, sourceData.vertexSize, sourceData.sourceData.owner),
|
||||
Vulkan::Buffer(graphics, sourceData.sourceData.size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, currentOwner, false, sourceData.name) {
|
||||
if (sourceData.sourceData.data != nullptr) {
|
||||
void* data = map();
|
||||
std::memcpy(data, sourceData.sourceData.data, sourceData.sourceData.size);
|
||||
unmap();
|
||||
}
|
||||
}
|
||||
|
||||
VertexBuffer::~VertexBuffer() {}
|
||||
|
||||
void VertexBuffer::updateRegion(DataSource update) {
|
||||
void *data = mapRegion(update.offset, update.size);
|
||||
std::memcpy(data, update.data, update.size);
|
||||
unmap();
|
||||
}
|
||||
|
||||
void VertexBuffer::download(Array<uint8> &buffer) {
|
||||
void *data = map(false);
|
||||
buffer.resize(getSize());
|
||||
std::memcpy(buffer.data(), data, getSize());
|
||||
unmap();
|
||||
}
|
||||
|
||||
void VertexBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner) {
|
||||
Gfx::QueueOwnedResource::transferOwnership(newOwner);
|
||||
}
|
||||
|
||||
void VertexBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) {
|
||||
Vulkan::Buffer::executeOwnershipBarrier(newOwner);
|
||||
}
|
||||
|
||||
void VertexBuffer::executePipelineBarrier(VkAccessFlags srcAccess,
|
||||
VkPipelineStageFlags srcStage,
|
||||
VkAccessFlags dstAccess,
|
||||
VkPipelineStageFlags dstStage) {
|
||||
Vulkan::Buffer::executePipelineBarrier(srcAccess, srcStage, dstAccess,
|
||||
dstStage);
|
||||
}
|
||||
|
||||
VkAccessFlags VertexBuffer::getSourceAccessMask() {
|
||||
return VK_ACCESS_MEMORY_WRITE_BIT;
|
||||
}
|
||||
|
||||
VkAccessFlags VertexBuffer::getDestAccessMask() {
|
||||
return VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;
|
||||
}
|
||||
|
||||
IndexBuffer::IndexBuffer(PGraphics graphics,
|
||||
const IndexBufferCreateInfo &sourceData)
|
||||
: Gfx::IndexBuffer(graphics->getFamilyMapping(), sourceData.sourceData.size,
|
||||
sourceData.indexType, sourceData.sourceData.owner),
|
||||
Vulkan::Buffer(
|
||||
graphics, sourceData.sourceData.size,
|
||||
VK_BUFFER_USAGE_INDEX_BUFFER_BIT |
|
||||
VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR |
|
||||
VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
|
||||
currentOwner, false, sourceData.name) {
|
||||
if (sourceData.sourceData.data != nullptr) {
|
||||
void *data = map();
|
||||
std::memcpy(data, sourceData.sourceData.data, sourceData.sourceData.size);
|
||||
void* data = mapRegion(update.offset, update.size);
|
||||
std::memcpy(data, update.data, update.size);
|
||||
unmap();
|
||||
}
|
||||
}
|
||||
|
||||
void VertexBuffer::download(Array<uint8>& buffer) {
|
||||
void* data = map(false);
|
||||
buffer.resize(getSize());
|
||||
std::memcpy(buffer.data(), data, getSize());
|
||||
unmap();
|
||||
}
|
||||
|
||||
void VertexBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner) { Gfx::QueueOwnedResource::transferOwnership(newOwner); }
|
||||
|
||||
void VertexBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) { Vulkan::Buffer::executeOwnershipBarrier(newOwner); }
|
||||
|
||||
void VertexBuffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess,
|
||||
VkPipelineStageFlags dstStage) {
|
||||
Vulkan::Buffer::executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
|
||||
}
|
||||
|
||||
VkAccessFlags VertexBuffer::getSourceAccessMask() { return VK_ACCESS_MEMORY_WRITE_BIT; }
|
||||
|
||||
VkAccessFlags VertexBuffer::getDestAccessMask() { return VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT; }
|
||||
|
||||
IndexBuffer::IndexBuffer(PGraphics graphics, const IndexBufferCreateInfo& sourceData)
|
||||
: Gfx::IndexBuffer(graphics->getFamilyMapping(), sourceData.sourceData.size, sourceData.indexType, sourceData.sourceData.owner),
|
||||
Vulkan::Buffer(graphics, sourceData.sourceData.size,
|
||||
VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR |
|
||||
VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
|
||||
currentOwner, false, sourceData.name) {
|
||||
if (sourceData.sourceData.data != nullptr) {
|
||||
void* data = map();
|
||||
std::memcpy(data, sourceData.sourceData.data, sourceData.sourceData.size);
|
||||
unmap();
|
||||
}
|
||||
}
|
||||
|
||||
IndexBuffer::~IndexBuffer() {}
|
||||
|
||||
void IndexBuffer::download(Array<uint8> &buffer) {
|
||||
void *data = map(false);
|
||||
buffer.resize(getSize());
|
||||
std::memcpy(buffer.data(), data, getSize());
|
||||
unmap();
|
||||
void IndexBuffer::download(Array<uint8>& buffer) {
|
||||
void* data = map(false);
|
||||
buffer.resize(getSize());
|
||||
std::memcpy(buffer.data(), data, getSize());
|
||||
unmap();
|
||||
}
|
||||
|
||||
void IndexBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner) {
|
||||
Gfx::QueueOwnedResource::transferOwnership(newOwner);
|
||||
}
|
||||
void IndexBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner) { Gfx::QueueOwnedResource::transferOwnership(newOwner); }
|
||||
|
||||
void IndexBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) {
|
||||
Vulkan::Buffer::executeOwnershipBarrier(newOwner);
|
||||
}
|
||||
void IndexBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) { Vulkan::Buffer::executeOwnershipBarrier(newOwner); }
|
||||
|
||||
void IndexBuffer::executePipelineBarrier(VkAccessFlags srcAccess,
|
||||
VkPipelineStageFlags srcStage,
|
||||
VkAccessFlags dstAccess,
|
||||
void IndexBuffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess,
|
||||
VkPipelineStageFlags dstStage) {
|
||||
Vulkan::Buffer::executePipelineBarrier(srcAccess, srcStage, dstAccess,
|
||||
dstStage);
|
||||
Vulkan::Buffer::executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
|
||||
}
|
||||
|
||||
VkAccessFlags IndexBuffer::getSourceAccessMask() {
|
||||
return VK_ACCESS_MEMORY_WRITE_BIT;
|
||||
}
|
||||
VkAccessFlags IndexBuffer::getSourceAccessMask() { return VK_ACCESS_MEMORY_WRITE_BIT; }
|
||||
|
||||
VkAccessFlags IndexBuffer::getDestAccessMask() {
|
||||
return VK_ACCESS_INDEX_READ_BIT;
|
||||
}
|
||||
VkAccessFlags IndexBuffer::getDestAccessMask() { return VK_ACCESS_INDEX_READ_BIT; }
|
||||
@@ -8,153 +8,133 @@ namespace Vulkan {
|
||||
DECLARE_REF(Command)
|
||||
DECLARE_REF(Fence)
|
||||
class BufferAllocation : public CommandBoundResource {
|
||||
public:
|
||||
BufferAllocation(PGraphics graphics);
|
||||
virtual ~BufferAllocation();
|
||||
VkBuffer buffer = VK_NULL_HANDLE;
|
||||
VmaAllocation allocation = VmaAllocation();
|
||||
VmaAllocationInfo info = VmaAllocationInfo();
|
||||
VkMemoryPropertyFlags properties = 0;
|
||||
uint64 size = 0;
|
||||
VkDeviceAddress deviceAddress;
|
||||
public:
|
||||
BufferAllocation(PGraphics graphics);
|
||||
virtual ~BufferAllocation();
|
||||
VkBuffer buffer = VK_NULL_HANDLE;
|
||||
VmaAllocation allocation = VmaAllocation();
|
||||
VmaAllocationInfo info = VmaAllocationInfo();
|
||||
VkMemoryPropertyFlags properties = 0;
|
||||
uint64 size = 0;
|
||||
VkDeviceAddress deviceAddress;
|
||||
};
|
||||
DEFINE_REF(BufferAllocation);
|
||||
class Buffer {
|
||||
public:
|
||||
Buffer(PGraphics graphics, uint64 size, VkBufferUsageFlags usage,
|
||||
Gfx::QueueType &queueType, bool dynamic, std::string name);
|
||||
virtual ~Buffer();
|
||||
VkBuffer getHandle() const { return buffers[currentBuffer]->buffer; }
|
||||
VkDeviceAddress getDeviceAddress() const {
|
||||
return buffers[currentBuffer]->deviceAddress;
|
||||
}
|
||||
PBufferAllocation getAlloc() const { return buffers[currentBuffer]; }
|
||||
uint64 getSize() const { return buffers[currentBuffer]->size; }
|
||||
void *map(bool writeOnly = true);
|
||||
void *mapRegion(uint64 regionOffset, uint64 regionSize,
|
||||
bool writeOnly = true);
|
||||
void unmap();
|
||||
public:
|
||||
Buffer(PGraphics graphics, uint64 size, VkBufferUsageFlags usage, Gfx::QueueType& queueType, bool dynamic, std::string name);
|
||||
virtual ~Buffer();
|
||||
VkBuffer getHandle() const { return buffers[currentBuffer]->buffer; }
|
||||
VkDeviceAddress getDeviceAddress() const { return buffers[currentBuffer]->deviceAddress; }
|
||||
PBufferAllocation getAlloc() const { return buffers[currentBuffer]; }
|
||||
uint64 getSize() const { return buffers[currentBuffer]->size; }
|
||||
void* map(bool writeOnly = true);
|
||||
void* mapRegion(uint64 regionOffset, uint64 regionSize, bool writeOnly = true);
|
||||
void unmap();
|
||||
|
||||
protected:
|
||||
PGraphics graphics;
|
||||
uint32 currentBuffer;
|
||||
Gfx::QueueType &owner;
|
||||
Array<OBufferAllocation> buffers;
|
||||
VkBufferUsageFlags usage;
|
||||
bool dynamic;
|
||||
std::string name;
|
||||
void rotateBuffer(uint64 size, bool preserveContents = false);
|
||||
void createBuffer(uint64 size);
|
||||
void copyBuffer(uint64 src, uint64 dest);
|
||||
protected:
|
||||
PGraphics graphics;
|
||||
uint32 currentBuffer;
|
||||
Gfx::QueueType& owner;
|
||||
Array<OBufferAllocation> buffers;
|
||||
VkBufferUsageFlags usage;
|
||||
bool dynamic;
|
||||
std::string name;
|
||||
void rotateBuffer(uint64 size, bool preserveContents = false);
|
||||
void createBuffer(uint64 size);
|
||||
void copyBuffer(uint64 src, uint64 dest);
|
||||
|
||||
void executeOwnershipBarrier(Gfx::QueueType newOwner);
|
||||
void executePipelineBarrier(VkAccessFlags srcAccess,
|
||||
VkPipelineStageFlags srcStage,
|
||||
VkAccessFlags dstAccess,
|
||||
VkPipelineStageFlags dstStage);
|
||||
void executeOwnershipBarrier(Gfx::QueueType newOwner);
|
||||
void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess,
|
||||
VkPipelineStageFlags dstStage);
|
||||
|
||||
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner) = 0;
|
||||
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner) = 0;
|
||||
|
||||
virtual VkAccessFlags getSourceAccessMask() = 0;
|
||||
virtual VkAccessFlags getDestAccessMask() = 0;
|
||||
virtual VkAccessFlags getSourceAccessMask() = 0;
|
||||
virtual VkAccessFlags getDestAccessMask() = 0;
|
||||
};
|
||||
DEFINE_REF(Buffer)
|
||||
|
||||
class VertexBuffer : public Gfx::VertexBuffer, public Buffer {
|
||||
public:
|
||||
VertexBuffer(PGraphics graphics, const VertexBufferCreateInfo &sourceData);
|
||||
virtual ~VertexBuffer();
|
||||
public:
|
||||
VertexBuffer(PGraphics graphics, const VertexBufferCreateInfo& sourceData);
|
||||
virtual ~VertexBuffer();
|
||||
|
||||
virtual void updateRegion(DataSource update) override;
|
||||
virtual void download(Array<uint8> &buffer) override;
|
||||
virtual void updateRegion(DataSource update) override;
|
||||
virtual void download(Array<uint8>& buffer) override;
|
||||
|
||||
protected:
|
||||
// Inherited via Vulkan::Buffer
|
||||
virtual VkAccessFlags getSourceAccessMask() override;
|
||||
virtual VkAccessFlags getDestAccessMask() override;
|
||||
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner) override;
|
||||
// Inherited via QueueOwnedResource
|
||||
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner) override;
|
||||
virtual void
|
||||
executePipelineBarrier(Gfx::SeAccessFlags srcAccess,
|
||||
Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess,
|
||||
Gfx::SePipelineStageFlags dstStage) override;
|
||||
protected:
|
||||
// Inherited via Vulkan::Buffer
|
||||
virtual VkAccessFlags getSourceAccessMask() override;
|
||||
virtual VkAccessFlags getDestAccessMask() override;
|
||||
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner) override;
|
||||
// Inherited via QueueOwnedResource
|
||||
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner) override;
|
||||
virtual void executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, Gfx::SeAccessFlags dstAccess,
|
||||
Gfx::SePipelineStageFlags dstStage) override;
|
||||
};
|
||||
DEFINE_REF(VertexBuffer)
|
||||
|
||||
class IndexBuffer : public Gfx::IndexBuffer, public Buffer {
|
||||
public:
|
||||
IndexBuffer(PGraphics graphics, const IndexBufferCreateInfo &sourceData);
|
||||
virtual ~IndexBuffer();
|
||||
public:
|
||||
IndexBuffer(PGraphics graphics, const IndexBufferCreateInfo& sourceData);
|
||||
virtual ~IndexBuffer();
|
||||
|
||||
virtual void download(Array<uint8> &buffer) override;
|
||||
virtual void download(Array<uint8>& buffer) override;
|
||||
|
||||
protected:
|
||||
// Inherited via Vulkan::Buffer
|
||||
virtual VkAccessFlags getSourceAccessMask() override;
|
||||
virtual VkAccessFlags getDestAccessMask() override;
|
||||
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner) override;
|
||||
// Inherited via QueueOwnedResource
|
||||
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner) override;
|
||||
virtual void
|
||||
executePipelineBarrier(Gfx::SeAccessFlags srcAccess,
|
||||
Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess,
|
||||
Gfx::SePipelineStageFlags dstStage) override;
|
||||
protected:
|
||||
// Inherited via Vulkan::Buffer
|
||||
virtual VkAccessFlags getSourceAccessMask() override;
|
||||
virtual VkAccessFlags getDestAccessMask() override;
|
||||
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner) override;
|
||||
// Inherited via QueueOwnedResource
|
||||
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner) override;
|
||||
virtual void executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, Gfx::SeAccessFlags dstAccess,
|
||||
Gfx::SePipelineStageFlags dstStage) override;
|
||||
};
|
||||
DEFINE_REF(IndexBuffer)
|
||||
class UniformBuffer : public Gfx::UniformBuffer, public Buffer {
|
||||
public:
|
||||
UniformBuffer(PGraphics graphics, const UniformBufferCreateInfo &sourceData);
|
||||
virtual ~UniformBuffer();
|
||||
virtual void updateContents(const DataSource &sourceData) override;
|
||||
virtual void rotateBuffer(uint64 size) override;
|
||||
public:
|
||||
UniformBuffer(PGraphics graphics, const UniformBufferCreateInfo& sourceData);
|
||||
virtual ~UniformBuffer();
|
||||
virtual void updateContents(const DataSource& sourceData) override;
|
||||
virtual void rotateBuffer(uint64 size) override;
|
||||
|
||||
protected:
|
||||
// Inherited via Vulkan::Buffer
|
||||
virtual VkAccessFlags getSourceAccessMask() override;
|
||||
virtual VkAccessFlags getDestAccessMask() override;
|
||||
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner) override;
|
||||
// Inherited via QueueOwnedResource
|
||||
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner) override;
|
||||
virtual void
|
||||
executePipelineBarrier(Gfx::SeAccessFlags srcAccess,
|
||||
Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess,
|
||||
Gfx::SePipelineStageFlags dstStage) override;
|
||||
protected:
|
||||
// Inherited via Vulkan::Buffer
|
||||
virtual VkAccessFlags getSourceAccessMask() override;
|
||||
virtual VkAccessFlags getDestAccessMask() override;
|
||||
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner) override;
|
||||
// Inherited via QueueOwnedResource
|
||||
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner) override;
|
||||
virtual void executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, Gfx::SeAccessFlags dstAccess,
|
||||
Gfx::SePipelineStageFlags dstStage) override;
|
||||
|
||||
private:
|
||||
private:
|
||||
};
|
||||
DEFINE_REF(UniformBuffer)
|
||||
|
||||
class ShaderBuffer : public Gfx::ShaderBuffer, public Buffer {
|
||||
public:
|
||||
ShaderBuffer(PGraphics graphics, const ShaderBufferCreateInfo &sourceData);
|
||||
virtual ~ShaderBuffer();
|
||||
virtual void
|
||||
updateContents(const ShaderBufferCreateInfo &createInfo) override;
|
||||
virtual void rotateBuffer(uint64 size,
|
||||
bool preserveContents = false) override;
|
||||
virtual void *mapRegion(uint64 offset, uint64 size, bool writeOnly) override;
|
||||
virtual void unmap() override;
|
||||
public:
|
||||
ShaderBuffer(PGraphics graphics, const ShaderBufferCreateInfo& sourceData);
|
||||
virtual ~ShaderBuffer();
|
||||
virtual void updateContents(const ShaderBufferCreateInfo& createInfo) override;
|
||||
virtual void rotateBuffer(uint64 size, bool preserveContents = false) override;
|
||||
virtual void* mapRegion(uint64 offset, uint64 size, bool writeOnly) override;
|
||||
virtual void unmap() override;
|
||||
|
||||
virtual void clear() override;
|
||||
virtual void clear() override;
|
||||
|
||||
protected:
|
||||
// Inherited via Vulkan::Buffer
|
||||
virtual VkAccessFlags getSourceAccessMask() override;
|
||||
virtual VkAccessFlags getDestAccessMask() override;
|
||||
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner) override;
|
||||
// Inherited via QueueOwnedResource
|
||||
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner) override;
|
||||
virtual void
|
||||
executePipelineBarrier(Gfx::SeAccessFlags srcAccess,
|
||||
Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess,
|
||||
Gfx::SePipelineStageFlags dstStage) override;
|
||||
protected:
|
||||
// Inherited via Vulkan::Buffer
|
||||
virtual VkAccessFlags getSourceAccessMask() override;
|
||||
virtual VkAccessFlags getDestAccessMask() override;
|
||||
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner) override;
|
||||
// Inherited via QueueOwnedResource
|
||||
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner) override;
|
||||
virtual void executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, Gfx::SeAccessFlags dstAccess,
|
||||
Gfx::SePipelineStageFlags dstStage) override;
|
||||
|
||||
private:
|
||||
private:
|
||||
};
|
||||
DEFINE_REF(ShaderBuffer)
|
||||
|
||||
|
||||
@@ -1,21 +1,17 @@
|
||||
#include "Command.h"
|
||||
#include "Graphics.h"
|
||||
#include "Pipeline.h"
|
||||
#include "Descriptor.h"
|
||||
#include "Enums.h"
|
||||
#include "Framebuffer.h"
|
||||
#include "RenderPass.h"
|
||||
#include "Graphics.h"
|
||||
#include "Pipeline.h"
|
||||
#include "Descriptor.h"
|
||||
#include "RenderPass.h"
|
||||
#include "Window.h"
|
||||
|
||||
|
||||
using namespace Seele;
|
||||
using namespace Seele::Vulkan;
|
||||
|
||||
|
||||
Command::Command(PGraphics graphics, PCommandPool pool)
|
||||
: graphics(graphics)
|
||||
, pool(pool)
|
||||
{
|
||||
Command::Command(PGraphics graphics, PCommandPool pool) : graphics(graphics), pool(pool) {
|
||||
VkCommandBufferAllocateInfo allocInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
|
||||
.pNext = nullptr,
|
||||
@@ -28,17 +24,15 @@ Command::Command(PGraphics graphics, PCommandPool pool)
|
||||
fence = new Fence(graphics);
|
||||
signalSemaphore = new Semaphore(graphics);
|
||||
state = State::Init;
|
||||
//std::cout << "Cmd " << handle << " semaphore " << signalSemaphore->getHandle() << std::endl;
|
||||
// std::cout << "Cmd " << handle << " semaphore " << signalSemaphore->getHandle() << std::endl;
|
||||
}
|
||||
|
||||
Command::~Command()
|
||||
{
|
||||
Command::~Command() {
|
||||
vkFreeCommandBuffers(graphics->getDevice(), pool->getHandle(), 1, &handle);
|
||||
waitSemaphores.clear();
|
||||
}
|
||||
|
||||
void Command::begin()
|
||||
{
|
||||
void Command::begin() {
|
||||
VkCommandBufferBeginInfo beginInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
|
||||
.pNext = nullptr,
|
||||
@@ -49,14 +43,12 @@ void Command::begin()
|
||||
state = State::Begin;
|
||||
}
|
||||
|
||||
void Command::end()
|
||||
{
|
||||
void Command::end() {
|
||||
VK_CHECK(vkEndCommandBuffer(handle));
|
||||
state = State::End;
|
||||
}
|
||||
|
||||
void Command::beginRenderPass(PRenderPass renderPass, PFramebuffer framebuffer)
|
||||
{
|
||||
void Command::beginRenderPass(PRenderPass renderPass, PFramebuffer framebuffer) {
|
||||
assert(state == State::Begin);
|
||||
boundRenderPass = renderPass;
|
||||
boundFramebuffer = framebuffer;
|
||||
@@ -73,8 +65,7 @@ void Command::beginRenderPass(PRenderPass renderPass, PFramebuffer framebuffer)
|
||||
state = State::RenderPass;
|
||||
}
|
||||
|
||||
void Command::endRenderPass()
|
||||
{
|
||||
void Command::endRenderPass() {
|
||||
boundRenderPass->endRenderPass();
|
||||
boundRenderPass = nullptr;
|
||||
boundFramebuffer = nullptr;
|
||||
@@ -82,23 +73,19 @@ void Command::endRenderPass()
|
||||
state = State::Begin;
|
||||
}
|
||||
|
||||
void Command::executeCommands(Array<Gfx::ORenderCommand> commands)
|
||||
{
|
||||
void Command::executeCommands(Array<Gfx::ORenderCommand> commands) {
|
||||
assert(state == State::RenderPass);
|
||||
if(commands.size() == 0)
|
||||
{
|
||||
//std::cout << "No commands provided" << std::endl;
|
||||
if (commands.size() == 0) {
|
||||
// std::cout << "No commands provided" << std::endl;
|
||||
return;
|
||||
}
|
||||
Array<VkCommandBuffer> cmdBuffers(commands.size());
|
||||
for (uint32 i = 0; i < commands.size(); ++i)
|
||||
{
|
||||
for (uint32 i = 0; i < commands.size(); ++i) {
|
||||
auto command = Gfx::PRenderCommand(commands[i]).cast<RenderCommand>();
|
||||
command->end();
|
||||
for(auto& descriptor : command->boundResources)
|
||||
{
|
||||
for (auto& descriptor : command->boundResources) {
|
||||
boundResources.add(descriptor);
|
||||
//std::cout << "Cmd " << handle << " bound descriptor " << descriptor->getHandle() << std::endl;
|
||||
// std::cout << "Cmd " << handle << " bound descriptor " << descriptor->getHandle() << std::endl;
|
||||
}
|
||||
cmdBuffers[i] = command->getHandle();
|
||||
executingRenders.add(std::move(commands[i]));
|
||||
@@ -106,21 +93,17 @@ void Command::executeCommands(Array<Gfx::ORenderCommand> commands)
|
||||
vkCmdExecuteCommands(handle, (uint32)cmdBuffers.size(), cmdBuffers.data());
|
||||
}
|
||||
|
||||
void Command::executeCommands(Array<Gfx::OComputeCommand> commands)
|
||||
{
|
||||
if(commands.size() == 0)
|
||||
{
|
||||
void Command::executeCommands(Array<Gfx::OComputeCommand> commands) {
|
||||
if (commands.size() == 0) {
|
||||
return;
|
||||
}
|
||||
Array<VkCommandBuffer> cmdBuffers(commands.size());
|
||||
for (uint32 i = 0; i < commands.size(); ++i)
|
||||
{
|
||||
for (uint32 i = 0; i < commands.size(); ++i) {
|
||||
auto command = Gfx::PComputeCommand(commands[i]).cast<ComputeCommand>();
|
||||
command->end();
|
||||
for(auto& descriptor : command->boundResources)
|
||||
{
|
||||
for (auto& descriptor : command->boundResources) {
|
||||
boundResources.add(descriptor);
|
||||
//std::cout << "Cmd " << handle << " bound descriptor " << descriptor->getHandle() << std::endl;
|
||||
// std::cout << "Cmd " << handle << " bound descriptor " << descriptor->getHandle() << std::endl;
|
||||
}
|
||||
cmdBuffers[i] = command->getHandle();
|
||||
executingComputes.add(std::move(commands[i]));
|
||||
@@ -128,35 +111,29 @@ void Command::executeCommands(Array<Gfx::OComputeCommand> commands)
|
||||
vkCmdExecuteCommands(handle, (uint32)cmdBuffers.size(), cmdBuffers.data());
|
||||
}
|
||||
|
||||
void Command::waitForSemaphore(VkPipelineStageFlags flags, PSemaphore semaphore)
|
||||
{
|
||||
void Command::waitForSemaphore(VkPipelineStageFlags flags, PSemaphore semaphore) {
|
||||
waitSemaphores.add(semaphore);
|
||||
waitFlags.add(flags);
|
||||
//std::cout << "Cmd " << handle << " wait for " << semaphore->getHandle() << std::endl;
|
||||
// std::cout << "Cmd " << handle << " wait for " << semaphore->getHandle() << std::endl;
|
||||
}
|
||||
|
||||
void Command::checkFence()
|
||||
{
|
||||
void Command::checkFence() {
|
||||
assert(state == State::Submit || !fence->isSignaled());
|
||||
if (fence->isSignaled())
|
||||
{
|
||||
//std::cout << "Cmd " << handle << " was signaled" << std::endl;
|
||||
if (fence->isSignaled()) {
|
||||
// std::cout << "Cmd " << handle << " was signaled" << std::endl;
|
||||
vkResetCommandBuffer(handle, VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT);
|
||||
fence->reset();
|
||||
for(auto& command : executingComputes)
|
||||
{
|
||||
for (auto& command : executingComputes) {
|
||||
command->reset();
|
||||
}
|
||||
pool->cacheCommands(std::move(executingComputes));
|
||||
for(auto& command : executingRenders)
|
||||
{
|
||||
for (auto& command : executingRenders) {
|
||||
command->reset();
|
||||
}
|
||||
pool->cacheCommands(std::move(executingRenders));
|
||||
for(auto& descriptor : boundResources)
|
||||
{
|
||||
for (auto& descriptor : boundResources) {
|
||||
descriptor->unbind();
|
||||
//std::cout << "Cmd " << handle << " unbind " << descriptor->getHandle() << std::endl;
|
||||
// std::cout << "Cmd " << handle << " unbind " << descriptor->getHandle() << std::endl;
|
||||
}
|
||||
boundResources.clear();
|
||||
graphics->getDestructionManager()->notifyCommandComplete();
|
||||
@@ -164,11 +141,9 @@ void Command::checkFence()
|
||||
}
|
||||
}
|
||||
|
||||
void Command::waitForCommand(uint32 timeout)
|
||||
{
|
||||
void Command::waitForCommand(uint32 timeout) {
|
||||
pool->submitCommands();
|
||||
if (state == State::Begin)
|
||||
{
|
||||
if (state == State::Begin) {
|
||||
// is already done
|
||||
return;
|
||||
}
|
||||
@@ -176,26 +151,16 @@ void Command::waitForCommand(uint32 timeout)
|
||||
checkFence();
|
||||
}
|
||||
|
||||
void Command::bindResource(PCommandBoundResource resource)
|
||||
{
|
||||
void Command::bindResource(PCommandBoundResource resource) {
|
||||
resource->bind();
|
||||
boundResources.add(resource);
|
||||
}
|
||||
|
||||
PFence Command::getFence()
|
||||
{
|
||||
return fence;
|
||||
}
|
||||
PFence Command::getFence() { return fence; }
|
||||
|
||||
PCommandPool Command::getPool()
|
||||
{
|
||||
return pool;
|
||||
}
|
||||
PCommandPool Command::getPool() { return pool; }
|
||||
|
||||
RenderCommand::RenderCommand(PGraphics graphics, VkCommandPool cmdPool)
|
||||
: graphics(graphics)
|
||||
, owner(cmdPool)
|
||||
{
|
||||
RenderCommand::RenderCommand(PGraphics graphics, VkCommandPool cmdPool) : graphics(graphics), owner(cmdPool) {
|
||||
VkCommandBufferAllocateInfo allocInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
|
||||
.pNext = nullptr,
|
||||
@@ -206,14 +171,9 @@ RenderCommand::RenderCommand(PGraphics graphics, VkCommandPool cmdPool)
|
||||
VK_CHECK(vkAllocateCommandBuffers(graphics->getDevice(), &allocInfo, &handle));
|
||||
}
|
||||
|
||||
RenderCommand::~RenderCommand() { vkFreeCommandBuffers(graphics->getDevice(), owner, 1, &handle); }
|
||||
|
||||
RenderCommand::~RenderCommand()
|
||||
{
|
||||
vkFreeCommandBuffers(graphics->getDevice(), owner, 1, &handle);
|
||||
}
|
||||
|
||||
void RenderCommand::begin(PRenderPass renderPass, PFramebuffer framebuffer)
|
||||
{
|
||||
void RenderCommand::begin(PRenderPass renderPass, PFramebuffer framebuffer) {
|
||||
threadId = std::this_thread::get_id();
|
||||
ready = false;
|
||||
VkCommandBufferInheritanceInfo inheritanceInfo = {
|
||||
@@ -234,93 +194,81 @@ void RenderCommand::begin(PRenderPass renderPass, PFramebuffer framebuffer)
|
||||
VK_CHECK(vkBeginCommandBuffer(handle, &beginInfo));
|
||||
}
|
||||
|
||||
void RenderCommand::end()
|
||||
{
|
||||
VK_CHECK(vkEndCommandBuffer(handle));
|
||||
}
|
||||
void RenderCommand::end() { VK_CHECK(vkEndCommandBuffer(handle)); }
|
||||
|
||||
void RenderCommand::reset()
|
||||
{
|
||||
void RenderCommand::reset() {
|
||||
vkResetCommandBuffer(handle, VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT);
|
||||
boundResources.clear();
|
||||
ready = true;
|
||||
}
|
||||
|
||||
bool RenderCommand::isReady()
|
||||
{
|
||||
return ready;
|
||||
}
|
||||
bool RenderCommand::isReady() { return ready; }
|
||||
|
||||
void RenderCommand::setViewport(Gfx::PViewport viewport)
|
||||
{
|
||||
void RenderCommand::setViewport(Gfx::PViewport viewport) {
|
||||
assert(threadId == std::this_thread::get_id());
|
||||
VkViewport vp = viewport.cast<Viewport>()->getHandle();
|
||||
VkRect2D scissors = {
|
||||
.offset = {
|
||||
.x = (int32)viewport->getOffsetX(),
|
||||
.y = (int32)viewport->getOffsetY(),
|
||||
},
|
||||
.extent = {
|
||||
.width = viewport->getWidth(),
|
||||
.height = viewport->getHeight(),
|
||||
},
|
||||
.offset =
|
||||
{
|
||||
.x = (int32)viewport->getOffsetX(),
|
||||
.y = (int32)viewport->getOffsetY(),
|
||||
},
|
||||
.extent =
|
||||
{
|
||||
.width = viewport->getWidth(),
|
||||
.height = viewport->getHeight(),
|
||||
},
|
||||
};
|
||||
vkCmdSetViewport(handle, 0, 1, &vp);
|
||||
vkCmdSetScissor(handle, 0, 1, &scissors);
|
||||
}
|
||||
|
||||
void RenderCommand::bindPipeline(Gfx::PGraphicsPipeline gfxPipeline)
|
||||
{
|
||||
void RenderCommand::bindPipeline(Gfx::PGraphicsPipeline gfxPipeline) {
|
||||
assert(threadId == std::this_thread::get_id());
|
||||
pipeline = gfxPipeline.cast<GraphicsPipeline>();
|
||||
pipeline->bind(handle);
|
||||
}
|
||||
void RenderCommand::bindDescriptor(Gfx::PDescriptorSet descriptorSet, Array<uint32> dynamicOffsets)
|
||||
{
|
||||
void RenderCommand::bindDescriptor(Gfx::PDescriptorSet descriptorSet, Array<uint32> dynamicOffsets) {
|
||||
assert(threadId == std::this_thread::get_id());
|
||||
auto descriptor = descriptorSet.cast<DescriptorSet>();
|
||||
assert(descriptor->writeDescriptors.size() == 0);
|
||||
descriptor->bind();
|
||||
boundResources.add(descriptor.getHandle());
|
||||
for (auto binding : descriptor->boundResources)
|
||||
{
|
||||
for (auto binding : descriptor->boundResources) {
|
||||
binding->bind();
|
||||
boundResources.add(binding);
|
||||
}
|
||||
|
||||
VkDescriptorSet setHandle = descriptor->getHandle();
|
||||
vkCmdBindDescriptorSets(handle, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->getLayout(), pipeline->getPipelineLayout()->findParameter(descriptorSet->getName()), 1, &setHandle, dynamicOffsets.size(), dynamicOffsets.data());
|
||||
vkCmdBindDescriptorSets(handle, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->getLayout(),
|
||||
pipeline->getPipelineLayout()->findParameter(descriptorSet->getName()), 1, &setHandle, dynamicOffsets.size(),
|
||||
dynamicOffsets.data());
|
||||
}
|
||||
|
||||
void RenderCommand::bindDescriptor(const Array<Gfx::PDescriptorSet>& descriptorSets, Array<uint32> dynamicOffsets)
|
||||
{
|
||||
void RenderCommand::bindDescriptor(const Array<Gfx::PDescriptorSet>& descriptorSets, Array<uint32> dynamicOffsets) {
|
||||
assert(threadId == std::this_thread::get_id());
|
||||
VkDescriptorSet* sets = new VkDescriptorSet[descriptorSets.size()];
|
||||
for(uint32 i = 0; i < descriptorSets.size(); ++i)
|
||||
{
|
||||
for (uint32 i = 0; i < descriptorSets.size(); ++i) {
|
||||
auto descriptorSet = descriptorSets[i].cast<DescriptorSet>();
|
||||
assert(descriptorSet->writeDescriptors.size() == 0);
|
||||
descriptorSet->bind();
|
||||
boundResources.add(descriptorSet.getHandle());
|
||||
|
||||
for (auto binding : descriptorSet->boundResources)
|
||||
{
|
||||
for (auto binding : descriptorSet->boundResources) {
|
||||
binding->bind();
|
||||
boundResources.add(binding);
|
||||
}
|
||||
sets[pipeline->getPipelineLayout()->findParameter(descriptorSet->getName())] = descriptorSet->getHandle();
|
||||
}
|
||||
vkCmdBindDescriptorSets(handle, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->getLayout(), 0, (uint32)descriptorSets.size(), sets, dynamicOffsets.size(), dynamicOffsets.data());
|
||||
vkCmdBindDescriptorSets(handle, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->getLayout(), 0, (uint32)descriptorSets.size(), sets,
|
||||
dynamicOffsets.size(), dynamicOffsets.data());
|
||||
delete[] sets;
|
||||
|
||||
}
|
||||
void RenderCommand::bindVertexBuffer(const Array<Gfx::PVertexBuffer>& streams)
|
||||
{
|
||||
void RenderCommand::bindVertexBuffer(const Array<Gfx::PVertexBuffer>& streams) {
|
||||
assert(threadId == std::this_thread::get_id());
|
||||
Array<VkBuffer> buffers(streams.size());
|
||||
Array<VkDeviceSize> offsets(streams.size());
|
||||
for(uint32 i = 0; i < streams.size(); ++i)
|
||||
{
|
||||
for (uint32 i = 0; i < streams.size(); ++i) {
|
||||
PVertexBuffer buf = streams[i].cast<VertexBuffer>();
|
||||
buffers[i] = buf->getHandle();
|
||||
offsets[i] = 0;
|
||||
@@ -329,8 +277,7 @@ void RenderCommand::bindVertexBuffer(const Array<Gfx::PVertexBuffer>& streams)
|
||||
};
|
||||
vkCmdBindVertexBuffers(handle, 0, (uint32)streams.size(), buffers.data(), offsets.data());
|
||||
}
|
||||
void RenderCommand::bindIndexBuffer(Gfx::PIndexBuffer indexBuffer)
|
||||
{
|
||||
void RenderCommand::bindIndexBuffer(Gfx::PIndexBuffer indexBuffer) {
|
||||
assert(threadId == std::this_thread::get_id());
|
||||
PIndexBuffer buf = indexBuffer.cast<IndexBuffer>();
|
||||
buf->getAlloc()->bind();
|
||||
@@ -338,39 +285,31 @@ void RenderCommand::bindIndexBuffer(Gfx::PIndexBuffer indexBuffer)
|
||||
vkCmdBindIndexBuffer(handle, buf->getHandle(), 0, cast(buf->getIndexType()));
|
||||
}
|
||||
|
||||
void RenderCommand::pushConstants(Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size, const void* data)
|
||||
{
|
||||
void RenderCommand::pushConstants(Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size, const void* data) {
|
||||
assert(threadId == std::this_thread::get_id());
|
||||
vkCmdPushConstants(handle, pipeline->getLayout(), stage, offset, size, data);
|
||||
}
|
||||
|
||||
void RenderCommand::draw(uint32 vertexCount, uint32 instanceCount, int32 firstVertex, uint32 firstInstance)
|
||||
{
|
||||
void RenderCommand::draw(uint32 vertexCount, uint32 instanceCount, int32 firstVertex, uint32 firstInstance) {
|
||||
assert(threadId == std::this_thread::get_id());
|
||||
vkCmdDraw(handle, vertexCount, instanceCount, firstVertex, firstInstance);
|
||||
}
|
||||
|
||||
void RenderCommand::drawIndexed(uint32 indexCount, uint32 instanceCount, int32 firstIndex, uint32 vertexOffset, uint32 firstInstance)
|
||||
{
|
||||
void RenderCommand::drawIndexed(uint32 indexCount, uint32 instanceCount, int32 firstIndex, uint32 vertexOffset, uint32 firstInstance) {
|
||||
assert(threadId == std::this_thread::get_id());
|
||||
vkCmdDrawIndexed(handle, indexCount, instanceCount, firstIndex, vertexOffset, firstInstance);
|
||||
}
|
||||
void RenderCommand::drawMesh(uint32 groupX, uint32 groupY, uint32 groupZ)
|
||||
{
|
||||
void RenderCommand::drawMesh(uint32 groupX, uint32 groupY, uint32 groupZ) {
|
||||
assert(threadId == std::this_thread::get_id());
|
||||
graphics->vkCmdDrawMeshTasksEXT(handle, groupX, groupY, groupZ);
|
||||
}
|
||||
|
||||
void RenderCommand::drawMeshIndirect(Gfx::PShaderBuffer buffer, uint64 offset, uint32 drawCount, uint32 stride)
|
||||
{
|
||||
void RenderCommand::drawMeshIndirect(Gfx::PShaderBuffer buffer, uint64 offset, uint32 drawCount, uint32 stride) {
|
||||
assert(threadId == std::this_thread::get_id());
|
||||
graphics->vkCmdDrawMeshTasksIndirectEXT(handle, buffer.cast<ShaderBuffer>()->getHandle(), offset, drawCount, stride);
|
||||
}
|
||||
|
||||
ComputeCommand::ComputeCommand(PGraphics graphics, VkCommandPool cmdPool)
|
||||
: graphics(graphics)
|
||||
, owner(cmdPool)
|
||||
{
|
||||
ComputeCommand::ComputeCommand(PGraphics graphics, VkCommandPool cmdPool) : graphics(graphics), owner(cmdPool) {
|
||||
VkCommandBufferAllocateInfo allocInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
|
||||
.pNext = nullptr,
|
||||
@@ -381,14 +320,9 @@ ComputeCommand::ComputeCommand(PGraphics graphics, VkCommandPool cmdPool)
|
||||
VK_CHECK(vkAllocateCommandBuffers(graphics->getDevice(), &allocInfo, &handle));
|
||||
}
|
||||
|
||||
ComputeCommand::~ComputeCommand() { vkFreeCommandBuffers(graphics->getDevice(), owner, 1, &handle); }
|
||||
|
||||
ComputeCommand::~ComputeCommand()
|
||||
{
|
||||
vkFreeCommandBuffers(graphics->getDevice(), owner, 1, &handle);
|
||||
}
|
||||
|
||||
void ComputeCommand::begin()
|
||||
{
|
||||
void ComputeCommand::begin() {
|
||||
threadId = std::this_thread::get_id();
|
||||
ready = false;
|
||||
VkCommandBufferInheritanceInfo inheritanceInfo = {
|
||||
@@ -409,86 +343,74 @@ void ComputeCommand::begin()
|
||||
VK_CHECK(vkBeginCommandBuffer(handle, &beginInfo));
|
||||
}
|
||||
|
||||
void ComputeCommand::end()
|
||||
{
|
||||
void ComputeCommand::end() {
|
||||
assert(threadId == std::this_thread::get_id());
|
||||
VK_CHECK(vkEndCommandBuffer(handle));
|
||||
}
|
||||
|
||||
void ComputeCommand::reset()
|
||||
{
|
||||
void ComputeCommand::reset() {
|
||||
assert(threadId == std::this_thread::get_id());
|
||||
vkResetCommandBuffer(handle, VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT);
|
||||
boundResources.clear();
|
||||
ready = true;
|
||||
}
|
||||
bool ComputeCommand::isReady()
|
||||
{
|
||||
return ready;
|
||||
}
|
||||
bool ComputeCommand::isReady() { return ready; }
|
||||
|
||||
void ComputeCommand::bindPipeline(Gfx::PComputePipeline computePipeline)
|
||||
{
|
||||
void ComputeCommand::bindPipeline(Gfx::PComputePipeline computePipeline) {
|
||||
assert(threadId == std::this_thread::get_id());
|
||||
pipeline = computePipeline.cast<ComputePipeline>();
|
||||
pipeline->bind(handle);
|
||||
}
|
||||
|
||||
void ComputeCommand::bindDescriptor(Gfx::PDescriptorSet descriptorSet, Array<uint32> dynamicOffsets)
|
||||
{
|
||||
void ComputeCommand::bindDescriptor(Gfx::PDescriptorSet descriptorSet, Array<uint32> dynamicOffsets) {
|
||||
assert(threadId == std::this_thread::get_id());
|
||||
auto descriptor = descriptorSet.cast<DescriptorSet>();
|
||||
assert(descriptor->writeDescriptors.size() == 0);
|
||||
boundResources.add(descriptor.getHandle());
|
||||
|
||||
for (auto binding : descriptor->boundResources)
|
||||
{
|
||||
for (auto binding : descriptor->boundResources) {
|
||||
binding->bind();
|
||||
boundResources.add(binding);
|
||||
}
|
||||
|
||||
|
||||
VkDescriptorSet setHandle = descriptor->getHandle();
|
||||
vkCmdBindDescriptorSets(handle, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline->getLayout(), pipeline->getPipelineLayout()->findParameter(descriptorSet->getName()), 1, &setHandle, dynamicOffsets.size(), dynamicOffsets.data());
|
||||
vkCmdBindDescriptorSets(handle, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline->getLayout(),
|
||||
pipeline->getPipelineLayout()->findParameter(descriptorSet->getName()), 1, &setHandle, dynamicOffsets.size(),
|
||||
dynamicOffsets.data());
|
||||
}
|
||||
|
||||
void ComputeCommand::bindDescriptor(const Array<Gfx::PDescriptorSet>& descriptorSets, Array<uint32> dynamicOffsets)
|
||||
{
|
||||
void ComputeCommand::bindDescriptor(const Array<Gfx::PDescriptorSet>& descriptorSets, Array<uint32> dynamicOffsets) {
|
||||
assert(threadId == std::this_thread::get_id());
|
||||
VkDescriptorSet* sets = new VkDescriptorSet[descriptorSets.size()];
|
||||
for(uint32 i = 0; i < descriptorSets.size(); ++i)
|
||||
{
|
||||
for (uint32 i = 0; i < descriptorSets.size(); ++i) {
|
||||
auto descriptorSet = descriptorSets[i].cast<DescriptorSet>();
|
||||
assert(descriptorSet->writeDescriptors.size() == 0);
|
||||
descriptorSet->bind();
|
||||
boundResources.add(descriptorSet.getHandle());
|
||||
|
||||
//std::cout << "Binding descriptor " << descriptorSet->getHandle() << " to cmd " << handle << std::endl;
|
||||
for (auto binding : descriptorSet->boundResources)
|
||||
{
|
||||
// std::cout << "Binding descriptor " << descriptorSet->getHandle() << " to cmd " << handle << std::endl;
|
||||
for (auto binding : descriptorSet->boundResources) {
|
||||
binding->bind();
|
||||
boundResources.add(binding);
|
||||
}
|
||||
sets[pipeline->getPipelineLayout()->findParameter(descriptorSet->getName())] = descriptorSet->getHandle();
|
||||
}
|
||||
vkCmdBindDescriptorSets(handle, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline->getLayout(), 0, (uint32)descriptorSets.size(), sets, dynamicOffsets.size(), dynamicOffsets.data());
|
||||
vkCmdBindDescriptorSets(handle, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline->getLayout(), 0, (uint32)descriptorSets.size(), sets,
|
||||
dynamicOffsets.size(), dynamicOffsets.data());
|
||||
delete[] sets;
|
||||
}
|
||||
|
||||
void ComputeCommand::pushConstants(Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size, const void* data)
|
||||
{
|
||||
void ComputeCommand::pushConstants(Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size, const void* data) {
|
||||
assert(threadId == std::this_thread::get_id());
|
||||
vkCmdPushConstants(handle, pipeline->getLayout(), stage, offset, size, data);
|
||||
}
|
||||
|
||||
void ComputeCommand::dispatch(uint32 threadX, uint32 threadY, uint32 threadZ)
|
||||
{
|
||||
void ComputeCommand::dispatch(uint32 threadX, uint32 threadY, uint32 threadZ) {
|
||||
assert(threadId == std::this_thread::get_id());
|
||||
vkCmdDispatch(handle, threadX, threadY, threadZ);
|
||||
}
|
||||
|
||||
CommandPool::CommandPool(PGraphics graphics, PQueue queue)
|
||||
: graphics(graphics), queue(queue), queueFamilyIndex(queue->getFamilyIndex())
|
||||
{
|
||||
CommandPool::CommandPool(PGraphics graphics, PQueue queue) : graphics(graphics), queue(queue), queueFamilyIndex(queue->getFamilyIndex()) {
|
||||
VkCommandPoolCreateInfo info = {
|
||||
.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
@@ -498,16 +420,14 @@ CommandPool::CommandPool(PGraphics graphics, PQueue queue)
|
||||
VK_CHECK(vkCreateCommandPool(graphics->getDevice(), &info, nullptr, &commandPool));
|
||||
// TODO: dont reset individual commands, reset pool instead
|
||||
allocatedBuffers.add(new Command(graphics, this));
|
||||
|
||||
|
||||
command = allocatedBuffers.back();
|
||||
command->begin();
|
||||
}
|
||||
|
||||
CommandPool::~CommandPool()
|
||||
{
|
||||
CommandPool::~CommandPool() {
|
||||
vkDeviceWaitIdle(graphics->getDevice());
|
||||
for (auto& cmd : allocatedBuffers)
|
||||
{
|
||||
for (auto& cmd : allocatedBuffers) {
|
||||
cmd->checkFence();
|
||||
}
|
||||
allocatedRenderCommands.clear();
|
||||
@@ -518,32 +438,22 @@ CommandPool::~CommandPool()
|
||||
queue = nullptr;
|
||||
}
|
||||
|
||||
PCommand CommandPool::getCommands()
|
||||
{
|
||||
return command;
|
||||
}
|
||||
void CommandPool::cacheCommands(Array<ORenderCommand> commands)
|
||||
{
|
||||
for(auto&& cmd : commands)
|
||||
{
|
||||
allocatedRenderCommands.add(std::move(cmd));
|
||||
}
|
||||
PCommand CommandPool::getCommands() { return command; }
|
||||
void CommandPool::cacheCommands(Array<ORenderCommand> commands) {
|
||||
for (auto&& cmd : commands) {
|
||||
allocatedRenderCommands.add(std::move(cmd));
|
||||
}
|
||||
}
|
||||
|
||||
void CommandPool::cacheCommands(Array<OComputeCommand> commands)
|
||||
{
|
||||
for(auto&& cmd : commands)
|
||||
{
|
||||
allocatedComputeCommands.add(std::move(cmd));
|
||||
}
|
||||
void CommandPool::cacheCommands(Array<OComputeCommand> commands) {
|
||||
for (auto&& cmd : commands) {
|
||||
allocatedComputeCommands.add(std::move(cmd));
|
||||
}
|
||||
}
|
||||
|
||||
ORenderCommand CommandPool::createRenderCommand(const std::string& name)
|
||||
{
|
||||
for (uint32 i = 0; i < allocatedRenderCommands.size(); ++i)
|
||||
{
|
||||
if (allocatedRenderCommands[i]->isReady())
|
||||
{
|
||||
ORenderCommand CommandPool::createRenderCommand(const std::string& name) {
|
||||
for (uint32 i = 0; i < allocatedRenderCommands.size(); ++i) {
|
||||
if (allocatedRenderCommands[i]->isReady()) {
|
||||
ORenderCommand cmdBuffer = std::move(allocatedRenderCommands[i]);
|
||||
allocatedRenderCommands.removeAt(i, false);
|
||||
cmdBuffer->name = name;
|
||||
@@ -557,12 +467,9 @@ ORenderCommand CommandPool::createRenderCommand(const std::string& name)
|
||||
return result;
|
||||
}
|
||||
|
||||
OComputeCommand CommandPool::createComputeCommand(const std::string& name)
|
||||
{
|
||||
for (uint32 i = 0; i < allocatedComputeCommands.size(); ++i)
|
||||
{
|
||||
if (allocatedComputeCommands[i]->isReady())
|
||||
{
|
||||
OComputeCommand CommandPool::createComputeCommand(const std::string& name) {
|
||||
for (uint32 i = 0; i < allocatedComputeCommands.size(); ++i) {
|
||||
if (allocatedComputeCommands[i]->isReady()) {
|
||||
OComputeCommand cmdBuffer = std::move(allocatedComputeCommands[i]);
|
||||
allocatedComputeCommands.removeAt(i, false);
|
||||
cmdBuffer->name = name;
|
||||
@@ -576,32 +483,26 @@ OComputeCommand CommandPool::createComputeCommand(const std::string& name)
|
||||
return result;
|
||||
}
|
||||
|
||||
void CommandPool::submitCommands(PSemaphore signalSemaphore)
|
||||
{
|
||||
void CommandPool::submitCommands(PSemaphore signalSemaphore) {
|
||||
assert(command->state == Command::State::Begin); // Not in a renderpass
|
||||
command->end();
|
||||
Array<VkSemaphore> semaphores = { command->signalSemaphore->getHandle() };
|
||||
if (signalSemaphore != nullptr)
|
||||
{
|
||||
Array<VkSemaphore> semaphores = {command->signalSemaphore->getHandle()};
|
||||
if (signalSemaphore != nullptr) {
|
||||
semaphores.add(signalSemaphore->getHandle());
|
||||
}
|
||||
queue->submitCommandBuffer(command, semaphores);
|
||||
//std::cout << "Cmd " << command->getHandle() << " signalling " << command->signalSemaphore->getHandle() << std::endl;
|
||||
// std::cout << "Cmd " << command->getHandle() << " signalling " << command->signalSemaphore->getHandle() << std::endl;
|
||||
|
||||
PSemaphore waitSemaphore = command->signalSemaphore;
|
||||
for (uint32 i = 0; i < allocatedBuffers.size(); ++i)
|
||||
{
|
||||
for (uint32 i = 0; i < allocatedBuffers.size(); ++i) {
|
||||
PCommand cmdBuffer = allocatedBuffers[i];
|
||||
cmdBuffer->checkFence();
|
||||
if (cmdBuffer->state == Command::State::Init)
|
||||
{
|
||||
if (cmdBuffer->state == Command::State::Init) {
|
||||
command = cmdBuffer;
|
||||
command->begin();
|
||||
command->waitForSemaphore(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, waitSemaphore);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
assert(cmdBuffer->state == Command::State::Submit);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,143 +14,140 @@ DECLARE_REF(ComputeCommand)
|
||||
DECLARE_REF(DescriptorSet)
|
||||
DECLARE_REF(CommandPool)
|
||||
class Command {
|
||||
public:
|
||||
Command(PGraphics graphics, PCommandPool pool);
|
||||
~Command();
|
||||
constexpr VkCommandBuffer getHandle() { return handle; }
|
||||
void reset();
|
||||
void begin();
|
||||
void end();
|
||||
void beginRenderPass(PRenderPass renderPass, PFramebuffer framebuffer);
|
||||
void endRenderPass();
|
||||
void executeCommands(Array<Gfx::ORenderCommand> secondaryCommands);
|
||||
void executeCommands(Array<Gfx::OComputeCommand> secondaryCommands);
|
||||
void waitForSemaphore(VkPipelineStageFlags stages, PSemaphore waitSemaphore);
|
||||
void bindResource(PCommandBoundResource resource);
|
||||
void checkFence();
|
||||
void waitForCommand(uint32 timeToWait = 1000000u);
|
||||
PFence getFence();
|
||||
PCommandPool getPool();
|
||||
enum State {
|
||||
Init,
|
||||
Begin,
|
||||
RenderPass,
|
||||
End,
|
||||
Submit,
|
||||
};
|
||||
public:
|
||||
Command(PGraphics graphics, PCommandPool pool);
|
||||
~Command();
|
||||
constexpr VkCommandBuffer getHandle() { return handle; }
|
||||
void reset();
|
||||
void begin();
|
||||
void end();
|
||||
void beginRenderPass(PRenderPass renderPass, PFramebuffer framebuffer);
|
||||
void endRenderPass();
|
||||
void executeCommands(Array<Gfx::ORenderCommand> secondaryCommands);
|
||||
void executeCommands(Array<Gfx::OComputeCommand> secondaryCommands);
|
||||
void waitForSemaphore(VkPipelineStageFlags stages, PSemaphore waitSemaphore);
|
||||
void bindResource(PCommandBoundResource resource);
|
||||
void checkFence();
|
||||
void waitForCommand(uint32 timeToWait = 1000000u);
|
||||
PFence getFence();
|
||||
PCommandPool getPool();
|
||||
enum State {
|
||||
Init,
|
||||
Begin,
|
||||
RenderPass,
|
||||
End,
|
||||
Submit,
|
||||
};
|
||||
|
||||
private:
|
||||
PGraphics graphics;
|
||||
PCommandPool pool;
|
||||
OFence fence;
|
||||
OSemaphore signalSemaphore;
|
||||
State state;
|
||||
VkViewport currentViewport;
|
||||
VkRect2D currentScissor;
|
||||
VkCommandBuffer handle;
|
||||
PRenderPass boundRenderPass;
|
||||
PFramebuffer boundFramebuffer;
|
||||
Array<PSemaphore> waitSemaphores;
|
||||
Array<VkPipelineStageFlags> waitFlags;
|
||||
Array<ORenderCommand> executingRenders;
|
||||
Array<OComputeCommand> executingComputes;
|
||||
Array<PDescriptorSet> boundResources;
|
||||
friend class RenderCommand;
|
||||
friend class CommandPool;
|
||||
friend class Queue;
|
||||
private:
|
||||
PGraphics graphics;
|
||||
PCommandPool pool;
|
||||
OFence fence;
|
||||
OSemaphore signalSemaphore;
|
||||
State state;
|
||||
VkViewport currentViewport;
|
||||
VkRect2D currentScissor;
|
||||
VkCommandBuffer handle;
|
||||
PRenderPass boundRenderPass;
|
||||
PFramebuffer boundFramebuffer;
|
||||
Array<PSemaphore> waitSemaphores;
|
||||
Array<VkPipelineStageFlags> waitFlags;
|
||||
Array<ORenderCommand> executingRenders;
|
||||
Array<OComputeCommand> executingComputes;
|
||||
Array<PDescriptorSet> boundResources;
|
||||
friend class RenderCommand;
|
||||
friend class CommandPool;
|
||||
friend class Queue;
|
||||
};
|
||||
DEFINE_REF(Command)
|
||||
|
||||
DECLARE_REF(GraphicsPipeline)
|
||||
DECLARE_REF(ComputePipeline)
|
||||
class RenderCommand : public Gfx::RenderCommand {
|
||||
public:
|
||||
RenderCommand(PGraphics graphics, VkCommandPool cmdPool);
|
||||
virtual ~RenderCommand();
|
||||
constexpr VkCommandBuffer getHandle() { return handle; }
|
||||
void begin(PRenderPass renderPass, PFramebuffer framebuffer);
|
||||
void end();
|
||||
void reset();
|
||||
bool isReady();
|
||||
virtual void setViewport(Gfx::PViewport viewport) override;
|
||||
virtual void bindPipeline(Gfx::PGraphicsPipeline pipeline) override;
|
||||
virtual void bindDescriptor(Gfx::PDescriptorSet descriptorSet, Array<uint32> dynamicOffsets) override;
|
||||
virtual void bindDescriptor(const Array<Gfx::PDescriptorSet>& descriptorSets, Array<uint32> dynamicOffsets) override;
|
||||
virtual void bindVertexBuffer(const Array<Gfx::PVertexBuffer>& buffers) override;
|
||||
virtual void bindIndexBuffer(Gfx::PIndexBuffer indexBuffer) override;
|
||||
virtual void pushConstants(Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size,
|
||||
const void* data) override;
|
||||
virtual void draw(uint32 vertexCount, uint32 instanceCount, int32 firstVertex, uint32 firstInstance) override;
|
||||
virtual void drawIndexed(uint32 indexCount, uint32 instanceCount, int32 firstIndex, uint32 vertexOffset,
|
||||
uint32 firstInstance) override;
|
||||
virtual void drawMesh(uint32 groupX, uint32 groupY, uint32 groupZ) override;
|
||||
virtual void drawMeshIndirect(Gfx::PShaderBuffer buffer, uint64 offset, uint32 drawCount, uint32 stride) override;
|
||||
public:
|
||||
RenderCommand(PGraphics graphics, VkCommandPool cmdPool);
|
||||
virtual ~RenderCommand();
|
||||
constexpr VkCommandBuffer getHandle() { return handle; }
|
||||
void begin(PRenderPass renderPass, PFramebuffer framebuffer);
|
||||
void end();
|
||||
void reset();
|
||||
bool isReady();
|
||||
virtual void setViewport(Gfx::PViewport viewport) override;
|
||||
virtual void bindPipeline(Gfx::PGraphicsPipeline pipeline) override;
|
||||
virtual void bindDescriptor(Gfx::PDescriptorSet descriptorSet, Array<uint32> dynamicOffsets) override;
|
||||
virtual void bindDescriptor(const Array<Gfx::PDescriptorSet>& descriptorSets, Array<uint32> dynamicOffsets) override;
|
||||
virtual void bindVertexBuffer(const Array<Gfx::PVertexBuffer>& buffers) override;
|
||||
virtual void bindIndexBuffer(Gfx::PIndexBuffer indexBuffer) override;
|
||||
virtual void pushConstants(Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size, const void* data) override;
|
||||
virtual void draw(uint32 vertexCount, uint32 instanceCount, int32 firstVertex, uint32 firstInstance) override;
|
||||
virtual void drawIndexed(uint32 indexCount, uint32 instanceCount, int32 firstIndex, uint32 vertexOffset, uint32 firstInstance) override;
|
||||
virtual void drawMesh(uint32 groupX, uint32 groupY, uint32 groupZ) override;
|
||||
virtual void drawMeshIndirect(Gfx::PShaderBuffer buffer, uint64 offset, uint32 drawCount, uint32 stride) override;
|
||||
|
||||
private:
|
||||
PGraphicsPipeline pipeline;
|
||||
bool ready;
|
||||
Array<PCommandBoundResource> boundResources;
|
||||
VkViewport currentViewport;
|
||||
VkRect2D currentScissor;
|
||||
PGraphics graphics;
|
||||
std::thread::id threadId;
|
||||
VkCommandBuffer handle;
|
||||
VkCommandPool owner;
|
||||
friend class Command;
|
||||
private:
|
||||
PGraphicsPipeline pipeline;
|
||||
bool ready;
|
||||
Array<PCommandBoundResource> boundResources;
|
||||
VkViewport currentViewport;
|
||||
VkRect2D currentScissor;
|
||||
PGraphics graphics;
|
||||
std::thread::id threadId;
|
||||
VkCommandBuffer handle;
|
||||
VkCommandPool owner;
|
||||
friend class Command;
|
||||
};
|
||||
DEFINE_REF(RenderCommand)
|
||||
|
||||
class ComputeCommand : public Gfx::ComputeCommand {
|
||||
public:
|
||||
ComputeCommand(PGraphics graphics, VkCommandPool cmdPool);
|
||||
virtual ~ComputeCommand();
|
||||
inline VkCommandBuffer getHandle() { return handle; }
|
||||
void begin();
|
||||
void end();
|
||||
void reset();
|
||||
bool isReady();
|
||||
virtual void bindPipeline(Gfx::PComputePipeline pipeline) override;
|
||||
virtual void bindDescriptor(Gfx::PDescriptorSet set, Array<uint32> dynamicOffsets) override;
|
||||
virtual void bindDescriptor(const Array<Gfx::PDescriptorSet>& sets, Array<uint32> dynamicOffsets) override;
|
||||
virtual void pushConstants(Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size,
|
||||
const void* data) override;
|
||||
virtual void dispatch(uint32 threadX, uint32 threadY, uint32 threadZ) override;
|
||||
public:
|
||||
ComputeCommand(PGraphics graphics, VkCommandPool cmdPool);
|
||||
virtual ~ComputeCommand();
|
||||
inline VkCommandBuffer getHandle() { return handle; }
|
||||
void begin();
|
||||
void end();
|
||||
void reset();
|
||||
bool isReady();
|
||||
virtual void bindPipeline(Gfx::PComputePipeline pipeline) override;
|
||||
virtual void bindDescriptor(Gfx::PDescriptorSet set, Array<uint32> dynamicOffsets) override;
|
||||
virtual void bindDescriptor(const Array<Gfx::PDescriptorSet>& sets, Array<uint32> dynamicOffsets) override;
|
||||
virtual void pushConstants(Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size, const void* data) override;
|
||||
virtual void dispatch(uint32 threadX, uint32 threadY, uint32 threadZ) override;
|
||||
|
||||
private:
|
||||
PComputePipeline pipeline;
|
||||
bool ready;
|
||||
Array<PCommandBoundResource> boundResources;
|
||||
VkViewport currentViewport;
|
||||
VkRect2D currentScissor;
|
||||
PGraphics graphics;
|
||||
std::thread::id threadId;
|
||||
VkCommandBuffer handle;
|
||||
VkCommandPool owner;
|
||||
friend class Command;
|
||||
private:
|
||||
PComputePipeline pipeline;
|
||||
bool ready;
|
||||
Array<PCommandBoundResource> boundResources;
|
||||
VkViewport currentViewport;
|
||||
VkRect2D currentScissor;
|
||||
PGraphics graphics;
|
||||
std::thread::id threadId;
|
||||
VkCommandBuffer handle;
|
||||
VkCommandPool owner;
|
||||
friend class Command;
|
||||
};
|
||||
DEFINE_REF(ComputeCommand)
|
||||
class CommandPool {
|
||||
public:
|
||||
CommandPool(PGraphics graphics, PQueue queue);
|
||||
virtual ~CommandPool();
|
||||
constexpr PQueue getQueue() const { return queue; }
|
||||
PCommand getCommands();
|
||||
void cacheCommands(Array<ORenderCommand> commands);
|
||||
void cacheCommands(Array<OComputeCommand> commands);
|
||||
ORenderCommand createRenderCommand(const std::string& name);
|
||||
OComputeCommand createComputeCommand(const std::string& name);
|
||||
constexpr VkCommandPool getHandle() const { return commandPool; }
|
||||
void submitCommands(PSemaphore signalSemaphore = nullptr);
|
||||
public:
|
||||
CommandPool(PGraphics graphics, PQueue queue);
|
||||
virtual ~CommandPool();
|
||||
constexpr PQueue getQueue() const { return queue; }
|
||||
PCommand getCommands();
|
||||
void cacheCommands(Array<ORenderCommand> commands);
|
||||
void cacheCommands(Array<OComputeCommand> commands);
|
||||
ORenderCommand createRenderCommand(const std::string& name);
|
||||
OComputeCommand createComputeCommand(const std::string& name);
|
||||
constexpr VkCommandPool getHandle() const { return commandPool; }
|
||||
void submitCommands(PSemaphore signalSemaphore = nullptr);
|
||||
|
||||
private:
|
||||
PGraphics graphics;
|
||||
VkCommandPool commandPool;
|
||||
PQueue queue;
|
||||
uint32 queueFamilyIndex;
|
||||
PCommand command;
|
||||
Array<OCommand> allocatedBuffers;
|
||||
Array<ORenderCommand> allocatedRenderCommands;
|
||||
Array<OComputeCommand> allocatedComputeCommands;
|
||||
private:
|
||||
PGraphics graphics;
|
||||
VkCommandPool commandPool;
|
||||
PQueue queue;
|
||||
uint32 queueFamilyIndex;
|
||||
PCommand command;
|
||||
Array<OCommand> allocatedBuffers;
|
||||
Array<ORenderCommand> allocatedRenderCommands;
|
||||
Array<OComputeCommand> allocatedComputeCommands;
|
||||
};
|
||||
DEFINE_REF(CommandPool)
|
||||
} // namespace Vulkan
|
||||
|
||||
@@ -3,34 +3,26 @@
|
||||
|
||||
using namespace Seele::Vulkan;
|
||||
|
||||
VkBool32 Seele::Vulkan::debugCallback(
|
||||
VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
|
||||
VkDebugUtilsMessageTypeFlagsEXT messageTypes,
|
||||
const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,
|
||||
void* pUserData)
|
||||
{
|
||||
std::cerr << pCallbackData->pMessage << std::endl;
|
||||
return VK_FALSE;
|
||||
VkBool32 Seele::Vulkan::debugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageTypeFlagsEXT messageTypes,
|
||||
const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData, void* pUserData) {
|
||||
std::cerr << pCallbackData->pMessage << std::endl;
|
||||
return VK_FALSE;
|
||||
}
|
||||
|
||||
VkResult Seele::Vulkan::CreateDebugUtilsMessengerEXT(VkInstance instance, const VkDebugUtilsMessengerCreateInfoEXT *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkDebugUtilsMessengerEXT *pCallback)
|
||||
{
|
||||
auto func = (PFN_vkCreateDebugUtilsMessengerEXT)vkGetInstanceProcAddr(instance, "vkCreateDebugUtilsMessengerEXT");
|
||||
if (func != nullptr)
|
||||
{
|
||||
return func(instance, pCreateInfo, pAllocator, pCallback);
|
||||
}
|
||||
else
|
||||
{
|
||||
return VK_ERROR_EXTENSION_NOT_PRESENT;
|
||||
}
|
||||
VkResult Seele::Vulkan::CreateDebugUtilsMessengerEXT(VkInstance instance, const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo,
|
||||
const VkAllocationCallbacks* pAllocator, VkDebugUtilsMessengerEXT* pCallback) {
|
||||
auto func = (PFN_vkCreateDebugUtilsMessengerEXT)vkGetInstanceProcAddr(instance, "vkCreateDebugUtilsMessengerEXT");
|
||||
if (func != nullptr) {
|
||||
return func(instance, pCreateInfo, pAllocator, pCallback);
|
||||
} else {
|
||||
return VK_ERROR_EXTENSION_NOT_PRESENT;
|
||||
}
|
||||
}
|
||||
|
||||
void Seele::Vulkan::DestroyDebugUtilsMessengerEXT(VkInstance instance, const VkAllocationCallbacks *pAllocator, VkDebugUtilsMessengerEXT pCallback)
|
||||
{
|
||||
auto func = (PFN_vkDestroyDebugUtilsMessengerEXT)vkGetInstanceProcAddr(instance, "vkDestroyDebugUtilsMessengerEXT");
|
||||
if (func != nullptr)
|
||||
{
|
||||
func(instance, pCallback, pAllocator);
|
||||
}
|
||||
void Seele::Vulkan::DestroyDebugUtilsMessengerEXT(VkInstance instance, const VkAllocationCallbacks* pAllocator,
|
||||
VkDebugUtilsMessengerEXT pCallback) {
|
||||
auto func = (PFN_vkDestroyDebugUtilsMessengerEXT)vkGetInstanceProcAddr(instance, "vkDestroyDebugUtilsMessengerEXT");
|
||||
if (func != nullptr) {
|
||||
func(instance, pCallback, pAllocator);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,17 +2,13 @@
|
||||
#include "Containers/Array.h"
|
||||
#include <vulkan/vulkan.h>
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
namespace Vulkan
|
||||
{
|
||||
VkBool32 debugCallback(
|
||||
VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
|
||||
VkDebugUtilsMessageTypeFlagsEXT messageTypes,
|
||||
const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,
|
||||
void* pUserData);
|
||||
namespace Seele {
|
||||
namespace Vulkan {
|
||||
VkBool32 debugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageTypeFlagsEXT messageTypes,
|
||||
const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData, void* pUserData);
|
||||
|
||||
VkResult CreateDebugUtilsMessengerEXT(VkInstance instance, const VkDebugUtilsMessengerCreateInfoEXT *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkDebugUtilsMessengerEXT *pCallback);
|
||||
void DestroyDebugUtilsMessengerEXT(VkInstance instance, const VkAllocationCallbacks *pAllocator, VkDebugUtilsMessengerEXT pCallback);
|
||||
VkResult CreateDebugUtilsMessengerEXT(VkInstance instance, const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo,
|
||||
const VkAllocationCallbacks* pAllocator, VkDebugUtilsMessengerEXT* pCallback);
|
||||
void DestroyDebugUtilsMessengerEXT(VkInstance instance, const VkAllocationCallbacks* pAllocator, VkDebugUtilsMessengerEXT pCallback);
|
||||
} // namespace Vulkan
|
||||
} // namespace Seele
|
||||
@@ -1,9 +1,10 @@
|
||||
#include "Descriptor.h"
|
||||
#include "Buffer.h"
|
||||
#include "CRC.h"
|
||||
#include "Command.h"
|
||||
#include "Graphics.h"
|
||||
#include "Texture.h"
|
||||
#include "CRC.h"
|
||||
|
||||
|
||||
using namespace Seele;
|
||||
using namespace Seele::Vulkan;
|
||||
@@ -56,9 +57,7 @@ void DescriptorLayout::create() {
|
||||
}
|
||||
|
||||
DescriptorPool::DescriptorPool(PGraphics graphics, PDescriptorLayout layout)
|
||||
: CommandBoundResource(graphics)
|
||||
, graphics(graphics)
|
||||
, layout(layout) {
|
||||
: CommandBoundResource(graphics), graphics(graphics), layout(layout) {
|
||||
for (uint32 i = 0; i < cachedHandles.size(); ++i) {
|
||||
cachedHandles[i] = nullptr;
|
||||
}
|
||||
@@ -91,10 +90,8 @@ DescriptorPool::DescriptorPool(PGraphics graphics, PDescriptorLayout layout)
|
||||
}
|
||||
|
||||
DescriptorPool::~DescriptorPool() {
|
||||
for (size_t i = 0; i < maxSets; ++i)
|
||||
{
|
||||
if (cachedHandles[i] != nullptr)
|
||||
{
|
||||
for (size_t i = 0; i < maxSets; ++i) {
|
||||
if (cachedHandles[i] != nullptr) {
|
||||
cachedHandles[i] = nullptr;
|
||||
}
|
||||
}
|
||||
@@ -168,26 +165,16 @@ void DescriptorPool::reset() {
|
||||
}
|
||||
|
||||
DescriptorSet::DescriptorSet(PGraphics graphics, PDescriptorPool owner)
|
||||
: Gfx::DescriptorSet(owner->getLayout())
|
||||
, CommandBoundResource(graphics)
|
||||
, setHandle(VK_NULL_HANDLE)
|
||||
, graphics(graphics)
|
||||
, owner(owner)
|
||||
, bindCount(0)
|
||||
, currentlyInUse(false)
|
||||
{
|
||||
: Gfx::DescriptorSet(owner->getLayout()), CommandBoundResource(graphics), setHandle(VK_NULL_HANDLE), graphics(graphics), owner(owner),
|
||||
bindCount(0), currentlyInUse(false) {
|
||||
boundResources.resize(owner->getLayout()->getBindings().size());
|
||||
}
|
||||
|
||||
DescriptorSet::~DescriptorSet()
|
||||
{
|
||||
vkFreeDescriptorSets(graphics->getDevice(), owner->getHandle(), 1, &setHandle);
|
||||
}
|
||||
DescriptorSet::~DescriptorSet() { vkFreeDescriptorSets(graphics->getDevice(), owner->getHandle(), 1, &setHandle); }
|
||||
|
||||
void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBuffer) {
|
||||
PUniformBuffer vulkanBuffer = uniformBuffer.cast<UniformBuffer>();
|
||||
if (boundResources[binding] == vulkanBuffer->getAlloc())
|
||||
{
|
||||
if (boundResources[binding] == vulkanBuffer->getAlloc()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -195,7 +182,7 @@ void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBu
|
||||
.buffer = vulkanBuffer->getHandle(),
|
||||
.offset = 0,
|
||||
.range = vulkanBuffer->getSize(),
|
||||
});
|
||||
});
|
||||
|
||||
writeDescriptors.add(VkWriteDescriptorSet{
|
||||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
@@ -206,15 +193,14 @@ void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBu
|
||||
.descriptorCount = 1,
|
||||
.descriptorType = cast(layout->getBindings()[binding].descriptorType),
|
||||
.pBufferInfo = &bufferInfos.back(),
|
||||
});
|
||||
});
|
||||
|
||||
boundResources[binding] = vulkanBuffer->getAlloc();
|
||||
}
|
||||
|
||||
void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PShaderBuffer shaderBuffer) {
|
||||
PShaderBuffer vulkanBuffer = shaderBuffer.cast<ShaderBuffer>();
|
||||
if (boundResources[binding] == vulkanBuffer->getAlloc())
|
||||
{
|
||||
if (boundResources[binding] == vulkanBuffer->getAlloc()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -222,7 +208,7 @@ void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PShaderBuffer shaderBuff
|
||||
.buffer = vulkanBuffer->getHandle(),
|
||||
.offset = 0,
|
||||
.range = vulkanBuffer->getSize(),
|
||||
});
|
||||
});
|
||||
writeDescriptors.add(VkWriteDescriptorSet{
|
||||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
.pNext = nullptr,
|
||||
@@ -232,15 +218,14 @@ void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PShaderBuffer shaderBuff
|
||||
.descriptorCount = 1,
|
||||
.descriptorType = cast(layout->getBindings()[binding].descriptorType),
|
||||
.pBufferInfo = &bufferInfos.back(),
|
||||
});
|
||||
});
|
||||
|
||||
boundResources[binding] = vulkanBuffer->getAlloc();
|
||||
}
|
||||
|
||||
void DescriptorSet::updateBuffer(uint32_t binding, uint32 index, Gfx::PShaderBuffer shaderBuffer) {
|
||||
PShaderBuffer vulkanBuffer = shaderBuffer.cast<ShaderBuffer>();
|
||||
if (boundResources[binding] == vulkanBuffer->getAlloc())
|
||||
{
|
||||
if (boundResources[binding] == vulkanBuffer->getAlloc()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -248,7 +233,7 @@ void DescriptorSet::updateBuffer(uint32_t binding, uint32 index, Gfx::PShaderBuf
|
||||
.buffer = vulkanBuffer->getHandle(),
|
||||
.offset = 0,
|
||||
.range = vulkanBuffer->getSize(),
|
||||
});
|
||||
});
|
||||
|
||||
writeDescriptors.add(VkWriteDescriptorSet{
|
||||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
@@ -259,15 +244,14 @@ void DescriptorSet::updateBuffer(uint32_t binding, uint32 index, Gfx::PShaderBuf
|
||||
.descriptorCount = 1,
|
||||
.descriptorType = cast(layout->getBindings()[binding].descriptorType),
|
||||
.pBufferInfo = &bufferInfos.back(),
|
||||
});
|
||||
});
|
||||
|
||||
boundResources[binding] = vulkanBuffer->getAlloc();
|
||||
}
|
||||
|
||||
void DescriptorSet::updateSampler(uint32_t binding, Gfx::PSampler samplerState) {
|
||||
PSampler vulkanSampler = samplerState.cast<Sampler>();
|
||||
if (boundResources[binding] == vulkanSampler->getHandle())
|
||||
{
|
||||
if (boundResources[binding] == vulkanSampler->getHandle()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -275,7 +259,7 @@ void DescriptorSet::updateSampler(uint32_t binding, Gfx::PSampler samplerState)
|
||||
.sampler = vulkanSampler->getSampler(),
|
||||
.imageView = VK_NULL_HANDLE,
|
||||
.imageLayout = VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
});
|
||||
});
|
||||
|
||||
writeDescriptors.add(VkWriteDescriptorSet{
|
||||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
@@ -286,15 +270,14 @@ void DescriptorSet::updateSampler(uint32_t binding, Gfx::PSampler samplerState)
|
||||
.descriptorCount = 1,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER,
|
||||
.pImageInfo = &imageInfos.back(),
|
||||
});
|
||||
});
|
||||
|
||||
boundResources[binding] = vulkanSampler->getHandle();
|
||||
}
|
||||
|
||||
void DescriptorSet::updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::PSampler samplerState) {
|
||||
TextureBase* vulkanTexture = texture.cast<TextureBase>().getHandle();
|
||||
if (boundResources[binding] == vulkanTexture->getHandle())
|
||||
{
|
||||
if (boundResources[binding] == vulkanTexture->getHandle()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -303,12 +286,11 @@ void DescriptorSet::updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::
|
||||
.sampler = samplerState != nullptr ? samplerState.cast<Sampler>()->getSampler() : VK_NULL_HANDLE,
|
||||
.imageView = vulkanTexture->getView(),
|
||||
.imageLayout = cast(vulkanTexture->getLayout()),
|
||||
});
|
||||
});
|
||||
VkDescriptorType descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
|
||||
if (samplerState != nullptr) {
|
||||
descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||
}
|
||||
else if (vulkanTexture->getUsage() & VK_IMAGE_USAGE_STORAGE_BIT) {
|
||||
} else if (vulkanTexture->getUsage() & VK_IMAGE_USAGE_STORAGE_BIT) {
|
||||
descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
|
||||
}
|
||||
writeDescriptors.add(VkWriteDescriptorSet{
|
||||
@@ -320,7 +302,7 @@ void DescriptorSet::updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::
|
||||
.descriptorCount = 1,
|
||||
.descriptorType = descriptorType,
|
||||
.pImageInfo = &imageInfos.back(),
|
||||
});
|
||||
});
|
||||
|
||||
boundResources[binding] = vulkanTexture->getHandle();
|
||||
}
|
||||
@@ -330,15 +312,14 @@ void DescriptorSet::updateTextureArray(uint32_t binding, Array<Gfx::PTexture> te
|
||||
boundResources.resize(binding + textures.size());
|
||||
for (auto& gfxTexture : textures) {
|
||||
TextureBase* vulkanTexture = gfxTexture.cast<TextureBase>().getHandle();
|
||||
if (boundResources[binding + arrayElement] == vulkanTexture->getHandle())
|
||||
{
|
||||
if (boundResources[binding + arrayElement] == vulkanTexture->getHandle()) {
|
||||
continue;
|
||||
}
|
||||
imageInfos.add(VkDescriptorImageInfo{
|
||||
.sampler = VK_NULL_HANDLE,
|
||||
.imageView = vulkanTexture->getView(),
|
||||
.imageLayout = cast(vulkanTexture->getLayout()),
|
||||
});
|
||||
});
|
||||
|
||||
VkDescriptorType descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
|
||||
if (vulkanTexture->getUsage() & VK_IMAGE_USAGE_STORAGE_BIT) {
|
||||
@@ -354,7 +335,7 @@ void DescriptorSet::updateTextureArray(uint32_t binding, Array<Gfx::PTexture> te
|
||||
.descriptorCount = 1,
|
||||
.descriptorType = descriptorType,
|
||||
.pImageInfo = &imageInfos.back(),
|
||||
});
|
||||
});
|
||||
vulkanTexture->getHandle()->bind();
|
||||
}
|
||||
}
|
||||
@@ -385,8 +366,7 @@ void PipelineLayout::create() {
|
||||
PDescriptorLayout layout = desc.cast<DescriptorLayout>();
|
||||
layout->create();
|
||||
uint32 parameterIndex = parameterMapping[layout->getName()];
|
||||
if (parameterIndex >= vulkanDescriptorLayouts.size())
|
||||
{
|
||||
if (parameterIndex >= vulkanDescriptorLayouts.size()) {
|
||||
vulkanDescriptorLayouts.resize(parameterIndex + 1);
|
||||
}
|
||||
vulkanDescriptorLayouts[parameterIndex] = layout->getHandle();
|
||||
@@ -409,10 +389,10 @@ void PipelineLayout::create() {
|
||||
.pPushConstantRanges = vkPushConstants.data(),
|
||||
};
|
||||
|
||||
layoutHash = CRC::Calculate(createInfo.pPushConstantRanges,
|
||||
sizeof(VkPushConstantRange) * createInfo.pushConstantRangeCount, CRC::CRC_32());
|
||||
layoutHash = CRC::Calculate(createInfo.pSetLayouts, sizeof(VkDescriptorSetLayout) * createInfo.setLayoutCount,
|
||||
CRC::CRC_32(), layoutHash);
|
||||
layoutHash =
|
||||
CRC::Calculate(createInfo.pPushConstantRanges, sizeof(VkPushConstantRange) * createInfo.pushConstantRangeCount, CRC::CRC_32());
|
||||
layoutHash =
|
||||
CRC::Calculate(createInfo.pSetLayouts, sizeof(VkDescriptorSetLayout) * createInfo.setLayoutCount, CRC::CRC_32(), layoutHash);
|
||||
|
||||
std::unique_lock l(layoutLock);
|
||||
if (cachedLayouts.contains(layoutHash)) {
|
||||
|
||||
@@ -8,90 +8,90 @@ namespace Seele {
|
||||
namespace Vulkan {
|
||||
DECLARE_REF(Graphics)
|
||||
class DescriptorLayout : public Gfx::DescriptorLayout {
|
||||
public:
|
||||
DescriptorLayout(PGraphics graphics, const std::string& name);
|
||||
virtual ~DescriptorLayout();
|
||||
virtual void create() override;
|
||||
constexpr VkDescriptorSetLayout getHandle() const { return layoutHandle; }
|
||||
public:
|
||||
DescriptorLayout(PGraphics graphics, const std::string& name);
|
||||
virtual ~DescriptorLayout();
|
||||
virtual void create() override;
|
||||
constexpr VkDescriptorSetLayout getHandle() const { return layoutHandle; }
|
||||
|
||||
private:
|
||||
PGraphics graphics;
|
||||
Array<VkDescriptorSetLayoutBinding> bindings;
|
||||
VkDescriptorSetLayout layoutHandle;
|
||||
friend class DescriptorPool;
|
||||
private:
|
||||
PGraphics graphics;
|
||||
Array<VkDescriptorSetLayoutBinding> bindings;
|
||||
VkDescriptorSetLayout layoutHandle;
|
||||
friend class DescriptorPool;
|
||||
};
|
||||
DEFINE_REF(DescriptorLayout)
|
||||
|
||||
DECLARE_REF(DescriptorSet)
|
||||
class DescriptorPool : public Gfx::DescriptorPool, public CommandBoundResource {
|
||||
public:
|
||||
DescriptorPool(PGraphics graphics, PDescriptorLayout layout);
|
||||
virtual ~DescriptorPool();
|
||||
virtual Gfx::PDescriptorSet allocateDescriptorSet() override;
|
||||
virtual void reset() override;
|
||||
public:
|
||||
DescriptorPool(PGraphics graphics, PDescriptorLayout layout);
|
||||
virtual ~DescriptorPool();
|
||||
virtual Gfx::PDescriptorSet allocateDescriptorSet() override;
|
||||
virtual void reset() override;
|
||||
|
||||
constexpr VkDescriptorPool getHandle() const { return poolHandle; }
|
||||
constexpr PDescriptorLayout getLayout() const { return layout; }
|
||||
constexpr VkDescriptorPool getHandle() const { return poolHandle; }
|
||||
constexpr PDescriptorLayout getLayout() const { return layout; }
|
||||
|
||||
private:
|
||||
PGraphics graphics;
|
||||
PDescriptorLayout layout;
|
||||
const static int maxSets = 64;
|
||||
StaticArray<ODescriptorSet, maxSets> cachedHandles;
|
||||
VkDescriptorPool poolHandle;
|
||||
DescriptorPool* nextAlloc = nullptr;
|
||||
private:
|
||||
PGraphics graphics;
|
||||
PDescriptorLayout layout;
|
||||
const static int maxSets = 64;
|
||||
StaticArray<ODescriptorSet, maxSets> cachedHandles;
|
||||
VkDescriptorPool poolHandle;
|
||||
DescriptorPool* nextAlloc = nullptr;
|
||||
};
|
||||
DEFINE_REF(DescriptorPool)
|
||||
|
||||
class DescriptorSet : public Gfx::DescriptorSet, public CommandBoundResource {
|
||||
public:
|
||||
DescriptorSet(PGraphics graphics, PDescriptorPool owner);
|
||||
virtual ~DescriptorSet();
|
||||
virtual void writeChanges() override;
|
||||
virtual void updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBuffer) override;
|
||||
virtual void updateBuffer(uint32_t binding, Gfx::PShaderBuffer uniformBuffer) override;
|
||||
virtual void updateBuffer(uint32_t binding, uint32 index, Gfx::PShaderBuffer uniformBuffer) override;
|
||||
virtual void updateSampler(uint32_t binding, Gfx::PSampler samplerState) override;
|
||||
virtual void updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::PSampler sampler = nullptr) override;
|
||||
virtual void updateTextureArray(uint32_t binding, Array<Gfx::PTexture> texture) override;
|
||||
public:
|
||||
DescriptorSet(PGraphics graphics, PDescriptorPool owner);
|
||||
virtual ~DescriptorSet();
|
||||
virtual void writeChanges() override;
|
||||
virtual void updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBuffer) override;
|
||||
virtual void updateBuffer(uint32_t binding, Gfx::PShaderBuffer uniformBuffer) override;
|
||||
virtual void updateBuffer(uint32_t binding, uint32 index, Gfx::PShaderBuffer uniformBuffer) override;
|
||||
virtual void updateSampler(uint32_t binding, Gfx::PSampler samplerState) override;
|
||||
virtual void updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::PSampler sampler = nullptr) override;
|
||||
virtual void updateTextureArray(uint32_t binding, Array<Gfx::PTexture> texture) override;
|
||||
|
||||
constexpr bool isCurrentlyInUse() const { return currentlyInUse; }
|
||||
constexpr void allocate() { currentlyInUse = true; }
|
||||
constexpr void free() { currentlyInUse = false; }
|
||||
constexpr VkDescriptorSet getHandle() const { return setHandle; }
|
||||
constexpr bool isCurrentlyInUse() const { return currentlyInUse; }
|
||||
constexpr void allocate() { currentlyInUse = true; }
|
||||
constexpr void free() { currentlyInUse = false; }
|
||||
constexpr VkDescriptorSet getHandle() const { return setHandle; }
|
||||
|
||||
private:
|
||||
List<VkDescriptorImageInfo> imageInfos;
|
||||
List<VkDescriptorBufferInfo> bufferInfos;
|
||||
Array<VkWriteDescriptorSet> writeDescriptors;
|
||||
// contains the previously bound resources at every binding
|
||||
// since the layout is fixed, trying to bind a texture to a buffer
|
||||
// would not work anyways, so casts should be safe
|
||||
//Array<void*> cachedData;
|
||||
Array<PCommandBoundResource> boundResources;
|
||||
VkDescriptorSet setHandle;
|
||||
PGraphics graphics;
|
||||
PDescriptorPool owner;
|
||||
uint32 bindCount;
|
||||
bool currentlyInUse;
|
||||
friend class DescriptorPool;
|
||||
friend class Command;
|
||||
friend class RenderCommand;
|
||||
friend class ComputeCommand;
|
||||
private:
|
||||
List<VkDescriptorImageInfo> imageInfos;
|
||||
List<VkDescriptorBufferInfo> bufferInfos;
|
||||
Array<VkWriteDescriptorSet> writeDescriptors;
|
||||
// contains the previously bound resources at every binding
|
||||
// since the layout is fixed, trying to bind a texture to a buffer
|
||||
// would not work anyways, so casts should be safe
|
||||
// Array<void*> cachedData;
|
||||
Array<PCommandBoundResource> boundResources;
|
||||
VkDescriptorSet setHandle;
|
||||
PGraphics graphics;
|
||||
PDescriptorPool owner;
|
||||
uint32 bindCount;
|
||||
bool currentlyInUse;
|
||||
friend class DescriptorPool;
|
||||
friend class Command;
|
||||
friend class RenderCommand;
|
||||
friend class ComputeCommand;
|
||||
};
|
||||
DEFINE_REF(DescriptorSet)
|
||||
|
||||
class PipelineLayout : public Gfx::PipelineLayout {
|
||||
public:
|
||||
PipelineLayout(PGraphics graphics, const std::string& name, Gfx::PPipelineLayout baseLayout);
|
||||
virtual ~PipelineLayout();
|
||||
virtual void create();
|
||||
constexpr VkPipelineLayout getHandle() const { return layoutHandle; }
|
||||
public:
|
||||
PipelineLayout(PGraphics graphics, const std::string& name, Gfx::PPipelineLayout baseLayout);
|
||||
virtual ~PipelineLayout();
|
||||
virtual void create();
|
||||
constexpr VkPipelineLayout getHandle() const { return layoutHandle; }
|
||||
|
||||
private:
|
||||
Array<VkDescriptorSetLayout> vulkanDescriptorLayouts;
|
||||
PGraphics graphics;
|
||||
VkPipelineLayout layoutHandle;
|
||||
private:
|
||||
Array<VkDescriptorSetLayout> vulkanDescriptorLayouts;
|
||||
PGraphics graphics;
|
||||
VkPipelineLayout layoutHandle;
|
||||
};
|
||||
DEFINE_REF(PipelineLayout)
|
||||
|
||||
|
||||
@@ -5,10 +5,8 @@ using namespace Seele;
|
||||
using namespace Seele::Vulkan;
|
||||
using namespace Seele::Gfx;
|
||||
|
||||
VkDescriptorType Seele::Vulkan::cast(const Seele::Gfx::SeDescriptorType &descriptorType)
|
||||
{
|
||||
switch (descriptorType)
|
||||
{
|
||||
VkDescriptorType Seele::Vulkan::cast(const Seele::Gfx::SeDescriptorType& descriptorType) {
|
||||
switch (descriptorType) {
|
||||
case SE_DESCRIPTOR_TYPE_SAMPLER:
|
||||
return VK_DESCRIPTOR_TYPE_SAMPLER;
|
||||
case SE_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
|
||||
@@ -43,10 +41,8 @@ VkDescriptorType Seele::Vulkan::cast(const Seele::Gfx::SeDescriptorType &descrip
|
||||
return VK_DESCRIPTOR_TYPE_MAX_ENUM;
|
||||
}
|
||||
|
||||
Seele::Gfx::SeDescriptorType Seele::Vulkan::cast(const VkDescriptorType &descriptorType)
|
||||
{
|
||||
switch (descriptorType)
|
||||
{
|
||||
Seele::Gfx::SeDescriptorType Seele::Vulkan::cast(const VkDescriptorType& descriptorType) {
|
||||
switch (descriptorType) {
|
||||
|
||||
case VK_DESCRIPTOR_TYPE_SAMPLER:
|
||||
return SE_DESCRIPTOR_TYPE_SAMPLER;
|
||||
@@ -77,14 +73,12 @@ Seele::Gfx::SeDescriptorType Seele::Vulkan::cast(const VkDescriptorType &descrip
|
||||
return SE_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV;
|
||||
#endif
|
||||
default:
|
||||
throw std::logic_error("Not implemented");
|
||||
throw std::logic_error("Not implemented");
|
||||
}
|
||||
}
|
||||
|
||||
VkShaderStageFlagBits Seele::Vulkan::cast(const Seele::Gfx::SeShaderStageFlagBits &stage)
|
||||
{
|
||||
switch (stage)
|
||||
{
|
||||
VkShaderStageFlagBits Seele::Vulkan::cast(const Seele::Gfx::SeShaderStageFlagBits& stage) {
|
||||
switch (stage) {
|
||||
|
||||
case SE_SHADER_STAGE_VERTEX_BIT:
|
||||
return VK_SHADER_STAGE_VERTEX_BIT;
|
||||
@@ -102,15 +96,13 @@ VkShaderStageFlagBits Seele::Vulkan::cast(const Seele::Gfx::SeShaderStageFlagBit
|
||||
return VK_SHADER_STAGE_ALL_GRAPHICS;
|
||||
case SE_SHADER_STAGE_ALL:
|
||||
return VK_SHADER_STAGE_ALL;
|
||||
default: throw std::logic_error("Not implemented");
|
||||
|
||||
default:
|
||||
throw std::logic_error("Not implemented");
|
||||
}
|
||||
}
|
||||
|
||||
Seele::Gfx::SeShaderStageFlagBits Seele::Vulkan::cast(const VkShaderStageFlagBits &stage)
|
||||
{
|
||||
switch (stage)
|
||||
{
|
||||
Seele::Gfx::SeShaderStageFlagBits Seele::Vulkan::cast(const VkShaderStageFlagBits& stage) {
|
||||
switch (stage) {
|
||||
case VK_SHADER_STAGE_VERTEX_BIT:
|
||||
return SE_SHADER_STAGE_VERTEX_BIT;
|
||||
case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
|
||||
@@ -127,16 +119,13 @@ Seele::Gfx::SeShaderStageFlagBits Seele::Vulkan::cast(const VkShaderStageFlagBit
|
||||
return SE_SHADER_STAGE_ALL_GRAPHICS;
|
||||
case VK_SHADER_STAGE_ALL:
|
||||
return SE_SHADER_STAGE_ALL;
|
||||
default: throw std::logic_error("Not implemented");
|
||||
|
||||
default:
|
||||
throw std::logic_error("Not implemented");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
VkFormat Seele::Vulkan::cast(const Seele::Gfx::SeFormat &format)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
VkFormat Seele::Vulkan::cast(const Seele::Gfx::SeFormat& format) {
|
||||
switch (format) {
|
||||
case SE_FORMAT_UNDEFINED:
|
||||
return VK_FORMAT_UNDEFINED;
|
||||
case SE_FORMAT_R4G4_UNORM_PACK8:
|
||||
@@ -595,10 +584,8 @@ VkFormat Seele::Vulkan::cast(const Seele::Gfx::SeFormat &format)
|
||||
return VK_FORMAT_MAX_ENUM;
|
||||
}
|
||||
}
|
||||
Seele::Gfx::SeFormat Seele::Vulkan::cast(const VkFormat &format)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
Seele::Gfx::SeFormat Seele::Vulkan::cast(const VkFormat& format) {
|
||||
switch (format) {
|
||||
case VK_FORMAT_UNDEFINED:
|
||||
return SE_FORMAT_UNDEFINED;
|
||||
case VK_FORMAT_R4G4_UNORM_PACK8:
|
||||
@@ -1053,15 +1040,13 @@ Seele::Gfx::SeFormat Seele::Vulkan::cast(const VkFormat &format)
|
||||
return SE_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG;
|
||||
case VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG:
|
||||
return SE_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG;
|
||||
default: throw std::logic_error("Not implemented");
|
||||
|
||||
default:
|
||||
throw std::logic_error("Not implemented");
|
||||
}
|
||||
}
|
||||
|
||||
VkImageLayout Seele::Vulkan::cast(const Gfx::SeImageLayout &imageLayout)
|
||||
{
|
||||
switch (imageLayout)
|
||||
{
|
||||
VkImageLayout Seele::Vulkan::cast(const Gfx::SeImageLayout& imageLayout) {
|
||||
switch (imageLayout) {
|
||||
case SE_IMAGE_LAYOUT_UNDEFINED:
|
||||
return VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
case SE_IMAGE_LAYOUT_GENERAL:
|
||||
@@ -1092,14 +1077,12 @@ VkImageLayout Seele::Vulkan::cast(const Gfx::SeImageLayout &imageLayout)
|
||||
return VK_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV;
|
||||
case SE_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT:
|
||||
return VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT;
|
||||
default: throw std::logic_error("Not implemented");
|
||||
|
||||
default:
|
||||
throw std::logic_error("Not implemented");
|
||||
}
|
||||
}
|
||||
Gfx::SeImageLayout Seele::Vulkan::cast(const VkImageLayout &imageLayout)
|
||||
{
|
||||
switch (imageLayout)
|
||||
{
|
||||
Gfx::SeImageLayout Seele::Vulkan::cast(const VkImageLayout& imageLayout) {
|
||||
switch (imageLayout) {
|
||||
case VK_IMAGE_LAYOUT_UNDEFINED:
|
||||
return SE_IMAGE_LAYOUT_UNDEFINED;
|
||||
case VK_IMAGE_LAYOUT_GENERAL:
|
||||
@@ -1130,67 +1113,57 @@ Gfx::SeImageLayout Seele::Vulkan::cast(const VkImageLayout &imageLayout)
|
||||
return SE_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV;
|
||||
case VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT:
|
||||
return SE_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT;
|
||||
default: throw std::logic_error("Not implemented");
|
||||
|
||||
default:
|
||||
throw std::logic_error("Not implemented");
|
||||
}
|
||||
}
|
||||
VkAttachmentStoreOp Seele::Vulkan::cast(const Gfx::SeAttachmentStoreOp &storeOp)
|
||||
{
|
||||
switch (storeOp)
|
||||
{
|
||||
VkAttachmentStoreOp Seele::Vulkan::cast(const Gfx::SeAttachmentStoreOp& storeOp) {
|
||||
switch (storeOp) {
|
||||
case SE_ATTACHMENT_STORE_OP_STORE:
|
||||
return VK_ATTACHMENT_STORE_OP_STORE;
|
||||
case SE_ATTACHMENT_STORE_OP_DONT_CARE:
|
||||
return VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||
default: throw std::logic_error("Not implemented");
|
||||
|
||||
default:
|
||||
throw std::logic_error("Not implemented");
|
||||
}
|
||||
}
|
||||
Gfx::SeAttachmentStoreOp Seele::Vulkan::cast(const VkAttachmentStoreOp &storeOp)
|
||||
{
|
||||
switch (storeOp)
|
||||
{
|
||||
Gfx::SeAttachmentStoreOp Seele::Vulkan::cast(const VkAttachmentStoreOp& storeOp) {
|
||||
switch (storeOp) {
|
||||
case VK_ATTACHMENT_STORE_OP_STORE:
|
||||
return SE_ATTACHMENT_STORE_OP_STORE;
|
||||
case VK_ATTACHMENT_STORE_OP_DONT_CARE:
|
||||
return SE_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||
default: throw std::logic_error("Not implemented");
|
||||
|
||||
default:
|
||||
throw std::logic_error("Not implemented");
|
||||
}
|
||||
}
|
||||
VkAttachmentLoadOp Seele::Vulkan::cast(const Gfx::SeAttachmentLoadOp &loadOp)
|
||||
{
|
||||
switch (loadOp)
|
||||
{
|
||||
VkAttachmentLoadOp Seele::Vulkan::cast(const Gfx::SeAttachmentLoadOp& loadOp) {
|
||||
switch (loadOp) {
|
||||
case SE_ATTACHMENT_LOAD_OP_LOAD:
|
||||
return VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
case SE_ATTACHMENT_LOAD_OP_CLEAR:
|
||||
return VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||
case SE_ATTACHMENT_LOAD_OP_DONT_CARE:
|
||||
return VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||
default: throw std::logic_error("Not implemented");
|
||||
|
||||
default:
|
||||
throw std::logic_error("Not implemented");
|
||||
}
|
||||
}
|
||||
Gfx::SeAttachmentLoadOp Seele::Vulkan::cast(const VkAttachmentLoadOp &loadOp)
|
||||
{
|
||||
switch (loadOp)
|
||||
{
|
||||
Gfx::SeAttachmentLoadOp Seele::Vulkan::cast(const VkAttachmentLoadOp& loadOp) {
|
||||
switch (loadOp) {
|
||||
case VK_ATTACHMENT_LOAD_OP_LOAD:
|
||||
return SE_ATTACHMENT_LOAD_OP_LOAD;
|
||||
case VK_ATTACHMENT_LOAD_OP_CLEAR:
|
||||
return SE_ATTACHMENT_LOAD_OP_CLEAR;
|
||||
case VK_ATTACHMENT_LOAD_OP_DONT_CARE:
|
||||
return SE_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||
default: throw std::logic_error("Not implemented");
|
||||
|
||||
default:
|
||||
throw std::logic_error("Not implemented");
|
||||
}
|
||||
}
|
||||
|
||||
VkIndexType Seele::Vulkan::cast(const Gfx::SeIndexType &indexType)
|
||||
{
|
||||
switch (indexType)
|
||||
{
|
||||
VkIndexType Seele::Vulkan::cast(const Gfx::SeIndexType& indexType) {
|
||||
switch (indexType) {
|
||||
case Gfx::SE_INDEX_TYPE_UINT16:
|
||||
return VK_INDEX_TYPE_UINT16;
|
||||
case Gfx::SE_INDEX_TYPE_UINT32:
|
||||
@@ -1199,23 +1172,19 @@ VkIndexType Seele::Vulkan::cast(const Gfx::SeIndexType &indexType)
|
||||
return VK_INDEX_TYPE_MAX_ENUM;
|
||||
}
|
||||
}
|
||||
Gfx::SeIndexType Seele::Vulkan::cast(const VkIndexType &indexType)
|
||||
{
|
||||
switch (indexType)
|
||||
{
|
||||
Gfx::SeIndexType Seele::Vulkan::cast(const VkIndexType& indexType) {
|
||||
switch (indexType) {
|
||||
case VK_INDEX_TYPE_UINT16:
|
||||
return Gfx::SE_INDEX_TYPE_UINT16;
|
||||
case VK_INDEX_TYPE_UINT32:
|
||||
return Gfx::SE_INDEX_TYPE_UINT32;
|
||||
default: throw std::logic_error("Not implemented");
|
||||
|
||||
default:
|
||||
throw std::logic_error("Not implemented");
|
||||
}
|
||||
}
|
||||
|
||||
VkPrimitiveTopology Seele::Vulkan::cast(const Gfx::SePrimitiveTopology &topology)
|
||||
{
|
||||
switch (topology)
|
||||
{
|
||||
VkPrimitiveTopology Seele::Vulkan::cast(const Gfx::SePrimitiveTopology& topology) {
|
||||
switch (topology) {
|
||||
case SE_PRIMITIVE_TOPOLOGY_POINT_LIST:
|
||||
return VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
|
||||
case SE_PRIMITIVE_TOPOLOGY_LINE_LIST:
|
||||
@@ -1242,10 +1211,8 @@ VkPrimitiveTopology Seele::Vulkan::cast(const Gfx::SePrimitiveTopology &topology
|
||||
return VK_PRIMITIVE_TOPOLOGY_MAX_ENUM;
|
||||
}
|
||||
}
|
||||
Gfx::SePrimitiveTopology Seele::Vulkan::cast(const VkPrimitiveTopology &topology)
|
||||
{
|
||||
switch (topology)
|
||||
{
|
||||
Gfx::SePrimitiveTopology Seele::Vulkan::cast(const VkPrimitiveTopology& topology) {
|
||||
switch (topology) {
|
||||
case VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
|
||||
return SE_PRIMITIVE_TOPOLOGY_POINT_LIST;
|
||||
case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
|
||||
@@ -1268,15 +1235,13 @@ Gfx::SePrimitiveTopology Seele::Vulkan::cast(const VkPrimitiveTopology &topology
|
||||
return SE_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY;
|
||||
case VK_PRIMITIVE_TOPOLOGY_PATCH_LIST:
|
||||
return SE_PRIMITIVE_TOPOLOGY_PATCH_LIST;
|
||||
default: throw std::logic_error("Not implemented");
|
||||
|
||||
default:
|
||||
throw std::logic_error("Not implemented");
|
||||
}
|
||||
}
|
||||
|
||||
VkPolygonMode Seele::Vulkan::cast(const Gfx::SePolygonMode &mode)
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
VkPolygonMode Seele::Vulkan::cast(const Gfx::SePolygonMode& mode) {
|
||||
switch (mode) {
|
||||
case SE_POLYGON_MODE_FILL:
|
||||
return VK_POLYGON_MODE_FILL;
|
||||
case SE_POLYGON_MODE_LINE:
|
||||
@@ -1287,24 +1252,20 @@ VkPolygonMode Seele::Vulkan::cast(const Gfx::SePolygonMode &mode)
|
||||
return VK_POLYGON_MODE_MAX_ENUM;
|
||||
}
|
||||
}
|
||||
Gfx::SePolygonMode Seele::Vulkan::cast(const VkPolygonMode &mode)
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
Gfx::SePolygonMode Seele::Vulkan::cast(const VkPolygonMode& mode) {
|
||||
switch (mode) {
|
||||
case VK_POLYGON_MODE_FILL:
|
||||
return SE_POLYGON_MODE_FILL;
|
||||
case VK_POLYGON_MODE_LINE:
|
||||
return SE_POLYGON_MODE_LINE;
|
||||
case VK_POLYGON_MODE_POINT:
|
||||
return SE_POLYGON_MODE_POINT;
|
||||
default: throw std::logic_error("Not implemented");
|
||||
|
||||
default:
|
||||
throw std::logic_error("Not implemented");
|
||||
}
|
||||
}
|
||||
VkCompareOp Seele::Vulkan::cast(const Gfx::SeCompareOp &op)
|
||||
{
|
||||
switch (op)
|
||||
{
|
||||
VkCompareOp Seele::Vulkan::cast(const Gfx::SeCompareOp& op) {
|
||||
switch (op) {
|
||||
case SE_COMPARE_OP_NEVER:
|
||||
return VK_COMPARE_OP_NEVER;
|
||||
case SE_COMPARE_OP_LESS:
|
||||
@@ -1321,14 +1282,12 @@ VkCompareOp Seele::Vulkan::cast(const Gfx::SeCompareOp &op)
|
||||
return VK_COMPARE_OP_GREATER_OR_EQUAL;
|
||||
case SE_COMPARE_OP_ALWAYS:
|
||||
return VK_COMPARE_OP_ALWAYS;
|
||||
default: throw std::logic_error("Not implemented");
|
||||
|
||||
default:
|
||||
throw std::logic_error("Not implemented");
|
||||
}
|
||||
}
|
||||
Gfx::SeCompareOp Seele::Vulkan::cast(const VkCompareOp &op)
|
||||
{
|
||||
switch (op)
|
||||
{
|
||||
Gfx::SeCompareOp Seele::Vulkan::cast(const VkCompareOp& op) {
|
||||
switch (op) {
|
||||
case VK_COMPARE_OP_NEVER:
|
||||
return SE_COMPARE_OP_NEVER;
|
||||
case VK_COMPARE_OP_LESS:
|
||||
@@ -1345,181 +1304,155 @@ Gfx::SeCompareOp Seele::Vulkan::cast(const VkCompareOp &op)
|
||||
return SE_COMPARE_OP_GREATER_OR_EQUAL;
|
||||
case VK_COMPARE_OP_ALWAYS:
|
||||
return SE_COMPARE_OP_ALWAYS;
|
||||
default: throw std::logic_error("Not implemented");
|
||||
|
||||
default:
|
||||
throw std::logic_error("Not implemented");
|
||||
}
|
||||
}
|
||||
|
||||
VkClearValue Seele::Vulkan::cast(const Gfx::SeClearValue& clear)
|
||||
{
|
||||
VkClearValue Seele::Vulkan::cast(const Gfx::SeClearValue& clear) {
|
||||
VkClearValue result;
|
||||
if constexpr (sizeof(clear) == sizeof(Gfx::SeClearColorValue))
|
||||
{
|
||||
if constexpr (sizeof(clear) == sizeof(Gfx::SeClearColorValue)) {
|
||||
result.color.float32[0] = clear.color.float32[0];
|
||||
result.color.float32[1] = clear.color.float32[1];
|
||||
result.color.float32[2] = clear.color.float32[2];
|
||||
result.color.float32[3] = clear.color.float32[3];
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
result.depthStencil.depth = clear.depthStencil.depth;
|
||||
result.depthStencil.stencil = clear.depthStencil.stencil;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Gfx::SeClearValue Seele::Vulkan::cast(const VkClearValue& clear)
|
||||
{
|
||||
Gfx::SeClearValue Seele::Vulkan::cast(const VkClearValue& clear) {
|
||||
Gfx::SeClearValue result;
|
||||
if constexpr (sizeof(clear) == sizeof(VkClearColorValue))
|
||||
{
|
||||
if constexpr (sizeof(clear) == sizeof(VkClearColorValue)) {
|
||||
result.color.float32[0] = clear.color.float32[0];
|
||||
result.color.float32[1] = clear.color.float32[1];
|
||||
result.color.float32[2] = clear.color.float32[2];
|
||||
result.color.float32[3] = clear.color.float32[3];
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
result.depthStencil.depth = clear.depthStencil.depth;
|
||||
result.depthStencil.stencil = clear.depthStencil.stencil;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
VkSamplerAddressMode Seele::Vulkan::cast(const Gfx::SeSamplerAddressMode &mode)
|
||||
{
|
||||
switch(mode)
|
||||
{
|
||||
case SE_SAMPLER_ADDRESS_MODE_REPEAT:
|
||||
VkSamplerAddressMode Seele::Vulkan::cast(const Gfx::SeSamplerAddressMode& mode) {
|
||||
switch (mode) {
|
||||
case SE_SAMPLER_ADDRESS_MODE_REPEAT:
|
||||
return VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||
case SE_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT:
|
||||
case SE_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT:
|
||||
return VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT;
|
||||
case SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE:
|
||||
case SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE:
|
||||
return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
|
||||
case SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER:
|
||||
case SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER:
|
||||
return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER;
|
||||
case SE_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE:
|
||||
case SE_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE:
|
||||
return VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE;
|
||||
default:
|
||||
return VK_SAMPLER_ADDRESS_MODE_MAX_ENUM;
|
||||
}
|
||||
}
|
||||
Gfx::SeSamplerAddressMode Seele::Vulkan::cast(const VkSamplerAddressMode &mode)
|
||||
{
|
||||
switch(mode)
|
||||
{
|
||||
case VK_SAMPLER_ADDRESS_MODE_REPEAT:
|
||||
Gfx::SeSamplerAddressMode Seele::Vulkan::cast(const VkSamplerAddressMode& mode) {
|
||||
switch (mode) {
|
||||
case VK_SAMPLER_ADDRESS_MODE_REPEAT:
|
||||
return SE_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||
case VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT:
|
||||
case VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT:
|
||||
return SE_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT;
|
||||
case VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE:
|
||||
case VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE:
|
||||
return SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
|
||||
case VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER:
|
||||
case VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER:
|
||||
return SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER;
|
||||
case VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE:
|
||||
case VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE:
|
||||
return SE_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE;
|
||||
default: throw std::logic_error("Not implemented");
|
||||
|
||||
default:
|
||||
throw std::logic_error("Not implemented");
|
||||
}
|
||||
}
|
||||
VkBorderColor Seele::Vulkan::cast(const Gfx::SeBorderColor &color)
|
||||
{
|
||||
switch(color)
|
||||
{
|
||||
case SE_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK:
|
||||
VkBorderColor Seele::Vulkan::cast(const Gfx::SeBorderColor& color) {
|
||||
switch (color) {
|
||||
case SE_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK:
|
||||
return VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
|
||||
case SE_BORDER_COLOR_INT_TRANSPARENT_BLACK:
|
||||
case SE_BORDER_COLOR_INT_TRANSPARENT_BLACK:
|
||||
return VK_BORDER_COLOR_INT_TRANSPARENT_BLACK;
|
||||
case SE_BORDER_COLOR_FLOAT_OPAQUE_BLACK:
|
||||
case SE_BORDER_COLOR_FLOAT_OPAQUE_BLACK:
|
||||
return VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK;
|
||||
case SE_BORDER_COLOR_INT_OPAQUE_BLACK:
|
||||
case SE_BORDER_COLOR_INT_OPAQUE_BLACK:
|
||||
return VK_BORDER_COLOR_INT_OPAQUE_BLACK;
|
||||
case SE_BORDER_COLOR_FLOAT_OPAQUE_WHITE:
|
||||
case SE_BORDER_COLOR_FLOAT_OPAQUE_WHITE:
|
||||
return VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
|
||||
case SE_BORDER_COLOR_INT_OPAQUE_WHITE:
|
||||
case SE_BORDER_COLOR_INT_OPAQUE_WHITE:
|
||||
return VK_BORDER_COLOR_INT_OPAQUE_WHITE;
|
||||
default:
|
||||
return VK_BORDER_COLOR_MAX_ENUM;
|
||||
}
|
||||
}
|
||||
Gfx::SeBorderColor Seele::Vulkan::cast(const VkBorderColor &color)
|
||||
{
|
||||
switch(color)
|
||||
{
|
||||
case VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK:
|
||||
return SE_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
|
||||
case VK_BORDER_COLOR_INT_TRANSPARENT_BLACK:
|
||||
return SE_BORDER_COLOR_INT_TRANSPARENT_BLACK;
|
||||
case VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK:
|
||||
return SE_BORDER_COLOR_FLOAT_OPAQUE_BLACK;
|
||||
case VK_BORDER_COLOR_INT_OPAQUE_BLACK:
|
||||
return SE_BORDER_COLOR_INT_OPAQUE_BLACK;
|
||||
case VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE:
|
||||
return SE_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
|
||||
case VK_BORDER_COLOR_INT_OPAQUE_WHITE:
|
||||
return SE_BORDER_COLOR_INT_OPAQUE_WHITE;
|
||||
default: throw std::logic_error("Not implemented");
|
||||
|
||||
Gfx::SeBorderColor Seele::Vulkan::cast(const VkBorderColor& color) {
|
||||
switch (color) {
|
||||
case VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK:
|
||||
return SE_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
|
||||
case VK_BORDER_COLOR_INT_TRANSPARENT_BLACK:
|
||||
return SE_BORDER_COLOR_INT_TRANSPARENT_BLACK;
|
||||
case VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK:
|
||||
return SE_BORDER_COLOR_FLOAT_OPAQUE_BLACK;
|
||||
case VK_BORDER_COLOR_INT_OPAQUE_BLACK:
|
||||
return SE_BORDER_COLOR_INT_OPAQUE_BLACK;
|
||||
case VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE:
|
||||
return SE_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
|
||||
case VK_BORDER_COLOR_INT_OPAQUE_WHITE:
|
||||
return SE_BORDER_COLOR_INT_OPAQUE_WHITE;
|
||||
default:
|
||||
throw std::logic_error("Not implemented");
|
||||
}
|
||||
}
|
||||
|
||||
VkFilter Seele::Vulkan::cast(const Gfx::SeFilter &filter)
|
||||
{
|
||||
switch(filter)
|
||||
{
|
||||
case SE_FILTER_NEAREST:
|
||||
VkFilter Seele::Vulkan::cast(const Gfx::SeFilter& filter) {
|
||||
switch (filter) {
|
||||
case SE_FILTER_NEAREST:
|
||||
return VK_FILTER_NEAREST;
|
||||
case SE_FILTER_LINEAR:
|
||||
case SE_FILTER_LINEAR:
|
||||
return VK_FILTER_LINEAR;
|
||||
case SE_FILTER_CUBIC_IMG:
|
||||
case SE_FILTER_CUBIC_IMG:
|
||||
return VK_FILTER_CUBIC_IMG;
|
||||
default: throw std::logic_error("Not implemented");
|
||||
|
||||
default:
|
||||
throw std::logic_error("Not implemented");
|
||||
}
|
||||
}
|
||||
Gfx::SeFilter Seele::Vulkan::cast(const VkFilter &filter)
|
||||
{
|
||||
switch(filter)
|
||||
{
|
||||
case VK_FILTER_NEAREST:
|
||||
Gfx::SeFilter Seele::Vulkan::cast(const VkFilter& filter) {
|
||||
switch (filter) {
|
||||
case VK_FILTER_NEAREST:
|
||||
return SE_FILTER_NEAREST;
|
||||
case VK_FILTER_LINEAR:
|
||||
case VK_FILTER_LINEAR:
|
||||
return SE_FILTER_LINEAR;
|
||||
case VK_FILTER_CUBIC_IMG:
|
||||
case VK_FILTER_CUBIC_IMG:
|
||||
return SE_FILTER_CUBIC_IMG;
|
||||
default: throw std::logic_error("Not implemented");
|
||||
|
||||
default:
|
||||
throw std::logic_error("Not implemented");
|
||||
}
|
||||
}
|
||||
|
||||
VkSamplerMipmapMode Seele::Vulkan::cast(const Gfx::SeSamplerMipmapMode &filter)
|
||||
{
|
||||
switch(filter)
|
||||
{
|
||||
VkSamplerMipmapMode Seele::Vulkan::cast(const Gfx::SeSamplerMipmapMode& filter) {
|
||||
switch (filter) {
|
||||
case SE_SAMPLER_MIPMAP_MODE_NEAREST:
|
||||
return VK_SAMPLER_MIPMAP_MODE_NEAREST;
|
||||
case SE_SAMPLER_MIPMAP_MODE_LINEAR:
|
||||
return VK_SAMPLER_MIPMAP_MODE_LINEAR;
|
||||
default: throw std::logic_error("Not implemented");
|
||||
|
||||
default:
|
||||
throw std::logic_error("Not implemented");
|
||||
}
|
||||
}
|
||||
Gfx::SeSamplerMipmapMode Seele::Vulkan::cast(const VkSamplerMipmapMode &filter)
|
||||
{
|
||||
switch(filter)
|
||||
{
|
||||
Gfx::SeSamplerMipmapMode Seele::Vulkan::cast(const VkSamplerMipmapMode& filter) {
|
||||
switch (filter) {
|
||||
case VK_SAMPLER_MIPMAP_MODE_NEAREST:
|
||||
return SE_SAMPLER_MIPMAP_MODE_NEAREST;
|
||||
case VK_SAMPLER_MIPMAP_MODE_LINEAR:
|
||||
return SE_SAMPLER_MIPMAP_MODE_LINEAR;
|
||||
default: throw std::logic_error("Not implemented");
|
||||
|
||||
default:
|
||||
throw std::logic_error("Not implemented");
|
||||
}
|
||||
}
|
||||
VkAccessFlagBits Seele::Vulkan::cast(const Gfx::SeAccessFlagBits &flags)
|
||||
{
|
||||
switch(flags)
|
||||
{
|
||||
VkAccessFlagBits Seele::Vulkan::cast(const Gfx::SeAccessFlagBits& flags) {
|
||||
switch (flags) {
|
||||
case SE_ACCESS_INDIRECT_COMMAND_READ_BIT:
|
||||
return VK_ACCESS_INDIRECT_COMMAND_READ_BIT;
|
||||
case SE_ACCESS_INDEX_READ_BIT:
|
||||
@@ -1575,10 +1508,8 @@ VkAccessFlagBits Seele::Vulkan::cast(const Gfx::SeAccessFlagBits &flags)
|
||||
}
|
||||
}
|
||||
|
||||
Gfx::SeAccessFlagBits Seele::Vulkan::cast(const VkAccessFlagBits &flags)
|
||||
{
|
||||
switch(flags)
|
||||
{
|
||||
Gfx::SeAccessFlagBits Seele::Vulkan::cast(const VkAccessFlagBits& flags) {
|
||||
switch (flags) {
|
||||
case VK_ACCESS_INDIRECT_COMMAND_READ_BIT:
|
||||
return SE_ACCESS_INDIRECT_COMMAND_READ_BIT;
|
||||
case VK_ACCESS_INDEX_READ_BIT:
|
||||
@@ -1633,10 +1564,8 @@ Gfx::SeAccessFlagBits Seele::Vulkan::cast(const VkAccessFlagBits &flags)
|
||||
return SE_ACCESS_FLAG_BITS_MAX_ENUM;
|
||||
}
|
||||
}
|
||||
VkPipelineStageFlagBits Seele::Vulkan::cast(const Gfx::SePipelineStageFlagBits &flags)
|
||||
{
|
||||
switch(flags)
|
||||
{
|
||||
VkPipelineStageFlagBits Seele::Vulkan::cast(const Gfx::SePipelineStageFlagBits& flags) {
|
||||
switch (flags) {
|
||||
case SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT:
|
||||
return VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
|
||||
case SE_PIPELINE_STAGE_DRAW_INDIRECT_BIT:
|
||||
@@ -1695,10 +1624,8 @@ VkPipelineStageFlagBits Seele::Vulkan::cast(const Gfx::SePipelineStageFlagBits &
|
||||
return VK_PIPELINE_STAGE_FLAG_BITS_MAX_ENUM;
|
||||
}
|
||||
}
|
||||
Gfx::SePipelineStageFlagBits Seele::Vulkan::cast(const VkPipelineStageFlagBits &flags)
|
||||
{
|
||||
switch(flags)
|
||||
{
|
||||
Gfx::SePipelineStageFlagBits Seele::Vulkan::cast(const VkPipelineStageFlagBits& flags) {
|
||||
switch (flags) {
|
||||
case VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT:
|
||||
return SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
|
||||
case VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT:
|
||||
|
||||
@@ -1,60 +1,57 @@
|
||||
#pragma once
|
||||
#include "Graphics/Enums.h"
|
||||
#include <vulkan/vulkan.h>
|
||||
#include <iostream>
|
||||
#include <thread>
|
||||
#include <vulkan/vulkan.h>
|
||||
|
||||
#define VK_CHECK(f) \
|
||||
{ \
|
||||
VkResult res = (f); \
|
||||
if (res != VK_SUCCESS) \
|
||||
{ \
|
||||
if(res == VK_ERROR_DEVICE_LOST) \
|
||||
{ \
|
||||
std::this_thread::sleep_for(std::chrono::seconds(3)); \
|
||||
} \
|
||||
std::cout << "Fatal : VkResult is " << res << " in " << __FILE__ << " at line " << __LINE__ << std::endl; \
|
||||
abort(); \
|
||||
} \
|
||||
}
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
namespace Vulkan
|
||||
{
|
||||
VkDescriptorType cast(const Gfx::SeDescriptorType &descriptorType);
|
||||
Gfx::SeDescriptorType cast(const VkDescriptorType &descriptorType);
|
||||
VkShaderStageFlagBits cast(const Gfx::SeShaderStageFlagBits &stage);
|
||||
Gfx::SeShaderStageFlagBits cast(const VkShaderStageFlagBits &stage);
|
||||
VkFormat cast(const Gfx::SeFormat &format);
|
||||
Gfx::SeFormat cast(const VkFormat &format);
|
||||
VkImageLayout cast(const Gfx::SeImageLayout &imageLayout);
|
||||
Gfx::SeImageLayout cast(const VkImageLayout &imageLayout);
|
||||
VkAttachmentStoreOp cast(const Gfx::SeAttachmentStoreOp &storeOp);
|
||||
Gfx::SeAttachmentStoreOp cast(const VkAttachmentStoreOp &storeOp);
|
||||
VkAttachmentLoadOp cast(const Gfx::SeAttachmentLoadOp &loadOp);
|
||||
Gfx::SeAttachmentLoadOp cast(const VkAttachmentLoadOp &loadOp);
|
||||
VkIndexType cast(const Gfx::SeIndexType &indexType);
|
||||
Gfx::SeIndexType cast(const VkIndexType &indexType);
|
||||
VkPrimitiveTopology cast(const Gfx::SePrimitiveTopology &topology);
|
||||
Gfx::SePrimitiveTopology cast(const VkPrimitiveTopology &topology);
|
||||
VkPolygonMode cast(const Gfx::SePolygonMode &mode);
|
||||
Gfx::SePolygonMode cast(const VkPolygonMode &mode);
|
||||
VkCompareOp cast(const Gfx::SeCompareOp &op);
|
||||
Gfx::SeCompareOp cast(const VkCompareOp &op);
|
||||
VkClearValue cast(const Gfx::SeClearValue &clear);
|
||||
Gfx::SeClearValue cast(const VkClearValue &clear);
|
||||
VkSamplerAddressMode cast(const Gfx::SeSamplerAddressMode &mode);
|
||||
Gfx::SeSamplerAddressMode cast(const VkSamplerAddressMode &mode);
|
||||
VkBorderColor cast(const Gfx::SeBorderColor &color);
|
||||
Gfx::SeBorderColor cast(const VkBorderColor &color);
|
||||
VkFilter cast(const Gfx::SeFilter &filter);
|
||||
Gfx::SeFilter cast(const VkFilter &filter);
|
||||
VkSamplerMipmapMode cast(const Gfx::SeSamplerMipmapMode &filter);
|
||||
Gfx::SeSamplerMipmapMode cast(const VkSamplerMipmapMode &filter);
|
||||
VkAccessFlagBits cast(const Gfx::SeAccessFlagBits &flags);
|
||||
Gfx::SeAccessFlagBits cast(const VkAccessFlagBits &flags);
|
||||
VkPipelineStageFlagBits cast(const Gfx::SePipelineStageFlagBits &flags);
|
||||
Gfx::SePipelineStageFlagBits cast(const VkPipelineStageFlagBits &flags);
|
||||
#define VK_CHECK(f) \
|
||||
{ \
|
||||
VkResult res = (f); \
|
||||
if (res != VK_SUCCESS) { \
|
||||
if (res == VK_ERROR_DEVICE_LOST) { \
|
||||
std::this_thread::sleep_for(std::chrono::seconds(3)); \
|
||||
} \
|
||||
std::cout << "Fatal : VkResult is " << res << " in " << __FILE__ << " at line " << __LINE__ << std::endl; \
|
||||
abort(); \
|
||||
} \
|
||||
}
|
||||
|
||||
namespace Seele {
|
||||
namespace Vulkan {
|
||||
VkDescriptorType cast(const Gfx::SeDescriptorType& descriptorType);
|
||||
Gfx::SeDescriptorType cast(const VkDescriptorType& descriptorType);
|
||||
VkShaderStageFlagBits cast(const Gfx::SeShaderStageFlagBits& stage);
|
||||
Gfx::SeShaderStageFlagBits cast(const VkShaderStageFlagBits& stage);
|
||||
VkFormat cast(const Gfx::SeFormat& format);
|
||||
Gfx::SeFormat cast(const VkFormat& format);
|
||||
VkImageLayout cast(const Gfx::SeImageLayout& imageLayout);
|
||||
Gfx::SeImageLayout cast(const VkImageLayout& imageLayout);
|
||||
VkAttachmentStoreOp cast(const Gfx::SeAttachmentStoreOp& storeOp);
|
||||
Gfx::SeAttachmentStoreOp cast(const VkAttachmentStoreOp& storeOp);
|
||||
VkAttachmentLoadOp cast(const Gfx::SeAttachmentLoadOp& loadOp);
|
||||
Gfx::SeAttachmentLoadOp cast(const VkAttachmentLoadOp& loadOp);
|
||||
VkIndexType cast(const Gfx::SeIndexType& indexType);
|
||||
Gfx::SeIndexType cast(const VkIndexType& indexType);
|
||||
VkPrimitiveTopology cast(const Gfx::SePrimitiveTopology& topology);
|
||||
Gfx::SePrimitiveTopology cast(const VkPrimitiveTopology& topology);
|
||||
VkPolygonMode cast(const Gfx::SePolygonMode& mode);
|
||||
Gfx::SePolygonMode cast(const VkPolygonMode& mode);
|
||||
VkCompareOp cast(const Gfx::SeCompareOp& op);
|
||||
Gfx::SeCompareOp cast(const VkCompareOp& op);
|
||||
VkClearValue cast(const Gfx::SeClearValue& clear);
|
||||
Gfx::SeClearValue cast(const VkClearValue& clear);
|
||||
VkSamplerAddressMode cast(const Gfx::SeSamplerAddressMode& mode);
|
||||
Gfx::SeSamplerAddressMode cast(const VkSamplerAddressMode& mode);
|
||||
VkBorderColor cast(const Gfx::SeBorderColor& color);
|
||||
Gfx::SeBorderColor cast(const VkBorderColor& color);
|
||||
VkFilter cast(const Gfx::SeFilter& filter);
|
||||
Gfx::SeFilter cast(const VkFilter& filter);
|
||||
VkSamplerMipmapMode cast(const Gfx::SeSamplerMipmapMode& filter);
|
||||
Gfx::SeSamplerMipmapMode cast(const VkSamplerMipmapMode& filter);
|
||||
VkAccessFlagBits cast(const Gfx::SeAccessFlagBits& flags);
|
||||
Gfx::SeAccessFlagBits cast(const VkAccessFlagBits& flags);
|
||||
VkPipelineStageFlagBits cast(const Gfx::SePipelineStageFlagBits& flags);
|
||||
Gfx::SePipelineStageFlagBits cast(const VkPipelineStageFlagBits& flags);
|
||||
} // namespace Vulkan
|
||||
} // namespace Seele
|
||||
|
||||
@@ -1,57 +1,50 @@
|
||||
#include "Framebuffer.h"
|
||||
#include "Enums.h"
|
||||
#include "RenderPass.h"
|
||||
#include "Graphics.h"
|
||||
#include "Texture.h"
|
||||
#include "CRC.h"
|
||||
#include "Enums.h"
|
||||
#include "Graphics.h"
|
||||
#include "RenderPass.h"
|
||||
#include "Texture.h"
|
||||
|
||||
|
||||
using namespace Seele;
|
||||
using namespace Seele::Vulkan;
|
||||
|
||||
Framebuffer::Framebuffer(PGraphics graphics, PRenderPass renderPass, Gfx::RenderTargetLayout renderTargetLayout)
|
||||
: graphics(graphics)
|
||||
, layout(renderTargetLayout)
|
||||
, renderPass(renderPass)
|
||||
{
|
||||
: graphics(graphics), layout(renderTargetLayout), renderPass(renderPass) {
|
||||
FramebufferDescription description;
|
||||
std::memset(&description, 0, sizeof(FramebufferDescription));
|
||||
Array<VkImageView> attachments;
|
||||
uint32 width = 0;
|
||||
uint32 height = 0;
|
||||
for (auto inputAttachment : layout.inputAttachments)
|
||||
{
|
||||
for (auto inputAttachment : layout.inputAttachments) {
|
||||
PTexture2D vkInputAttachment = inputAttachment.getTexture().cast<Texture2D>();
|
||||
attachments.add(vkInputAttachment->getView());
|
||||
description.inputAttachments[description.numInputAttachments++] = vkInputAttachment->getView();
|
||||
width = std::max(width, vkInputAttachment->getWidth());
|
||||
height = std::max(height, vkInputAttachment->getHeight());
|
||||
}
|
||||
for (auto colorAttachment : layout.colorAttachments)
|
||||
{
|
||||
for (auto colorAttachment : layout.colorAttachments) {
|
||||
PTexture2D vkColorAttachment = colorAttachment.getTexture().cast<Texture2D>();
|
||||
attachments.add(vkColorAttachment->getView());
|
||||
description.colorAttachments[description.numColorAttachments++] = vkColorAttachment->getView();
|
||||
width = std::max(width, vkColorAttachment->getWidth());
|
||||
height = std::max(height, vkColorAttachment->getHeight());
|
||||
}
|
||||
for (auto resolveAttachment : layout.resolveAttachments)
|
||||
{
|
||||
for (auto resolveAttachment : layout.resolveAttachments) {
|
||||
PTexture2D vkResolveAttachment = resolveAttachment.getTexture().cast<Texture2D>();
|
||||
attachments.add(vkResolveAttachment->getView());
|
||||
description.resolveAttachments[description.numResolveAttachments++] = vkResolveAttachment->getView();
|
||||
width = std::max(width, vkResolveAttachment->getWidth());
|
||||
height = std::max(height, vkResolveAttachment->getHeight());
|
||||
}
|
||||
if (layout.depthAttachment.getTexture() != nullptr)
|
||||
{
|
||||
if (layout.depthAttachment.getTexture() != nullptr) {
|
||||
PTexture2D vkDepthAttachment = layout.depthAttachment.getTexture().cast<Texture2D>();
|
||||
attachments.add(vkDepthAttachment->getView());
|
||||
description.depthAttachment = vkDepthAttachment->getView();
|
||||
width = std::max(width, vkDepthAttachment->getWidth());
|
||||
height = std::max(height, vkDepthAttachment->getHeight());
|
||||
}
|
||||
if (layout.depthResolveAttachment.getTexture() != nullptr)
|
||||
{
|
||||
if (layout.depthResolveAttachment.getTexture() != nullptr) {
|
||||
PTexture2D vkDepthAttachment = layout.depthResolveAttachment.getTexture().cast<Texture2D>();
|
||||
attachments.add(vkDepthAttachment->getView());
|
||||
description.depthResolveAttachment = vkDepthAttachment->getView();
|
||||
@@ -74,8 +67,7 @@ Framebuffer::Framebuffer(PGraphics graphics, PRenderPass renderPass, Gfx::Render
|
||||
hash = CRC::Calculate(&description, sizeof(FramebufferDescription), CRC::CRC_32());
|
||||
}
|
||||
|
||||
Framebuffer::~Framebuffer()
|
||||
{
|
||||
Framebuffer::~Framebuffer() {
|
||||
vkDestroyFramebuffer(graphics->getDevice(), handle, nullptr);
|
||||
graphics = nullptr;
|
||||
}
|
||||
@@ -3,13 +3,10 @@
|
||||
#include "Graphics.h"
|
||||
#include "Graphics/RenderTarget.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
namespace Vulkan
|
||||
{
|
||||
namespace Seele {
|
||||
namespace Vulkan {
|
||||
DECLARE_REF(RenderPass)
|
||||
struct FramebufferDescription
|
||||
{
|
||||
struct FramebufferDescription {
|
||||
StaticArray<VkImageView, 16> inputAttachments;
|
||||
StaticArray<VkImageView, 16> colorAttachments;
|
||||
StaticArray<VkImageView, 16> resolveAttachments;
|
||||
@@ -19,21 +16,14 @@ struct FramebufferDescription
|
||||
uint32 numColorAttachments;
|
||||
uint32 numResolveAttachments;
|
||||
};
|
||||
class Framebuffer
|
||||
{
|
||||
public:
|
||||
class Framebuffer {
|
||||
public:
|
||||
Framebuffer(PGraphics graphics, PRenderPass renderpass, Gfx::RenderTargetLayout renderTargetLayout);
|
||||
virtual ~Framebuffer();
|
||||
constexpr VkFramebuffer getHandle() const
|
||||
{
|
||||
return handle;
|
||||
}
|
||||
constexpr uint32 getHash() const
|
||||
{
|
||||
return hash;
|
||||
}
|
||||
constexpr VkFramebuffer getHandle() const { return handle; }
|
||||
constexpr uint32 getHash() const { return hash; }
|
||||
|
||||
private:
|
||||
private:
|
||||
uint32 hash;
|
||||
PGraphics graphics;
|
||||
VkFramebuffer handle;
|
||||
|
||||
@@ -1,21 +1,22 @@
|
||||
#include "Graphics.h"
|
||||
#include "Debug.h"
|
||||
#include "Allocator.h"
|
||||
#include "Buffer.h"
|
||||
#include "Command.h"
|
||||
#include "Debug.h"
|
||||
#include "Descriptor.h"
|
||||
#include "Framebuffer.h"
|
||||
#include "Graphics/Enums.h"
|
||||
#include "Graphics/Graphics.h"
|
||||
#include "Graphics/Initializer.h"
|
||||
#include "PipelineCache.h"
|
||||
#include "Command.h"
|
||||
#include "Descriptor.h"
|
||||
#include "Window.h"
|
||||
#include "RenderPass.h"
|
||||
#include "Framebuffer.h"
|
||||
#include "Shader.h"
|
||||
#include "RayTracing.h"
|
||||
#include "RenderPass.h"
|
||||
#include "Shader.h"
|
||||
#include "Window.h"
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <cstring>
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
#define VMA_IMPLEMENTATION
|
||||
#include "vk_mem_alloc.h"
|
||||
|
||||
@@ -26,16 +27,9 @@ thread_local PCommandPool Seele::Vulkan::Graphics::graphicsCommands = nullptr;
|
||||
thread_local PCommandPool Seele::Vulkan::Graphics::computeCommands = nullptr;
|
||||
thread_local PCommandPool Seele::Vulkan::Graphics::transferCommands = nullptr;
|
||||
|
||||
Graphics::Graphics()
|
||||
: instance(VK_NULL_HANDLE)
|
||||
, handle(VK_NULL_HANDLE)
|
||||
, physicalDevice(VK_NULL_HANDLE)
|
||||
, callback(VK_NULL_HANDLE)
|
||||
{
|
||||
}
|
||||
Graphics::Graphics() : instance(VK_NULL_HANDLE), handle(VK_NULL_HANDLE), physicalDevice(VK_NULL_HANDLE), callback(VK_NULL_HANDLE) {}
|
||||
|
||||
Graphics::~Graphics()
|
||||
{
|
||||
Graphics::~Graphics() {
|
||||
vkDeviceWaitIdle(handle);
|
||||
pipelineCache = nullptr;
|
||||
allocatedFramebuffers.clear();
|
||||
@@ -49,8 +43,7 @@ Graphics::~Graphics()
|
||||
vkDestroyInstance(instance, nullptr);
|
||||
}
|
||||
|
||||
void Graphics::init(GraphicsInitializer initInfo)
|
||||
{
|
||||
void Graphics::init(GraphicsInitializer initInfo) {
|
||||
initInstance(initInfo);
|
||||
#if ENABLE_VALIDATION
|
||||
setupDebugCallback();
|
||||
@@ -74,152 +67,102 @@ void Graphics::init(GraphicsInitializer initInfo)
|
||||
destructionManager = new DestructionManager(this);
|
||||
}
|
||||
|
||||
Gfx::OWindow Graphics::createWindow(const WindowCreateInfo &createInfo)
|
||||
{
|
||||
return new Window(this, createInfo);
|
||||
}
|
||||
Gfx::OWindow Graphics::createWindow(const WindowCreateInfo& createInfo) { return new Window(this, createInfo); }
|
||||
|
||||
Gfx::OViewport Graphics::createViewport(Gfx::PWindow owner, const ViewportCreateInfo &viewportInfo)
|
||||
{
|
||||
Gfx::OViewport Graphics::createViewport(Gfx::PWindow owner, const ViewportCreateInfo& viewportInfo) {
|
||||
return new Viewport(owner, viewportInfo);
|
||||
}
|
||||
|
||||
Gfx::ORenderPass Graphics::createRenderPass(Gfx::RenderTargetLayout layout, Array<Gfx::SubPassDependency> dependencies, Gfx::PViewport renderArea)
|
||||
{
|
||||
Gfx::ORenderPass Graphics::createRenderPass(Gfx::RenderTargetLayout layout, Array<Gfx::SubPassDependency> dependencies,
|
||||
Gfx::PViewport renderArea) {
|
||||
return new RenderPass(this, std::move(layout), std::move(dependencies), renderArea);
|
||||
}
|
||||
void Graphics::beginRenderPass(Gfx::PRenderPass renderPass)
|
||||
{
|
||||
void Graphics::beginRenderPass(Gfx::PRenderPass renderPass) {
|
||||
PRenderPass rp = renderPass.cast<RenderPass>();
|
||||
uint32 framebufferHash = rp->getFramebufferHash();
|
||||
PFramebuffer framebuffer;
|
||||
{
|
||||
auto found = allocatedFramebuffers.find(framebufferHash);
|
||||
if (found == allocatedFramebuffers.end())
|
||||
{
|
||||
if (found == allocatedFramebuffers.end()) {
|
||||
allocatedFramebuffers[framebufferHash] = new Framebuffer(this, rp, rp->getLayout());
|
||||
framebuffer = allocatedFramebuffers[framebufferHash];
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
framebuffer = std::move(found->value);
|
||||
}
|
||||
}
|
||||
getGraphicsCommands()->getCommands()->beginRenderPass(rp, framebuffer);
|
||||
}
|
||||
|
||||
void Graphics::endRenderPass()
|
||||
{
|
||||
void Graphics::endRenderPass() {
|
||||
getGraphicsCommands()->getCommands()->endRenderPass();
|
||||
getGraphicsCommands()->submitCommands();
|
||||
}
|
||||
|
||||
void Graphics::waitDeviceIdle()
|
||||
{
|
||||
vkDeviceWaitIdle(handle);
|
||||
}
|
||||
void Graphics::waitDeviceIdle() { vkDeviceWaitIdle(handle); }
|
||||
|
||||
void Graphics::executeCommands(Array<Gfx::ORenderCommand> commands)
|
||||
{
|
||||
void Graphics::executeCommands(Array<Gfx::ORenderCommand> commands) {
|
||||
getGraphicsCommands()->getCommands()->executeCommands(std::move(commands));
|
||||
}
|
||||
|
||||
void Graphics::executeCommands(Array<Gfx::OComputeCommand> commands)
|
||||
{
|
||||
void Graphics::executeCommands(Array<Gfx::OComputeCommand> commands) {
|
||||
getComputeCommands()->getCommands()->executeCommands(std::move(commands));
|
||||
}
|
||||
|
||||
Gfx::OTexture2D Graphics::createTexture2D(const TextureCreateInfo &createInfo)
|
||||
{
|
||||
return new Texture2D(this, createInfo);
|
||||
}
|
||||
Gfx::OTexture2D Graphics::createTexture2D(const TextureCreateInfo& createInfo) { return new Texture2D(this, createInfo); }
|
||||
|
||||
Gfx::OTexture3D Graphics::createTexture3D(const TextureCreateInfo &createInfo)
|
||||
{
|
||||
return new Texture3D(this, createInfo);
|
||||
}
|
||||
Gfx::OTexture3D Graphics::createTexture3D(const TextureCreateInfo& createInfo) { return new Texture3D(this, createInfo); }
|
||||
|
||||
Gfx::OTextureCube Graphics::createTextureCube(const TextureCreateInfo &createInfo)
|
||||
{
|
||||
return new TextureCube(this, createInfo);
|
||||
}
|
||||
Gfx::OTextureCube Graphics::createTextureCube(const TextureCreateInfo& createInfo) { return new TextureCube(this, createInfo); }
|
||||
|
||||
Gfx::OUniformBuffer Graphics::createUniformBuffer(const UniformBufferCreateInfo &bulkData)
|
||||
{
|
||||
return new UniformBuffer(this, bulkData);
|
||||
}
|
||||
Gfx::OUniformBuffer Graphics::createUniformBuffer(const UniformBufferCreateInfo& bulkData) { return new UniformBuffer(this, bulkData); }
|
||||
|
||||
Gfx::OShaderBuffer Graphics::createShaderBuffer(const ShaderBufferCreateInfo &bulkData)
|
||||
{
|
||||
return new ShaderBuffer(this, bulkData);
|
||||
}
|
||||
Gfx::OVertexBuffer Graphics::createVertexBuffer(const VertexBufferCreateInfo &bulkData)
|
||||
{
|
||||
return new VertexBuffer(this, bulkData);
|
||||
}
|
||||
Gfx::OShaderBuffer Graphics::createShaderBuffer(const ShaderBufferCreateInfo& bulkData) { return new ShaderBuffer(this, bulkData); }
|
||||
Gfx::OVertexBuffer Graphics::createVertexBuffer(const VertexBufferCreateInfo& bulkData) { return new VertexBuffer(this, bulkData); }
|
||||
|
||||
Gfx::OIndexBuffer Graphics::createIndexBuffer(const IndexBufferCreateInfo &bulkData)
|
||||
{
|
||||
return new IndexBuffer(this, bulkData);
|
||||
}
|
||||
Gfx::ORenderCommand Graphics::createRenderCommand(const std::string& name)
|
||||
{
|
||||
return getGraphicsCommands()->createRenderCommand(name);
|
||||
}
|
||||
Gfx::OIndexBuffer Graphics::createIndexBuffer(const IndexBufferCreateInfo& bulkData) { return new IndexBuffer(this, bulkData); }
|
||||
Gfx::ORenderCommand Graphics::createRenderCommand(const std::string& name) { return getGraphicsCommands()->createRenderCommand(name); }
|
||||
|
||||
Gfx::OComputeCommand Graphics::createComputeCommand(const std::string& name)
|
||||
{
|
||||
return getComputeCommands()->createComputeCommand(name);
|
||||
}
|
||||
Gfx::OComputeCommand Graphics::createComputeCommand(const std::string& name) { return getComputeCommands()->createComputeCommand(name); }
|
||||
|
||||
Gfx::OVertexShader Graphics::createVertexShader(const ShaderCreateInfo& createInfo)
|
||||
{
|
||||
Gfx::OVertexShader Graphics::createVertexShader(const ShaderCreateInfo& createInfo) {
|
||||
OVertexShader shader = new VertexShader(this);
|
||||
shader->create(createInfo);
|
||||
return shader;
|
||||
}
|
||||
Gfx::OFragmentShader Graphics::createFragmentShader(const ShaderCreateInfo& createInfo)
|
||||
{
|
||||
Gfx::OFragmentShader Graphics::createFragmentShader(const ShaderCreateInfo& createInfo) {
|
||||
OFragmentShader shader = new FragmentShader(this);
|
||||
shader->create(createInfo);
|
||||
return shader;
|
||||
}
|
||||
Gfx::OComputeShader Graphics::createComputeShader(const ShaderCreateInfo& createInfo)
|
||||
{
|
||||
Gfx::OComputeShader Graphics::createComputeShader(const ShaderCreateInfo& createInfo) {
|
||||
OComputeShader shader = new ComputeShader(this);
|
||||
shader->create(createInfo);
|
||||
return shader;
|
||||
}
|
||||
Gfx::OTaskShader Graphics::createTaskShader(const ShaderCreateInfo& createInfo)
|
||||
{
|
||||
Gfx::OTaskShader Graphics::createTaskShader(const ShaderCreateInfo& createInfo) {
|
||||
OTaskShader shader = new TaskShader(this);
|
||||
shader->create(createInfo);
|
||||
return shader;
|
||||
}
|
||||
Gfx::OMeshShader Graphics::createMeshShader(const ShaderCreateInfo& createInfo)
|
||||
{
|
||||
Gfx::OMeshShader Graphics::createMeshShader(const ShaderCreateInfo& createInfo) {
|
||||
OMeshShader shader = new MeshShader(this);
|
||||
shader->create(createInfo);
|
||||
return shader;
|
||||
}
|
||||
|
||||
Gfx::PGraphicsPipeline Graphics::createGraphicsPipeline(Gfx::LegacyPipelineCreateInfo createInfo)
|
||||
{
|
||||
Gfx::PGraphicsPipeline Graphics::createGraphicsPipeline(Gfx::LegacyPipelineCreateInfo createInfo) {
|
||||
return pipelineCache->createPipeline(std::move(createInfo));
|
||||
}
|
||||
|
||||
Gfx::PGraphicsPipeline Graphics::createGraphicsPipeline(Gfx::MeshPipelineCreateInfo createInfo)
|
||||
{
|
||||
Gfx::PGraphicsPipeline Graphics::createGraphicsPipeline(Gfx::MeshPipelineCreateInfo createInfo) {
|
||||
return pipelineCache->createPipeline(std::move(createInfo));
|
||||
}
|
||||
|
||||
Gfx::PComputePipeline Graphics::createComputePipeline(Gfx::ComputePipelineCreateInfo createInfo)
|
||||
{
|
||||
Gfx::PComputePipeline Graphics::createComputePipeline(Gfx::ComputePipelineCreateInfo createInfo) {
|
||||
return pipelineCache->createPipeline(std::move(createInfo));
|
||||
}
|
||||
|
||||
Gfx::OSampler Graphics::createSampler(const SamplerCreateInfo& createInfo)
|
||||
{
|
||||
Gfx::OSampler Graphics::createSampler(const SamplerCreateInfo& createInfo) {
|
||||
VkSamplerCreateInfo vkInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
@@ -243,87 +186,75 @@ Gfx::OSampler Graphics::createSampler(const SamplerCreateInfo& createInfo)
|
||||
return new Sampler(this, vkInfo);
|
||||
}
|
||||
|
||||
Gfx::ODescriptorLayout Graphics::createDescriptorLayout(const std::string& name)
|
||||
{
|
||||
return new DescriptorLayout(this, name);
|
||||
}
|
||||
Gfx::ODescriptorLayout Graphics::createDescriptorLayout(const std::string& name) { return new DescriptorLayout(this, name); }
|
||||
|
||||
Gfx::OPipelineLayout Graphics::createPipelineLayout(const std::string& name, Gfx::PPipelineLayout baseLayout)
|
||||
{
|
||||
Gfx::OPipelineLayout Graphics::createPipelineLayout(const std::string& name, Gfx::PPipelineLayout baseLayout) {
|
||||
return new PipelineLayout(this, name, baseLayout);
|
||||
}
|
||||
|
||||
Gfx::OVertexInput Graphics::createVertexInput(VertexInputStateCreateInfo createInfo)
|
||||
{
|
||||
return new VertexInput(createInfo);
|
||||
}
|
||||
Gfx::OVertexInput Graphics::createVertexInput(VertexInputStateCreateInfo createInfo) { return new VertexInput(createInfo); }
|
||||
|
||||
void Graphics::resolveTexture(Gfx::PTexture source, Gfx::PTexture destination)
|
||||
{
|
||||
void Graphics::resolveTexture(Gfx::PTexture source, Gfx::PTexture destination) {
|
||||
PTextureBase sourceTex = source.cast<TextureBase>();
|
||||
PTextureBase destinationTex = destination.cast<TextureBase>();
|
||||
VkImageResolve resolve = {
|
||||
.srcSubresource = VkImageSubresourceLayers {
|
||||
.aspectMask = sourceTex->getAspect(),
|
||||
.mipLevel = 0,
|
||||
.baseArrayLayer = 0,
|
||||
.layerCount = 1,
|
||||
},
|
||||
.srcOffset = VkOffset3D {
|
||||
.x = 0,
|
||||
.y = 0,
|
||||
.z = 0,
|
||||
},
|
||||
.dstSubresource = VkImageSubresourceLayers {
|
||||
.aspectMask = sourceTex->getAspect(),
|
||||
.mipLevel = 0,
|
||||
.baseArrayLayer = 0,
|
||||
.layerCount = 1,
|
||||
},
|
||||
.dstOffset = VkOffset3D {
|
||||
.x = 0,
|
||||
.y = 0,
|
||||
.z = 0,
|
||||
},
|
||||
.extent = VkExtent3D {
|
||||
.width = sourceTex->getWidth(),
|
||||
.height = sourceTex->getHeight(),
|
||||
.depth = sourceTex->getDepth(),
|
||||
},
|
||||
.srcSubresource =
|
||||
VkImageSubresourceLayers{
|
||||
.aspectMask = sourceTex->getAspect(),
|
||||
.mipLevel = 0,
|
||||
.baseArrayLayer = 0,
|
||||
.layerCount = 1,
|
||||
},
|
||||
.srcOffset =
|
||||
VkOffset3D{
|
||||
.x = 0,
|
||||
.y = 0,
|
||||
.z = 0,
|
||||
},
|
||||
.dstSubresource =
|
||||
VkImageSubresourceLayers{
|
||||
.aspectMask = sourceTex->getAspect(),
|
||||
.mipLevel = 0,
|
||||
.baseArrayLayer = 0,
|
||||
.layerCount = 1,
|
||||
},
|
||||
.dstOffset =
|
||||
VkOffset3D{
|
||||
.x = 0,
|
||||
.y = 0,
|
||||
.z = 0,
|
||||
},
|
||||
.extent =
|
||||
VkExtent3D{
|
||||
.width = sourceTex->getWidth(),
|
||||
.height = sourceTex->getHeight(),
|
||||
.depth = sourceTex->getDepth(),
|
||||
},
|
||||
};
|
||||
vkCmdResolveImage(getGraphicsCommands()->getCommands()->getHandle(), sourceTex->getImage(), cast(sourceTex->getLayout()), destinationTex->getImage(), cast(destinationTex->getLayout()), 1, &resolve);
|
||||
vkCmdResolveImage(getGraphicsCommands()->getCommands()->getHandle(), sourceTex->getImage(), cast(sourceTex->getLayout()),
|
||||
destinationTex->getImage(), cast(destinationTex->getLayout()), 1, &resolve);
|
||||
}
|
||||
|
||||
Gfx::OBottomLevelAS Graphics::createBottomLevelAccelerationStructure(const Gfx::BottomLevelASCreateInfo& createInfo)
|
||||
{
|
||||
Gfx::OBottomLevelAS Graphics::createBottomLevelAccelerationStructure(const Gfx::BottomLevelASCreateInfo& createInfo) {
|
||||
return new BottomLevelAS(this, createInfo);
|
||||
}
|
||||
|
||||
Gfx::OTopLevelAS Graphics::createTopLevelAccelerationStructure(const Gfx::TopLevelASCreateInfo& createInfo)
|
||||
{
|
||||
Gfx::OTopLevelAS Graphics::createTopLevelAccelerationStructure(const Gfx::TopLevelASCreateInfo& createInfo) {
|
||||
return new TopLevelAS(this, createInfo);
|
||||
}
|
||||
|
||||
void Graphics::vkCmdDrawMeshTasksEXT(VkCommandBuffer cmd, uint32 groupX, uint32 groupY, uint32 groupZ)
|
||||
{
|
||||
void Graphics::vkCmdDrawMeshTasksEXT(VkCommandBuffer cmd, uint32 groupX, uint32 groupY, uint32 groupZ) {
|
||||
cmdDrawMeshTasks(cmd, groupX, groupY, groupZ);
|
||||
}
|
||||
|
||||
void Graphics::vkCmdDrawMeshTasksIndirectEXT(VkCommandBuffer cmd, VkBuffer buffer, uint64 offset, uint32 drawCount, uint32 stride)
|
||||
{
|
||||
void Graphics::vkCmdDrawMeshTasksIndirectEXT(VkCommandBuffer cmd, VkBuffer buffer, uint64 offset, uint32 drawCount, uint32 stride) {
|
||||
cmdDrawMeshTasksIndirect(cmd, buffer, offset, drawCount, stride);
|
||||
}
|
||||
|
||||
void Graphics::vkSetDebugUtilsObjectNameEXT(VkDebugUtilsObjectNameInfoEXT* info)
|
||||
{
|
||||
VK_CHECK(setDebugUtilsObjectName(handle, info));
|
||||
}
|
||||
void Graphics::vkSetDebugUtilsObjectNameEXT(VkDebugUtilsObjectNameInfoEXT* info) { VK_CHECK(setDebugUtilsObjectName(handle, info)); }
|
||||
|
||||
|
||||
PCommandPool Graphics::getQueueCommands(Gfx::QueueType queueType)
|
||||
{
|
||||
switch (queueType)
|
||||
{
|
||||
PCommandPool Graphics::getQueueCommands(Gfx::QueueType queueType) {
|
||||
switch (queueType) {
|
||||
case Gfx::QueueType::GRAPHICS:
|
||||
return getGraphicsCommands();
|
||||
case Gfx::QueueType::COMPUTE:
|
||||
@@ -334,41 +265,29 @@ PCommandPool Graphics::getQueueCommands(Gfx::QueueType queueType)
|
||||
throw new std::logic_error("invalid queue type");
|
||||
}
|
||||
}
|
||||
PCommandPool Graphics::getGraphicsCommands()
|
||||
{
|
||||
if(graphicsCommands == nullptr)
|
||||
{
|
||||
PCommandPool Graphics::getGraphicsCommands() {
|
||||
if (graphicsCommands == nullptr) {
|
||||
std::unique_lock l(poolLock);
|
||||
graphicsCommands = pools.add(new CommandPool(this, queues[graphicsQueue]));
|
||||
}
|
||||
return graphicsCommands;
|
||||
}
|
||||
PCommandPool Graphics::getComputeCommands()
|
||||
{
|
||||
if(computeCommands == nullptr)
|
||||
{
|
||||
if(graphicsQueue == computeQueue)
|
||||
{
|
||||
PCommandPool Graphics::getComputeCommands() {
|
||||
if (computeCommands == nullptr) {
|
||||
if (graphicsQueue == computeQueue) {
|
||||
computeCommands = getGraphicsCommands();
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
std::unique_lock l(poolLock);
|
||||
computeCommands = pools.add(new CommandPool(this, queues[computeQueue]));
|
||||
}
|
||||
}
|
||||
return computeCommands;
|
||||
}
|
||||
PCommandPool Graphics::getTransferCommands()
|
||||
{
|
||||
if(transferCommands == nullptr)
|
||||
{
|
||||
if(graphicsQueue == transferQueue)
|
||||
{
|
||||
PCommandPool Graphics::getTransferCommands() {
|
||||
if (transferCommands == nullptr) {
|
||||
if (graphicsQueue == transferQueue) {
|
||||
transferCommands = getGraphicsCommands();
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
std::unique_lock l(poolLock);
|
||||
transferCommands = pools.add(new CommandPool(this, queues[transferQueue]));
|
||||
}
|
||||
@@ -376,25 +295,17 @@ PCommandPool Graphics::getTransferCommands()
|
||||
return transferCommands;
|
||||
}
|
||||
|
||||
VmaAllocator Graphics::getAllocator()
|
||||
{
|
||||
return allocator;
|
||||
}
|
||||
VmaAllocator Graphics::getAllocator() { return allocator; }
|
||||
|
||||
PDestructionManager Graphics::getDestructionManager()
|
||||
{
|
||||
return destructionManager;
|
||||
}
|
||||
PDestructionManager Graphics::getDestructionManager() { return destructionManager; }
|
||||
|
||||
Array<const char *> Graphics::getRequiredExtensions()
|
||||
{
|
||||
Array<const char *> extensions;
|
||||
Array<const char*> Graphics::getRequiredExtensions() {
|
||||
Array<const char*> extensions;
|
||||
|
||||
unsigned int glfwExtensionCount = 0;
|
||||
const char **glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount);
|
||||
const char** glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount);
|
||||
|
||||
for (unsigned int i = 0; i < glfwExtensionCount; i++)
|
||||
{
|
||||
for (unsigned int i = 0; i < glfwExtensionCount; i++) {
|
||||
extensions.add(glfwExtensions[i]);
|
||||
}
|
||||
#if ENABLE_VALIDATION
|
||||
@@ -402,8 +313,7 @@ Array<const char *> Graphics::getRequiredExtensions()
|
||||
#endif // ENABLE_VALIDATION
|
||||
return extensions;
|
||||
}
|
||||
void Graphics::initInstance(GraphicsInitializer initInfo)
|
||||
{
|
||||
void Graphics::initInstance(GraphicsInitializer initInfo) {
|
||||
glfwInit();
|
||||
assert(glfwVulkanSupported());
|
||||
VkApplicationInfo appInfo = {
|
||||
@@ -415,10 +325,9 @@ void Graphics::initInstance(GraphicsInitializer initInfo)
|
||||
.engineVersion = VK_MAKE_VERSION(0, 0, 1),
|
||||
.apiVersion = VK_API_VERSION_1_3,
|
||||
};
|
||||
|
||||
|
||||
Array<const char*> extensions = getRequiredExtensions();
|
||||
for (uint32 i = 0; i < initInfo.instanceExtensions.size(); ++i)
|
||||
{
|
||||
for (uint32 i = 0; i < initInfo.instanceExtensions.size(); ++i) {
|
||||
extensions.add(initInfo.instanceExtensions[i]);
|
||||
}
|
||||
#ifdef __APPLE__
|
||||
@@ -441,22 +350,21 @@ void Graphics::initInstance(GraphicsInitializer initInfo)
|
||||
};
|
||||
VK_CHECK(vkCreateInstance(&info, nullptr, &instance));
|
||||
}
|
||||
void Graphics::setupDebugCallback()
|
||||
{
|
||||
void Graphics::setupDebugCallback() {
|
||||
VkDebugUtilsMessengerCreateInfoEXT createInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT,
|
||||
.pNext = nullptr,
|
||||
.flags = 0,
|
||||
.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT| VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT,
|
||||
.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT,
|
||||
.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT,
|
||||
.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT |
|
||||
VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT,
|
||||
.pfnUserCallback = &debugCallback,
|
||||
.pUserData = nullptr,
|
||||
};
|
||||
VK_CHECK(CreateDebugUtilsMessengerEXT(instance, &createInfo, nullptr, &callback));
|
||||
}
|
||||
|
||||
void Graphics::pickPhysicalDevice()
|
||||
{
|
||||
void Graphics::pickPhysicalDevice() {
|
||||
uint32 physicalDeviceCount;
|
||||
vkEnumeratePhysicalDevices(instance, &physicalDeviceCount, nullptr);
|
||||
Array<VkPhysicalDevice> physicalDevices(physicalDeviceCount);
|
||||
@@ -474,26 +382,21 @@ void Graphics::pickPhysicalDevice()
|
||||
features12.pNext = &features13;
|
||||
features13.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES;
|
||||
features13.pNext = nullptr;
|
||||
for (auto dev : physicalDevices)
|
||||
{
|
||||
for (auto dev : physicalDevices) {
|
||||
uint32 currentRating = 0;
|
||||
vkGetPhysicalDeviceProperties(dev, &props);
|
||||
vkGetPhysicalDeviceFeatures2(dev, &features);
|
||||
if (props.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU)
|
||||
{
|
||||
if (props.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) {
|
||||
std::cout << "found dedicated gpu " << props.deviceName << std::endl;
|
||||
currentRating += 100;
|
||||
}
|
||||
else if (props.deviceType == VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU)
|
||||
{
|
||||
} else if (props.deviceType == VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU) {
|
||||
std::cout << "found integrated gpu " << props.deviceName << std::endl;
|
||||
currentRating += 10;
|
||||
}
|
||||
if (currentRating > deviceRating)
|
||||
{
|
||||
if (currentRating > deviceRating) {
|
||||
deviceRating = currentRating;
|
||||
bestDevice = dev;
|
||||
std::cout << "bestDevice: " << props.deviceName << std::endl;
|
||||
std::cout << "bestDevice: " << props.deviceName << std::endl;
|
||||
}
|
||||
}
|
||||
physicalDevice = bestDevice;
|
||||
@@ -501,16 +404,13 @@ void Graphics::pickPhysicalDevice()
|
||||
vkGetPhysicalDeviceProperties(physicalDevice, &props);
|
||||
vkGetPhysicalDeviceFeatures2(physicalDevice, &features);
|
||||
features.features.robustBufferAccess = 0;
|
||||
if (Gfx::useMeshShading)
|
||||
{
|
||||
if (Gfx::useMeshShading) {
|
||||
uint32 count = 0;
|
||||
vkEnumerateDeviceExtensionProperties(physicalDevice, NULL, &count, nullptr);
|
||||
Array<VkExtensionProperties> extensionProps(count);
|
||||
vkEnumerateDeviceExtensionProperties(physicalDevice, NULL, &count, extensionProps.data());
|
||||
for (size_t i = 0; i < count; ++i)
|
||||
{
|
||||
if (std::strcmp(VK_EXT_MESH_SHADER_EXTENSION_NAME, extensionProps[i].extensionName) == 0)
|
||||
{
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
if (std::strcmp(VK_EXT_MESH_SHADER_EXTENSION_NAME, extensionProps[i].extensionName) == 0) {
|
||||
meshShadingEnabled = true;
|
||||
break;
|
||||
}
|
||||
@@ -518,16 +418,14 @@ void Graphics::pickPhysicalDevice()
|
||||
}
|
||||
}
|
||||
|
||||
void Graphics::createDevice(GraphicsInitializer initializer)
|
||||
{
|
||||
void Graphics::createDevice(GraphicsInitializer initializer) {
|
||||
uint32_t numQueueFamilies = 0;
|
||||
vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &numQueueFamilies, nullptr);
|
||||
Array<VkQueueFamilyProperties> queueProperties(numQueueFamilies);
|
||||
vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &numQueueFamilies, queueProperties.data());
|
||||
|
||||
Array<VkDeviceQueueCreateInfo> queueInfos;
|
||||
struct QueueCreateInfo
|
||||
{
|
||||
struct QueueCreateInfo {
|
||||
int32 familyIndex = -1;
|
||||
int32 queueIndex = -1;
|
||||
};
|
||||
@@ -535,42 +433,35 @@ void Graphics::createDevice(GraphicsInitializer initializer)
|
||||
QueueCreateInfo transferQueueInfo;
|
||||
QueueCreateInfo computeQueueInfo;
|
||||
uint32 numPriorities = 0;
|
||||
auto checkFamilyProperty = [](VkQueueFamilyProperties currProps, uint32 checkBit){
|
||||
auto checkFamilyProperty = [](VkQueueFamilyProperties currProps, uint32 checkBit) {
|
||||
return (currProps.queueFlags & checkBit) == checkBit;
|
||||
};
|
||||
auto updateQueueInfo = [&queueProperties](uint32 familyIndex, QueueCreateInfo& info, uint32& numQueues) {
|
||||
if(info.familyIndex == -1) {
|
||||
if(queueProperties[familyIndex].queueCount == numQueues)
|
||||
{
|
||||
if (info.familyIndex == -1) {
|
||||
if (queueProperties[familyIndex].queueCount == numQueues) {
|
||||
return;
|
||||
}
|
||||
info.familyIndex = familyIndex;
|
||||
info.queueIndex = numQueues++;
|
||||
}
|
||||
};
|
||||
for (uint32 familyIndex = 0; familyIndex < queueProperties.size(); ++familyIndex)
|
||||
{
|
||||
for (uint32 familyIndex = 0; familyIndex < queueProperties.size(); ++familyIndex) {
|
||||
uint32 numQueuesForFamily = 0;
|
||||
VkQueueFamilyProperties currProps = queueProperties[familyIndex];
|
||||
|
||||
if (checkFamilyProperty(currProps, VK_QUEUE_GRAPHICS_BIT))
|
||||
{
|
||||
if (checkFamilyProperty(currProps, VK_QUEUE_GRAPHICS_BIT)) {
|
||||
updateQueueInfo(familyIndex, graphicsQueueInfo, numQueuesForFamily);
|
||||
}
|
||||
if(Gfx::useAsyncCompute)
|
||||
{
|
||||
if(checkFamilyProperty(currProps, VK_QUEUE_COMPUTE_BIT))
|
||||
{
|
||||
if (Gfx::useAsyncCompute) {
|
||||
if (checkFamilyProperty(currProps, VK_QUEUE_COMPUTE_BIT)) {
|
||||
updateQueueInfo(familyIndex, computeQueueInfo, numQueuesForFamily);
|
||||
}
|
||||
}
|
||||
if ((currProps.queueFlags ^ VK_QUEUE_TRANSFER_BIT) == 0)
|
||||
{
|
||||
if ((currProps.queueFlags ^ VK_QUEUE_TRANSFER_BIT) == 0) {
|
||||
updateQueueInfo(familyIndex, transferQueueInfo, numQueuesForFamily);
|
||||
}
|
||||
|
||||
if (numQueuesForFamily > 0)
|
||||
{
|
||||
|
||||
if (numQueuesForFamily > 0) {
|
||||
VkDeviceQueueCreateInfo info = {
|
||||
.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
@@ -585,14 +476,12 @@ void Graphics::createDevice(GraphicsInitializer initializer)
|
||||
}
|
||||
Array<float> queuePriorities;
|
||||
queuePriorities.resize(numPriorities);
|
||||
float *currentPriority = queuePriorities.data();
|
||||
for (uint32 index = 0; index < queueInfos.size(); ++index)
|
||||
{
|
||||
VkDeviceQueueCreateInfo &currQueue = queueInfos[index];
|
||||
float* currentPriority = queuePriorities.data();
|
||||
for (uint32 index = 0; index < queueInfos.size(); ++index) {
|
||||
VkDeviceQueueCreateInfo& currQueue = queueInfos[index];
|
||||
currQueue.pQueuePriorities = currentPriority;
|
||||
|
||||
for (int32_t queueIndex = 0; queueIndex < (int32_t)currQueue.queueCount; ++queueIndex)
|
||||
{
|
||||
for (int32_t queueIndex = 0; queueIndex < (int32_t)currQueue.queueCount; ++queueIndex) {
|
||||
*currentPriority++ = 1.0f;
|
||||
}
|
||||
}
|
||||
@@ -602,8 +491,7 @@ void Graphics::createDevice(GraphicsInitializer initializer)
|
||||
.taskShader = VK_TRUE,
|
||||
.meshShader = VK_TRUE,
|
||||
};
|
||||
if (supportMeshShading())
|
||||
{
|
||||
if (supportMeshShading()) {
|
||||
features12.pNext = &enabledMeshShaderFeatures;
|
||||
initializer.deviceExtensions.add(VK_EXT_MESH_SHADER_EXTENSION_NAME);
|
||||
}
|
||||
@@ -621,7 +509,7 @@ void Graphics::createDevice(GraphicsInitializer initializer)
|
||||
};
|
||||
|
||||
VK_CHECK(vkCreateDevice(physicalDevice, &deviceInfo, nullptr, &handle));
|
||||
//std::cout << "Vulkan handle: " << handle << std::endl;
|
||||
// std::cout << "Vulkan handle: " << handle << std::endl;
|
||||
|
||||
cmdDrawMeshTasks = (PFN_vkCmdDrawMeshTasksEXT)vkGetDeviceProcAddr(handle, "vkCmdDrawMeshTasksEXT");
|
||||
|
||||
@@ -629,20 +517,17 @@ void Graphics::createDevice(GraphicsInitializer initializer)
|
||||
computeQueue = 0;
|
||||
transferQueue = 0;
|
||||
queues.add(new Queue(this, graphicsQueueInfo.familyIndex, graphicsQueueInfo.queueIndex));
|
||||
if(computeQueueInfo.familyIndex != -1)
|
||||
{
|
||||
if (computeQueueInfo.familyIndex != -1) {
|
||||
computeQueue = queues.size();
|
||||
queues.add(new Queue(this, computeQueueInfo.familyIndex, computeQueueInfo.queueIndex));
|
||||
}
|
||||
if(transferQueueInfo.familyIndex != -1)
|
||||
{
|
||||
if (transferQueueInfo.familyIndex != -1) {
|
||||
transferQueue = queues.size();
|
||||
queues.add(new Queue(this, transferQueueInfo.familyIndex, transferQueueInfo.queueIndex));
|
||||
}
|
||||
|
||||
|
||||
queueMapping.graphicsFamily = queues[graphicsQueue]->getFamilyIndex();
|
||||
queueMapping.computeFamily = queues[computeQueue]->getFamilyIndex();
|
||||
queueMapping.transferFamily = queues[transferQueue]->getFamilyIndex();
|
||||
setDebugUtilsObjectName = (PFN_vkSetDebugUtilsObjectNameEXT)vkGetInstanceProcAddr(instance, "vkSetDebugUtilsObjectNameEXT");
|
||||
|
||||
}
|
||||
|
||||
@@ -2,18 +2,15 @@
|
||||
#include "Graphics/Graphics.h"
|
||||
#include <vk_mem_alloc.h>
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
namespace Vulkan
|
||||
{
|
||||
namespace Seele {
|
||||
namespace Vulkan {
|
||||
DECLARE_REF(DestructionManager)
|
||||
DECLARE_REF(CommandPool)
|
||||
DECLARE_REF(Queue)
|
||||
DECLARE_REF(PipelineCache)
|
||||
DECLARE_REF(Framebuffer)
|
||||
class Graphics : public Gfx::Graphics
|
||||
{
|
||||
public:
|
||||
class Graphics : public Gfx::Graphics {
|
||||
public:
|
||||
Graphics();
|
||||
virtual ~Graphics();
|
||||
constexpr VkInstance getInstance() const { return instance; };
|
||||
@@ -30,10 +27,11 @@ public:
|
||||
|
||||
// Inherited via Graphics
|
||||
virtual void init(GraphicsInitializer initializer) override;
|
||||
virtual Gfx::OWindow createWindow(const WindowCreateInfo &createInfo) override;
|
||||
virtual Gfx::OViewport createViewport(Gfx::PWindow owner, const ViewportCreateInfo &createInfo) override;
|
||||
virtual Gfx::OWindow createWindow(const WindowCreateInfo& createInfo) override;
|
||||
virtual Gfx::OViewport createViewport(Gfx::PWindow owner, const ViewportCreateInfo& createInfo) override;
|
||||
|
||||
virtual Gfx::ORenderPass createRenderPass(Gfx::RenderTargetLayout layout, Array<Gfx::SubPassDependency> dependencies, Gfx::PViewport renderArea) override;
|
||||
virtual Gfx::ORenderPass createRenderPass(Gfx::RenderTargetLayout layout, Array<Gfx::SubPassDependency> dependencies,
|
||||
Gfx::PViewport renderArea) override;
|
||||
virtual void beginRenderPass(Gfx::PRenderPass renderPass) override;
|
||||
virtual void endRenderPass() override;
|
||||
virtual void waitDeviceIdle() override;
|
||||
@@ -41,17 +39,17 @@ public:
|
||||
virtual void executeCommands(Array<Gfx::ORenderCommand> commands) override;
|
||||
virtual void executeCommands(Array<Gfx::OComputeCommand> commands) override;
|
||||
|
||||
virtual Gfx::OTexture2D createTexture2D(const TextureCreateInfo &createInfo) override;
|
||||
virtual Gfx::OTexture3D createTexture3D(const TextureCreateInfo &createInfo) override;
|
||||
virtual Gfx::OTextureCube createTextureCube(const TextureCreateInfo &createInfo) override;
|
||||
virtual Gfx::OUniformBuffer createUniformBuffer(const UniformBufferCreateInfo &bulkData) override;
|
||||
virtual Gfx::OShaderBuffer createShaderBuffer(const ShaderBufferCreateInfo &bulkData) override;
|
||||
virtual Gfx::OVertexBuffer createVertexBuffer(const VertexBufferCreateInfo &bulkData) override;
|
||||
virtual Gfx::OIndexBuffer createIndexBuffer(const IndexBufferCreateInfo &bulkData) override;
|
||||
|
||||
virtual Gfx::OTexture2D createTexture2D(const TextureCreateInfo& createInfo) override;
|
||||
virtual Gfx::OTexture3D createTexture3D(const TextureCreateInfo& createInfo) override;
|
||||
virtual Gfx::OTextureCube createTextureCube(const TextureCreateInfo& createInfo) override;
|
||||
virtual Gfx::OUniformBuffer createUniformBuffer(const UniformBufferCreateInfo& bulkData) override;
|
||||
virtual Gfx::OShaderBuffer createShaderBuffer(const ShaderBufferCreateInfo& bulkData) override;
|
||||
virtual Gfx::OVertexBuffer createVertexBuffer(const VertexBufferCreateInfo& bulkData) override;
|
||||
virtual Gfx::OIndexBuffer createIndexBuffer(const IndexBufferCreateInfo& bulkData) override;
|
||||
|
||||
virtual Gfx::ORenderCommand createRenderCommand(const std::string& name) override;
|
||||
virtual Gfx::OComputeCommand createComputeCommand(const std::string& name) 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;
|
||||
@@ -77,11 +75,11 @@ public:
|
||||
void vkCmdDrawMeshTasksIndirectEXT(VkCommandBuffer handle, VkBuffer buffer, uint64 offset, uint32 drawCount, uint32 stride);
|
||||
void vkSetDebugUtilsObjectNameEXT(VkDebugUtilsObjectNameInfoEXT* info);
|
||||
|
||||
protected:
|
||||
protected:
|
||||
PFN_vkCmdDrawMeshTasksEXT cmdDrawMeshTasks;
|
||||
PFN_vkCmdDrawMeshTasksIndirectEXT cmdDrawMeshTasksIndirect;
|
||||
PFN_vkSetDebugUtilsObjectNameEXT setDebugUtilsObjectName;
|
||||
Array<const char *> getRequiredExtensions();
|
||||
Array<const char*> getRequiredExtensions();
|
||||
void initInstance(GraphicsInitializer initInfo);
|
||||
void setupDebugCallback();
|
||||
void pickPhysicalDevice();
|
||||
|
||||
@@ -5,54 +5,24 @@
|
||||
using namespace Seele;
|
||||
using namespace Seele::Vulkan;
|
||||
|
||||
VertexInput::VertexInput(VertexInputStateCreateInfo createInfo)
|
||||
: Gfx::VertexInput(createInfo)
|
||||
{
|
||||
}
|
||||
VertexInput::VertexInput(VertexInputStateCreateInfo createInfo) : Gfx::VertexInput(createInfo) {}
|
||||
|
||||
VertexInput::~VertexInput()
|
||||
{
|
||||
}
|
||||
VertexInput::~VertexInput() {}
|
||||
|
||||
GraphicsPipeline::GraphicsPipeline(PGraphics graphics, VkPipeline handle, Gfx::PPipelineLayout pipelineLayout)
|
||||
: Gfx::GraphicsPipeline(std::move(pipelineLayout))
|
||||
, graphics(graphics)
|
||||
, pipeline(handle)
|
||||
{
|
||||
}
|
||||
: Gfx::GraphicsPipeline(std::move(pipelineLayout)), graphics(graphics), pipeline(handle) {}
|
||||
|
||||
GraphicsPipeline::~GraphicsPipeline()
|
||||
{
|
||||
}
|
||||
GraphicsPipeline::~GraphicsPipeline() {}
|
||||
|
||||
void GraphicsPipeline::bind(VkCommandBuffer handle)
|
||||
{
|
||||
vkCmdBindPipeline(handle, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
|
||||
}
|
||||
void GraphicsPipeline::bind(VkCommandBuffer handle) { vkCmdBindPipeline(handle, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); }
|
||||
|
||||
VkPipelineLayout GraphicsPipeline::getLayout() const
|
||||
{
|
||||
return Gfx::PPipelineLayout(layout).cast<PipelineLayout>()->getHandle();
|
||||
}
|
||||
VkPipelineLayout GraphicsPipeline::getLayout() const { return Gfx::PPipelineLayout(layout).cast<PipelineLayout>()->getHandle(); }
|
||||
|
||||
ComputePipeline::ComputePipeline(PGraphics graphics, VkPipeline handle, Gfx::PPipelineLayout pipelineLayout)
|
||||
: Gfx::ComputePipeline(std::move(pipelineLayout))
|
||||
, graphics(graphics)
|
||||
, pipeline(handle)
|
||||
{
|
||||
|
||||
}
|
||||
ComputePipeline::ComputePipeline(PGraphics graphics, VkPipeline handle, Gfx::PPipelineLayout pipelineLayout)
|
||||
: Gfx::ComputePipeline(std::move(pipelineLayout)), graphics(graphics), pipeline(handle) {}
|
||||
|
||||
ComputePipeline::~ComputePipeline()
|
||||
{
|
||||
}
|
||||
ComputePipeline::~ComputePipeline() {}
|
||||
|
||||
void ComputePipeline::bind(VkCommandBuffer handle)
|
||||
{
|
||||
vkCmdBindPipeline(handle, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline);
|
||||
}
|
||||
void ComputePipeline::bind(VkCommandBuffer handle) { vkCmdBindPipeline(handle, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline); }
|
||||
|
||||
VkPipelineLayout ComputePipeline::getLayout() const
|
||||
{
|
||||
return Gfx::PPipelineLayout(layout).cast<PipelineLayout>()->getHandle();
|
||||
}
|
||||
VkPipelineLayout ComputePipeline::getLayout() const { return Gfx::PPipelineLayout(layout).cast<PipelineLayout>()->getHandle(); }
|
||||
@@ -2,39 +2,37 @@
|
||||
#include "Enums.h"
|
||||
#include "Graphics/Pipeline.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
namespace Vulkan
|
||||
{
|
||||
class VertexInput : public Gfx::VertexInput
|
||||
{
|
||||
public:
|
||||
namespace Seele {
|
||||
namespace Vulkan {
|
||||
class VertexInput : public Gfx::VertexInput {
|
||||
public:
|
||||
VertexInput(VertexInputStateCreateInfo createInfo);
|
||||
virtual ~VertexInput();
|
||||
private:
|
||||
|
||||
private:
|
||||
};
|
||||
DECLARE_REF(PipelineLayout)
|
||||
DECLARE_REF(Graphics)
|
||||
class GraphicsPipeline : public Gfx::GraphicsPipeline
|
||||
{
|
||||
public:
|
||||
class GraphicsPipeline : public Gfx::GraphicsPipeline {
|
||||
public:
|
||||
GraphicsPipeline(PGraphics graphics, VkPipeline handle, Gfx::PPipelineLayout pipelineLayout);
|
||||
virtual ~GraphicsPipeline();
|
||||
void bind(VkCommandBuffer handle);
|
||||
VkPipelineLayout getLayout() const;
|
||||
private:
|
||||
|
||||
private:
|
||||
PGraphics graphics;
|
||||
VkPipeline pipeline;
|
||||
};
|
||||
DEFINE_REF(GraphicsPipeline)
|
||||
class ComputePipeline : public Gfx::ComputePipeline
|
||||
{
|
||||
public:
|
||||
class ComputePipeline : public Gfx::ComputePipeline {
|
||||
public:
|
||||
ComputePipeline(PGraphics graphics, VkPipeline handle, Gfx::PPipelineLayout pipelineLayout);
|
||||
virtual ~ComputePipeline();
|
||||
void bind(VkCommandBuffer handle);
|
||||
VkPipelineLayout getLayout() const;
|
||||
private:
|
||||
|
||||
private:
|
||||
PGraphics graphics;
|
||||
VkPipeline pipeline;
|
||||
};
|
||||
|
||||
@@ -1,18 +1,16 @@
|
||||
#include "PipelineCache.h"
|
||||
#include "Graphics.h"
|
||||
#include "Enums.h"
|
||||
#include "RenderPass.h"
|
||||
#include "Descriptor.h"
|
||||
#include "Enums.h"
|
||||
#include "Graphics.h"
|
||||
#include "RenderPass.h"
|
||||
#include "Shader.h"
|
||||
#include <fstream>
|
||||
|
||||
|
||||
using namespace Seele;
|
||||
using namespace Seele::Vulkan;
|
||||
|
||||
PipelineCache::PipelineCache(PGraphics graphics, const std::string& cacheFilePath)
|
||||
: graphics(graphics)
|
||||
, cacheFile(cacheFilePath)
|
||||
{
|
||||
PipelineCache::PipelineCache(PGraphics graphics, const std::string& cacheFilePath) : graphics(graphics), cacheFile(cacheFilePath) {
|
||||
std::ifstream stream(cacheFilePath, std::ios::binary | std::ios::ate);
|
||||
VkPipelineCacheCreateInfo cacheCreateInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,
|
||||
@@ -20,8 +18,7 @@ PipelineCache::PipelineCache(PGraphics graphics, const std::string& cacheFilePat
|
||||
.flags = 0,
|
||||
.initialDataSize = 0,
|
||||
};
|
||||
if(stream.good())
|
||||
{
|
||||
if (stream.good()) {
|
||||
Array<uint8> cacheData;
|
||||
uint32 fileSize = static_cast<uint32>(stream.tellg());
|
||||
cacheData.resize(fileSize);
|
||||
@@ -34,8 +31,7 @@ PipelineCache::PipelineCache(PGraphics graphics, const std::string& cacheFilePat
|
||||
VK_CHECK(vkCreatePipelineCache(graphics->getDevice(), &cacheCreateInfo, nullptr, &cache));
|
||||
}
|
||||
|
||||
PipelineCache::~PipelineCache()
|
||||
{
|
||||
PipelineCache::~PipelineCache() {
|
||||
size_t cacheSize;
|
||||
VK_CHECK(vkGetPipelineCacheData(graphics->getDevice(), cache, &cacheSize, nullptr));
|
||||
Array<uint8> cacheData(cacheSize);
|
||||
@@ -48,29 +44,24 @@ PipelineCache::~PipelineCache()
|
||||
std::cout << "Written " << cacheSize << " bytes to cache" << std::endl;
|
||||
}
|
||||
|
||||
PGraphicsPipeline PipelineCache::createPipeline(Gfx::LegacyPipelineCreateInfo gfxInfo)
|
||||
{
|
||||
PGraphicsPipeline PipelineCache::createPipeline(Gfx::LegacyPipelineCreateInfo gfxInfo) {
|
||||
uint32 hash = CRC::Calculate(&gfxInfo, sizeof(Gfx::LegacyPipelineCreateInfo), CRC::CRC_32());
|
||||
if (graphicsPipelines.contains(hash))
|
||||
{
|
||||
if (graphicsPipelines.contains(hash)) {
|
||||
return graphicsPipelines[hash];
|
||||
}
|
||||
PPipelineLayout layout = Gfx::PPipelineLayout(gfxInfo.pipelineLayout).cast<PipelineLayout>();
|
||||
Array<VkVertexInputBindingDescription> bindings;
|
||||
Array<VkVertexInputAttributeDescription> attributes;
|
||||
if (gfxInfo.vertexInput != nullptr)
|
||||
{
|
||||
if (gfxInfo.vertexInput != nullptr) {
|
||||
const VertexInputStateCreateInfo& vertexInputDesc = gfxInfo.vertexInput->getInfo();
|
||||
for (const auto& b : vertexInputDesc.bindings)
|
||||
{
|
||||
for (const auto& b : vertexInputDesc.bindings) {
|
||||
bindings.add() = {
|
||||
.binding = b.binding,
|
||||
.stride = b.stride,
|
||||
.inputRate = VkVertexInputRate(b.inputRate),
|
||||
};
|
||||
}
|
||||
for (const auto& a : vertexInputDesc.attributes)
|
||||
{
|
||||
for (const auto& a : vertexInputDesc.attributes) {
|
||||
attributes.add() = {
|
||||
.location = a.location,
|
||||
.binding = a.binding,
|
||||
@@ -104,8 +95,7 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::LegacyPipelineCreateInfo gf
|
||||
.pSpecializationInfo = nullptr,
|
||||
};
|
||||
|
||||
if (gfxInfo.fragmentShader != nullptr)
|
||||
{
|
||||
if (gfxInfo.fragmentShader != nullptr) {
|
||||
PFragmentShader fragment = gfxInfo.fragmentShader.cast<FragmentShader>();
|
||||
|
||||
stageInfos[stageCount++] = {
|
||||
@@ -173,8 +163,7 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::LegacyPipelineCreateInfo gf
|
||||
.maxDepthBounds = gfxInfo.depthStencilState.maxDepthBounds,
|
||||
};
|
||||
Array<VkPipelineColorBlendAttachmentState> blendAttachments;
|
||||
for(uint32 i = 0; i < gfxInfo.colorBlend.attachmentCount; ++i)
|
||||
{
|
||||
for (uint32 i = 0; i < gfxInfo.colorBlend.attachmentCount; ++i) {
|
||||
const Gfx::ColorBlendState::BlendAttachment& attachment = gfxInfo.colorBlend.blendAttachments[i];
|
||||
blendAttachments.add() = {
|
||||
.blendEnable = attachment.blendEnable,
|
||||
@@ -235,31 +224,26 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::LegacyPipelineCreateInfo gf
|
||||
auto endTime = std::chrono::high_resolution_clock::now();
|
||||
int64 delta = std::chrono::duration_cast<std::chrono::microseconds>(endTime - beginTime).count();
|
||||
std::cout << "Gfx creation time: " << delta << std::endl;
|
||||
|
||||
|
||||
OGraphicsPipeline pipeline = new GraphicsPipeline(graphics, pipelineHandle, gfxInfo.pipelineLayout);
|
||||
PGraphicsPipeline result = pipeline;
|
||||
graphicsPipelines[hash] = std::move(pipeline);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
PGraphicsPipeline PipelineCache::createPipeline(Gfx::MeshPipelineCreateInfo gfxInfo)
|
||||
{
|
||||
PGraphicsPipeline PipelineCache::createPipeline(Gfx::MeshPipelineCreateInfo gfxInfo) {
|
||||
uint32 hash = CRC::Calculate(&gfxInfo, sizeof(Gfx::MeshPipelineCreateInfo), CRC::CRC_32());
|
||||
if (graphicsPipelines.contains(hash))
|
||||
{
|
||||
if (graphicsPipelines.contains(hash)) {
|
||||
return graphicsPipelines[hash];
|
||||
}
|
||||
PPipelineLayout layout = Gfx::PPipelineLayout(gfxInfo.pipelineLayout).cast<PipelineLayout>();
|
||||
//uint32 hash = layout->getHash();
|
||||
// uint32 hash = layout->getHash();
|
||||
uint32 stageCount = 0;
|
||||
|
||||
|
||||
VkPipelineShaderStageCreateInfo stageInfos[3];
|
||||
std::memset(stageInfos, 0, sizeof(stageInfos));
|
||||
|
||||
if (gfxInfo.taskShader != nullptr)
|
||||
{
|
||||
if (gfxInfo.taskShader != nullptr) {
|
||||
PTaskShader taskShader = gfxInfo.taskShader.cast<TaskShader>();
|
||||
stageInfos[stageCount++] = {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
|
||||
@@ -283,8 +267,7 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::MeshPipelineCreateInfo gfxI
|
||||
.pSpecializationInfo = nullptr,
|
||||
};
|
||||
|
||||
if (gfxInfo.fragmentShader != nullptr)
|
||||
{
|
||||
if (gfxInfo.fragmentShader != nullptr) {
|
||||
PFragmentShader fragment = gfxInfo.fragmentShader.cast<FragmentShader>();
|
||||
|
||||
stageInfos[stageCount++] = {
|
||||
@@ -297,7 +280,7 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::MeshPipelineCreateInfo gfxI
|
||||
.pSpecializationInfo = nullptr,
|
||||
};
|
||||
}
|
||||
//hash = CRC::Calculate(stageInfos, sizeof(stageInfos), CRC::CRC_32(), hash);
|
||||
// hash = CRC::Calculate(stageInfos, sizeof(stageInfos), CRC::CRC_32(), hash);
|
||||
|
||||
VkPipelineViewportStateCreateInfo viewportInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
|
||||
@@ -308,7 +291,7 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::MeshPipelineCreateInfo gfxI
|
||||
.scissorCount = 1,
|
||||
.pScissors = nullptr,
|
||||
};
|
||||
//hash = CRC::Calculate(&viewportInfo, sizeof(VkPipelineViewportStateCreateInfo), CRC::CRC_32(), hash);
|
||||
// hash = CRC::Calculate(&viewportInfo, sizeof(VkPipelineViewportStateCreateInfo), CRC::CRC_32(), hash);
|
||||
VkPipelineRasterizationStateCreateInfo rasterizationState = {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
@@ -324,7 +307,7 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::MeshPipelineCreateInfo gfxI
|
||||
.depthBiasSlopeFactor = gfxInfo.rasterizationState.depthBiasSlopeFactor,
|
||||
.lineWidth = 0,
|
||||
};
|
||||
//hash = CRC::Calculate(&rasterizationState, sizeof(VkPipelineRasterizationStateCreateInfo), CRC::CRC_32(), hash);
|
||||
// hash = CRC::Calculate(&rasterizationState, sizeof(VkPipelineRasterizationStateCreateInfo), CRC::CRC_32(), hash);
|
||||
|
||||
VkPipelineMultisampleStateCreateInfo multisampleState = {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
|
||||
@@ -337,7 +320,7 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::MeshPipelineCreateInfo gfxI
|
||||
.alphaToCoverageEnable = gfxInfo.multisampleState.alphaCoverageEnable,
|
||||
.alphaToOneEnable = gfxInfo.multisampleState.alphaToOneEnable,
|
||||
};
|
||||
//hash = CRC::Calculate(&multisampleState, sizeof(VkPipelineMultisampleStateCreateInfo), CRC::CRC_32(), hash);
|
||||
// hash = CRC::Calculate(&multisampleState, sizeof(VkPipelineMultisampleStateCreateInfo), CRC::CRC_32(), hash);
|
||||
|
||||
VkPipelineDepthStencilStateCreateInfo depthStencilState = {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
|
||||
@@ -348,32 +331,33 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::MeshPipelineCreateInfo gfxI
|
||||
.depthCompareOp = cast(gfxInfo.depthStencilState.depthCompareOp),
|
||||
.depthBoundsTestEnable = gfxInfo.depthStencilState.depthBoundsTestEnable,
|
||||
.stencilTestEnable = gfxInfo.depthStencilState.stencilTestEnable,
|
||||
.front = VkStencilOpState{
|
||||
.failOp = VK_STENCIL_OP_ZERO,
|
||||
.passOp = (VkStencilOp)gfxInfo.depthStencilState.front,
|
||||
.depthFailOp = VK_STENCIL_OP_ZERO,
|
||||
.compareOp = VK_COMPARE_OP_ALWAYS,
|
||||
.compareMask = 0,
|
||||
.writeMask = 0,
|
||||
.reference = 0,
|
||||
},
|
||||
.back = VkStencilOpState{
|
||||
.failOp = VK_STENCIL_OP_ZERO,
|
||||
.passOp = (VkStencilOp)gfxInfo.depthStencilState.back,
|
||||
.depthFailOp = VK_STENCIL_OP_ZERO,
|
||||
.compareOp = VK_COMPARE_OP_ALWAYS,
|
||||
.compareMask = 0,
|
||||
.writeMask = 0,
|
||||
.reference = 0,
|
||||
},
|
||||
.front =
|
||||
VkStencilOpState{
|
||||
.failOp = VK_STENCIL_OP_ZERO,
|
||||
.passOp = (VkStencilOp)gfxInfo.depthStencilState.front,
|
||||
.depthFailOp = VK_STENCIL_OP_ZERO,
|
||||
.compareOp = VK_COMPARE_OP_ALWAYS,
|
||||
.compareMask = 0,
|
||||
.writeMask = 0,
|
||||
.reference = 0,
|
||||
},
|
||||
.back =
|
||||
VkStencilOpState{
|
||||
.failOp = VK_STENCIL_OP_ZERO,
|
||||
.passOp = (VkStencilOp)gfxInfo.depthStencilState.back,
|
||||
.depthFailOp = VK_STENCIL_OP_ZERO,
|
||||
.compareOp = VK_COMPARE_OP_ALWAYS,
|
||||
.compareMask = 0,
|
||||
.writeMask = 0,
|
||||
.reference = 0,
|
||||
},
|
||||
.minDepthBounds = gfxInfo.depthStencilState.minDepthBounds,
|
||||
.maxDepthBounds = gfxInfo.depthStencilState.maxDepthBounds,
|
||||
};
|
||||
//hash = CRC::Calculate(&depthStencilState, sizeof(VkPipelineDepthStencilStateCreateInfo), CRC::CRC_32(), hash);
|
||||
// hash = CRC::Calculate(&depthStencilState, sizeof(VkPipelineDepthStencilStateCreateInfo), CRC::CRC_32(), hash);
|
||||
|
||||
Array<VkPipelineColorBlendAttachmentState> blendAttachments;
|
||||
for (uint32 i = 0; i < gfxInfo.colorBlend.attachmentCount; ++i)
|
||||
{
|
||||
for (uint32 i = 0; i < gfxInfo.colorBlend.attachmentCount; ++i) {
|
||||
const Gfx::ColorBlendState::BlendAttachment& attachment = gfxInfo.colorBlend.blendAttachments[i];
|
||||
blendAttachments.add() = {
|
||||
.blendEnable = attachment.blendEnable,
|
||||
@@ -386,7 +370,8 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::MeshPipelineCreateInfo gfxI
|
||||
.colorWriteMask = attachment.colorWriteMask,
|
||||
};
|
||||
}
|
||||
//hash = CRC::Calculate(blendAttachments.data(), blendAttachments.size() * sizeof(VkPipelineColorBlendAttachmentState), CRC::CRC_32(), hash);
|
||||
// hash = CRC::Calculate(blendAttachments.data(), blendAttachments.size() * sizeof(VkPipelineColorBlendAttachmentState), CRC::CRC_32(),
|
||||
// hash);
|
||||
|
||||
VkPipelineColorBlendStateCreateInfo blendState = {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
|
||||
@@ -403,7 +388,7 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::MeshPipelineCreateInfo gfxI
|
||||
StaticArray<VkDynamicState, 2> dynamicEnabled;
|
||||
dynamicEnabled[numDynamicEnabled++] = VK_DYNAMIC_STATE_VIEWPORT;
|
||||
dynamicEnabled[numDynamicEnabled++] = VK_DYNAMIC_STATE_SCISSOR;
|
||||
//hash = CRC::Calculate(dynamicEnabled.data(), sizeof(dynamicEnabled), CRC::CRC_32(), hash);
|
||||
// hash = CRC::Calculate(dynamicEnabled.data(), sizeof(dynamicEnabled), CRC::CRC_32(), hash);
|
||||
|
||||
VkPipelineDynamicStateCreateInfo dynamicState = {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
|
||||
@@ -443,9 +428,7 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::MeshPipelineCreateInfo gfxI
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
PComputePipeline PipelineCache::createPipeline(Gfx::ComputePipelineCreateInfo computeInfo)
|
||||
{
|
||||
PComputePipeline PipelineCache::createPipeline(Gfx::ComputePipelineCreateInfo computeInfo) {
|
||||
PPipelineLayout layout = Gfx::PPipelineLayout(computeInfo.pipelineLayout).cast<PipelineLayout>();
|
||||
auto computeStage = computeInfo.computeShader.cast<ComputeShader>();
|
||||
|
||||
@@ -455,20 +438,21 @@ PComputePipeline PipelineCache::createPipeline(Gfx::ComputePipelineCreateInfo co
|
||||
.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
|
||||
.pNext = 0,
|
||||
.flags = 0,
|
||||
.stage = {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
.flags = 0,
|
||||
.stage = VK_SHADER_STAGE_COMPUTE_BIT,
|
||||
.module = computeStage->getModuleHandle(),
|
||||
.pName = computeStage->getEntryPointName(),
|
||||
},
|
||||
.stage =
|
||||
{
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
.flags = 0,
|
||||
.stage = VK_SHADER_STAGE_COMPUTE_BIT,
|
||||
.module = computeStage->getModuleHandle(),
|
||||
.pName = computeStage->getEntryPointName(),
|
||||
},
|
||||
.layout = layout->getHandle(),
|
||||
.basePipelineHandle = VK_NULL_HANDLE,
|
||||
.basePipelineIndex = 0,
|
||||
};
|
||||
hash = CRC::Calculate(&createInfo, sizeof(createInfo), CRC::CRC_32(), hash);
|
||||
|
||||
|
||||
VkPipeline pipelineHandle;
|
||||
auto beginTime = std::chrono::high_resolution_clock::now();
|
||||
VK_CHECK(vkCreateComputePipelines(graphics->getDevice(), cache, 1, &createInfo, nullptr, &pipelineHandle));
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user