From a0161f1d83a55282024b2bc28e0d2d46cf2e2b85 Mon Sep 17 00:00:00 2001 From: Dynamitos Date: Tue, 9 Apr 2024 18:24:21 +0200 Subject: [PATCH] More metal changes --- src/Editor/main.cpp | 7 +- src/Engine/Graphics/Metal/Enums.h | 2 - src/Engine/Graphics/Metal/Graphics.h | 62 ++++----- src/Engine/Graphics/Metal/Texture.h | 117 ++++++++++++++-- src/Engine/Graphics/Metal/Texture.mm | 192 ++++++++++++++++++++++----- 5 files changed, 297 insertions(+), 83 deletions(-) diff --git a/src/Editor/main.cpp b/src/Editor/main.cpp index b1f0ac8..c68c1d5 100644 --- a/src/Editor/main.cpp +++ b/src/Editor/main.cpp @@ -1,3 +1,4 @@ +#include "Graphics/Metal/Graphics.h" #include "Window/WindowManager.h" #include "Window/SceneView.h" #include "Window/PlayView.h" @@ -6,6 +7,7 @@ #include "Asset/AssetImporter.h" #include "Asset/TextureLoader.h" #include "Graphics/Vulkan/Graphics.h" +#include "Graphics/Metal/Graphics.h" #include "Asset/MeshLoader.h" #include "Asset/TextureLoader.h" #include "Asset/MaterialLoader.h" @@ -38,8 +40,11 @@ int main() std::string gameName = "TrackClear"; std::filesystem::path cmakePath = outputPath / "cmake"; +#ifdef __APPLE__ + graphics = new Metal::Graphics(); +#else graphics = new Vulkan::Graphics(); - +#endif GraphicsInitializer initializer; graphics->init(initializer); StaticMeshVertexData* vd = StaticMeshVertexData::getInstance(); diff --git a/src/Engine/Graphics/Metal/Enums.h b/src/Engine/Graphics/Metal/Enums.h index b116d7a..7696839 100644 --- a/src/Engine/Graphics/Metal/Enums.h +++ b/src/Engine/Graphics/Metal/Enums.h @@ -9,7 +9,5 @@ namespace Metal { MTL::PixelFormat cast(Gfx::SeFormat format); Gfx::SeFormat cast(MTL::PixelFormat format); -MTL::TextureUsage cast(Gfx::SeImageUsageFlags usage); -Gfx::SeImageUsageFlags cast(MTL::TextureUsage usage); } } \ No newline at end of file diff --git a/src/Engine/Graphics/Metal/Graphics.h b/src/Engine/Graphics/Metal/Graphics.h index f6ebcba..ce7b236 100644 --- a/src/Engine/Graphics/Metal/Graphics.h +++ b/src/Engine/Graphics/Metal/Graphics.h @@ -11,46 +11,46 @@ class Graphics : public Gfx::Graphics public: Graphics(); virtual ~Graphics(); - virtual void init(GraphicsInitializer initializer) = 0; + virtual void init(GraphicsInitializer initializer) override; - virtual Gfx::OWindow createWindow(const WindowCreateInfo &createInfo) = 0; - virtual Gfx::OViewport createViewport(Gfx::PWindow owner, const ViewportCreateInfo &createInfo) = 0; + virtual Gfx::OWindow createWindow(const WindowCreateInfo &createInfo) override; + virtual Gfx::OViewport createViewport(Gfx::PWindow owner, const ViewportCreateInfo &createInfo) override; - virtual Gfx::ORenderPass createRenderPass(Gfx::RenderTargetLayout layout, Array dependencies, Gfx::PViewport renderArea) = 0; - virtual void beginRenderPass(Gfx::PRenderPass renderPass) = 0; - virtual void endRenderPass() = 0; - virtual void waitDeviceIdle() = 0; + virtual Gfx::ORenderPass createRenderPass(Gfx::RenderTargetLayout layout, Array dependencies, Gfx::PViewport renderArea) override; + virtual void beginRenderPass(Gfx::PRenderPass renderPass) override; + virtual void endRenderPass() override; + virtual void waitDeviceIdle() override; - virtual void executeCommands(const Array& commands) = 0; - virtual void executeCommands(const Array& commands) = 0; + virtual void executeCommands(const Array& commands) override; + virtual void executeCommands(const Array& commands) override; - virtual Gfx::OTexture2D createTexture2D(const TextureCreateInfo &createInfo) = 0; - virtual Gfx::OTexture3D createTexture3D(const TextureCreateInfo &createInfo) = 0; - virtual Gfx::OTextureCube createTextureCube(const TextureCreateInfo &createInfo) = 0; - virtual Gfx::OUniformBuffer createUniformBuffer(const UniformBufferCreateInfo &bulkData) = 0; - virtual Gfx::OShaderBuffer createShaderBuffer(const ShaderBufferCreateInfo &bulkData) = 0; - virtual Gfx::OVertexBuffer createVertexBuffer(const VertexBufferCreateInfo &bulkData) = 0; - virtual Gfx::OIndexBuffer createIndexBuffer(const IndexBufferCreateInfo &bulkData) = 0; + virtual Gfx::OTexture2D createTexture2D(const TextureCreateInfo &createInfo) override; + virtual Gfx::OTexture3D createTexture3D(const TextureCreateInfo &createInfo) override; + virtual Gfx::OTextureCube createTextureCube(const TextureCreateInfo &createInfo) override; + virtual Gfx::OUniformBuffer createUniformBuffer(const UniformBufferCreateInfo &bulkData) override; + virtual Gfx::OShaderBuffer createShaderBuffer(const ShaderBufferCreateInfo &bulkData) override; + virtual Gfx::OVertexBuffer createVertexBuffer(const VertexBufferCreateInfo &bulkData) override; + virtual Gfx::OIndexBuffer createIndexBuffer(const IndexBufferCreateInfo &bulkData) override; - virtual Gfx::PRenderCommand createRenderCommand(const std::string& name = "") = 0; - virtual Gfx::PComputeCommand createComputeCommand(const std::string& name = "") = 0; + virtual Gfx::PRenderCommand createRenderCommand(const std::string& name = "") override; + virtual Gfx::PComputeCommand createComputeCommand(const std::string& name = "") override; - virtual Gfx::OVertexShader createVertexShader(const ShaderCreateInfo& createInfo) = 0; - virtual Gfx::OFragmentShader createFragmentShader(const ShaderCreateInfo& createInfo) = 0; - virtual Gfx::OComputeShader createComputeShader(const ShaderCreateInfo& createInfo) = 0; - virtual Gfx::OMeshShader createMeshShader(const ShaderCreateInfo& createInfo) = 0; - virtual Gfx::OTaskShader createTaskShader(const ShaderCreateInfo& createInfo) = 0; - virtual Gfx::PGraphicsPipeline createGraphicsPipeline(Gfx::LegacyPipelineCreateInfo createInfo) = 0; - virtual Gfx::PGraphicsPipeline createGraphicsPipeline(Gfx::MeshPipelineCreateInfo createInfo) = 0; - virtual Gfx::PComputePipeline createComputePipeline(Gfx::ComputePipelineCreateInfo createInfo) = 0; - virtual Gfx::OSampler createSampler(const SamplerCreateInfo& createInfo) = 0; + virtual Gfx::OVertexShader createVertexShader(const ShaderCreateInfo& createInfo) override; + virtual Gfx::OFragmentShader createFragmentShader(const ShaderCreateInfo& createInfo) override; + virtual Gfx::OComputeShader createComputeShader(const ShaderCreateInfo& createInfo) override; + virtual Gfx::OMeshShader createMeshShader(const ShaderCreateInfo& createInfo) override; + virtual Gfx::OTaskShader createTaskShader(const ShaderCreateInfo& createInfo) override; + virtual Gfx::PGraphicsPipeline createGraphicsPipeline(Gfx::LegacyPipelineCreateInfo createInfo) override; + virtual Gfx::PGraphicsPipeline createGraphicsPipeline(Gfx::MeshPipelineCreateInfo createInfo) override; + virtual Gfx::PComputePipeline createComputePipeline(Gfx::ComputePipelineCreateInfo createInfo) override; + virtual Gfx::OSampler createSampler(const SamplerCreateInfo& createInfo) override; - virtual Gfx::ODescriptorLayout createDescriptorLayout(const std::string& name = "") = 0; - virtual Gfx::OPipelineLayout createPipelineLayout(Gfx::PPipelineLayout baseLayout = nullptr) = 0; + virtual Gfx::ODescriptorLayout createDescriptorLayout(const std::string& name = "") override; + virtual Gfx::OPipelineLayout createPipelineLayout(Gfx::PPipelineLayout baseLayout = nullptr) override; - virtual Gfx::OVertexInput createVertexInput(VertexInputStateCreateInfo createInfo) = 0; + virtual Gfx::OVertexInput createVertexInput(VertexInputStateCreateInfo createInfo) override; - virtual void resolveTexture(Gfx::PTexture source, Gfx::PTexture destination) = 0; + virtual void resolveTexture(Gfx::PTexture source, Gfx::PTexture destination) override; MTL::Device* getDevice() const { return device; } protected: diff --git a/src/Engine/Graphics/Metal/Texture.h b/src/Engine/Graphics/Metal/Texture.h index abbd779..7ff0583 100644 --- a/src/Engine/Graphics/Metal/Texture.h +++ b/src/Engine/Graphics/Metal/Texture.h @@ -76,36 +76,127 @@ protected: friend class Graphics; }; DEFINE_REF(TextureBase) -class Texture2D : public Gfx::Texture2D +class Texture2D : public Gfx::Texture2D, public TextureBase { public: - Texture2D(PGraphics graphics, const TextureCreateInfo& createInfo, MTL::Texture* existingImage = nullptr); + Texture2D(PGraphics graphics, const TextureCreateInfo& createInfo, MTL::Texture* exisitingTexture = nullptr); virtual ~Texture2D(); - - virtual Gfx::SeFormat getFormat() const override; - virtual uint32 getWidth() const override; - virtual uint32 getHeight() const override; - virtual uint32 getDepth() const override; - virtual Gfx::SeSampleCountFlags getNumSamples() const override; - virtual uint32 getMipLevels() const override; + virtual uint32 getWidth() const override + { + return width; + } + virtual uint32 getHeight() const override + { + return height; + } + virtual uint32 getDepth() const override + { + return depth; + } + virtual Gfx::SeFormat getFormat() const override + { + return format; + } + virtual Gfx::SeSampleCountFlags getNumSamples() const override + { + return samples; + } + virtual uint32 getMipLevels() const override + { + return mipLevels; + } virtual void changeLayout(Gfx::SeImageLayout newLayout, Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) override; + virtual void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array& buffer) override; + protected: - //Inherited via QueueOwnedResource + // Inherited via QueueOwnedResource virtual void executeOwnershipBarrier(Gfx::QueueType newOwner) override; virtual void executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) override; }; DEFINE_REF(Texture2D) -class Texture3D : public Gfx::Texture3D +class Texture3D : public Gfx::Texture3D, public TextureBase { +public: + Texture3D(PGraphics graphics, const TextureCreateInfo& createInfo); + virtual ~Texture3D(); + virtual uint32 getWidth() const override + { + return width; + } + virtual uint32 getHeight() const override + { + return height; + } + virtual uint32 getDepth() const override + { + return depth; + } + virtual Gfx::SeFormat getFormat() const override + { + return format; + } + virtual Gfx::SeSampleCountFlags getNumSamples() const override + { + return samples; + } + virtual uint32 getMipLevels() const override + { + return mipLevels; + } + virtual void changeLayout(Gfx::SeImageLayout newLayout, + Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, + Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) override; + virtual void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array& buffer) override; + +protected: + // Inherited via QueueOwnedResource + virtual void executeOwnershipBarrier(Gfx::QueueType newOwner) override; + virtual void executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, + Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) override; }; DEFINE_REF(Texture3D) -class TextureCube : public Gfx::TextureCube +class TextureCube : public Gfx::TextureCube, TextureBase { - +public: + TextureCube(PGraphics graphics, const TextureCreateInfo& createInfo); + virtual ~TextureCube(); + virtual uint32 getWidth() const override + { + return width; + } + virtual uint32 getHeight() const override + { + return height; + } + virtual uint32 getDepth() const override + { + return depth; + } + virtual Gfx::SeFormat getFormat() const override + { + return format; + } + virtual Gfx::SeSampleCountFlags getNumSamples() const override + { + return samples; + } + virtual uint32 getMipLevels() const override + { + return mipLevels; + } + virtual void changeLayout(Gfx::SeImageLayout newLayout, + Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, + Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) override; + virtual void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array& buffer) override; +protected: + // Inherited via QueueOwnedResource + virtual void executeOwnershipBarrier(Gfx::QueueType newOwner) override; + virtual void executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, + Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) override; }; DEFINE_REF(TextureCube) } diff --git a/src/Engine/Graphics/Metal/Texture.mm b/src/Engine/Graphics/Metal/Texture.mm index 391ad64..2c211e6 100644 --- a/src/Engine/Graphics/Metal/Texture.mm +++ b/src/Engine/Graphics/Metal/Texture.mm @@ -1,50 +1,170 @@ #include "Texture.h" +#include "Enums.h" #include "Graphics/Enums.h" #include "Graphics/Initializer.h" #include "Graphics/Metal/Graphics.h" +#include "Metal/MTLCommandEncoder.hpp" #include "Metal/MTLTexture.hpp" -#include "Enums.h" using namespace Seele; using namespace Seele::Metal; -TextureBase::TextureBase(PGraphics graphics, MTL::TextureType type, const TextureCreateInfo& createInfo, Gfx::QueueType& owner, MTL::Texture* existingImage) - : currentOwner(owner) - , graphics(graphics) - , width(createInfo.width) - , height(createInfo.height) - , depth(createInfo.depth) - , arrayCount(createInfo.elements) - , layerCount(createInfo.layers) - , mipLevels(createInfo.mipLevels) - , samples(createInfo.samples) - , format(createInfo.format) - , usage(createInfo.usage) - , texture(existingImage) - , type(type) - , layout(Gfx::SE_IMAGE_LAYOUT_UNDEFINED) - , ownsImage(existingImage == nullptr) -{ - if(existingImage == nullptr) +TextureBase::TextureBase(PGraphics graphics, MTL::TextureType type, + const TextureCreateInfo &createInfo, + Gfx::QueueType &owner, MTL::Texture *existingImage) + : currentOwner(owner), graphics(graphics), width(createInfo.width), + height(createInfo.height), depth(createInfo.depth), + arrayCount(createInfo.elements), layerCount(createInfo.layers), + mipLevels(createInfo.mipLevels), samples(createInfo.samples), + format(createInfo.format), usage(createInfo.usage), + texture(existingImage), type(type), + layout(Gfx::SE_IMAGE_LAYOUT_UNDEFINED), + ownsImage(existingImage == nullptr) { + if (existingImage == nullptr) { + MTL::TextureUsage mtlUsage = 0; + if(usage & Gfx::SE_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) { - MTL::TextureDescriptor* descriptor = MTL::TextureDescriptor::alloc()->init(); - descriptor->setPixelFormat(cast(format)); - descriptor->setWidth(width); - descriptor->setHeight(height); - descriptor->setDepth(depth); - descriptor->setArrayLength(arrayCount); - descriptor->setMipmapLevelCount(mipLevels); - descriptor->setTextureType(type); - descriptor->setSampleCount(samples); - descriptor->setUsage(cast(usage)); - - - - descriptor->release(); + mtlUsage |= MTL::TextureUsageRenderTarget; } + if(usage & Gfx::SE_IMAGE_USAGE_SAMPLED_BIT) + { + mtlUsage |= MTL::TextureUsageShaderRead; + } + MTL::TextureDescriptor *descriptor = + MTL::TextureDescriptor::alloc()->init(); + descriptor->setPixelFormat(cast(format)); + descriptor->setWidth(width); + descriptor->setHeight(height); + descriptor->setDepth(depth); + descriptor->setArrayLength(arrayCount); + descriptor->setMipmapLevelCount(mipLevels); + descriptor->setTextureType(type); + descriptor->setSampleCount(samples); + descriptor->setUsage(mtlUsage); + + texture = graphics->getDevice()->newTexture(descriptor); + + descriptor->release(); + } } -Texture::~Texture() +TextureBase::~TextureBase() { + if (ownsImage) { + texture->release(); + } +} + +void TextureBase::executePipelineBarrier(Gfx::SeAccessFlags, + Gfx::SePipelineStageFlags, + Gfx::SeAccessFlags, + Gfx::SePipelineStageFlags) {} + +void TextureBase::changeLayout(Gfx::SeImageLayout, Gfx::SeAccessFlags, + Gfx::SePipelineStageFlags, Gfx::SeAccessFlags, + Gfx::SePipelineStageFlags) {} + +void TextureBase::download(uint32, uint32, uint32, Array&) +{} + +Texture2D::Texture2D(PGraphics graphics, const TextureCreateInfo &createInfo, + MTL::Texture *exisitingTexture) + : Gfx::Texture2D(graphics->getFamilyMapping(), createInfo.sourceData.owner), + TextureBase(graphics, + createInfo.elements > 1 + ? (createInfo.samples > 1 + ? MTL::TextureType2DMultisampleArray + : MTL::TextureType2DArray) + : (createInfo.samples > 1 ? MTL::TextureType2DMultisample + : MTL::TextureType2D), + createInfo, Gfx::Texture2D::currentOwner, exisitingTexture) {} + +Texture2D::~Texture2D() { - -} \ No newline at end of file +} + +void Texture2D::changeLayout(Gfx::SeImageLayout newLayout, + Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, + Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) +{ + TextureBase::changeLayout(newLayout, srcAccess, srcStage, dstAccess, dstStage); +} + +void Texture2D::download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array& buffer) +{ + TextureBase::download(mipLevel, arrayLayer, face, buffer); +} + +void Texture2D::executeOwnershipBarrier(Gfx::QueueType newOwner) +{ + TextureBase::executeOwnershipBarrier(newOwner); +} + +void Texture2D::executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, + Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) +{ + TextureBase::executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage); +} + +Texture3D::Texture3D(PGraphics graphics, const TextureCreateInfo& createInfo) + : Gfx::Texture3D(graphics->getFamilyMapping(), createInfo.sourceData.owner) + , TextureBase(graphics, MTL::TextureType3D, createInfo, Gfx::Texture3D::currentOwner) {} + + +Texture3D::~Texture3D() +{ +} + +void Texture3D::changeLayout(Gfx::SeImageLayout newLayout, + Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, + Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) +{ + TextureBase::changeLayout(newLayout, srcAccess, srcStage, dstAccess, dstStage); +} + +void Texture3D::download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array& buffer) +{ + TextureBase::download(mipLevel, arrayLayer, face, buffer); +} +void Texture3D::executeOwnershipBarrier(Gfx::QueueType newOwner) +{ + TextureBase::executeOwnershipBarrier(newOwner); +} + +void Texture3D::executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, + Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) +{ + TextureBase::executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage); +} + +TextureCube::TextureCube(PGraphics graphics, const TextureCreateInfo& createInfo) + : Gfx::TextureCube(graphics->getFamilyMapping(), createInfo.sourceData.owner) + , TextureBase(graphics, createInfo.elements > 1 ? MTL::TextureTypeCubeArray : MTL::TextureTypeCube, + createInfo, Gfx::TextureCube::currentOwner) +{ +} + +TextureCube::~TextureCube() +{ +} + +void TextureCube::changeLayout(Gfx::SeImageLayout newLayout, + Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, + Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) +{ + TextureBase::changeLayout(newLayout, srcAccess, srcStage, dstAccess, dstStage); +} + +void TextureCube::download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array& buffer) +{ + TextureBase::download(mipLevel, arrayLayer, face, buffer); +} +void TextureCube::executeOwnershipBarrier(Gfx::QueueType newOwner) +{ + TextureBase::executeOwnershipBarrier(newOwner); +} + +void TextureCube::executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, + Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) +{ + TextureBase::executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage); +}