diff --git a/src/Engine/Containers/Array.h b/src/Engine/Containers/Array.h index 97224c6..14482dd 100644 --- a/src/Engine/Containers/Array.h +++ b/src/Engine/Containers/Array.h @@ -242,7 +242,7 @@ template > s template requires std::predicate - constexpr iterator find(Pred pred) noexcept { + constexpr iterator find(Pred&& pred) noexcept { for (size_type i = 0; i < arraySize; ++i) { if (pred(_data[i])) { return iterator(&_data[i]); @@ -292,8 +292,11 @@ template > s } template requires std::predicate - constexpr void remove_if(Pred pred, bool keepOrder = true) { - remove(find(pred), keepOrder); + constexpr void remove_if(Pred&& pred, bool keepOrder = true) { + Iterator it; + while((it = find(pred)) != end()) { + erase(it, keepOrder); + } } constexpr void remove(const value_type& element, bool keepOrder = true) { erase(find(element), keepOrder); } constexpr void remove(value_type&& element, bool keepOrder = true) { erase(find(element), keepOrder); } @@ -326,11 +329,11 @@ template > s arraySize = 0; allocated = 0; } - constexpr size_type indexOf(iterator iterator) { return iterator - begin(); } - constexpr size_type indexOf(const_iterator iterator) const { return iterator.p - begin().p; } - constexpr size_type indexOf(T& t) { return indexOf(find(t)); } - constexpr size_type indexOf(const T& t) const { return indexOf(find(t)); } - constexpr size_type size() const noexcept { return arraySize; } + [[nodiscard]] constexpr size_type indexOf(iterator iterator) { return iterator - begin(); } + [[nodiscard]] constexpr size_type indexOf(const_iterator iterator) const { return iterator.p - begin().p; } + [[nodiscard]] constexpr size_type indexOf(T& t) { return indexOf(find(t)); } + [[nodiscard]] constexpr size_type indexOf(const T& t) const { return indexOf(find(t)); } + [[nodiscard]] constexpr size_type size() const noexcept { return arraySize; } [[nodiscard]] constexpr bool empty() const noexcept { return arraySize == 0; } constexpr void reserve(size_type new_cap) { if (new_cap > allocated) { diff --git a/src/Engine/Graphics/Metal/Buffer.mm b/src/Engine/Graphics/Metal/Buffer.mm index ffa7605..35ae8c2 100644 --- a/src/Engine/Graphics/Metal/Buffer.mm +++ b/src/Engine/Graphics/Metal/Buffer.mm @@ -42,8 +42,7 @@ void BufferAllocation::unmap() {} Buffer::Buffer(PGraphics graphics, uint64 size, Gfx::SeBufferUsageFlags usage, Gfx::QueueType queueType, bool dynamic, std::string name, bool createCleared, uint32 clearValue) : graphics(graphics), currentBuffer(0), dynamic(dynamic), createCleared(createCleared), name(name), clearValue(clearValue) { - if(size > 0) - { + if(size > 0) { buffers.add(nullptr); createBuffer(size, 0); } @@ -53,6 +52,7 @@ Buffer::~Buffer() { for (size_t i = 0; i < buffers.size(); ++i) { // TODO } + buffers.clear(); } void Buffer::updateContents(uint64 regionOffset, uint64 regionSize, void* ptr) { diff --git a/src/Engine/Graphics/Metal/Command.h b/src/Engine/Graphics/Metal/Command.h index d47f9f1..6e15af6 100644 --- a/src/Engine/Graphics/Metal/Command.h +++ b/src/Engine/Graphics/Metal/Command.h @@ -63,7 +63,7 @@ class RenderCommand : public Gfx::RenderCommand { virtual void bindIndexBuffer(Gfx::PIndexBuffer indexBuffer) override; virtual void pushConstants(Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size, const void* data) override; virtual void draw(uint32 vertexCount, uint32 instanceCount, int32 firstVertex, uint32 firstInstance) override; - virtual void drawIndirect(Gfx::PShaderBuffer buffer, uint64 offset, uint32 drawCount, uint32 stride); + virtual void drawIndirect(Gfx::PShaderBuffer buffer, uint64 offset, uint32 drawCount, uint32 stride) override; virtual void drawIndexed(uint32 indexCount, uint32 instanceCount, int32 firstIndex, uint32 vertexOffset, uint32 firstInstance) override; virtual void drawMesh(uint32 groupX, uint32 groupY, uint32 groupZ) override; virtual void drawMeshIndirect(Gfx::PShaderBuffer buffer, uint64 offset, uint32 drawCount, uint32 stride) override; @@ -73,7 +73,6 @@ class RenderCommand : public Gfx::RenderCommand { PGraphicsPipeline boundPipeline; PIndexBuffer boundIndexBuffer; MTL::RenderCommandEncoder* encoder; - MTL::Buffer* constantsBuffer; std::string name; }; DEFINE_REF(RenderCommand) @@ -93,7 +92,6 @@ class ComputeCommand : public Gfx::ComputeCommand { PComputePipeline boundPipeline; MTL::CommandBuffer* commandBuffer; MTL::ComputeCommandEncoder* encoder; - MTL::Buffer* constantsBuffer; std::string name; }; DEFINE_REF(ComputeCommand) diff --git a/src/Engine/Graphics/Metal/Command.mm b/src/Engine/Graphics/Metal/Command.mm index 8d25dd4..9c02d23 100644 --- a/src/Engine/Graphics/Metal/Command.mm +++ b/src/Engine/Graphics/Metal/Command.mm @@ -24,19 +24,29 @@ using namespace Seele::Metal; Command::Command(PGraphics graphics, MTL::CommandBuffer* cmdBuffer) : graphics(graphics), completed(new Event(graphics)), cmdBuffer(cmdBuffer) {} -Command::~Command() {} +Command::~Command() { + assert(parallelEncoder == nullptr); + if(blitEncoder != nullptr) { + blitEncoder->endEncoding(); + blitEncoder->release(); + } + cmdBuffer->release(); +} void Command::beginRenderPass(PRenderPass renderPass) { if (blitEncoder) { blitEncoder->endEncoding(); + blitEncoder->release(); blitEncoder = nullptr; } renderPass->updateRenderPass(); parallelEncoder = cmdBuffer->parallelRenderCommandEncoder(renderPass->getDescriptor()); + parallelEncoder->setLabel(NS::String::string(renderPass->getName().c_str(), NS::ASCIIStringEncoding)); } void Command::endRenderPass() { parallelEncoder->endEncoding(); + parallelEncoder->release(); parallelEncoder = nullptr; } @@ -46,6 +56,8 @@ void Command::end(PEvent signal) { assert(!parallelEncoder); if (blitEncoder) { blitEncoder->endEncoding(); + blitEncoder->release(); + blitEncoder = nullptr; } if (signal != nullptr) { cmdBuffer->encodeSignalEvent(signal->getHandle(), 1); @@ -62,7 +74,7 @@ void Command::waitForEvent(PEvent event) { cmdBuffer->encodeWait(event->getHandl RenderCommand::RenderCommand(MTL::RenderCommandEncoder* encoder, const std::string& name) : encoder(encoder), name(name) {} -RenderCommand::~RenderCommand() {} +RenderCommand::~RenderCommand() { encoder->release(); } void RenderCommand::end() { encoder->endEncoding(); } @@ -81,9 +93,7 @@ void RenderCommand::setViewport(Gfx::PViewport viewport) { void RenderCommand::bindPipeline(Gfx::PGraphicsPipeline pipeline) { boundPipeline = pipeline.cast(); encoder->setRenderPipelineState(boundPipeline->getHandle()); - if (boundPipeline->getPipelineLayout()->hasPushConstants()) { - constantsBuffer = boundPipeline->graphics->getDevice()->newBuffer(boundPipeline->getPipelineLayout()->getPushConstantsSize(), 0); - } + encoder->setDepthStencilState(boundPipeline->depth); } void RenderCommand::bindPipeline(Gfx::PRayTracingPipeline pipeline) {} @@ -150,19 +160,18 @@ void RenderCommand::bindVertexBuffer(const Array& buffers) { void RenderCommand::bindIndexBuffer(Gfx::PIndexBuffer gfxIndexBuffer) { boundIndexBuffer = gfxIndexBuffer.cast(); } void RenderCommand::pushConstants(Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size, const void* data) { - std::memcpy(constantsBuffer->contents(), data, size); uint pushIndex = boundPipeline->getPipelineLayout()->findParameter("pOffsets"); if (stage & Gfx::SE_SHADER_STAGE_VERTEX_BIT) { - encoder->setVertexBuffer(constantsBuffer, 0, pushIndex); // TODO: hardcoded + encoder->setVertexBytes(data, size, pushIndex); // TODO: hardcoded } if (stage & Gfx::SE_SHADER_STAGE_FRAGMENT_BIT) { - encoder->setFragmentBuffer(constantsBuffer, 0, pushIndex); // TODO: hardcoded + encoder->setFragmentBytes(data, size, pushIndex); // TODO: hardcoded } if (stage & Gfx::SE_SHADER_STAGE_TASK_BIT_EXT) { - encoder->setObjectBuffer(constantsBuffer, 0, pushIndex); // TODO: hardcoded + encoder->setObjectBytes(data, size, pushIndex); // TODO: hardcoded } if (stage & Gfx::SE_SHADER_STAGE_MESH_BIT_EXT) { - encoder->setMeshBuffer(constantsBuffer, 0, pushIndex); // TODO: hardcoded + encoder->setMeshBytes(data, size, pushIndex); // TODO: hardcoded } } @@ -191,7 +200,7 @@ void RenderCommand::traceRays(uint32 width, uint32 height, uint32 depth) {} ComputeCommand::ComputeCommand(MTL::CommandBuffer* cmdBuffer, const std::string& name) : commandBuffer(cmdBuffer), encoder(cmdBuffer->computeCommandEncoder()), name(name) {} -ComputeCommand::~ComputeCommand() {} +ComputeCommand::~ComputeCommand() { encoder->release(); commandBuffer->release(); } void ComputeCommand::end() { encoder->endEncoding(); @@ -201,9 +210,6 @@ void ComputeCommand::end() { void ComputeCommand::bindPipeline(Gfx::PComputePipeline pipeline) { boundPipeline = pipeline.cast(); encoder->setComputePipelineState(boundPipeline->getHandle()); - if (boundPipeline->getPipelineLayout()->hasPushConstants()) { - constantsBuffer = boundPipeline->graphics->getDevice()->newBuffer(boundPipeline->getPipelineLayout()->getPushConstantsSize(), 0); - } } void ComputeCommand::bindDescriptor(Gfx::PDescriptorSet set) { @@ -248,9 +254,8 @@ void ComputeCommand::bindDescriptor(const Array& sets) { } void ComputeCommand::pushConstants(Gfx::SeShaderStageFlags, uint32 offset, uint32 size, const void* data) { - std::memcpy(constantsBuffer->contents(), data, size); uint pushIndex = boundPipeline->getPipelineLayout()->findParameter("pMipParam"); - encoder->setBuffer(constantsBuffer, 0, pushIndex); // TODO: hardcoded + encoder->setBytes(data, size, pushIndex); // TODO: hardcoded } void ComputeCommand::dispatch(uint32 threadX, uint32 threadY, uint32 threadZ) { diff --git a/src/Engine/Graphics/Metal/Descriptor.mm b/src/Engine/Graphics/Metal/Descriptor.mm index fda4763..09f9227 100644 --- a/src/Engine/Graphics/Metal/Descriptor.mm +++ b/src/Engine/Graphics/Metal/Descriptor.mm @@ -26,7 +26,7 @@ using namespace Seele::Metal; DescriptorLayout::DescriptorLayout(PGraphics graphics, const std::string& name) : Gfx::DescriptorLayout(name), graphics(graphics) {} -DescriptorLayout::~DescriptorLayout() {} +DescriptorLayout::~DescriptorLayout() { arguments->release(); } void DescriptorLayout::create() { pool = new DescriptorPool(graphics, this); @@ -36,14 +36,14 @@ void DescriptorLayout::create() { for (uint32 i = 0; i < descriptorBindings.size(); ++i) { if (descriptorBindings[i].descriptorType != Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER) { plainDescriptor = false; - } else { - objects[i] = MTL::ArgumentDescriptor::alloc()->init(); - objects[i]->setIndex(mappingCounter); - objects[i]->setAccess(MTL::BindingAccessReadOnly); - objects[i]->setArrayLength(descriptorBindings[i].descriptorCount); - objects[i]->setDataType(MTL::DataTypeChar); - objects[i]->setArrayLength(descriptorBindings[i].uniformLength); } + objects[i] = MTL::ArgumentDescriptor::alloc()->init(); + objects[i]->setIndex(mappingCounter); + objects[i]->setAccess(MTL::BindingAccessReadOnly); + objects[i]->setArrayLength(descriptorBindings[i].descriptorCount); + objects[i]->setDataType(MTL::DataTypeChar); + objects[i]->setArrayLength(descriptorBindings[i].uniformLength); + variableMapping[descriptorBindings[i].name] = DescriptorMapping{ .index = mappingCounter, .constantSize = descriptorBindings[i].uniformLength, @@ -53,6 +53,7 @@ void DescriptorLayout::create() { } numResources = mappingCounter; arguments = NS::Array::array((NS::Object**)objects, descriptorBindings.size()); + delete[] objects; } MTL::ArgumentEncoder* DescriptorLayout::createEncoder() { return graphics->getDevice()->newArgumentEncoder(arguments); } @@ -79,9 +80,18 @@ void DescriptorPool::reset() {} DescriptorSet::DescriptorSet(PGraphics graphics, PDescriptorPool owner) : Gfx::DescriptorSet(owner->getLayout()), CommandBoundResource(graphics), graphics(graphics), owner(owner) { + std::cout << "New Descriptor set" << std::endl; } -DescriptorSet::~DescriptorSet() {} +DescriptorSet::~DescriptorSet() { + if(encoder != nullptr) { + encoder->release(); + } + if(argumentBuffer != nullptr) { + argumentBuffer->release(); + } + std::cout << "destroying descriptor set" << std::endl; +} void DescriptorSet::reset() { uniformWrites.clear(); diff --git a/src/Engine/Graphics/Metal/Pipeline.h b/src/Engine/Graphics/Metal/Pipeline.h index dbc01ca..df400a1 100644 --- a/src/Engine/Graphics/Metal/Pipeline.h +++ b/src/Engine/Graphics/Metal/Pipeline.h @@ -21,6 +21,7 @@ class GraphicsPipeline : public Gfx::GraphicsPipeline { constexpr MTL::PrimitiveType getPrimitive() const { return primitiveType; } PGraphics graphics; MTL::RenderPipelineState* state; + MTL::DepthStencilState* depth; MTL::PrimitiveType primitiveType; MTL::Function* taskFunction = nullptr; Array taskSets; diff --git a/src/Engine/Graphics/Metal/PipelineCache.mm b/src/Engine/Graphics/Metal/PipelineCache.mm index 2b8c949..4e70fbf 100644 --- a/src/Engine/Graphics/Metal/PipelineCache.mm +++ b/src/Engine/Graphics/Metal/PipelineCache.mm @@ -86,7 +86,11 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::LegacyPipelineCreateInfo cr desc->setBlendingEnabled(false); pipelineDescriptor->colorAttachments()->setObject(desc, c); } + + MTL::DepthStencilDescriptor* depthDescriptor = MTL::DepthStencilDescriptor::alloc()->init(); if (createInfo.renderPass->getLayout().depthAttachment.getTexture() != nullptr) { + depthDescriptor->setDepthWriteEnabled(createInfo.depthStencilState.depthWriteEnable); + depthDescriptor->setDepthCompareFunction(cast(createInfo.depthStencilState.depthCompareOp)); pipelineDescriptor->setDepthAttachmentPixelFormat( cast(createInfo.renderPass->getLayout().depthAttachment.getTexture().cast()->getFormat())); } @@ -94,7 +98,10 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::LegacyPipelineCreateInfo cr pipelineDescriptor->setAlphaToOneEnabled(createInfo.multisampleState.alphaToOneEnable); pipelineDescriptor->setRasterSampleCount(createInfo.multisampleState.samples); pipelineDescriptor->setRasterizationEnabled(!createInfo.rasterizationState.rasterizerDiscardEnable); - + + MTL::DepthStencilState* depthState = graphics->getDevice()->newDepthStencilState(depthDescriptor); + depthDescriptor->release(); + uint32 hash = pipelineDescriptor->hash(); if (graphicsPipelines.contains(hash)) { @@ -145,10 +152,12 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::LegacyPipelineCreateInfo cr } pipelineDescriptor->release(); + graphicsPipelines[hash]->vertexSets = vertexSets; graphicsPipelines[hash]->vertexFunction = vertexFunction; graphicsPipelines[hash]->fragmentSets = fragmentSets; graphicsPipelines[hash]->fragmentFunction = fragmentFunction; + graphicsPipelines[hash]->depth = depthState; return graphicsPipelines[hash]; } diff --git a/src/Engine/Graphics/Metal/RenderPass.h b/src/Engine/Graphics/Metal/RenderPass.h index ef92ab2..10ecbc0 100644 --- a/src/Engine/Graphics/Metal/RenderPass.h +++ b/src/Engine/Graphics/Metal/RenderPass.h @@ -12,12 +12,14 @@ class RenderPass : public Gfx::RenderPass { virtual ~RenderPass(); void updateRenderPass(); MTL::RenderPassDescriptor* getDescriptor() const { return renderPass; } + const std::string& getName() const { return name; } private: PGraphics graphics; Gfx::PViewport viewport; MTL::RenderPassDescriptor* renderPass; + std::string name; }; DEFINE_REF(RenderPass) } // namespace Metal -} // namespace Seele \ No newline at end of file +} // namespace Seele diff --git a/src/Engine/Graphics/Metal/RenderPass.mm b/src/Engine/Graphics/Metal/RenderPass.mm index 294c5de..4f04c38 100644 --- a/src/Engine/Graphics/Metal/RenderPass.mm +++ b/src/Engine/Graphics/Metal/RenderPass.mm @@ -7,9 +7,9 @@ using namespace Seele; using namespace Seele::Metal; -RenderPass::RenderPass(PGraphics graphics, Gfx::RenderTargetLayout layout, Array dependencies, +RenderPass::RenderPass(PGraphics graphics, Gfx::RenderTargetLayout _layout, Array dependencies, Gfx::PViewport viewport, const std::string& name) - : Gfx::RenderPass(layout, dependencies), graphics(graphics), viewport(viewport) { + : Gfx::RenderPass(std::move(_layout), dependencies), graphics(graphics), viewport(viewport), name(name) { renderPass = MTL::RenderPassDescriptor::renderPassDescriptor(); renderPass->setRenderTargetArrayLength(1); renderPass->setRenderTargetWidth(viewport->getWidth()); @@ -27,7 +27,12 @@ RenderPass::RenderPass(PGraphics graphics, Gfx::RenderTargetLayout layout, Array if (!layout.resolveAttachments.empty()) { const auto& resolve = layout.resolveAttachments[i]; desc->setResolveLevel(0); - desc->setStoreAction(MTL::StoreActionStoreAndMultisampleResolve); + // store multisampled attachment as well + if(color.getStoreOp() == Gfx::SE_ATTACHMENT_STORE_OP_STORE) { + desc->setStoreAction(MTL::StoreActionStoreAndMultisampleResolve); + } else { + desc->setStoreAction(MTL::StoreActionMultisampleResolve); + } desc->setResolveTexture(resolve.getTexture().cast()->getImage()); } } @@ -38,8 +43,13 @@ RenderPass::RenderPass(PGraphics graphics, Gfx::RenderTargetLayout layout, Array depth->setStoreAction(cast(layout.depthAttachment.getStoreOp())); if (layout.depthResolveAttachment.getTexture() != nullptr) { + // store multisampled attachment as well + if(layout.depthAttachment.getStoreOp() == Gfx::SE_ATTACHMENT_STORE_OP_STORE) { + depth->setStoreAction(MTL::StoreActionStoreAndMultisampleResolve); + } else { + depth->setStoreAction(MTL::StoreActionMultisampleResolve); + } depth->setResolveTexture(layout.depthResolveAttachment.getTexture().cast()->getImage()); - depth->setStoreAction(MTL::StoreActionStoreAndMultisampleResolve); } } // TODO: stencil @@ -56,4 +66,4 @@ void RenderPass::updateRenderPass() { auto depth = renderPass->depthAttachment(); depth->setTexture(layout.depthAttachment.getTexture().cast()->getImage()); } -} \ No newline at end of file +} diff --git a/src/Engine/Graphics/Metal/Texture.h b/src/Engine/Graphics/Metal/Texture.h index b67787f..70b0ed2 100644 --- a/src/Engine/Graphics/Metal/Texture.h +++ b/src/Engine/Graphics/Metal/Texture.h @@ -24,7 +24,6 @@ class TextureHandle { uint32 height; uint32 depth; uint32 arrayCount; - uint32 layerCount; uint32 mipLevels; uint32 samples; Gfx::SeFormat format; @@ -140,4 +139,4 @@ class TextureCube : public Gfx::TextureCube, public TextureBase { }; DEFINE_REF(TextureCube) } // namespace Metal -} // namespace Seele \ No newline at end of file +} // namespace Seele diff --git a/src/Engine/Graphics/Metal/Texture.mm b/src/Engine/Graphics/Metal/Texture.mm index 1ebf4e9..5f56976 100644 --- a/src/Engine/Graphics/Metal/Texture.mm +++ b/src/Engine/Graphics/Metal/Texture.mm @@ -3,6 +3,7 @@ #include "Graphics/Enums.h" #include "Graphics/Initializer.h" #include "Graphics/Metal/Graphics.h" +#include "Command.h" #include "Metal/MTLTexture.hpp" #include "Metal/MTLTypes.hpp" @@ -11,7 +12,7 @@ using namespace Seele::Metal; TextureHandle::TextureHandle(PGraphics graphics, MTL::TextureType type, const TextureCreateInfo& createInfo, MTL::Texture* existingImage) : texture(existingImage), type(type), width(createInfo.width), height(createInfo.height), depth(createInfo.depth), - arrayCount(createInfo.elements), layerCount(createInfo.layers), mipLevels(1), samples(createInfo.samples), format(createInfo.format), + arrayCount(createInfo.elements), mipLevels(1), samples(createInfo.samples), format(createInfo.format), usage(createInfo.usage), layout(Gfx::SE_IMAGE_LAYOUT_UNDEFINED), ownsImage(existingImage == nullptr) { if (createInfo.useMip) { mipLevels = static_cast(std::floor(std::log2(std::max(width, height)))) + 1; @@ -37,17 +38,36 @@ TextureHandle::TextureHandle(PGraphics graphics, MTL::TextureType type, const Te descriptor->setTextureType(type); descriptor->setSampleCount(samples); descriptor->setUsage(mtlUsage); + descriptor->setStorageMode(MTL::StorageModePrivate); + if(usage & Gfx::SE_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) { + descriptor->setStorageMode(MTL::StorageModeMemoryless); + } texture = graphics->getDevice()->newTexture(descriptor); + texture->setLabel(NS::String::string(createInfo.name.c_str(), NS::ASCIIStringEncoding)); descriptor->release(); } - // if(createInfo.sourceData.data != nullptr) - // { - // MTL::Region region(0, 0, 0, width, height, depth); - // texture->replaceRegion(region, 0, createInfo.sourceData.data, - // createInfo.sourceData.size / (depth * height)); - // } + if(createInfo.sourceData.data != nullptr) + { + MTL::Buffer* stagingBuffer = graphics->getDevice()->newBuffer(createInfo.sourceData.size, MTL::ResourceStorageModeShared); + std::memcpy(stagingBuffer->contents(), createInfo.sourceData.data, createInfo.sourceData.size); + MTL::BlitCommandEncoder* blitEnc = graphics->getQueue()->getCommands()->getBlitEncoder(); + uint32 sliceSize = createInfo.sourceData.size / arrayCount; + uint32 numSlices = arrayCount; + if(type == MTL::TextureTypeCube || type == MTL::TextureTypeCubeArray) { + sliceSize /= 6; + numSlices *= 6; + } + uint32 offset = 0; + for(uint32 slice = 0; slice < numSlices; ++slice){ + blitEnc->copyFromBuffer(stagingBuffer, offset, sliceSize / createInfo.height, arrayCount == 1 ? 0 : sliceSize, MTL::Size(createInfo.width, createInfo.height, createInfo.depth), texture, slice, 0, MTL::Origin()); + offset += sliceSize; + } + if(mipLevels > 1) { + blitEnc->generateMipmaps(texture); + } + } } TextureHandle::~TextureHandle() { diff --git a/src/Engine/Graphics/Metal/Window.mm b/src/Engine/Graphics/Metal/Window.mm index f10a085..93fcbc5 100644 --- a/src/Engine/Graphics/Metal/Window.mm +++ b/src/Engine/Graphics/Metal/Window.mm @@ -87,11 +87,11 @@ Window::Window(PGraphics graphics, const WindowCreateInfo& createInfo) : graphic metalWindow = glfwGetCocoaWindow(handle); metalLayer = [CAMetalLayer layer]; metalLayer.device = (__bridge id)graphics->getDevice(); - metalLayer.pixelFormat = MTLPixelFormatBGRA8Unorm; + metalLayer.pixelFormat = MTLPixelFormatBGRA8Unorm_sRGB; metalLayer.drawableSize = CGSizeMake(createInfo.width, createInfo.height); metalWindow.contentView.layer = metalLayer; metalWindow.contentView.wantsLayer = YES; - framebufferFormat = Gfx::SE_FORMAT_B8G8R8A8_UNORM; + framebufferFormat = Gfx::SE_FORMAT_B8G8R8A8_SRGB; drawable = (__bridge CA::MetalDrawable*)[metalLayer nextDrawable]; createBackBuffer(); @@ -104,8 +104,6 @@ void Window::show() { glfwShowWindow(windowHandle); } void Window::pollInput() { glfwPollEvents(); } void Window::beginFrame() { - drawable = (__bridge CA::MetalDrawable*)[metalLayer nextDrawable]; - createBackBuffer(); static double start = glfwGetTime(); double end = glfwGetTime(); currentFrameDelta = end - start; @@ -114,9 +112,12 @@ void Window::beginFrame() { } void Window::endFrame() { + graphics->waitDeviceIdle(); graphics->getQueue()->getCommands()->present(drawable); graphics->getQueue()->submitCommands(); currentFrameIndex++; + drawable = (__bridge CA::MetalDrawable*)[metalLayer nextDrawable]; + createBackBuffer(); } void Window::onWindowCloseEvent() {} @@ -156,17 +157,17 @@ void Window::resize(int width, int height) { } paused = true; metalLayer.drawableSize = CGSizeMake(width, height); - drawable->release(); + [drawable release]; framebufferWidth = width; framebufferHeight = height; // Deallocate the textures if they have been created - drawable = (__bridge CA::MetalDrawable*)[[metalLayer nextDrawable] autorelease]; + drawable = (__bridge CA::MetalDrawable*)[metalLayer nextDrawable]; createBackBuffer(); resizeCallback(width, height); } void Window::createBackBuffer() { - MTL::Texture* buf = drawable->texture(); + MTL::Texture* buf = (__bridge MTL::Texture*)[drawable texture]; backBuffer = new Texture2D(graphics, TextureCreateInfo{ .width = static_cast(buf->width()), @@ -186,8 +187,8 @@ Viewport::Viewport(PWindow owner, const ViewportCreateInfo& createInfo) : Gfx::V viewport.height = sizeY; viewport.originX = offsetX; viewport.originY = offsetY; - viewport.znear = 0.0f; - viewport.zfar = 1.0f; + viewport.znear = 1.0f; + viewport.zfar = 0.0f; } Viewport::~Viewport() {} diff --git a/src/Engine/Graphics/RenderPass/BasePass.cpp b/src/Engine/Graphics/RenderPass/BasePass.cpp index 9d57ff4..117205d 100644 --- a/src/Engine/Graphics/RenderPass/BasePass.cpp +++ b/src/Engine/Graphics/RenderPass/BasePass.cpp @@ -259,7 +259,6 @@ void BasePass::render() { graphics->executeCommands(std::move(skyboxCommand)); } graphics->endRenderPass(); - graphics->waitDeviceIdle(); /* // Transparent rendering { @@ -416,13 +415,18 @@ void BasePass::publishOutputs() { msDepthAttachment = Gfx::RenderTargetAttachment(msBasePassDepth, Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, Gfx::SE_ATTACHMENT_LOAD_OP_CLEAR, Gfx::SE_ATTACHMENT_STORE_OP_DONT_CARE); + msDepthAttachment.clear.depthStencil.depth = 0.0f; colorAttachment = Gfx::RenderTargetAttachment(viewport, Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, - Gfx::SE_ATTACHMENT_LOAD_OP_DONT_CARE, Gfx::SE_ATTACHMENT_STORE_OP_STORE); + Gfx::SE_ATTACHMENT_LOAD_OP_DONT_CARE, Gfx::SE_ATTACHMENT_STORE_OP_DONT_CARE); msColorAttachment = Gfx::RenderTargetAttachment(msBasePassColor, Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, Gfx::SE_ATTACHMENT_LOAD_OP_CLEAR, Gfx::SE_ATTACHMENT_STORE_OP_DONT_CARE); + msColorAttachment.clear.color.float32[0] = 0; + msColorAttachment.clear.color.float32[1] = 1; + msColorAttachment.clear.color.float32[2] = 0; + msColorAttachment.clear.color.float32[3] = 1; resources->registerRenderPassOutput("BASEPASS_COLOR", colorAttachment); resources->registerRenderPassOutput("BASEPASS_DEPTH", depthAttachment); diff --git a/src/Engine/Graphics/Vulkan/Texture.cpp b/src/Engine/Graphics/Vulkan/Texture.cpp index 2a4527c..ec16f74 100644 --- a/src/Engine/Graphics/Vulkan/Texture.cpp +++ b/src/Engine/Graphics/Vulkan/Texture.cpp @@ -95,62 +95,62 @@ TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType, const .pObjectName = name.c_str(), }; vkSetDebugUtilsObjectNameEXT(graphics->getDevice(), &nameInfo); - ownsImage = true; - } - const DataSource& sourceData = createInfo.sourceData; - if (sourceData.size > 0) { - changeLayout(Gfx::SE_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_ACCESS_NONE, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, - VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); - void* data; - VkBufferCreateInfo stagingInfo = { - .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, - .pNext = nullptr, - .flags = 0, - .size = sourceData.size, - .usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT, - .sharingMode = VK_SHARING_MODE_EXCLUSIVE, - }; - VmaAllocationCreateInfo alloc = { - .flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT, - .usage = VMA_MEMORY_USAGE_AUTO, - }; - OBufferAllocation stagingAlloc = - new BufferAllocation(graphics, fmt::format("{}Staging", createInfo.name), stagingInfo, alloc, Gfx::QueueType::TRANSFER); - vmaMapMemory(graphics->getAllocator(), stagingAlloc->allocation, &data); - std::memcpy(data, sourceData.data, sourceData.size); - vmaUnmapMemory(graphics->getAllocator(), stagingAlloc->allocation); - - PCommandPool commandPool = graphics->getQueueCommands(owner); - VkBufferImageCopy region = { - .bufferOffset = 0, - .bufferRowLength = 0, - .bufferImageHeight = 0, - .imageSubresource = - { - .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, - .mipLevel = 0, - .baseArrayLayer = 0, - .layerCount = arrayCount * layerCount, - }, - .imageOffset = - { - .x = 0, - .y = 0, - .z = 0, - }, - .imageExtent = {.width = width, .height = height, .depth = depth}, - }; - - vkCmdCopyBufferToImage(commandPool->getCommands()->getHandle(), stagingAlloc->buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - 1, ®ion); - - commandPool->getCommands()->bindResource(PBufferAllocation(stagingAlloc)); - generateMipmaps(); - // When loading a texture from a file, we will almost always use it as a texture map for fragment shaders - changeLayout(Gfx::SE_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_ACCESS_TRANSFER_READ_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, - VK_ACCESS_SHADER_READ_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); - graphics->getDestructionManager()->queueResourceForDestruction(std::move(stagingAlloc)); + ownsImage = true;const DataSource& sourceData = createInfo.sourceData; + if (sourceData.size > 0) { + changeLayout(Gfx::SE_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_ACCESS_NONE, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, + VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); + void* data; + VkBufferCreateInfo stagingInfo = { + .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .size = sourceData.size, + .usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT, + .sharingMode = VK_SHARING_MODE_EXCLUSIVE, + }; + VmaAllocationCreateInfo alloc = { + .flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT, + .usage = VMA_MEMORY_USAGE_AUTO, + }; + OBufferAllocation stagingAlloc = + new BufferAllocation(graphics, fmt::format("{}Staging", createInfo.name), stagingInfo, alloc, Gfx::QueueType::TRANSFER); + vmaMapMemory(graphics->getAllocator(), stagingAlloc->allocation, &data); + std::memcpy(data, sourceData.data, sourceData.size); + vmaUnmapMemory(graphics->getAllocator(), stagingAlloc->allocation); + + PCommandPool commandPool = graphics->getQueueCommands(owner); + VkBufferImageCopy region = { + .bufferOffset = 0, + .bufferRowLength = 0, + .bufferImageHeight = 0, + .imageSubresource = + { + .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, + .mipLevel = 0, + .baseArrayLayer = 0, + .layerCount = arrayCount * layerCount, + }, + .imageOffset = + { + .x = 0, + .y = 0, + .z = 0, + }, + .imageExtent = {.width = width, .height = height, .depth = depth}, + }; + + vkCmdCopyBufferToImage(commandPool->getCommands()->getHandle(), stagingAlloc->buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + 1, ®ion); + + commandPool->getCommands()->bindResource(PBufferAllocation(stagingAlloc)); + generateMipmaps(); + // When loading a texture from a file, we will almost always use it as a texture map for fragment shaders + changeLayout(Gfx::SE_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_ACCESS_TRANSFER_READ_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, + VK_ACCESS_SHADER_READ_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); + graphics->getDestructionManager()->queueResourceForDestruction(std::move(stagingAlloc)); + } } + VkImageViewCreateInfo viewInfo = { .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, .pNext = nullptr,