diff --git a/external/slang b/external/slang index 4b8ceed..f83fe55 160000 --- a/external/slang +++ b/external/slang @@ -1 +1 @@ -Subproject commit 4b8ceed9d64f0878501189a40c1fd89f74c7f9ce +Subproject commit f83fe55a8c0859e2de832b71555b42a3630103a3 diff --git a/src/Engine/Graphics/Buffer.cpp b/src/Engine/Graphics/Buffer.cpp index d78ed10..e0fec8e 100644 --- a/src/Engine/Graphics/Buffer.cpp +++ b/src/Engine/Graphics/Buffer.cpp @@ -1,5 +1,4 @@ #include "Buffer.h" -#include "Buffer.h" using namespace Seele; using namespace Seele::Gfx; @@ -42,6 +41,7 @@ IndexBuffer::IndexBuffer(QueueFamilyMapping mapping, uint64 size, Gfx::SeIndexTy IndexBuffer::~IndexBuffer() { } + UniformBuffer::UniformBuffer(QueueFamilyMapping mapping, const DataSource& sourceData) : Buffer(mapping, sourceData.owner) {} diff --git a/src/Engine/Graphics/Buffer.h b/src/Engine/Graphics/Buffer.h index 001ed9a..245ae54 100644 --- a/src/Engine/Graphics/Buffer.h +++ b/src/Engine/Graphics/Buffer.h @@ -1,5 +1,6 @@ #pragma once #include "Resources.h" +#include "Initializer.h" namespace Seele { namespace Gfx { diff --git a/src/Engine/Graphics/CMakeLists.txt b/src/Engine/Graphics/CMakeLists.txt index 5fdd7c2..0ac77b0 100644 --- a/src/Engine/Graphics/CMakeLists.txt +++ b/src/Engine/Graphics/CMakeLists.txt @@ -14,10 +14,13 @@ target_sources(Engine Initializer.h Mesh.h Mesh.cpp + MeshData.h Meshlet.h Meshlet.cpp Pipeline.h Pipeline.cpp + RayTracing.h + RayTracing.cpp RenderTarget.h RenderTarget.cpp Resources.h @@ -47,7 +50,9 @@ target_sources(Engine Initializer.h Mesh.h Meshlet.h + MeshData.h Pipeline.h + RayTracing.h RenderTarget.h Resources.h Shader.h diff --git a/src/Engine/Graphics/Descriptor.h b/src/Engine/Graphics/Descriptor.h index bed9a11..5b4ae49 100644 --- a/src/Engine/Graphics/Descriptor.h +++ b/src/Engine/Graphics/Descriptor.h @@ -1,7 +1,7 @@ #pragma once #include "Enums.h" #include "Resources.h" -#include +#include "Initializer.h" namespace Seele { namespace Gfx { @@ -19,17 +19,19 @@ DECLARE_REF(DescriptorPool) DECLARE_REF(DescriptorSet) class DescriptorLayout { public: - DescriptorLayout(const std::string& name); - DescriptorLayout(const DescriptorLayout& other); - DescriptorLayout& operator=(const DescriptorLayout& other); + 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& getBindings() const { return descriptorBindings; } + constexpr const Array &getBindings() const { + return descriptorBindings; + } constexpr uint32 getHash() const { return hash; } - constexpr const std::string& getName() const { return name; } + constexpr const std::string &getName() const { return name; } protected: Array descriptorBindings; @@ -61,40 +63,48 @@ public: 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 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 texture) = 0; + virtual void updateTexture(uint32 binding, PTexture texture, + PSampler samplerState = nullptr) = 0; + virtual void updateTextureArray(uint32_t binding, + Array texture) = 0; bool operator<(PDescriptorSet other); constexpr PDescriptorLayout getLayout() const { return layout; } - constexpr const std::string& getName() const { return layout->getName(); } + constexpr const std::string &getName() const { return layout->getName(); } protected: PDescriptorLayout layout; }; DEFINE_REF(DescriptorSet) +DECLARE_REF(PipelineLayout) class PipelineLayout { public: - PipelineLayout(const std::string& name); - PipelineLayout(const std::string& name, PPipelineLayout baseLayout); + 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); + void addPushConstants(const SePushConstantRange &pushConstants); constexpr uint32 getHash() const { return layoutHash; } - constexpr const Map& getLayouts() const { return descriptorSetLayouts; } - constexpr uint32 findParameter(const std::string& param) const { return parameterMapping[param]; } - void addMapping(Map mapping); - constexpr std::string getName() const {return name;}; + constexpr const Map &getLayouts() const { + return descriptorSetLayouts; + } + constexpr uint32 findParameter(const std::string ¶m) const { + return parameterMapping[param]; + } + void addMapping(Map mapping); + constexpr std::string getName() const { return name; }; protected: uint32 layoutHash = 0; Map descriptorSetLayouts; - Map parameterMapping; + Map parameterMapping; Array pushConstants; - std::string name; + std::string name; }; DEFINE_REF(PipelineLayout) } // namespace Gfx diff --git a/src/Engine/Graphics/Graphics.h b/src/Engine/Graphics/Graphics.h index 1e96041..94bfc13 100644 --- a/src/Engine/Graphics/Graphics.h +++ b/src/Engine/Graphics/Graphics.h @@ -31,6 +31,8 @@ DECLARE_REF(GraphicsPipeline) DECLARE_REF(ComputePipeline) DECLARE_REF(RenderCommand) DECLARE_REF(ComputeCommand) +DECLARE_REF(BottomLevelAS) +DECLARE_REF(TopLevelAS) class Graphics { public: @@ -88,6 +90,10 @@ public: virtual void resolveTexture(Gfx::PTexture source, Gfx::PTexture destination) = 0; bool supportMeshShading() const { return meshShadingEnabled; } + + // Ray Tracing + virtual OBottomLevelAS createBottomLevelAccelerationStructure(const BottomLevelASCreateInfo& createInfo) = 0; + virtual OTopLevelAS createTopLevelAccelerationStructure(const TopLevelASCreateInfo& createInfo) = 0; protected: QueueFamilyMapping queueMapping; OShaderCompiler shaderCompiler; diff --git a/src/Engine/Graphics/Initializer.h b/src/Engine/Graphics/Initializer.h index b8778dc..2d61e4e 100644 --- a/src/Engine/Graphics/Initializer.h +++ b/src/Engine/Graphics/Initializer.h @@ -2,6 +2,8 @@ #include "Enums.h" #include "Containers/Map.h" #include "Math/Math.h" +#include "MinimalEngine.h" +#include "MeshData.h" namespace Seele { @@ -113,6 +115,7 @@ namespace Seele DataSource sourceData = DataSource(); uint64 numElements = 1; uint8 dynamic = 0; + uint8 vertexBuffer = 0; std::string name = "Unnamed"; }; DECLARE_NAME_REF(Gfx, PipelineLayout) @@ -144,6 +147,7 @@ namespace Seele Array bindings; Array attributes; }; + DECLARE_REF(MaterialInstance) namespace Gfx { struct SePushConstantRange @@ -244,5 +248,19 @@ namespace Seele 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 + { + + }; } // namespace Gfx } // namespace Seele diff --git a/src/Engine/Graphics/MeshData.h b/src/Engine/Graphics/MeshData.h new file mode 100644 index 0000000..7181e1d --- /dev/null +++ b/src/Engine/Graphics/MeshData.h @@ -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; +}; +} \ No newline at end of file diff --git a/src/Engine/Graphics/RayTracing.cpp b/src/Engine/Graphics/RayTracing.cpp new file mode 100644 index 0000000..f542472 --- /dev/null +++ b/src/Engine/Graphics/RayTracing.cpp @@ -0,0 +1,15 @@ +#include "RayTracing.h" + +using namespace Seele::Gfx; + +BottomLevelAS::BottomLevelAS() +{} + +BottomLevelAS::~BottomLevelAS() +{} + +TopLevelAS::TopLevelAS() +{} + +TopLevelAS::~TopLevelAS() +{} \ No newline at end of file diff --git a/src/Engine/Graphics/RayTracing.h b/src/Engine/Graphics/RayTracing.h new file mode 100644 index 0000000..274f140 --- /dev/null +++ b/src/Engine/Graphics/RayTracing.h @@ -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) +} +} \ No newline at end of file diff --git a/src/Engine/Graphics/RenderPass/RayTracingPass.h b/src/Engine/Graphics/RenderPass/RayTracingPass.h index 8bf3431..ed995b3 100644 --- a/src/Engine/Graphics/RenderPass/RayTracingPass.h +++ b/src/Engine/Graphics/RenderPass/RayTracingPass.h @@ -5,6 +5,16 @@ namespace Seele { 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: + }; } \ No newline at end of file diff --git a/src/Engine/Graphics/Resources.h b/src/Engine/Graphics/Resources.h index 7342723..1d167df 100644 --- a/src/Engine/Graphics/Resources.h +++ b/src/Engine/Graphics/Resources.h @@ -2,12 +2,6 @@ #include "Math/Math.h" #include "Enums.h" #include "Containers/Array.h" -#include "Containers/List.h" -#include "Initializer.h" -#include "Descriptor.h" -#include "CRC.h" -#include - #ifndef ENABLE_VALIDATION #define ENABLE_VALIDATION 1 diff --git a/src/Engine/Graphics/StaticMeshVertexData.cpp b/src/Engine/Graphics/StaticMeshVertexData.cpp index e48ff4e..e6ecb3a 100644 --- a/src/Engine/Graphics/StaticMeshVertexData.cpp +++ b/src/Engine/Graphics/StaticMeshVertexData.cpp @@ -201,9 +201,11 @@ void StaticMeshVertexData::resizeBuffers() }, .numElements = verticesAllocated * 3, .dynamic = false, + .vertexBuffer = 1, .name = "Positions", }; positions = graphics->createShaderBuffer(createInfo); + createInfo.vertexBuffer = false; createInfo.name = "Normals"; normals = graphics->createShaderBuffer(createInfo); createInfo.name = "Tangents"; diff --git a/src/Engine/Graphics/VertexData.cpp b/src/Engine/Graphics/VertexData.cpp index 32556e8..34537aa 100644 --- a/src/Engine/Graphics/VertexData.cpp +++ b/src/Engine/Graphics/VertexData.cpp @@ -4,10 +4,9 @@ #include "Material/Material.h" #include "Graphics/Graphics.h" #include "Graphics/Descriptor.h" -#include "Component/Mesh.h" #include "Graphics/Shader.h" #include "Graphics/Mesh.h" -#include "Containers/Set.h" +#include "Material/MaterialInstance.h" using namespace Seele; @@ -114,7 +113,6 @@ void VertexData::createDescriptors() instanceData.clear(); instanceMeshData.clear(); - uint32 numMeshlets = 0; Array cullingOffsets; for (auto &mat : materialData) { @@ -130,7 +128,6 @@ void VertexData::createDescriptors() instanceMeshData.add(instance.instanceMeshData[i]); // instance.numMeshlets += instance.instanceMeshData[i].numMeshlets; // cullingOffsets.add(numMeshlets); - numMeshlets += instance.instanceMeshData[i].numMeshlets; } } } diff --git a/src/Engine/Graphics/VertexData.h b/src/Engine/Graphics/VertexData.h index 50ec11a..a9c548a 100644 --- a/src/Engine/Graphics/VertexData.h +++ b/src/Engine/Graphics/VertexData.h @@ -1,156 +1,135 @@ #pragma once -#include "Graphics/Initializer.h" -#include "Material/MaterialInstance.h" #include "Component/Transform.h" #include "Containers/List.h" +#include "Graphics/Buffer.h" #include "Graphics/Command.h" #include "Graphics/Descriptor.h" -#include "Graphics/Buffer.h" +#include "MeshData.h" #include "Meshlet.h" #include + constexpr uint64 MAX_TEXCOORDS = 8; -namespace Seele -{ - 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; - } +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; } +}; +class VertexData { +public: + struct DrawCallOffsets { + uint32 instanceOffset = 0; }; - class VertexData - { - public: - struct InstanceData - { - 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; - }; - struct MeshletCullingInfo - { - uint64_t cull[256 / 64]; - }; - struct BatchedDrawCall - { - PMaterialInstance materialInstance; - DrawCallOffsets offsets; - Array instanceData; - Array instanceMeshData; - Array cullingOffsets; - }; - struct MaterialData - { - PMaterial material; - Array instances; - }; - void resetMeshData(); - void updateMesh(entt::entity id, uint32 meshIndex, PMesh mesh, Component::Transform &transform); - void createDescriptors(); - void loadMesh(MeshId id, Array indices, Array 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 &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 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; - std::mutex vertexDataLock; - Map meshData; - Map meshOffsets; - Map meshVertexCounts; - Array meshlets; - Array primitiveIndices; - Array vertexIndices; - Array indices; - - struct MeshMapping - { - entt::entity id; - uint32 meshId; - auto operator<=>(const MeshMapping& other) const = default; - }; - static Map 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 + struct MeshletCullingInfo { + uint64_t cull[256 / 64]; + }; + struct BatchedDrawCall { + PMaterialInstance materialInstance; + DrawCallOffsets offsets; Array instanceData; - Gfx::OShaderBuffer instanceBuffer; Array instanceMeshData; - Gfx::OShaderBuffer instanceMeshDataBuffer; - Gfx::PDescriptorSet descriptorSet; - uint64 idCounter; - uint64 head; - uint64 verticesAllocated; - bool dirty; + Array cullingOffsets; }; -} + struct MaterialData { + PMaterial material; + Array instances; + }; + void resetMeshData(); + void updateMesh(entt::entity id, uint32 meshIndex, PMesh mesh, + Component::Transform &transform); + void createDescriptors(); + void loadMesh(MeshId id, Array indices, Array 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 &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 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; + std::mutex vertexDataLock; + Map meshData; + Map meshOffsets; + Map meshVertexCounts; + Array meshlets; + Array primitiveIndices; + Array vertexIndices; + Array indices; + + struct MeshMapping { + entt::entity id; + uint32 meshId; + auto operator<=>(const MeshMapping &other) const = default; + }; + static Map 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; + Gfx::OShaderBuffer instanceBuffer; + Array instanceMeshData; + Gfx::OShaderBuffer instanceMeshDataBuffer; + Gfx::PDescriptorSet descriptorSet; + uint64 idCounter; + uint64 head; + uint64 verticesAllocated; + bool dirty; +}; +} // namespace Seele diff --git a/src/Engine/Graphics/Vulkan/Buffer.cpp b/src/Engine/Graphics/Vulkan/Buffer.cpp index bd83e0a..59a6c42 100644 --- a/src/Engine/Graphics/Vulkan/Buffer.cpp +++ b/src/Engine/Graphics/Vulkan/Buffer.cpp @@ -1,5 +1,7 @@ #include "Buffer.h" #include "Command.h" +#include "Enums.h" +#include using namespace Seele; using namespace Seele::Vulkan; @@ -7,20 +9,17 @@ using namespace Seele::Vulkan; BufferAllocation::BufferAllocation(PGraphics graphics) : CommandBoundResource(graphics) {} -BufferAllocation::~BufferAllocation() -{ - if (buffer != VK_NULL_HANDLE) - { - vmaDestroyBuffer(graphics->getAllocator(), buffer, allocation); - } +BufferAllocation::~BufferAllocation() { + if (buffer != VK_NULL_HANDLE) { + vmaDestroyBuffer(graphics->getAllocator(), buffer, allocation); + } } -struct PendingBuffer -{ - OBufferAllocation allocation; - uint64 offset; - Gfx::QueueType prevQueue; - bool writeOnly; +struct PendingBuffer { + OBufferAllocation allocation; + uint64 offset; + Gfx::QueueType prevQueue; + bool writeOnly; }; static Map pendingBuffers; @@ -28,364 +27,335 @@ static Map pendingBuffers; 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])); - } +Buffer::~Buffer() { + 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::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); + 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; + 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"); - } + 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); + } else { + assert(false); + } + pendingBuffers[this] = std::move(pending); - assert(data); - return data; + 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(); +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(); - 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); + 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); + } } -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; - } - if (preserveContents) - { - copyBuffer(currentBuffer, i); - } - currentBuffer = i; - return; +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; } - createBuffer(size); - if (preserveContents) - { - copyBuffer(currentBuffer, buffers.size() - 1); + 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; } - currentBuffer = buffers.size() - 1; + if (preserveContents) { + copyBuffer(currentBuffer, i); + } + currentBuffer = i; + return; + } + createBuffer(size); + if (preserveContents) { + copyBuffer(currentBuffer, buffers.size() - 1); + } + currentBuffer = buffers.size() - 1; } -void Buffer::createBuffer(uint64 size) -{ - VkBufferCreateInfo info = { - .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, +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, .pNext = nullptr, - .size = size, - .usage = usage, - .sharingMode = VK_SHARING_MODE_EXCLUSIVE, + .buffer = buffers.back()->buffer, }; - 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); - 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); - } + 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); +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); } UniformBuffer::UniformBuffer(PGraphics graphics, @@ -393,134 +363,121 @@ UniformBuffer::UniformBuffer(PGraphics graphics, : 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(); - } + 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::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::rotateBuffer(uint64 size) { + Vulkan::Buffer::rotateBuffer(size); } -void UniformBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner) -{ - Gfx::QueueOwnedResource::transferOwnership(newOwner); +void UniformBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner) { + Gfx::QueueOwnedResource::transferOwnership(newOwner); } -void UniformBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) -{ - Vulkan::Buffer::executeOwnershipBarrier(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); + VkPipelineStageFlags dstStage) { + Vulkan::Buffer::executePipelineBarrier(srcAccess, srcStage, dstAccess, + dstStage); } -VkAccessFlags UniformBuffer::getSourceAccessMask() -{ - return VK_ACCESS_MEMORY_WRITE_BIT; +VkAccessFlags UniformBuffer::getSourceAccessMask() { + return VK_ACCESS_MEMORY_WRITE_BIT; } -VkAccessFlags UniformBuffer::getDestAccessMask() -{ - return VK_ACCESS_UNIFORM_READ_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, 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(); - } + 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); +void ShaderBuffer::clear() { + 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, - VkPipelineStageFlags dstStage) -{ - Vulkan::Buffer::executePipelineBarrier(srcAccess, srcStage, dstAccess, - dstStage); + VkPipelineStageFlags 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, @@ -529,113 +486,99 @@ VertexBuffer::VertexBuffer(PGraphics graphics, 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(); - } + 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::updateRegion(DataSource update) { + void *data = mapRegion(update.offset, update.size); + std::memcpy(data, update.data, update.size); + unmap(); } -void VertexBuffer::download(Array &buffer) -{ - void *data = map(false); - buffer.resize(getSize()); - std::memcpy(buffer.data(), data, getSize()); - unmap(); +void VertexBuffer::download(Array &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::requestOwnershipTransfer(Gfx::QueueType newOwner) { + Gfx::QueueOwnedResource::transferOwnership(newOwner); } -void VertexBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) -{ - Vulkan::Buffer::executeOwnershipBarrier(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); + VkPipelineStageFlags dstStage) { + Vulkan::Buffer::executePipelineBarrier(srcAccess, srcStage, dstAccess, + dstStage); } -VkAccessFlags VertexBuffer::getSourceAccessMask() -{ - return VK_ACCESS_MEMORY_WRITE_BIT; +VkAccessFlags VertexBuffer::getSourceAccessMask() { + return VK_ACCESS_MEMORY_WRITE_BIT; } -VkAccessFlags VertexBuffer::getDestAccessMask() -{ - return VK_ACCESS_VERTEX_ATTRIBUTE_READ_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, currentOwner, false, - sourceData.name) -{ - if (sourceData.sourceData.data != nullptr) - { - void *data = map(); - std::memcpy(data, sourceData.sourceData.data, sourceData.sourceData.size); - unmap(); - } + 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 &buffer) -{ - void *data = map(false); - buffer.resize(getSize()); - std::memcpy(buffer.data(), data, getSize()); - unmap(); +void IndexBuffer::download(Array &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, - VkPipelineStageFlags dstStage) -{ - Vulkan::Buffer::executePipelineBarrier(srcAccess, srcStage, dstAccess, - dstStage); + VkPipelineStageFlags 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; } \ No newline at end of file diff --git a/src/Engine/Graphics/Vulkan/Buffer.h b/src/Engine/Graphics/Vulkan/Buffer.h index d3fc91d..92539fc 100644 --- a/src/Engine/Graphics/Vulkan/Buffer.h +++ b/src/Engine/Graphics/Vulkan/Buffer.h @@ -16,6 +16,7 @@ public: VmaAllocationInfo info = VmaAllocationInfo(); VkMemoryPropertyFlags properties = 0; uint64 size = 0; + VkDeviceAddress deviceAddress; }; DEFINE_REF(BufferAllocation); class Buffer { @@ -24,6 +25,9 @@ public: 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); @@ -130,7 +134,8 @@ public: virtual ~ShaderBuffer(); virtual void 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 unmap() override; diff --git a/src/Engine/Graphics/Vulkan/CMakeLists.txt b/src/Engine/Graphics/Vulkan/CMakeLists.txt index de441bb..3dd3455 100644 --- a/src/Engine/Graphics/Vulkan/CMakeLists.txt +++ b/src/Engine/Graphics/Vulkan/CMakeLists.txt @@ -22,6 +22,8 @@ target_sources(Engine PipelineCache.cpp Queue.h Queue.cpp + RayTracing.h + RayTracing.cpp RenderPass.h RenderPass.cpp Resources.h @@ -47,6 +49,7 @@ target_sources(Engine Pipeline.h PipelineCache.h Queue.h + RayTracing.h RenderPass.h Resources.h Shader.h diff --git a/src/Engine/Graphics/Vulkan/Descriptor.cpp b/src/Engine/Graphics/Vulkan/Descriptor.cpp index 7776452..c21fd69 100644 --- a/src/Engine/Graphics/Vulkan/Descriptor.cpp +++ b/src/Engine/Graphics/Vulkan/Descriptor.cpp @@ -3,6 +3,7 @@ #include "Command.h" #include "Graphics.h" #include "Texture.h" +#include "CRC.h" using namespace Seele; using namespace Seele::Vulkan; diff --git a/src/Engine/Graphics/Vulkan/Framebuffer.cpp b/src/Engine/Graphics/Vulkan/Framebuffer.cpp index f779e2d..9f5791b 100644 --- a/src/Engine/Graphics/Vulkan/Framebuffer.cpp +++ b/src/Engine/Graphics/Vulkan/Framebuffer.cpp @@ -3,6 +3,7 @@ #include "RenderPass.h" #include "Graphics.h" #include "Texture.h" +#include "CRC.h" using namespace Seele; using namespace Seele::Vulkan; diff --git a/src/Engine/Graphics/Vulkan/Graphics.cpp b/src/Engine/Graphics/Vulkan/Graphics.cpp index 08eb0e9..2c08587 100644 --- a/src/Engine/Graphics/Vulkan/Graphics.cpp +++ b/src/Engine/Graphics/Vulkan/Graphics.cpp @@ -3,6 +3,8 @@ #include "Allocator.h" #include "Buffer.h" #include "Graphics/Enums.h" +#include "Graphics/Graphics.h" +#include "Graphics/Initializer.h" #include "PipelineCache.h" #include "Command.h" #include "Descriptor.h" @@ -10,6 +12,7 @@ #include "RenderPass.h" #include "Framebuffer.h" #include "Shader.h" +#include "RayTracing.h" #include #include #include @@ -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); } -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) @@ -395,6 +408,7 @@ void Graphics::initInstance(GraphicsInitializer initInfo) assert(glfwVulkanSupported()); VkApplicationInfo appInfo = { .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO, + .pNext = nullptr, .pApplicationName = initInfo.applicationName, .applicationVersion = VK_MAKE_VERSION(0, 0, 1), .pEngineName = initInfo.engineName, @@ -415,6 +429,7 @@ void Graphics::initInstance(GraphicsInitializer initInfo) #endif VkInstanceCreateInfo info = { .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, + .pNext = nullptr, #if __APPLE__ .flags = VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR, #endif @@ -562,6 +577,7 @@ void Graphics::createDevice(GraphicsInitializer initializer) .flags = 0, .queueFamilyIndex = familyIndex, .queueCount = numQueuesForFamily, + .pQueuePriorities = nullptr, }; numPriorities += numQueuesForFamily; queueInfos.add(info); diff --git a/src/Engine/Graphics/Vulkan/Graphics.h b/src/Engine/Graphics/Vulkan/Graphics.h index afa33f1..9b9e7e7 100644 --- a/src/Engine/Graphics/Vulkan/Graphics.h +++ b/src/Engine/Graphics/Vulkan/Graphics.h @@ -1,5 +1,4 @@ #pragma once -#include "Enums.h" #include "Graphics/Graphics.h" #include @@ -70,6 +69,10 @@ public: 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 vkCmdDrawMeshTasksIndirectEXT(VkCommandBuffer handle, VkBuffer buffer, uint64 offset, uint32 drawCount, uint32 stride); void vkSetDebugUtilsObjectNameEXT(VkDebugUtilsObjectNameInfoEXT* info); diff --git a/src/Engine/Graphics/Vulkan/Queue.cpp b/src/Engine/Graphics/Vulkan/Queue.cpp index 07c5288..3fc51c3 100644 --- a/src/Engine/Graphics/Vulkan/Queue.cpp +++ b/src/Engine/Graphics/Vulkan/Queue.cpp @@ -2,6 +2,7 @@ #include "Graphics.h" #include "Allocator.h" #include "Command.h" +#include "Enums.h" using namespace Seele; using namespace Seele::Vulkan; diff --git a/src/Engine/Graphics/Vulkan/RayTracing.cpp b/src/Engine/Graphics/Vulkan/RayTracing.cpp new file mode 100644 index 0000000..8f7d3da --- /dev/null +++ b/src/Engine/Graphics/Vulkan/RayTracing.cpp @@ -0,0 +1,67 @@ +#include "RayTracing.h" +#include "Buffer.h" +#include "Graphics/Initializer.h" +#include + +using namespace Seele::Vulkan; + +BottomLevelAS::BottomLevelAS(PGraphics graphics, const Gfx::BottomLevelASCreateInfo& createInfo) +{ + VkDeviceOrHostAddressConstKHR vertexDataDeviceAddress = { + .deviceAddress = createInfo.positionBuffer.cast()->getDeviceAddress() + createInfo.verticesOffset, + }; + VkDeviceOrHostAddressConstKHR indexDataDeviceAddress = { + .deviceAddress = createInfo.indexBuffer.cast()->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() +{ + +} \ No newline at end of file diff --git a/src/Engine/Graphics/Vulkan/RayTracing.h b/src/Engine/Graphics/Vulkan/RayTracing.h new file mode 100644 index 0000000..fad71b0 --- /dev/null +++ b/src/Engine/Graphics/Vulkan/RayTracing.h @@ -0,0 +1,32 @@ +#pragma once +#include "Graphics/Initializer.h" +#include "Graphics.h" +#include "Graphics/RayTracing.h" +#include + +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) +} +} \ No newline at end of file diff --git a/src/Engine/Graphics/Vulkan/RenderPass.cpp b/src/Engine/Graphics/Vulkan/RenderPass.cpp index 38715b4..52736cb 100644 --- a/src/Engine/Graphics/Vulkan/RenderPass.cpp +++ b/src/Engine/Graphics/Vulkan/RenderPass.cpp @@ -4,6 +4,7 @@ #include "Texture.h" #include "Resources.h" #include "Command.h" +#include "CRC.h" using namespace Seele; using namespace Seele::Vulkan; diff --git a/src/Engine/Graphics/Vulkan/Texture.cpp b/src/Engine/Graphics/Vulkan/Texture.cpp index bf1cf22..59c384b 100644 --- a/src/Engine/Graphics/Vulkan/Texture.cpp +++ b/src/Engine/Graphics/Vulkan/Texture.cpp @@ -1,5 +1,6 @@ #include "Texture.h" #include "Command.h" +#include "Enums.h" #include using namespace Seele; diff --git a/src/Engine/Graphics/Window.h b/src/Engine/Graphics/Window.h index ebc6312..e3dcf73 100644 --- a/src/Engine/Graphics/Window.h +++ b/src/Engine/Graphics/Window.h @@ -1,6 +1,7 @@ #pragma once #include "Initializer.h" #include "Texture.h" +#include namespace Seele {