More Ray tracing changes

This commit is contained in:
Dynamitos
2024-06-09 10:44:24 +02:00
parent 31e66192f1
commit f18bf8acbe
28 changed files with 817 additions and 662 deletions
+1 -1
+1 -1
View File
@@ -1,5 +1,4 @@
#include "Buffer.h" #include "Buffer.h"
#include "Buffer.h"
using namespace Seele; using namespace Seele;
using namespace Seele::Gfx; using namespace Seele::Gfx;
@@ -42,6 +41,7 @@ IndexBuffer::IndexBuffer(QueueFamilyMapping mapping, uint64 size, Gfx::SeIndexTy
IndexBuffer::~IndexBuffer() IndexBuffer::~IndexBuffer()
{ {
} }
UniformBuffer::UniformBuffer(QueueFamilyMapping mapping, const DataSource& sourceData) UniformBuffer::UniformBuffer(QueueFamilyMapping mapping, const DataSource& sourceData)
: Buffer(mapping, sourceData.owner) : Buffer(mapping, sourceData.owner)
{} {}
+1
View File
@@ -1,5 +1,6 @@
#pragma once #pragma once
#include "Resources.h" #include "Resources.h"
#include "Initializer.h"
namespace Seele { namespace Seele {
namespace Gfx { namespace Gfx {
+5
View File
@@ -14,10 +14,13 @@ target_sources(Engine
Initializer.h Initializer.h
Mesh.h Mesh.h
Mesh.cpp Mesh.cpp
MeshData.h
Meshlet.h Meshlet.h
Meshlet.cpp Meshlet.cpp
Pipeline.h Pipeline.h
Pipeline.cpp Pipeline.cpp
RayTracing.h
RayTracing.cpp
RenderTarget.h RenderTarget.h
RenderTarget.cpp RenderTarget.cpp
Resources.h Resources.h
@@ -47,7 +50,9 @@ target_sources(Engine
Initializer.h Initializer.h
Mesh.h Mesh.h
Meshlet.h Meshlet.h
MeshData.h
Pipeline.h Pipeline.h
RayTracing.h
RenderTarget.h RenderTarget.h
Resources.h Resources.h
Shader.h Shader.h
+17 -7
View File
@@ -1,7 +1,7 @@
#pragma once #pragma once
#include "Enums.h" #include "Enums.h"
#include "Resources.h" #include "Resources.h"
#include <compare> #include "Initializer.h"
namespace Seele { namespace Seele {
namespace Gfx { namespace Gfx {
@@ -27,7 +27,9 @@ public:
void reset(); void reset();
PDescriptorSet allocateDescriptorSet(); PDescriptorSet allocateDescriptorSet();
virtual void create() = 0; virtual void create() = 0;
constexpr const Array<DescriptorBinding>& getBindings() const { return descriptorBindings; } constexpr const Array<DescriptorBinding> &getBindings() const {
return descriptorBindings;
}
constexpr uint32 getHash() const { return hash; } constexpr uint32 getHash() const { return hash; }
constexpr const std::string &getName() const { return name; } constexpr const std::string &getName() const { return name; }
@@ -61,10 +63,13 @@ public:
virtual void writeChanges() = 0; virtual void writeChanges() = 0;
virtual void updateBuffer(uint32 binding, PUniformBuffer uniformBuffer) = 0; virtual void updateBuffer(uint32 binding, PUniformBuffer uniformBuffer) = 0;
virtual void updateBuffer(uint32 binding, PShaderBuffer ShaderBuffer) = 0; virtual void updateBuffer(uint32 binding, PShaderBuffer ShaderBuffer) = 0;
virtual void updateBuffer(uint32_t binding, uint32 index, Gfx::PShaderBuffer uniformBuffer) = 0; virtual void updateBuffer(uint32_t binding, uint32 index,
Gfx::PShaderBuffer uniformBuffer) = 0;
virtual void updateSampler(uint32 binding, PSampler sampler) = 0; virtual void updateSampler(uint32 binding, PSampler sampler) = 0;
virtual void updateTexture(uint32 binding, PTexture texture, PSampler samplerState = nullptr) = 0; virtual void updateTexture(uint32 binding, PTexture texture,
virtual void updateTextureArray(uint32_t binding, Array<PTexture> texture) = 0; PSampler samplerState = nullptr) = 0;
virtual void updateTextureArray(uint32_t binding,
Array<PTexture> texture) = 0;
bool operator<(PDescriptorSet other); bool operator<(PDescriptorSet other);
constexpr PDescriptorLayout getLayout() const { return layout; } constexpr PDescriptorLayout getLayout() const { return layout; }
@@ -75,6 +80,7 @@ protected:
}; };
DEFINE_REF(DescriptorSet) DEFINE_REF(DescriptorSet)
DECLARE_REF(PipelineLayout)
class PipelineLayout { class PipelineLayout {
public: public:
PipelineLayout(const std::string &name); PipelineLayout(const std::string &name);
@@ -84,8 +90,12 @@ public:
void addDescriptorLayout(PDescriptorLayout layout); void addDescriptorLayout(PDescriptorLayout layout);
void addPushConstants(const SePushConstantRange &pushConstants); void addPushConstants(const SePushConstantRange &pushConstants);
constexpr uint32 getHash() const { return layoutHash; } constexpr uint32 getHash() const { return layoutHash; }
constexpr const Map<std::string, PDescriptorLayout>& getLayouts() const { return descriptorSetLayouts; } constexpr const Map<std::string, PDescriptorLayout> &getLayouts() const {
constexpr uint32 findParameter(const std::string& param) const { return parameterMapping[param]; } return descriptorSetLayouts;
}
constexpr uint32 findParameter(const std::string &param) const {
return parameterMapping[param];
}
void addMapping(Map<std::string, uint32> mapping); void addMapping(Map<std::string, uint32> mapping);
constexpr std::string getName() const { return name; }; constexpr std::string getName() const { return name; };
+6
View File
@@ -31,6 +31,8 @@ DECLARE_REF(GraphicsPipeline)
DECLARE_REF(ComputePipeline) DECLARE_REF(ComputePipeline)
DECLARE_REF(RenderCommand) DECLARE_REF(RenderCommand)
DECLARE_REF(ComputeCommand) DECLARE_REF(ComputeCommand)
DECLARE_REF(BottomLevelAS)
DECLARE_REF(TopLevelAS)
class Graphics class Graphics
{ {
public: public:
@@ -88,6 +90,10 @@ public:
virtual void resolveTexture(Gfx::PTexture source, Gfx::PTexture destination) = 0; virtual void resolveTexture(Gfx::PTexture source, Gfx::PTexture destination) = 0;
bool supportMeshShading() const { return meshShadingEnabled; } bool supportMeshShading() const { return meshShadingEnabled; }
// Ray Tracing
virtual OBottomLevelAS createBottomLevelAccelerationStructure(const BottomLevelASCreateInfo& createInfo) = 0;
virtual OTopLevelAS createTopLevelAccelerationStructure(const TopLevelASCreateInfo& createInfo) = 0;
protected: protected:
QueueFamilyMapping queueMapping; QueueFamilyMapping queueMapping;
OShaderCompiler shaderCompiler; OShaderCompiler shaderCompiler;
+18
View File
@@ -2,6 +2,8 @@
#include "Enums.h" #include "Enums.h"
#include "Containers/Map.h" #include "Containers/Map.h"
#include "Math/Math.h" #include "Math/Math.h"
#include "MinimalEngine.h"
#include "MeshData.h"
namespace Seele namespace Seele
{ {
@@ -113,6 +115,7 @@ namespace Seele
DataSource sourceData = DataSource(); DataSource sourceData = DataSource();
uint64 numElements = 1; uint64 numElements = 1;
uint8 dynamic = 0; uint8 dynamic = 0;
uint8 vertexBuffer = 0;
std::string name = "Unnamed"; std::string name = "Unnamed";
}; };
DECLARE_NAME_REF(Gfx, PipelineLayout) DECLARE_NAME_REF(Gfx, PipelineLayout)
@@ -144,6 +147,7 @@ namespace Seele
Array<VertexInputBinding> bindings; Array<VertexInputBinding> bindings;
Array<VertexInputAttribute> attributes; Array<VertexInputAttribute> attributes;
}; };
DECLARE_REF(MaterialInstance)
namespace Gfx namespace Gfx
{ {
struct SePushConstantRange struct SePushConstantRange
@@ -244,5 +248,19 @@ namespace Seele
Gfx::PComputeShader computeShader = nullptr; Gfx::PComputeShader computeShader = nullptr;
Gfx::PPipelineLayout pipelineLayout = nullptr; Gfx::PPipelineLayout pipelineLayout = nullptr;
}; };
DECLARE_REF(ShaderBuffer)
struct BottomLevelASCreateInfo
{
PShaderBuffer positionBuffer;
PShaderBuffer indexBuffer;
MeshData meshData;
PMaterialInstance material;
uint64 verticesOffset;
uint64 indicesOffset;
};
struct TopLevelASCreateInfo
{
};
} // namespace Gfx } // namespace Gfx
} // namespace Seele } // namespace Seele
+18
View File
@@ -0,0 +1,18 @@
#pragma once
#include "Math/AABB.h"
namespace Seele
{
struct MeshData
{
AABB bounding;
uint32 numMeshlets = 0;
uint32 meshletOffset = 0;
uint32 firstIndex = 0;
uint32 numIndices = 0;
};
struct InstanceData
{
Matrix4 transformMatrix;
Matrix4 inverseTransformMatrix;
};
}
+15
View File
@@ -0,0 +1,15 @@
#include "RayTracing.h"
using namespace Seele::Gfx;
BottomLevelAS::BottomLevelAS()
{}
BottomLevelAS::~BottomLevelAS()
{}
TopLevelAS::TopLevelAS()
{}
TopLevelAS::~TopLevelAS()
{}
+25
View File
@@ -0,0 +1,25 @@
#pragma once
#include "Resources.h"
namespace Seele
{
namespace Gfx
{
class BottomLevelAS
{
public:
BottomLevelAS();
~BottomLevelAS();
private:
};
DEFINE_REF(BottomLevelAS)
class TopLevelAS
{
public:
TopLevelAS();
~TopLevelAS();
private:
};
DEFINE_REF(TopLevelAS)
}
}
@@ -5,6 +5,16 @@ namespace Seele
{ {
class RayTracingPass : public RenderPass class RayTracingPass : public RenderPass
{ {
public:
RayTracingPass(Gfx::PGraphics graphics, PScene scene);
RayTracingPass(RayTracingPass&& other) = default;
RayTracingPass& operator=(RayTracingPass&& other) = default;
virtual void beginFrame(const Component::Camera& cam) override;
virtual void render() override;
virtual void endFrame() override;
virtual void publishOutputs() override;
virtual void createRenderPass() override;
private:
}; };
} }
-6
View File
@@ -2,12 +2,6 @@
#include "Math/Math.h" #include "Math/Math.h"
#include "Enums.h" #include "Enums.h"
#include "Containers/Array.h" #include "Containers/Array.h"
#include "Containers/List.h"
#include "Initializer.h"
#include "Descriptor.h"
#include "CRC.h"
#include <functional>
#ifndef ENABLE_VALIDATION #ifndef ENABLE_VALIDATION
#define ENABLE_VALIDATION 1 #define ENABLE_VALIDATION 1
@@ -201,9 +201,11 @@ void StaticMeshVertexData::resizeBuffers()
}, },
.numElements = verticesAllocated * 3, .numElements = verticesAllocated * 3,
.dynamic = false, .dynamic = false,
.vertexBuffer = 1,
.name = "Positions", .name = "Positions",
}; };
positions = graphics->createShaderBuffer(createInfo); positions = graphics->createShaderBuffer(createInfo);
createInfo.vertexBuffer = false;
createInfo.name = "Normals"; createInfo.name = "Normals";
normals = graphics->createShaderBuffer(createInfo); normals = graphics->createShaderBuffer(createInfo);
createInfo.name = "Tangents"; createInfo.name = "Tangents";
+1 -4
View File
@@ -4,10 +4,9 @@
#include "Material/Material.h" #include "Material/Material.h"
#include "Graphics/Graphics.h" #include "Graphics/Graphics.h"
#include "Graphics/Descriptor.h" #include "Graphics/Descriptor.h"
#include "Component/Mesh.h"
#include "Graphics/Shader.h" #include "Graphics/Shader.h"
#include "Graphics/Mesh.h" #include "Graphics/Mesh.h"
#include "Containers/Set.h" #include "Material/MaterialInstance.h"
using namespace Seele; using namespace Seele;
@@ -114,7 +113,6 @@ void VertexData::createDescriptors()
instanceData.clear(); instanceData.clear();
instanceMeshData.clear(); instanceMeshData.clear();
uint32 numMeshlets = 0;
Array<uint32> cullingOffsets; Array<uint32> cullingOffsets;
for (auto &mat : materialData) for (auto &mat : materialData)
{ {
@@ -130,7 +128,6 @@ void VertexData::createDescriptors()
instanceMeshData.add(instance.instanceMeshData[i]); instanceMeshData.add(instance.instanceMeshData[i]);
// instance.numMeshlets += instance.instanceMeshData[i].numMeshlets; // instance.numMeshlets += instance.instanceMeshData[i].numMeshlets;
// cullingOffsets.add(numMeshlets); // cullingOffsets.add(numMeshlets);
numMeshlets += instance.instanceMeshData[i].numMeshlets;
} }
} }
} }
+26 -47
View File
@@ -1,77 +1,56 @@
#pragma once #pragma once
#include "Graphics/Initializer.h"
#include "Material/MaterialInstance.h"
#include "Component/Transform.h" #include "Component/Transform.h"
#include "Containers/List.h" #include "Containers/List.h"
#include "Graphics/Buffer.h"
#include "Graphics/Command.h" #include "Graphics/Command.h"
#include "Graphics/Descriptor.h" #include "Graphics/Descriptor.h"
#include "Graphics/Buffer.h" #include "MeshData.h"
#include "Meshlet.h" #include "Meshlet.h"
#include <entt/entt.hpp> #include <entt/entt.hpp>
constexpr uint64 MAX_TEXCOORDS = 8; constexpr uint64 MAX_TEXCOORDS = 8;
namespace Seele namespace Seele {
{ DECLARE_REF(MaterialInstance)
DECLARE_REF(Mesh) DECLARE_REF(Mesh)
struct MeshId struct MeshId {
{
uint64 id; uint64 id;
std::strong_ordering operator<=>(const MeshId &other) const std::strong_ordering operator<=>(const MeshId &other) const {
{
return id <=> other.id; return id <=> other.id;
} }
bool operator==(const MeshId &other) const bool operator==(const MeshId &other) const { return id == other.id; }
{
return id == other.id;
}
}; };
class VertexData class VertexData {
{
public: public:
struct InstanceData struct DrawCallOffsets {
{
Matrix4 transformMatrix;
Matrix4 inverseTransformMatrix;
};
struct MeshData
{
AABB bounding;
uint32 numMeshlets = 0;
uint32 meshletOffset = 0;
uint32 firstIndex = 0;
uint32 numIndices = 0;
};
struct DrawCallOffsets
{
uint32 instanceOffset = 0; uint32 instanceOffset = 0;
}; };
struct MeshletCullingInfo struct MeshletCullingInfo {
{
uint64_t cull[256 / 64]; uint64_t cull[256 / 64];
}; };
struct BatchedDrawCall struct BatchedDrawCall {
{
PMaterialInstance materialInstance; PMaterialInstance materialInstance;
DrawCallOffsets offsets; DrawCallOffsets offsets;
Array<InstanceData> instanceData; Array<InstanceData> instanceData;
Array<MeshData> instanceMeshData; Array<MeshData> instanceMeshData;
Array<uint32> cullingOffsets; Array<uint32> cullingOffsets;
}; };
struct MaterialData struct MaterialData {
{
PMaterial material; PMaterial material;
Array<BatchedDrawCall> instances; Array<BatchedDrawCall> instances;
}; };
void resetMeshData(); void resetMeshData();
void updateMesh(entt::entity id, uint32 meshIndex, PMesh mesh, Component::Transform &transform); void updateMesh(entt::entity id, uint32 meshIndex, PMesh mesh,
Component::Transform &transform);
void createDescriptors(); void createDescriptors();
void loadMesh(MeshId id, Array<uint32> indices, Array<Meshlet> meshlets); void loadMesh(MeshId id, Array<uint32> indices, Array<Meshlet> meshlets);
MeshId allocateVertexData(uint64 numVertices); MeshId allocateVertexData(uint64 numVertices);
uint64 getMeshOffset(MeshId id); uint64 getMeshOffset(MeshId id);
uint64 getMeshVertexCount(MeshId id); uint64 getMeshVertexCount(MeshId id);
virtual void serializeMesh(MeshId id, uint64 numVertices, ArchiveBuffer &buffer) = 0; virtual void serializeMesh(MeshId id, uint64 numVertices,
ArchiveBuffer &buffer) = 0;
virtual void deserializeMesh(MeshId id, ArchiveBuffer &buffer) = 0; virtual void deserializeMesh(MeshId id, ArchiveBuffer &buffer) = 0;
virtual void bindBuffers(Gfx::PRenderCommand command) = 0; virtual void bindBuffers(Gfx::PRenderCommand command) = 0;
virtual Gfx::PDescriptorLayout getVertexDataLayout() = 0; virtual Gfx::PDescriptorLayout getVertexDataLayout() = 0;
@@ -82,19 +61,21 @@ namespace Seele
Gfx::PDescriptorSet getInstanceDataSet() { return descriptorSet; } Gfx::PDescriptorSet getInstanceDataSet() { return descriptorSet; }
const Array<MaterialData> &getMaterialData() const { return materialData; } const Array<MaterialData> &getMaterialData() const { return materialData; }
const MeshData &getMeshData(MeshId id) { return meshData[id]; } const MeshData &getMeshData(MeshId id) { return meshData[id]; }
uint64 getIndicesOffset(uint32 meshletIndex) { return meshlets[meshletIndex].indicesOffset; } uint64 getIndicesOffset(uint32 meshletIndex) {
return meshlets[meshletIndex].indicesOffset;
}
uint64 getNumInstances() const { return instanceData.size(); } uint64 getNumInstances() const { return instanceData.size(); }
static List<VertexData *> getList(); static List<VertexData *> getList();
static VertexData *findByTypeName(std::string name); static VertexData *findByTypeName(std::string name);
virtual void init(Gfx::PGraphics graphics); virtual void init(Gfx::PGraphics graphics);
virtual void destroy(); virtual void destroy();
struct CullingMapping struct CullingMapping {
{
uint64 instanceId; uint64 instanceId;
uint32 cullingOffset; uint32 cullingOffset;
}; };
static CullingMapping getCullingMapping(entt::entity id, uint32 meshIndex, uint32 numMeshlets); static CullingMapping getCullingMapping(entt::entity id, uint32 meshIndex,
uint32 numMeshlets);
static uint64 getInstanceCount() { return instanceCount; } static uint64 getInstanceCount() { return instanceCount; }
static uint64 getMeshletCount() { return meshletCount; } static uint64 getMeshletCount() { return meshletCount; }
@@ -102,8 +83,7 @@ namespace Seele
virtual void resizeBuffers() = 0; virtual void resizeBuffers() = 0;
virtual void updateBuffers() = 0; virtual void updateBuffers() = 0;
VertexData(); VertexData();
struct MeshletDescription struct MeshletDescription {
{
AABB bounding; AABB bounding;
uint32 vertexCount; uint32 vertexCount;
uint32 primitiveCount; uint32 primitiveCount;
@@ -123,8 +103,7 @@ namespace Seele
Array<uint32> vertexIndices; Array<uint32> vertexIndices;
Array<uint32> indices; Array<uint32> indices;
struct MeshMapping struct MeshMapping {
{
entt::entity id; entt::entity id;
uint32 meshId; uint32 meshId;
auto operator<=>(const MeshMapping &other) const = default; auto operator<=>(const MeshMapping &other) const = default;
@@ -153,4 +132,4 @@ namespace Seele
uint64 verticesAllocated; uint64 verticesAllocated;
bool dirty; bool dirty;
}; };
} } // namespace Seele
+112 -169
View File
@@ -1,5 +1,7 @@
#include "Buffer.h" #include "Buffer.h"
#include "Command.h" #include "Command.h"
#include "Enums.h"
#include <vulkan/vulkan_core.h>
using namespace Seele; using namespace Seele;
using namespace Seele::Vulkan; using namespace Seele::Vulkan;
@@ -7,16 +9,13 @@ using namespace Seele::Vulkan;
BufferAllocation::BufferAllocation(PGraphics graphics) BufferAllocation::BufferAllocation(PGraphics graphics)
: CommandBoundResource(graphics) {} : CommandBoundResource(graphics) {}
BufferAllocation::~BufferAllocation() BufferAllocation::~BufferAllocation() {
{ if (buffer != VK_NULL_HANDLE) {
if (buffer != VK_NULL_HANDLE)
{
vmaDestroyBuffer(graphics->getAllocator(), buffer, allocation); vmaDestroyBuffer(graphics->getAllocator(), buffer, allocation);
} }
} }
struct PendingBuffer struct PendingBuffer {
{
OBufferAllocation allocation; OBufferAllocation allocation;
uint64 offset; uint64 offset;
Gfx::QueueType prevQueue; Gfx::QueueType prevQueue;
@@ -28,23 +27,20 @@ static Map<Vulkan::Buffer *, PendingBuffer> pendingBuffers;
Buffer::Buffer(PGraphics graphics, uint64 size, VkBufferUsageFlags usage, Buffer::Buffer(PGraphics graphics, uint64 size, VkBufferUsageFlags usage,
Gfx::QueueType &queueType, bool dynamic, std::string name) Gfx::QueueType &queueType, bool dynamic, std::string name)
: graphics(graphics), currentBuffer(0), owner(queueType), : graphics(graphics), currentBuffer(0), owner(queueType),
usage(usage | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT), dynamic(dynamic), usage(usage | VK_BUFFER_USAGE_TRANSFER_DST_BIT |
name(name) VK_BUFFER_USAGE_TRANSFER_SRC_BIT),
{ dynamic(dynamic), name(name) {
createBuffer(size); createBuffer(size);
} }
Buffer::~Buffer() Buffer::~Buffer() {
{ for (uint32 i = 0; i < buffers.size(); ++i) {
for (uint32 i = 0; i < buffers.size(); ++i)
{
graphics->getDestructionManager()->queueResourceForDestruction( graphics->getDestructionManager()->queueResourceForDestruction(
std::move(buffers[i])); std::move(buffers[i]));
} }
} }
void Buffer::executeOwnershipBarrier(Gfx::QueueType newOwner) void Buffer::executeOwnershipBarrier(Gfx::QueueType newOwner) {
{
if (getSize() == 0) if (getSize() == 0)
return; return;
Gfx::QueueFamilyMapping mapping = graphics->getFamilyMapping(); Gfx::QueueFamilyMapping mapping = graphics->getFamilyMapping();
@@ -62,35 +58,25 @@ void Buffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
VkPipelineStageFlags srcStage = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; VkPipelineStageFlags srcStage = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
VkPipelineStageFlags dstStage = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; VkPipelineStageFlags dstStage = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
assert(barrier.srcQueueFamilyIndex != barrier.dstQueueFamilyIndex); assert(barrier.srcQueueFamilyIndex != barrier.dstQueueFamilyIndex);
if (owner == Gfx::QueueType::TRANSFER) if (owner == Gfx::QueueType::TRANSFER) {
{
barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
srcStage = VK_PIPELINE_STAGE_TRANSFER_BIT; srcStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
} } else if (owner == Gfx::QueueType::COMPUTE) {
else if (owner == Gfx::QueueType::COMPUTE)
{
barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT; barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
srcStage = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; srcStage = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
} } else if (owner == Gfx::QueueType::GRAPHICS) {
else if (owner == Gfx::QueueType::GRAPHICS)
{
barrier.srcAccessMask = getSourceAccessMask(); barrier.srcAccessMask = getSourceAccessMask();
srcStage = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT; srcStage = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT;
} }
if (newOwner == Gfx::QueueType::TRANSFER) if (newOwner == Gfx::QueueType::TRANSFER) {
{
barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
dstStage = VK_PIPELINE_STAGE_TRANSFER_BIT; dstStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
dstPool = graphics->getTransferCommands(); dstPool = graphics->getTransferCommands();
} } else if (newOwner == Gfx::QueueType::COMPUTE) {
else if (newOwner == Gfx::QueueType::COMPUTE)
{
barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
dstStage = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; dstStage = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
dstPool = graphics->getComputeCommands(); dstPool = graphics->getComputeCommands();
} } else if (newOwner == Gfx::QueueType::GRAPHICS) {
else if (newOwner == Gfx::QueueType::GRAPHICS)
{
barrier.dstAccessMask = getDestAccessMask(); barrier.dstAccessMask = getDestAccessMask();
dstStage = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT; dstStage = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT;
dstPool = graphics->getGraphicsCommands(); dstPool = graphics->getGraphicsCommands();
@@ -107,8 +93,7 @@ void Buffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
void Buffer::executePipelineBarrier(VkAccessFlags srcAccess, void Buffer::executePipelineBarrier(VkAccessFlags srcAccess,
VkPipelineStageFlags srcStage, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkAccessFlags dstAccess,
VkPipelineStageFlags dstStage) VkPipelineStageFlags dstStage) {
{
if (getSize() == 0) if (getSize() == 0)
return; return;
PCommand commandBuffer = graphics->getQueueCommands(owner)->getCommands(); PCommand commandBuffer = graphics->getQueueCommands(owner)->getCommands();
@@ -130,8 +115,7 @@ void Buffer::executePipelineBarrier(VkAccessFlags srcAccess,
void *Buffer::map(bool writeOnly) { return mapRegion(0, getSize(), writeOnly); } void *Buffer::map(bool writeOnly) { return mapRegion(0, getSize(), writeOnly); }
void *Buffer::mapRegion(uint64 regionOffset, uint64 regionSize, void *Buffer::mapRegion(uint64 regionOffset, uint64 regionSize,
bool writeOnly) bool writeOnly) {
{
if (regionSize == 0) if (regionSize == 0)
return nullptr; return nullptr;
void *data = nullptr; void *data = nullptr;
@@ -142,16 +126,12 @@ void *Buffer::mapRegion(uint64 regionOffset, uint64 regionSize,
pending.writeOnly = writeOnly; pending.writeOnly = writeOnly;
pending.prevQueue = owner; pending.prevQueue = owner;
pending.offset = regionOffset; pending.offset = regionOffset;
if (writeOnly) if (writeOnly) {
{
if (buffers[currentBuffer]->properties & if (buffers[currentBuffer]->properties &
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) {
{
VK_CHECK(vmaMapMemory(graphics->getAllocator(), VK_CHECK(vmaMapMemory(graphics->getAllocator(),
buffers[currentBuffer]->allocation, &data)); buffers[currentBuffer]->allocation, &data));
} } else {
else
{
VkBufferCreateInfo stagingInfo = { VkBufferCreateInfo stagingInfo = {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.pNext = nullptr, .pNext = nullptr,
@@ -174,9 +154,7 @@ void *Buffer::mapRegion(uint64 regionOffset, uint64 regionSize,
vmaSetAllocationName(graphics->getAllocator(), vmaSetAllocationName(graphics->getAllocator(),
pending.allocation->allocation, "MappingStaging"); pending.allocation->allocation, "MappingStaging");
} }
} } else {
else
{
assert(false); assert(false);
} }
pendingBuffers[this] = std::move(pending); pendingBuffers[this] = std::move(pending);
@@ -185,22 +163,16 @@ void *Buffer::mapRegion(uint64 regionOffset, uint64 regionSize,
return data; return data;
} }
void Buffer::unmap() void Buffer::unmap() {
{
auto found = pendingBuffers.find(this); auto found = pendingBuffers.find(this);
if (found != pendingBuffers.end()) if (found != pendingBuffers.end()) {
{
PendingBuffer &pending = found->value; PendingBuffer &pending = found->value;
if (pending.writeOnly) if (pending.writeOnly) {
{
if (buffers[currentBuffer]->properties & if (buffers[currentBuffer]->properties &
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) {
{
vmaUnmapMemory(graphics->getAllocator(), vmaUnmapMemory(graphics->getAllocator(),
buffers[currentBuffer]->allocation); buffers[currentBuffer]->allocation);
} } else {
else
{
vmaFlushAllocation(graphics->getAllocator(), vmaFlushAllocation(graphics->getAllocator(),
pending.allocation->allocation, 0, VK_WHOLE_SIZE); pending.allocation->allocation, 0, VK_WHOLE_SIZE);
vmaUnmapMemory(graphics->getAllocator(), vmaUnmapMemory(graphics->getAllocator(),
@@ -252,18 +224,14 @@ void Buffer::unmap()
} }
} }
void Buffer::rotateBuffer(uint64 size, bool preserveContents) void Buffer::rotateBuffer(uint64 size, bool preserveContents) {
{
assert(dynamic); assert(dynamic);
size = std::max(getSize(), size); size = std::max(getSize(), size);
for (size_t i = 0; i < buffers.size(); ++i) for (size_t i = 0; i < buffers.size(); ++i) {
{ if (buffers[i]->isCurrentlyBound()) {
if (buffers[i]->isCurrentlyBound())
{
continue; continue;
} }
if (buffers[i]->size < size) if (buffers[i]->size < size) {
{
vmaDestroyBuffer(graphics->getAllocator(), buffers[i]->buffer, vmaDestroyBuffer(graphics->getAllocator(), buffers[i]->buffer,
buffers[i]->allocation); buffers[i]->allocation);
VkBufferCreateInfo info = { VkBufferCreateInfo info = {
@@ -285,8 +253,7 @@ void Buffer::rotateBuffer(uint64 size, bool preserveContents)
vmaGetAllocationMemoryProperties(graphics->getAllocator(), vmaGetAllocationMemoryProperties(graphics->getAllocator(),
buffers[i]->allocation, buffers[i]->allocation,
&buffers[i]->properties); &buffers[i]->properties);
if (!name.empty()) if (!name.empty()) {
{
VkDebugUtilsObjectNameInfoEXT nameInfo = { VkDebugUtilsObjectNameInfoEXT nameInfo = {
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT, .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT,
.pNext = nullptr, .pNext = nullptr,
@@ -297,23 +264,20 @@ void Buffer::rotateBuffer(uint64 size, bool preserveContents)
} }
buffers[i]->size = size; buffers[i]->size = size;
} }
if (preserveContents) if (preserveContents) {
{
copyBuffer(currentBuffer, i); copyBuffer(currentBuffer, i);
} }
currentBuffer = i; currentBuffer = i;
return; return;
} }
createBuffer(size); createBuffer(size);
if (preserveContents) if (preserveContents) {
{
copyBuffer(currentBuffer, buffers.size() - 1); copyBuffer(currentBuffer, buffers.size() - 1);
} }
currentBuffer = buffers.size() - 1; currentBuffer = buffers.size() - 1;
} }
void Buffer::createBuffer(uint64 size) void Buffer::createBuffer(uint64 size) {
{
VkBufferCreateInfo info = { VkBufferCreateInfo info = {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.pNext = nullptr, .pNext = nullptr,
@@ -327,8 +291,7 @@ void Buffer::createBuffer(uint64 size)
.usage = VMA_MEMORY_USAGE_AUTO, .usage = VMA_MEMORY_USAGE_AUTO,
}; };
buffers.add(new BufferAllocation(graphics)); buffers.add(new BufferAllocation(graphics));
if (size > 0) if (size > 0) {
{
VK_CHECK(vmaCreateBuffer( VK_CHECK(vmaCreateBuffer(
graphics->getAllocator(), &info, &allocInfo, &buffers.back()->buffer, graphics->getAllocator(), &info, &allocInfo, &buffers.back()->buffer,
&buffers.back()->allocation, &buffers.back()->info)); &buffers.back()->allocation, &buffers.back()->info));
@@ -336,8 +299,14 @@ void Buffer::createBuffer(uint64 size)
vmaGetAllocationMemoryProperties(graphics->getAllocator(), vmaGetAllocationMemoryProperties(graphics->getAllocator(),
buffers.back()->allocation, buffers.back()->allocation,
&buffers.back()->properties); &buffers.back()->properties);
if (!name.empty()) 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 = { VkDebugUtilsObjectNameInfoEXT nameInfo = {
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT, .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT,
.pNext = nullptr, .pNext = nullptr,
@@ -349,10 +318,8 @@ void Buffer::createBuffer(uint64 size)
} }
} }
void Buffer::copyBuffer(uint64 src, uint64 dst) void Buffer::copyBuffer(uint64 src, uint64 dst) {
{ if (src == dst) {
if (src == dst)
{
return; return;
} }
PCommand command = graphics->getQueueCommands(owner)->getCommands(); PCommand command = graphics->getQueueCommands(owner)->getCommands();
@@ -367,13 +334,14 @@ void Buffer::copyBuffer(uint64 src, uint64 dst)
.offset = 0, .offset = 0,
.size = buffers[src]->size, .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); vkCmdPipelineBarrier(command->getHandle(),
VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 1,
&srcBarrier, 0, nullptr);
VkBufferCopy region = { VkBufferCopy region = {
.srcOffset = 0, .srcOffset = 0, .dstOffset = 0, .size = buffers[src]->size};
.dstOffset = 0, vkCmdCopyBuffer(command->getHandle(), buffers[src]->buffer,
.size = buffers[src]->size buffers[dst]->buffer, 1, &region);
};
vkCmdCopyBuffer(command->getHandle(), buffers[src]->buffer, buffers[dst]->buffer, 1, &region);
VkBufferMemoryBarrier dstBarrier = { VkBufferMemoryBarrier dstBarrier = {
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
.pNext = nullptr, .pNext = nullptr,
@@ -385,7 +353,9 @@ void Buffer::copyBuffer(uint64 src, uint64 dst)
.offset = 0, .offset = 0,
.size = buffers[dst]->size, .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); 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, UniformBuffer::UniformBuffer(PGraphics graphics,
@@ -393,10 +363,8 @@ UniformBuffer::UniformBuffer(PGraphics graphics,
: Gfx::UniformBuffer(graphics->getFamilyMapping(), createInfo.sourceData), : Gfx::UniformBuffer(graphics->getFamilyMapping(), createInfo.sourceData),
Vulkan::Buffer(graphics, createInfo.sourceData.size, Vulkan::Buffer(graphics, createInfo.sourceData.size,
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, currentOwner, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, currentOwner,
createInfo.dynamic, createInfo.name) createInfo.dynamic, createInfo.name) {
{ if (getSize() > 0 && createInfo.sourceData.data != nullptr) {
if (getSize() > 0 && createInfo.sourceData.data != nullptr)
{
void *data = map(); void *data = map();
std::memcpy(data, createInfo.sourceData.data, createInfo.sourceData.size); std::memcpy(data, createInfo.sourceData.data, createInfo.sourceData.size);
unmap(); unmap();
@@ -405,44 +373,37 @@ UniformBuffer::UniformBuffer(PGraphics graphics,
UniformBuffer::~UniformBuffer() {} UniformBuffer::~UniformBuffer() {}
void UniformBuffer::updateContents(const DataSource &sourceData) void UniformBuffer::updateContents(const DataSource &sourceData) {
{
void *data = map(); void *data = map();
std::memcpy(data, sourceData.data, sourceData.size); std::memcpy(data, sourceData.data, sourceData.size);
unmap(); unmap();
} }
void UniformBuffer::rotateBuffer(uint64 size) void UniformBuffer::rotateBuffer(uint64 size) {
{
Vulkan::Buffer::rotateBuffer(size); Vulkan::Buffer::rotateBuffer(size);
} }
void UniformBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner) void UniformBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner) {
{
Gfx::QueueOwnedResource::transferOwnership(newOwner); Gfx::QueueOwnedResource::transferOwnership(newOwner);
} }
void UniformBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) void UniformBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) {
{
Vulkan::Buffer::executeOwnershipBarrier(newOwner); Vulkan::Buffer::executeOwnershipBarrier(newOwner);
} }
void UniformBuffer::executePipelineBarrier(VkAccessFlags srcAccess, void UniformBuffer::executePipelineBarrier(VkAccessFlags srcAccess,
VkPipelineStageFlags srcStage, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkAccessFlags dstAccess,
VkPipelineStageFlags dstStage) VkPipelineStageFlags dstStage) {
{
Vulkan::Buffer::executePipelineBarrier(srcAccess, srcStage, dstAccess, Vulkan::Buffer::executePipelineBarrier(srcAccess, srcStage, dstAccess,
dstStage); dstStage);
} }
VkAccessFlags UniformBuffer::getSourceAccessMask() VkAccessFlags UniformBuffer::getSourceAccessMask() {
{
return VK_ACCESS_MEMORY_WRITE_BIT; return VK_ACCESS_MEMORY_WRITE_BIT;
} }
VkAccessFlags UniformBuffer::getDestAccessMask() VkAccessFlags UniformBuffer::getDestAccessMask() {
{
return VK_ACCESS_UNIFORM_READ_BIT; return VK_ACCESS_UNIFORM_READ_BIT;
} }
@@ -450,12 +411,15 @@ ShaderBuffer::ShaderBuffer(PGraphics graphics,
const ShaderBufferCreateInfo &sourceData) const ShaderBufferCreateInfo &sourceData)
: Gfx::ShaderBuffer(graphics->getFamilyMapping(), sourceData.numElements, : Gfx::ShaderBuffer(graphics->getFamilyMapping(), sourceData.numElements,
sourceData.sourceData), sourceData.sourceData),
Vulkan::Buffer(graphics, sourceData.sourceData.size, Vulkan::Buffer(
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, currentOwner, graphics, sourceData.sourceData.size,
sourceData.dynamic, sourceData.name) VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
{ (sourceData.vertexBuffer
if (getSize() > 0 && sourceData.sourceData.data != nullptr) ? 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(); void *data = map();
std::memcpy(data, sourceData.sourceData.data, sourceData.sourceData.size); std::memcpy(data, sourceData.sourceData.data, sourceData.sourceData.size);
unmap(); unmap();
@@ -464,62 +428,55 @@ ShaderBuffer::ShaderBuffer(PGraphics graphics,
ShaderBuffer::~ShaderBuffer() {} ShaderBuffer::~ShaderBuffer() {}
void ShaderBuffer::updateContents(const ShaderBufferCreateInfo &createInfo) void ShaderBuffer::updateContents(const ShaderBufferCreateInfo &createInfo) {
{ if (createInfo.sourceData.data == nullptr) {
if (createInfo.sourceData.data == nullptr)
{
return; return;
} }
// We always want to update, as the contents could be different on the GPU // We always want to update, as the contents could be different on the GPU
void *data = map(); void *data = map();
std::memcpy((char *)data + createInfo.sourceData.offset, createInfo.sourceData.data, createInfo.sourceData.size); std::memcpy((char *)data + createInfo.sourceData.offset,
createInfo.sourceData.data, createInfo.sourceData.size);
unmap(); unmap();
} }
void Seele::Vulkan::ShaderBuffer::rotateBuffer(uint64 size, bool preserveContents) void Seele::Vulkan::ShaderBuffer::rotateBuffer(uint64 size,
{ bool preserveContents) {
assert(dynamic); assert(dynamic);
Vulkan::Buffer::rotateBuffer(size, preserveContents); Vulkan::Buffer::rotateBuffer(size, preserveContents);
} }
void *ShaderBuffer::mapRegion(uint64 offset, uint64 size, bool writeOnly) void *ShaderBuffer::mapRegion(uint64 offset, uint64 size, bool writeOnly) {
{
return Vulkan::Buffer::mapRegion(offset, size, writeOnly); return Vulkan::Buffer::mapRegion(offset, size, writeOnly);
} }
void ShaderBuffer::unmap() { Vulkan::Buffer::unmap(); } void ShaderBuffer::unmap() { Vulkan::Buffer::unmap(); }
void ShaderBuffer::clear() void ShaderBuffer::clear() {
{ vkCmdFillBuffer(graphics->getQueueCommands(owner)->getCommands()->getHandle(),
vkCmdFillBuffer(graphics->getQueueCommands(owner)->getCommands()->getHandle(), Vulkan::Buffer::getHandle(), 0, VK_WHOLE_SIZE, 0); Vulkan::Buffer::getHandle(), 0, VK_WHOLE_SIZE, 0);
} }
void ShaderBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner) void ShaderBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner) {
{
Gfx::QueueOwnedResource::transferOwnership(newOwner); Gfx::QueueOwnedResource::transferOwnership(newOwner);
} }
void ShaderBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) void ShaderBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) {
{
Vulkan::Buffer::executeOwnershipBarrier(newOwner); Vulkan::Buffer::executeOwnershipBarrier(newOwner);
} }
void ShaderBuffer::executePipelineBarrier(VkAccessFlags srcAccess, void ShaderBuffer::executePipelineBarrier(VkAccessFlags srcAccess,
VkPipelineStageFlags srcStage, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkAccessFlags dstAccess,
VkPipelineStageFlags dstStage) VkPipelineStageFlags dstStage) {
{
Vulkan::Buffer::executePipelineBarrier(srcAccess, srcStage, dstAccess, Vulkan::Buffer::executePipelineBarrier(srcAccess, srcStage, dstAccess,
dstStage); dstStage);
} }
VkAccessFlags ShaderBuffer::getSourceAccessMask() VkAccessFlags ShaderBuffer::getSourceAccessMask() {
{
return VK_ACCESS_MEMORY_WRITE_BIT; return VK_ACCESS_MEMORY_WRITE_BIT;
} }
VkAccessFlags ShaderBuffer::getDestAccessMask() VkAccessFlags ShaderBuffer::getDestAccessMask() {
{
return VK_ACCESS_MEMORY_READ_BIT; return VK_ACCESS_MEMORY_READ_BIT;
} }
@@ -529,10 +486,8 @@ VertexBuffer::VertexBuffer(PGraphics graphics,
sourceData.vertexSize, sourceData.sourceData.owner), sourceData.vertexSize, sourceData.sourceData.owner),
Vulkan::Buffer(graphics, sourceData.sourceData.size, Vulkan::Buffer(graphics, sourceData.sourceData.size,
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, currentOwner, false, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, currentOwner, false,
sourceData.name) sourceData.name) {
{ if (sourceData.sourceData.data != nullptr) {
if (sourceData.sourceData.data != nullptr)
{
void *data = map(); void *data = map();
std::memcpy(data, sourceData.sourceData.data, sourceData.sourceData.size); std::memcpy(data, sourceData.sourceData.data, sourceData.sourceData.size);
unmap(); unmap();
@@ -541,47 +496,40 @@ VertexBuffer::VertexBuffer(PGraphics graphics,
VertexBuffer::~VertexBuffer() {} VertexBuffer::~VertexBuffer() {}
void VertexBuffer::updateRegion(DataSource update) void VertexBuffer::updateRegion(DataSource update) {
{
void *data = mapRegion(update.offset, update.size); void *data = mapRegion(update.offset, update.size);
std::memcpy(data, update.data, update.size); std::memcpy(data, update.data, update.size);
unmap(); unmap();
} }
void VertexBuffer::download(Array<uint8> &buffer) void VertexBuffer::download(Array<uint8> &buffer) {
{
void *data = map(false); void *data = map(false);
buffer.resize(getSize()); buffer.resize(getSize());
std::memcpy(buffer.data(), data, getSize()); std::memcpy(buffer.data(), data, getSize());
unmap(); unmap();
} }
void VertexBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner) void VertexBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner) {
{
Gfx::QueueOwnedResource::transferOwnership(newOwner); Gfx::QueueOwnedResource::transferOwnership(newOwner);
} }
void VertexBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) void VertexBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) {
{
Vulkan::Buffer::executeOwnershipBarrier(newOwner); Vulkan::Buffer::executeOwnershipBarrier(newOwner);
} }
void VertexBuffer::executePipelineBarrier(VkAccessFlags srcAccess, void VertexBuffer::executePipelineBarrier(VkAccessFlags srcAccess,
VkPipelineStageFlags srcStage, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkAccessFlags dstAccess,
VkPipelineStageFlags dstStage) VkPipelineStageFlags dstStage) {
{
Vulkan::Buffer::executePipelineBarrier(srcAccess, srcStage, dstAccess, Vulkan::Buffer::executePipelineBarrier(srcAccess, srcStage, dstAccess,
dstStage); dstStage);
} }
VkAccessFlags VertexBuffer::getSourceAccessMask() VkAccessFlags VertexBuffer::getSourceAccessMask() {
{
return VK_ACCESS_MEMORY_WRITE_BIT; return VK_ACCESS_MEMORY_WRITE_BIT;
} }
VkAccessFlags VertexBuffer::getDestAccessMask() VkAccessFlags VertexBuffer::getDestAccessMask() {
{
return VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT; return VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;
} }
@@ -589,12 +537,13 @@ IndexBuffer::IndexBuffer(PGraphics graphics,
const IndexBufferCreateInfo &sourceData) const IndexBufferCreateInfo &sourceData)
: Gfx::IndexBuffer(graphics->getFamilyMapping(), sourceData.sourceData.size, : Gfx::IndexBuffer(graphics->getFamilyMapping(), sourceData.sourceData.size,
sourceData.indexType, sourceData.sourceData.owner), sourceData.indexType, sourceData.sourceData.owner),
Vulkan::Buffer(graphics, sourceData.sourceData.size, Vulkan::Buffer(
VK_BUFFER_USAGE_INDEX_BUFFER_BIT, currentOwner, false, graphics, sourceData.sourceData.size,
sourceData.name) VK_BUFFER_USAGE_INDEX_BUFFER_BIT |
{ VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR |
if (sourceData.sourceData.data != nullptr) VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
{ currentOwner, false, sourceData.name) {
if (sourceData.sourceData.data != nullptr) {
void *data = map(); void *data = map();
std::memcpy(data, sourceData.sourceData.data, sourceData.sourceData.size); std::memcpy(data, sourceData.sourceData.data, sourceData.sourceData.size);
unmap(); unmap();
@@ -603,39 +552,33 @@ IndexBuffer::IndexBuffer(PGraphics graphics,
IndexBuffer::~IndexBuffer() {} IndexBuffer::~IndexBuffer() {}
void IndexBuffer::download(Array<uint8> &buffer) void IndexBuffer::download(Array<uint8> &buffer) {
{
void *data = map(false); void *data = map(false);
buffer.resize(getSize()); buffer.resize(getSize());
std::memcpy(buffer.data(), data, getSize()); std::memcpy(buffer.data(), data, getSize());
unmap(); unmap();
} }
void IndexBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner) void IndexBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner) {
{
Gfx::QueueOwnedResource::transferOwnership(newOwner); Gfx::QueueOwnedResource::transferOwnership(newOwner);
} }
void IndexBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) void IndexBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) {
{
Vulkan::Buffer::executeOwnershipBarrier(newOwner); Vulkan::Buffer::executeOwnershipBarrier(newOwner);
} }
void IndexBuffer::executePipelineBarrier(VkAccessFlags srcAccess, void IndexBuffer::executePipelineBarrier(VkAccessFlags srcAccess,
VkPipelineStageFlags srcStage, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkAccessFlags dstAccess,
VkPipelineStageFlags dstStage) VkPipelineStageFlags dstStage) {
{
Vulkan::Buffer::executePipelineBarrier(srcAccess, srcStage, dstAccess, Vulkan::Buffer::executePipelineBarrier(srcAccess, srcStage, dstAccess,
dstStage); dstStage);
} }
VkAccessFlags IndexBuffer::getSourceAccessMask() VkAccessFlags IndexBuffer::getSourceAccessMask() {
{
return VK_ACCESS_MEMORY_WRITE_BIT; return VK_ACCESS_MEMORY_WRITE_BIT;
} }
VkAccessFlags IndexBuffer::getDestAccessMask() VkAccessFlags IndexBuffer::getDestAccessMask() {
{
return VK_ACCESS_INDEX_READ_BIT; return VK_ACCESS_INDEX_READ_BIT;
} }
+6 -1
View File
@@ -16,6 +16,7 @@ public:
VmaAllocationInfo info = VmaAllocationInfo(); VmaAllocationInfo info = VmaAllocationInfo();
VkMemoryPropertyFlags properties = 0; VkMemoryPropertyFlags properties = 0;
uint64 size = 0; uint64 size = 0;
VkDeviceAddress deviceAddress;
}; };
DEFINE_REF(BufferAllocation); DEFINE_REF(BufferAllocation);
class Buffer { class Buffer {
@@ -24,6 +25,9 @@ public:
Gfx::QueueType &queueType, bool dynamic, std::string name); Gfx::QueueType &queueType, bool dynamic, std::string name);
virtual ~Buffer(); virtual ~Buffer();
VkBuffer getHandle() const { return buffers[currentBuffer]->buffer; } VkBuffer getHandle() const { return buffers[currentBuffer]->buffer; }
VkDeviceAddress getDeviceAddress() const {
return buffers[currentBuffer]->deviceAddress;
}
PBufferAllocation getAlloc() const { return buffers[currentBuffer]; } PBufferAllocation getAlloc() const { return buffers[currentBuffer]; }
uint64 getSize() const { return buffers[currentBuffer]->size; } uint64 getSize() const { return buffers[currentBuffer]->size; }
void *map(bool writeOnly = true); void *map(bool writeOnly = true);
@@ -130,7 +134,8 @@ public:
virtual ~ShaderBuffer(); virtual ~ShaderBuffer();
virtual void virtual void
updateContents(const ShaderBufferCreateInfo &createInfo) override; updateContents(const ShaderBufferCreateInfo &createInfo) override;
virtual void rotateBuffer(uint64 size, bool preserveContents = false) override; virtual void rotateBuffer(uint64 size,
bool preserveContents = false) override;
virtual void *mapRegion(uint64 offset, uint64 size, bool writeOnly) override; virtual void *mapRegion(uint64 offset, uint64 size, bool writeOnly) override;
virtual void unmap() override; virtual void unmap() override;
@@ -22,6 +22,8 @@ target_sources(Engine
PipelineCache.cpp PipelineCache.cpp
Queue.h Queue.h
Queue.cpp Queue.cpp
RayTracing.h
RayTracing.cpp
RenderPass.h RenderPass.h
RenderPass.cpp RenderPass.cpp
Resources.h Resources.h
@@ -47,6 +49,7 @@ target_sources(Engine
Pipeline.h Pipeline.h
PipelineCache.h PipelineCache.h
Queue.h Queue.h
RayTracing.h
RenderPass.h RenderPass.h
Resources.h Resources.h
Shader.h Shader.h
@@ -3,6 +3,7 @@
#include "Command.h" #include "Command.h"
#include "Graphics.h" #include "Graphics.h"
#include "Texture.h" #include "Texture.h"
#include "CRC.h"
using namespace Seele; using namespace Seele;
using namespace Seele::Vulkan; using namespace Seele::Vulkan;
@@ -3,6 +3,7 @@
#include "RenderPass.h" #include "RenderPass.h"
#include "Graphics.h" #include "Graphics.h"
#include "Texture.h" #include "Texture.h"
#include "CRC.h"
using namespace Seele; using namespace Seele;
using namespace Seele::Vulkan; using namespace Seele::Vulkan;
+20 -4
View File
@@ -3,6 +3,8 @@
#include "Allocator.h" #include "Allocator.h"
#include "Buffer.h" #include "Buffer.h"
#include "Graphics/Enums.h" #include "Graphics/Enums.h"
#include "Graphics/Graphics.h"
#include "Graphics/Initializer.h"
#include "PipelineCache.h" #include "PipelineCache.h"
#include "Command.h" #include "Command.h"
#include "Descriptor.h" #include "Descriptor.h"
@@ -10,6 +12,7 @@
#include "RenderPass.h" #include "RenderPass.h"
#include "Framebuffer.h" #include "Framebuffer.h"
#include "Shader.h" #include "Shader.h"
#include "RayTracing.h"
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
#include <cstring> #include <cstring>
#include <vulkan/vulkan_core.h> #include <vulkan/vulkan_core.h>
@@ -291,14 +294,24 @@ void Graphics::resolveTexture(Gfx::PTexture source, Gfx::PTexture destination)
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);
} }
void Graphics::vkCmdDrawMeshTasksEXT(VkCommandBuffer handle, uint32 groupX, uint32 groupY, uint32 groupZ) Gfx::OBottomLevelAS Graphics::createBottomLevelAccelerationStructure(const Gfx::BottomLevelASCreateInfo& createInfo)
{ {
cmdDrawMeshTasks(handle, groupX, groupY, groupZ); return new BottomLevelAS(this, createInfo);
} }
void Graphics::vkCmdDrawMeshTasksIndirectEXT(VkCommandBuffer handle, VkBuffer buffer, uint64 offset, uint32 drawCount, uint32 stride) Gfx::OTopLevelAS Graphics::createTopLevelAccelerationStructure(const Gfx::TopLevelASCreateInfo& createInfo)
{ {
cmdDrawMeshTasksIndirect(handle, buffer, offset, drawCount, stride); return new TopLevelAS(this, createInfo);
}
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)
{
cmdDrawMeshTasksIndirect(cmd, buffer, offset, drawCount, stride);
} }
void Graphics::vkSetDebugUtilsObjectNameEXT(VkDebugUtilsObjectNameInfoEXT* info) void Graphics::vkSetDebugUtilsObjectNameEXT(VkDebugUtilsObjectNameInfoEXT* info)
@@ -395,6 +408,7 @@ void Graphics::initInstance(GraphicsInitializer initInfo)
assert(glfwVulkanSupported()); assert(glfwVulkanSupported());
VkApplicationInfo appInfo = { VkApplicationInfo appInfo = {
.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO, .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
.pNext = nullptr,
.pApplicationName = initInfo.applicationName, .pApplicationName = initInfo.applicationName,
.applicationVersion = VK_MAKE_VERSION(0, 0, 1), .applicationVersion = VK_MAKE_VERSION(0, 0, 1),
.pEngineName = initInfo.engineName, .pEngineName = initInfo.engineName,
@@ -415,6 +429,7 @@ void Graphics::initInstance(GraphicsInitializer initInfo)
#endif #endif
VkInstanceCreateInfo info = { VkInstanceCreateInfo info = {
.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
.pNext = nullptr,
#if __APPLE__ #if __APPLE__
.flags = VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR, .flags = VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR,
#endif #endif
@@ -562,6 +577,7 @@ void Graphics::createDevice(GraphicsInitializer initializer)
.flags = 0, .flags = 0,
.queueFamilyIndex = familyIndex, .queueFamilyIndex = familyIndex,
.queueCount = numQueuesForFamily, .queueCount = numQueuesForFamily,
.pQueuePriorities = nullptr,
}; };
numPriorities += numQueuesForFamily; numPriorities += numQueuesForFamily;
queueInfos.add(info); queueInfos.add(info);
+4 -1
View File
@@ -1,5 +1,4 @@
#pragma once #pragma once
#include "Enums.h"
#include "Graphics/Graphics.h" #include "Graphics/Graphics.h"
#include <vk_mem_alloc.h> #include <vk_mem_alloc.h>
@@ -70,6 +69,10 @@ public:
virtual void resolveTexture(Gfx::PTexture source, Gfx::PTexture destination) override; virtual void resolveTexture(Gfx::PTexture source, Gfx::PTexture destination) override;
// Ray Tracing
virtual Gfx::OBottomLevelAS createBottomLevelAccelerationStructure(const Gfx::BottomLevelASCreateInfo& createInfo) override;
virtual Gfx::OTopLevelAS createTopLevelAccelerationStructure(const Gfx::TopLevelASCreateInfo& createInfo) override;
void vkCmdDrawMeshTasksEXT(VkCommandBuffer handle, uint32 groupX, uint32 groupY, uint32 groupZ); void vkCmdDrawMeshTasksEXT(VkCommandBuffer handle, uint32 groupX, uint32 groupY, uint32 groupZ);
void vkCmdDrawMeshTasksIndirectEXT(VkCommandBuffer handle, VkBuffer buffer, uint64 offset, uint32 drawCount, uint32 stride); void vkCmdDrawMeshTasksIndirectEXT(VkCommandBuffer handle, VkBuffer buffer, uint64 offset, uint32 drawCount, uint32 stride);
void vkSetDebugUtilsObjectNameEXT(VkDebugUtilsObjectNameInfoEXT* info); void vkSetDebugUtilsObjectNameEXT(VkDebugUtilsObjectNameInfoEXT* info);
+1
View File
@@ -2,6 +2,7 @@
#include "Graphics.h" #include "Graphics.h"
#include "Allocator.h" #include "Allocator.h"
#include "Command.h" #include "Command.h"
#include "Enums.h"
using namespace Seele; using namespace Seele;
using namespace Seele::Vulkan; using namespace Seele::Vulkan;
+67
View File
@@ -0,0 +1,67 @@
#include "RayTracing.h"
#include "Buffer.h"
#include "Graphics/Initializer.h"
#include <vulkan/vulkan_core.h>
using namespace Seele::Vulkan;
BottomLevelAS::BottomLevelAS(PGraphics graphics, const Gfx::BottomLevelASCreateInfo& createInfo)
{
VkDeviceOrHostAddressConstKHR vertexDataDeviceAddress = {
.deviceAddress = createInfo.positionBuffer.cast<Buffer>()->getDeviceAddress() + createInfo.verticesOffset,
};
VkDeviceOrHostAddressConstKHR indexDataDeviceAddress = {
.deviceAddress = createInfo.indexBuffer.cast<Buffer>()->getDeviceAddress() + createInfo.indicesOffset,
};
VkAccelerationStructureGeometryKHR accelerationStructureGeometry = {
.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR,
.pNext = nullptr,
.geometryType = VK_GEOMETRY_TYPE_TRIANGLES_KHR,
.geometry = {.triangles = {
.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_TRIANGLES_DATA_KHR,
.pNext = nullptr,
.vertexFormat = VK_FORMAT_R32G32B32_SFLOAT,
.vertexData = vertexDataDeviceAddress,
.vertexStride = sizeof(Vector),
.maxVertex = createInfo.positionBuffer->getNumElements(),
.indexType = VK_INDEX_TYPE_UINT32,
.indexData = indexDataDeviceAddress,
}},
.flags = VK_GEOMETRY_OPAQUE_BIT_KHR,
};
VkAccelerationStructureBuildRangeInfoKHR buildRangeInfo = {
.primitiveCount = createInfo.meshData.numIndices / 3,
.primitiveOffset = 0,
.firstVertex = 0,
.transformOffset = 0
};
VkAccelerationStructureBuildGeometryInfoKHR buildGeometry = {
.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR,
.pNext = nullptr,
.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR,
.flags = VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR,
};
VkAccelerationStructureCreateInfoKHR info = {
.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR,
.pNext = nullptr,
.createFlags = 0,
};
}
BottomLevelAS::~BottomLevelAS()
{
}
TopLevelAS::TopLevelAS(PGraphics graphics, const Gfx::TopLevelASCreateInfo& createInfo)
{
}
TopLevelAS::~TopLevelAS()
{
}
+32
View File
@@ -0,0 +1,32 @@
#pragma once
#include "Graphics/Initializer.h"
#include "Graphics.h"
#include "Graphics/RayTracing.h"
#include <vulkan/vulkan_core.h>
namespace Seele
{
namespace Vulkan
{
class BottomLevelAS : public Gfx::BottomLevelAS
{
public:
BottomLevelAS(PGraphics graphics, const Gfx::BottomLevelASCreateInfo& createInfo);
~BottomLevelAS();
private:
PGraphics graphics;
VkAccelerationStructureKHR handle;
};
DEFINE_REF(BottomLevelAS)
class TopLevelAS : public Gfx::TopLevelAS
{
public:
TopLevelAS(PGraphics graphics, const Gfx::TopLevelASCreateInfo& createInfo);
~TopLevelAS();
private:
PGraphics graphics;
VkAccelerationStructureKHR handle;
};
DEFINE_REF(TopLevelAS)
}
}
@@ -4,6 +4,7 @@
#include "Texture.h" #include "Texture.h"
#include "Resources.h" #include "Resources.h"
#include "Command.h" #include "Command.h"
#include "CRC.h"
using namespace Seele; using namespace Seele;
using namespace Seele::Vulkan; using namespace Seele::Vulkan;
+1
View File
@@ -1,5 +1,6 @@
#include "Texture.h" #include "Texture.h"
#include "Command.h" #include "Command.h"
#include "Enums.h"
#include <math.h> #include <math.h>
using namespace Seele; using namespace Seele;
+1
View File
@@ -1,6 +1,7 @@
#pragma once #pragma once
#include "Initializer.h" #include "Initializer.h"
#include "Texture.h" #include "Texture.h"
#include <functional>
namespace Seele namespace Seele
{ {