From d7b228d856d10cad5dfc138f02d1f63ab8bbbd71 Mon Sep 17 00:00:00 2001 From: Dynamitos Date: Wed, 10 Apr 2024 08:43:56 +0200 Subject: [PATCH] Basic commandbuffer implementation --- src/Engine/Graphics/Command.h | 4 +- src/Engine/Graphics/Metal/CMakeLists.txt | 2 + src/Engine/Graphics/Metal/Command.h | 88 +++++++++ src/Engine/Graphics/Metal/Command.mm | 172 ++++++++++++++++++ src/Engine/Graphics/Metal/Enums.h | 7 +- src/Engine/Graphics/Metal/Enums.mm | 49 +++++ src/Engine/Graphics/Metal/Graphics.h | 2 + src/Engine/Graphics/Metal/Graphics.mm | 5 +- src/Engine/Graphics/Metal/RenderPass.h | 8 + src/Engine/Graphics/Metal/RenderPass.mm | 61 ++++++- src/Engine/Graphics/Metal/Texture.mm | 2 - src/Engine/Graphics/Metal/Window.h | 11 +- src/Engine/Graphics/Metal/Window.mm | 36 +++- src/Engine/Graphics/RenderPass/BasePass.cpp | 2 +- .../Graphics/RenderPass/DepthPrepass.cpp | 2 +- src/Engine/Graphics/RenderTarget.h | 2 +- src/Engine/Graphics/Vulkan/Command.cpp | 13 +- src/Engine/Graphics/Vulkan/Command.h | 12 +- src/Engine/Graphics/Vulkan/Window.cpp | 2 +- src/Engine/Graphics/Vulkan/Window.h | 2 +- src/Engine/Graphics/Window.h | 2 +- 21 files changed, 435 insertions(+), 49 deletions(-) create mode 100644 src/Engine/Graphics/Metal/Command.h create mode 100644 src/Engine/Graphics/Metal/Command.mm diff --git a/src/Engine/Graphics/Command.h b/src/Engine/Graphics/Command.h index 0d0e3b6..ab6705c 100644 --- a/src/Engine/Graphics/Command.h +++ b/src/Engine/Graphics/Command.h @@ -12,7 +12,6 @@ class RenderCommand public: RenderCommand(); virtual ~RenderCommand(); - virtual bool isReady() = 0; virtual void setViewport(Gfx::PViewport viewport) = 0; virtual void bindPipeline(Gfx::PGraphicsPipeline pipeline) = 0; virtual void bindDescriptor(Gfx::PDescriptorSet set) = 0; @@ -22,7 +21,7 @@ public: virtual void pushConstants(Gfx::PPipelineLayout layout, Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size, const void* data) = 0; virtual void draw(uint32 vertexCount, uint32 instanceCount, int32 firstVertex, uint32 firstInstance) = 0; virtual void drawIndexed(uint32 indexCount, uint32 instanceCount, int32 firstIndex, uint32 vertexOffset, uint32 firstInstance) = 0; - virtual void dispatch(uint32 groupX, uint32 groupY, uint32 groupZ) = 0; + virtual void drawMesh(uint32 groupX, uint32 groupY, uint32 groupZ) = 0; std::string name; }; DEFINE_REF(RenderCommand) @@ -31,7 +30,6 @@ DEFINE_REF(RenderCommand) public: ComputeCommand(); virtual ~ComputeCommand(); - virtual bool isReady() = 0; virtual void bindPipeline(Gfx::PComputePipeline pipeline) = 0; virtual void bindDescriptor(Gfx::PDescriptorSet set) = 0; virtual void bindDescriptor(const Array& sets) = 0; diff --git a/src/Engine/Graphics/Metal/CMakeLists.txt b/src/Engine/Graphics/Metal/CMakeLists.txt index bcc5cdc..68703af 100644 --- a/src/Engine/Graphics/Metal/CMakeLists.txt +++ b/src/Engine/Graphics/Metal/CMakeLists.txt @@ -1,5 +1,7 @@ target_sources(Engine PRIVATE + Command.h + Command.mm Enums.h Enums.mm Graphics.h diff --git a/src/Engine/Graphics/Metal/Command.h b/src/Engine/Graphics/Metal/Command.h new file mode 100644 index 0000000..e37736a --- /dev/null +++ b/src/Engine/Graphics/Metal/Command.h @@ -0,0 +1,88 @@ +#pragma once +#include "Graphics/Command.h" +#include "Metal/MTLComputeCommandEncoder.hpp" +#include "Metal/MTLRenderCommandEncoder.hpp" +#include "MinimalEngine.h" +#include "RenderPass.h" +#include "Resources.h" +#include "Graphics.h" + +namespace Seele { +namespace Metal { +DECLARE_REF(CommandQueue) +DECLARE_REF(ComputeCommand) +DECLARE_REF(RenderCommand) +class Command +{ +public: + Command(PGraphics graphics, PCommandQueue owner); + ~Command(); + void beginRenderPass(PRenderPass renderPass); + void endRenderPass(); + void executeCommands(const Array& commands); + void executeCommands(const Array& commands); +private: + PGraphics graphics; + PCommandQueue owner; + MTL::CommandBuffer* cmdBuffer; + MTL::ParallelRenderCommandEncoder* renderEncoder; + PFence fence; + PSemaphore semaphore; +}; +DEFINE_REF(Command) +class RenderCommand : public Gfx::RenderCommand +{ +public: + RenderCommand(MTL::RenderCommandEncoder* encoder); + virtual ~RenderCommand(); + void end(); + virtual void setViewport(Gfx::PViewport viewport) override; + virtual void bindPipeline(Gfx::PGraphicsPipeline pipeline) override; + virtual void bindDescriptor(Gfx::PDescriptorSet descriptorSet) override; + virtual void bindDescriptor(const Array& descriptorSets) override; + virtual void bindVertexBuffer(const Array& buffers) override; + virtual void bindIndexBuffer(Gfx::PIndexBuffer indexBuffer) override; + virtual void pushConstants(Gfx::PPipelineLayout layout, Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size, const void* data) override; + virtual void draw(uint32 vertexCount, uint32 instanceCount, int32 firstVertex, uint32 firstInstance) override; + virtual void drawIndexed(uint32 indexCount, uint32 instanceCount, int32 firstIndex, uint32 vertexOffset, uint32 firstInstance) override; + virtual void drawMesh(uint32 groupX, uint32 groupY, uint32 groupZ) override; +private: + MTL::RenderCommandEncoder* encoder; +}; +DEFINE_REF(RenderCommand) +class ComputeCommand : public Gfx::ComputeCommand +{ +public: + ComputeCommand(MTL::ComputeCommandEncoder* encoder); + virtual ~ComputeCommand(); + void end(); + virtual void bindPipeline(Gfx::PComputePipeline pipeline) override; + virtual void bindDescriptor(Gfx::PDescriptorSet set) override; + virtual void bindDescriptor(const Array& sets) override; + virtual void pushConstants(Gfx::PPipelineLayout layout, Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size, const void* data) override; + virtual void dispatch(uint32 threadX, uint32 threadY, uint32 threadZ) override; +private: + MTL::ComputeCommandEncoder* encoder; +}; +DEFINE_REF(ComputeCommand) +class CommandQueue +{ +public: + CommandQueue(PGraphics graphics); + ~CommandQueue(); + constexpr MTL::CommandQueue* getHandle() + { + return queue; + } + PCommand getCommands(); + PRenderCommand getRenderCommand(const std::string& name); + PComputeCommand getComputeCommand(const std::string& name); + void submitCommands(PSemaphore signalSemaphore = nullptr); +private: + PGraphics graphics; + MTL::CommandQueue* queue; + Array allocatedCommands; + OCommand activeCommand; +}; +} +} \ No newline at end of file diff --git a/src/Engine/Graphics/Metal/Command.mm b/src/Engine/Graphics/Metal/Command.mm new file mode 100644 index 0000000..5e10ee0 --- /dev/null +++ b/src/Engine/Graphics/Metal/Command.mm @@ -0,0 +1,172 @@ +#include "Command.h" +#include "Metal/MTLComputeCommandEncoder.hpp" +#include "Metal/MTLRenderCommandEncoder.hpp" +#include "Window.h" + +using namespace Seele; +using namespace Seele::Metal; + +Command::Command(PGraphics graphics, PCommandQueue owner) + : graphics(graphics) + , owner(owner) + , cmdBuffer(owner->getHandle()->commandBuffer()) + , renderEncoder(nullptr) +{ +} + +Command::~Command() +{ + cmdBuffer->release(); +} + +void Command::beginRenderPass(PRenderPass renderPass) +{ + renderEncoder = cmdBuffer->parallelRenderCommandEncoder(renderPass->getDescriptor()); +} + +void Command::endRenderPass() +{ + renderEncoder->endEncoding(); +} + +void Command::executeCommands(const Array& commands) +{ + for(auto command : commands) + { + auto cmd = command.cast(); + cmd->end(); + } +} + +void Command::executeCommands(const Array& commands) +{ + for(auto command : commands) + { + auto cmd = command.cast(); + cmd->end(); + } +} + +RenderCommand::RenderCommand(MTL::RenderCommandEncoder* encoder) + : encoder(encoder) +{} + +RenderCommand::~RenderCommand() +{ + encoder->release(); +} + +void RenderCommand::end() +{ + encoder->endEncoding(); +} + +void RenderCommand::setViewport(Gfx::PViewport viewport) +{ + encoder->setViewport(viewport.cast()->getHandle()); +} + +void RenderCommand::bindPipeline(Gfx::PGraphicsPipeline pipeline) +{ + encoder->setRenderPipelineState(pipeline.cast()->getState()); +} + +void RenderCommand::bindDescriptor(Gfx::PDescriptorSet descriptorSet) +{ + encoder->set????? +} + +void RenderCommand::bindDescriptor(const Array& descriptorSets) +{ + encoder->set????? + +} + +void RenderCommand::bindVertexBuffer(const Array& buffers) +{ + encoder->setVertexBuffers(); +} + +void RenderCommand::bindIndexBuffer(Gfx::PIndexBuffer indexBuffer) +{ + encoder->setObjectBuffer(??, NS::UInteger offset, NS::UInteger index) +} + +void RenderCommand::pushConstants(Gfx::PPipelineLayout layout, Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size, const void* data) +{ +??? +} + +void RenderCommand::draw(uint32 vertexCount, uint32 instanceCount, int32 firstVertex, uint32 firstInstance) +{ + encoder->drawPrimitives(???, firstVertex, vertexCount, instanceCount, firstInstance); +} + +void RenderCommand::drawIndexed(uint32 indexCount, uint32 instanceCount, int32 firstIndex, uint32 vertexOffset, uint32 firstInstance) +{ + encoder->drawIndexedPrimitives(???, indexCount, indexbuffer->getType(), indexBuffer->getBuffer(), firstIndex, instanceCount, vertexOffset, firstInstance); +} + +void RenderCommand::drawMesh(uint32 groupX, uint32 groupY, uint32 groupZ) +{ + encoder->drawMeshThreads(MTL::Size threadsPerGrid, MTL::Size threadsPerObjectThreadgroup, MTL::Size threadsPerMeshThreadgroup) +} + +ComputeCommand::ComputeCommand(MTL::ComputeCommandEncoder* encoder) + : encoder(encoder) +{} + +ComputeCommand::~ComputeCommand() +{ + encoder->release(); +} + +void ComputeCommand::end() +{ + encoder->endEncoding(); +} + +void ComputeCommand::bindPipeline(Gfx::PComputePipeline pipeline) +{ + encoder->setComputePipelineState(pipeline); +} + +void ComputeCommand::bindDescriptor(Gfx::PDescriptorSet set) +{ + encoder->set??? +} + +void ComputeCommand::bindDescriptor(const Array& sets) +{ + encoder->set??? +} + +void ComputeCommand::pushConstants(Gfx::PPipelineLayout layout, Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size, const void* data) +{ + ??? +} + +void ComputeCommand::dispatch(uint32 threadX, uint32 threadY, uint32 threadZ) +{ + encoder->dispatchThreadgroups(???); +} + +CommandQueue::CommandQueue(PGraphics graphics) + : graphics(graphics) +{ + queue = graphics->getDevice()->newCommandQueue(); +} + +CommandQueue::~CommandQueue() +{ + queue->release(); +} + +PRenderCommand CommandQueue::getRenderCommand(const std::string& name) +{ +} + +PComputeCommand CommandQueue::getComputeCommand(const std::string& name) +{ + +} diff --git a/src/Engine/Graphics/Metal/Enums.h b/src/Engine/Graphics/Metal/Enums.h index 7696839..ec7492a 100644 --- a/src/Engine/Graphics/Metal/Enums.h +++ b/src/Engine/Graphics/Metal/Enums.h @@ -1,7 +1,6 @@ #pragma once #include "Graphics/Enums.h" -#include "Metal/MTLPixelFormat.hpp" -#include "Metal/MTLTexture.hpp" +#include "Resources.h" namespace Seele { @@ -9,5 +8,9 @@ namespace Metal { MTL::PixelFormat cast(Gfx::SeFormat format); Gfx::SeFormat cast(MTL::PixelFormat format); +MTL::LoadAction cast(Gfx::SeAttachmentLoadOp loadOp); +Gfx::SeAttachmentLoadOp cast(MTL::LoadAction loadOp); +MTL::StoreAction cast(Gfx::SeAttachmentStoreOp storeOp); +Gfx::SeAttachmentStoreOp cast(MTL::StoreAction storeOp); } } \ No newline at end of file diff --git a/src/Engine/Graphics/Metal/Enums.mm b/src/Engine/Graphics/Metal/Enums.mm index e8fde19..7e67260 100644 --- a/src/Engine/Graphics/Metal/Enums.mm +++ b/src/Engine/Graphics/Metal/Enums.mm @@ -1,4 +1,5 @@ #include "Enums.h" +#include "Graphics/Enums.h" #include using namespace Seele; @@ -538,3 +539,51 @@ Gfx::SeFormat Seele::Metal::cast(MTL::PixelFormat format) { throw std::logic_error("Not implemented"); } } + +MTL::LoadAction Seele::Metal::cast(Gfx::SeAttachmentLoadOp loadOp) { + switch (loadOp) { + case Seele::Gfx::SE_ATTACHMENT_LOAD_OP_LOAD: + return MTL::LoadActionLoad; + case Seele::Gfx::SE_ATTACHMENT_LOAD_OP_CLEAR: + return MTL::LoadActionClear; + case Seele::Gfx::SE_ATTACHMENT_LOAD_OP_DONT_CARE: + return MTL::LoadActionDontCare; + default: + throw std::logic_error("Not implemented"); + } +} + +Gfx::SeAttachmentLoadOp Seele::Metal::cast(MTL::LoadAction loadOp) { + switch (loadOp) { + case MTL::LoadActionDontCare: + return Gfx::SE_ATTACHMENT_LOAD_OP_DONT_CARE; + case MTL::LoadActionLoad: + return Gfx::SE_ATTACHMENT_LOAD_OP_LOAD; + case MTL::LoadActionClear: + return Gfx::SE_ATTACHMENT_LOAD_OP_CLEAR; + default: + throw std::logic_error("Not implemented"); + } +} + +MTL::StoreAction Seele::Metal::cast(Gfx::SeAttachmentStoreOp storeOp) { + switch (storeOp) { + case Seele::Gfx::SE_ATTACHMENT_STORE_OP_STORE: + return MTL::StoreActionStore; + case Seele::Gfx::SE_ATTACHMENT_STORE_OP_DONT_CARE: + return MTL::StoreActionDontCare; + default: + throw std::logic_error("Not implemented"); + } +} + +Gfx::SeAttachmentStoreOp Seele::Metal::cast(MTL::StoreAction storeOp) { + switch (storeOp) { + case MTL::StoreActionDontCare: + return Gfx::SE_ATTACHMENT_STORE_OP_DONT_CARE; + case MTL::StoreActionStore: + return Gfx::SE_ATTACHMENT_STORE_OP_STORE; + default: + throw std::logic_error("Not implemented"); + } +} diff --git a/src/Engine/Graphics/Metal/Graphics.h b/src/Engine/Graphics/Metal/Graphics.h index ce7b236..e792ec2 100644 --- a/src/Engine/Graphics/Metal/Graphics.h +++ b/src/Engine/Graphics/Metal/Graphics.h @@ -1,4 +1,5 @@ #pragma once +#include "Metal/MTLRenderCommandEncoder.hpp" #include "Metal/Metal.hpp" #include "Graphics/Graphics.h" @@ -57,6 +58,7 @@ protected: MTL::Device* device; MTL::Library* library; MTL::CommandQueue* queue; + MTL::RenderCommandEncoder* encoder; }; DEFINE_REF(Graphics) } // namespace Metal diff --git a/src/Engine/Graphics/Metal/Graphics.mm b/src/Engine/Graphics/Metal/Graphics.mm index 7e159c5..d3d7149 100644 --- a/src/Engine/Graphics/Metal/Graphics.mm +++ b/src/Engine/Graphics/Metal/Graphics.mm @@ -1,4 +1,5 @@ #include "Graphics.h" +#include "Graphics/Metal/RenderPass.h" #include "Window.h" using namespace Seele; @@ -34,13 +35,13 @@ Gfx::OViewport Graphics::createViewport(Gfx::PWindow owner, const ViewportCreate Gfx::ORenderPass Graphics::createRenderPass(Gfx::RenderTargetLayout layout, Array dependencies, Gfx::PViewport renderArea) { - + return new RenderPass(this, layout, dependencies, renderArea); } void Graphics::beginRenderPass(Gfx::PRenderPass renderPass) { - } + void Graphics::endRenderPass() { diff --git a/src/Engine/Graphics/Metal/RenderPass.h b/src/Engine/Graphics/Metal/RenderPass.h index de0de3b..98c9fc1 100644 --- a/src/Engine/Graphics/Metal/RenderPass.h +++ b/src/Engine/Graphics/Metal/RenderPass.h @@ -1,6 +1,7 @@ #pragma once #include "Graphics/RenderTarget.h" #include "Graphics.h" +#include "Metal/MTLRenderPass.hpp" namespace Seele { @@ -11,9 +12,16 @@ class RenderPass : public Gfx::RenderPass public: RenderPass(PGraphics graphics, Gfx::RenderTargetLayout layout, Array dependencies, Gfx::PViewport viewport); virtual ~RenderPass(); + MTL::RenderPassDescriptor* getDescriptor() const + { + return renderPass; + } private: PGraphics graphics; Gfx::PViewport viewport; + MTL::RenderPassDescriptor* renderPass; + MTL::RenderPassDepthAttachmentDescriptor* depth; + MTL::RenderPassStencilAttachmentDescriptor* stencil; }; DEFINE_REF(RenderPass) } // namespace Metal diff --git a/src/Engine/Graphics/Metal/RenderPass.mm b/src/Engine/Graphics/Metal/RenderPass.mm index b8a1090..c0cf747 100644 --- a/src/Engine/Graphics/Metal/RenderPass.mm +++ b/src/Engine/Graphics/Metal/RenderPass.mm @@ -1,17 +1,62 @@ #include "RenderPass.h" +#include "Enums.h" #include "Graphics/RenderTarget.h" #include "Metal/MTLRenderPass.hpp" +#include "Texture.h" using namespace Seele; using namespace Seele::Metal; -RenderPass::RenderPass(PGraphics graphics, Gfx::RenderTargetLayout layout, Array dependencies, Gfx::PViewport viewport) - : Gfx::RenderPass(layout, dependencies) - , graphics(graphics) - , viewport(viewport) -{ - +RenderPass::RenderPass(PGraphics graphics, Gfx::RenderTargetLayout layout, + Array dependencies, + Gfx::PViewport viewport) + : Gfx::RenderPass(layout, dependencies), graphics(graphics), + viewport(viewport) { + renderPass = MTL::RenderPassDescriptor::alloc()->init(); + renderPass->setRenderTargetArrayLength(1); + renderPass->setRenderTargetWidth(viewport->getWidth()); + renderPass->setRenderTargetHeight(viewport->getHeight()); + renderPass->setDefaultRasterSampleCount(viewport->getSamples()); + + for (size_t i = 0; i < layout.colorAttachments.size(); ++i) { + const auto &color = layout.colorAttachments[i]; + MTL::RenderPassColorAttachmentDescriptor *desc = + renderPass->colorAttachments()->object(i); + desc->setClearColor(MTL::ClearColor( + color.clear.color.float32[0], color.clear.color.float32[1], + color.clear.color.float32[2], color.clear.color.float32[3])); + desc->setLoadAction(cast(color.getLoadOp())); + desc->setStoreAction(cast(color.getStoreOp())); + desc->setLevel(0); + desc->setTexture(color.getTexture().cast()->getTexture()); + if (!layout.resolveAttachments.empty()) { + const auto &resolve = layout.resolveAttachments[i]; + desc->setResolveLevel(0); + desc->setStoreAction(MTL::StoreActionStoreAndMultisampleResolve); + desc->setResolveTexture( + resolve.getTexture().cast()->getTexture()); + } + colorAttachments->setObject(desc, i); + } + if (layout.depthAttachment.getTexture() != nullptr) { + depth = MTL::RenderPassDepthAttachmentDescriptor::alloc()->init(); + depth->setClearDepth(layout.depthAttachment.clear.depthStencil.depth); + depth->setLoadAction(cast(layout.depthAttachment.getLoadOp())); + depth->setStoreAction(cast(layout.depthAttachment.getStoreOp())); + depth->setTexture( + layout.depthAttachment.getTexture().cast()->getTexture()); + if (layout.depthResolveAttachment.getTexture() != nullptr) { + depth->setResolveTexture(layout.depthResolveAttachment.getTexture() + .cast() + ->getTexture()); + depth->setStoreAction(MTL::StoreActionStoreAndMultisampleResolve); + } + renderPass->setDepthAttachment(depth); + } + // TODO: stencil } -RenderPass::~RenderPass() -{ +RenderPass::~RenderPass() { + depth->release(); + stencil->release(); + renderPass->release(); } \ No newline at end of file diff --git a/src/Engine/Graphics/Metal/Texture.mm b/src/Engine/Graphics/Metal/Texture.mm index 2c211e6..3b09abe 100644 --- a/src/Engine/Graphics/Metal/Texture.mm +++ b/src/Engine/Graphics/Metal/Texture.mm @@ -3,8 +3,6 @@ #include "Graphics/Enums.h" #include "Graphics/Initializer.h" #include "Graphics/Metal/Graphics.h" -#include "Metal/MTLCommandEncoder.hpp" -#include "Metal/MTLTexture.hpp" using namespace Seele; using namespace Seele::Metal; diff --git a/src/Engine/Graphics/Metal/Window.h b/src/Engine/Graphics/Metal/Window.h index 286ad8f..e2eeb76 100644 --- a/src/Engine/Graphics/Metal/Window.h +++ b/src/Engine/Graphics/Metal/Window.h @@ -1,7 +1,9 @@ #pragma once #include "Graphics.h" #include "Graphics/Window.h" +#include "Metal/MTLRenderCommandEncoder.hpp" #include "Resources.h" +#include "Texture.h" #define GLFW_INCLUDE_NONE #include @@ -24,7 +26,7 @@ public: virtual void pollInput() override; virtual void beginFrame() override; virtual void endFrame() override; - virtual Gfx::PTexture2D getBackBuffer() override; + virtual Gfx::PTexture2D getBackBuffer() const override; virtual void onWindowCloseEvent() override; virtual void setKeyCallback(std::function callback) override; virtual void setMouseMoveCallback(std::function callback) override; @@ -48,6 +50,7 @@ private: NSWindow* metalWindow; CAMetalLayer* metalLayer; CA::MetalDrawable* drawable; + OTexture2D backBuffer; std::function keyCallback; std::function mouseMoveCallback; @@ -63,10 +66,14 @@ class Viewport : public Gfx::Viewport public: Viewport(PWindow owner, const ViewportCreateInfo& createInfo); virtual ~Viewport(); + constexpr MTL::Viewport getHandle() const + { + return viewport; + } virtual void resize(uint32 newX, uint32 newY); virtual void move(uint32 newOffset, uint32 newOffsetY); private: - Rect viewport; + MTL::Viewport viewport; }; } // namespace Metal } // namespace Seele diff --git a/src/Engine/Graphics/Metal/Window.mm b/src/Engine/Graphics/Metal/Window.mm index 10bb021..9d041fa 100644 --- a/src/Engine/Graphics/Metal/Window.mm +++ b/src/Engine/Graphics/Metal/Window.mm @@ -1,6 +1,9 @@ #include "Window.h" #include "Foundation/NSSharedPtr.hpp" +#include "Graphics/Initializer.h" +#include "Graphics/Metal/Enums.h" #include "Graphics/Texture.h" +#include "Metal/MTLTexture.hpp" using namespace Seele; using namespace Seele::Metal; @@ -98,6 +101,17 @@ void Window::beginFrame() { @autoreleasepool { drawable = (__bridge CA::MetalDrawable*)[metalLayer nextDrawable]; + MTL::Texture* buf = drawable->texture(); + backBuffer = new Texture2D(graphics, TextureCreateInfo { + .width = static_cast(buf->width()), + .height = static_cast(buf->height()), + .depth = static_cast(buf->depth()), + .elements = static_cast(buf->arrayLength()), + .mipLevels = static_cast(buf->mipmapLevelCount()), + .format = cast(buf->pixelFormat()), + .usage = MTL::TextureUsageRenderTarget, + .samples = static_cast(buf->sampleCount()), + }, buf); } } @@ -109,9 +123,9 @@ void Window::onWindowCloseEvent() { } -Gfx::PTexture2D Window::getBackBuffer() +Gfx::PTexture2D Window::getBackBuffer() const { - return nullptr; //drawable->texture() + return PTexture2D(backBuffer); } void Window::setKeyCallback(std::function callback) @@ -193,10 +207,12 @@ void Window::resize(int width, int height) Viewport::Viewport(PWindow owner, const ViewportCreateInfo& createInfo) : Gfx::Viewport(owner, createInfo) { - viewport.size.x = sizeX; - viewport.size.y = sizeY; - viewport.offset.x = offsetX; - viewport.offset.y = offsetY; + viewport.width = sizeX; + viewport.height = sizeY; + viewport.originX = offsetX; + viewport.originY = offsetY; + viewport.znear = 0.0f; + viewport.zfar = 1.0f; } Viewport::~Viewport() @@ -206,12 +222,12 @@ Viewport::~Viewport() void Viewport::resize(uint32 newX, uint32 newY) { - viewport.size.x = newX; - viewport.size.y = newY; + viewport.width = newX; + viewport.height = newY; } void Viewport::move(uint32 newOffset, uint32 newOffsetY) { - viewport.offset.x = newOffset; - viewport.offset.y = newOffsetY; + viewport.originX = newOffset; + viewport.originY = newOffsetY; } diff --git a/src/Engine/Graphics/RenderPass/BasePass.cpp b/src/Engine/Graphics/RenderPass/BasePass.cpp index 159c0a2..c6eaddd 100644 --- a/src/Engine/Graphics/RenderPass/BasePass.cpp +++ b/src/Engine/Graphics/RenderPass/BasePass.cpp @@ -143,7 +143,7 @@ void BasePass::render() command->bindDescriptor(descriptorSets); if (graphics->supportMeshShading()) { - command->dispatch(instance.meshes.size(), 1, 1); + command->drawMesh(instance.meshes.size(), 1, 1); } else { diff --git a/src/Engine/Graphics/RenderPass/DepthPrepass.cpp b/src/Engine/Graphics/RenderPass/DepthPrepass.cpp index d64fb63..5c8140c 100644 --- a/src/Engine/Graphics/RenderPass/DepthPrepass.cpp +++ b/src/Engine/Graphics/RenderPass/DepthPrepass.cpp @@ -111,7 +111,7 @@ void DepthPrepass::render() command->bindDescriptor(descriptorSets); if (graphics->supportMeshShading()) { - command->dispatch(instance.meshes.size(), 1, 1); + command->drawMesh(instance.meshes.size(), 1, 1); } else { diff --git a/src/Engine/Graphics/RenderTarget.h b/src/Engine/Graphics/RenderTarget.h index 37655b4..0e27c6b 100644 --- a/src/Engine/Graphics/RenderTarget.h +++ b/src/Engine/Graphics/RenderTarget.h @@ -28,7 +28,7 @@ public: SeAttachmentLoadOp stencilLoadOp = SE_ATTACHMENT_LOAD_OP_DONT_CARE, SeAttachmentStoreOp stencilStoreOp = SE_ATTACHMENT_STORE_OP_DONT_CARE); ~RenderTargetAttachment(); - PTexture2D getTexture() + PTexture2D getTexture() const { if(viewport != nullptr) { diff --git a/src/Engine/Graphics/Vulkan/Command.cpp b/src/Engine/Graphics/Vulkan/Command.cpp index 6f25e4a..f9868c5 100644 --- a/src/Engine/Graphics/Vulkan/Command.cpp +++ b/src/Engine/Graphics/Vulkan/Command.cpp @@ -12,15 +12,14 @@ using namespace Seele; using namespace Seele::Vulkan; -Command::Command(PGraphics graphics, VkCommandPool cmdPool, PCommandPool pool) +Command::Command(PGraphics graphics, PCommandPool pool) : graphics(graphics) , pool(pool) - , owner(cmdPool) { VkCommandBufferAllocateInfo allocInfo = { .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, .pNext = nullptr, - .commandPool = owner, + .commandPool = pool->getHandle(), .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY, .commandBufferCount = 1, }; @@ -34,7 +33,7 @@ Command::Command(PGraphics graphics, VkCommandPool cmdPool, PCommandPool pool) Command::~Command() { - vkFreeCommandBuffers(graphics->getDevice(), owner, 1, &handle); + vkFreeCommandBuffers(graphics->getDevice(), pool->getHandle(), 1, &handle); waitSemaphores.clear(); } @@ -335,7 +334,7 @@ void RenderCommand::drawIndexed(uint32 indexCount, uint32 instanceCount, int32 f assert(threadId == std::this_thread::get_id()); vkCmdDrawIndexed(handle, indexCount, instanceCount, firstIndex, vertexOffset, firstInstance); } -void RenderCommand::dispatch(uint32 groupX, uint32 groupY, uint32 groupZ) +void RenderCommand::drawMesh(uint32 groupX, uint32 groupY, uint32 groupZ) { assert(threadId == std::this_thread::get_id()); graphics->vkCmdDrawMeshTasksEXT(handle, groupX, groupY, groupZ); @@ -461,7 +460,7 @@ CommandPool::CommandPool(PGraphics graphics, PQueue queue) }; VK_CHECK(vkCreateCommandPool(graphics->getDevice(), &info, nullptr, &commandPool)); // TODO: dont reset individual commands, reset pool instead - allocatedBuffers.add(new Command(graphics, commandPool, this)); + allocatedBuffers.add(new Command(graphics, this)); command = allocatedBuffers.back(); command->begin(); @@ -554,7 +553,7 @@ void CommandPool::submitCommands(PSemaphore signalSemaphore) assert(cmdBuffer->state == Command::State::Submit); } } - allocatedBuffers.add(new Command(graphics, commandPool, this)); + allocatedBuffers.add(new Command(graphics, this)); command = allocatedBuffers.back(); command->begin(); command->waitForSemaphore(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, waitSemaphore); diff --git a/src/Engine/Graphics/Vulkan/Command.h b/src/Engine/Graphics/Vulkan/Command.h index 734ca7d..4f0620e 100644 --- a/src/Engine/Graphics/Vulkan/Command.h +++ b/src/Engine/Graphics/Vulkan/Command.h @@ -6,7 +6,6 @@ namespace Seele { -struct VertexInputStream; namespace Vulkan { DECLARE_REF(RenderPass) @@ -18,8 +17,8 @@ DECLARE_REF(CommandPool) class Command { public: - Command(PGraphics graphics, VkCommandPool cmdPool, PCommandPool pool); - virtual ~Command(); + Command(PGraphics graphics, PCommandPool pool); + ~Command(); constexpr VkCommandBuffer getHandle() { return handle; @@ -54,7 +53,6 @@ private: VkViewport currentViewport; VkRect2D currentScissor; VkCommandBuffer handle; - VkCommandPool owner; PRenderPass boundRenderPass; PFramebuffer boundFramebuffer; Array waitSemaphores; @@ -82,7 +80,7 @@ public: void begin(PRenderPass renderPass, PFramebuffer framebuffer); void end(); void reset(); - virtual bool isReady() override; + bool isReady(); virtual void setViewport(Gfx::PViewport viewport) override; virtual void bindPipeline(Gfx::PGraphicsPipeline pipeline) override; virtual void bindDescriptor(Gfx::PDescriptorSet descriptorSet) override; @@ -92,7 +90,7 @@ public: virtual void pushConstants(Gfx::PPipelineLayout layout, Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size, const void* data) override; virtual void draw(uint32 vertexCount, uint32 instanceCount, int32 firstVertex, uint32 firstInstance) override; virtual void drawIndexed(uint32 indexCount, uint32 instanceCount, int32 firstIndex, uint32 vertexOffset, uint32 firstInstance) override; - virtual void dispatch(uint32 groupX, uint32 groupY, uint32 groupZ) override; + virtual void drawMesh(uint32 groupX, uint32 groupY, uint32 groupZ) override; private: PGraphicsPipeline pipeline; bool ready; @@ -119,7 +117,7 @@ public: void begin(); void end(); void reset(); - virtual bool isReady() override; + bool isReady(); virtual void bindPipeline(Gfx::PComputePipeline pipeline) override; virtual void bindDescriptor(Gfx::PDescriptorSet set) override; virtual void bindDescriptor(const Array& sets) override; diff --git a/src/Engine/Graphics/Vulkan/Window.cpp b/src/Engine/Graphics/Vulkan/Window.cpp index c491fc4..0cf001e 100644 --- a/src/Engine/Graphics/Vulkan/Window.cpp +++ b/src/Engine/Graphics/Vulkan/Window.cpp @@ -149,7 +149,7 @@ void Window::onWindowCloseEvent() { } -Gfx::PTexture2D Window::getBackBuffer() +Gfx::PTexture2D Window::getBackBuffer() const { return PTexture2D(swapChainTextures[currentImageIndex]); } diff --git a/src/Engine/Graphics/Vulkan/Window.h b/src/Engine/Graphics/Vulkan/Window.h index a1a72de..ec3ddd1 100644 --- a/src/Engine/Graphics/Vulkan/Window.h +++ b/src/Engine/Graphics/Vulkan/Window.h @@ -16,7 +16,7 @@ public: virtual void pollInput() override; virtual void beginFrame() override; virtual void endFrame() override; - virtual Gfx::PTexture2D getBackBuffer() override; + virtual Gfx::PTexture2D getBackBuffer() const override; virtual void onWindowCloseEvent() override; virtual void setKeyCallback(std::function callback) override; virtual void setMouseMoveCallback(std::function callback) override; diff --git a/src/Engine/Graphics/Window.h b/src/Engine/Graphics/Window.h index 6041032..ebc6312 100644 --- a/src/Engine/Graphics/Window.h +++ b/src/Engine/Graphics/Window.h @@ -15,7 +15,7 @@ public: virtual void beginFrame() = 0; virtual void endFrame() = 0; virtual void onWindowCloseEvent() = 0; - virtual PTexture2D getBackBuffer() = 0; + virtual PTexture2D getBackBuffer() const = 0; virtual void setKeyCallback(std::function callback) = 0; virtual void setMouseMoveCallback(std::function callback) = 0; virtual void setMouseButtonCallback(std::function callback) = 0;