we are leaking lots of memory

This commit is contained in:
Dynamitos
2025-03-04 19:38:03 +09:00
parent 67b4a533f2
commit 5693802215
14 changed files with 182 additions and 120 deletions
+11 -8
View File
@@ -242,7 +242,7 @@ template <typename T, typename Allocator = std::pmr::polymorphic_allocator<T>> s
template <class Pred> template <class Pred>
requires std::predicate<Pred, value_type> requires std::predicate<Pred, value_type>
constexpr iterator find(Pred pred) noexcept { constexpr iterator find(Pred&& pred) noexcept {
for (size_type i = 0; i < arraySize; ++i) { for (size_type i = 0; i < arraySize; ++i) {
if (pred(_data[i])) { if (pred(_data[i])) {
return iterator(&_data[i]); return iterator(&_data[i]);
@@ -292,8 +292,11 @@ template <typename T, typename Allocator = std::pmr::polymorphic_allocator<T>> s
} }
template <class Pred> template <class Pred>
requires std::predicate<Pred, value_type> requires std::predicate<Pred, value_type>
constexpr void remove_if(Pred pred, bool keepOrder = true) { constexpr void remove_if(Pred&& pred, bool keepOrder = true) {
remove(find(pred), keepOrder); 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(const value_type& element, bool keepOrder = true) { erase(find(element), keepOrder); }
constexpr void remove(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 <typename T, typename Allocator = std::pmr::polymorphic_allocator<T>> s
arraySize = 0; arraySize = 0;
allocated = 0; allocated = 0;
} }
constexpr size_type indexOf(iterator iterator) { return iterator - begin(); } [[nodiscard]] constexpr size_type indexOf(iterator iterator) { return iterator - begin(); }
constexpr size_type indexOf(const_iterator iterator) const { return iterator.p - begin().p; } [[nodiscard]] constexpr size_type indexOf(const_iterator iterator) const { return iterator.p - begin().p; }
constexpr size_type indexOf(T& t) { return indexOf(find(t)); } [[nodiscard]] constexpr size_type indexOf(T& t) { return indexOf(find(t)); }
constexpr size_type indexOf(const T& t) const { return indexOf(find(t)); } [[nodiscard]] constexpr size_type indexOf(const T& t) const { return indexOf(find(t)); }
constexpr size_type size() const noexcept { return arraySize; } [[nodiscard]] constexpr size_type size() const noexcept { return arraySize; }
[[nodiscard]] constexpr bool empty() const noexcept { return arraySize == 0; } [[nodiscard]] constexpr bool empty() const noexcept { return arraySize == 0; }
constexpr void reserve(size_type new_cap) { constexpr void reserve(size_type new_cap) {
if (new_cap > allocated) { if (new_cap > allocated) {
+2 -2
View File
@@ -42,8 +42,7 @@ void BufferAllocation::unmap() {}
Buffer::Buffer(PGraphics graphics, uint64 size, Gfx::SeBufferUsageFlags usage, Gfx::QueueType queueType, bool dynamic, std::string name, Buffer::Buffer(PGraphics graphics, uint64 size, Gfx::SeBufferUsageFlags usage, Gfx::QueueType queueType, bool dynamic, std::string name,
bool createCleared, uint32 clearValue) bool createCleared, uint32 clearValue)
: graphics(graphics), currentBuffer(0), dynamic(dynamic), createCleared(createCleared), name(name), clearValue(clearValue) { : graphics(graphics), currentBuffer(0), dynamic(dynamic), createCleared(createCleared), name(name), clearValue(clearValue) {
if(size > 0) if(size > 0) {
{
buffers.add(nullptr); buffers.add(nullptr);
createBuffer(size, 0); createBuffer(size, 0);
} }
@@ -53,6 +52,7 @@ Buffer::~Buffer() {
for (size_t i = 0; i < buffers.size(); ++i) { for (size_t i = 0; i < buffers.size(); ++i) {
// TODO // TODO
} }
buffers.clear();
} }
void Buffer::updateContents(uint64 regionOffset, uint64 regionSize, void* ptr) { void Buffer::updateContents(uint64 regionOffset, uint64 regionSize, void* ptr) {
+1 -3
View File
@@ -63,7 +63,7 @@ class RenderCommand : public Gfx::RenderCommand {
virtual void bindIndexBuffer(Gfx::PIndexBuffer indexBuffer) override; virtual void bindIndexBuffer(Gfx::PIndexBuffer indexBuffer) override;
virtual void pushConstants(Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size, const void* data) 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 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 drawIndexed(uint32 indexCount, uint32 instanceCount, int32 firstIndex, uint32 vertexOffset, uint32 firstInstance) override;
virtual void drawMesh(uint32 groupX, uint32 groupY, uint32 groupZ) override; virtual void drawMesh(uint32 groupX, uint32 groupY, uint32 groupZ) override;
virtual void drawMeshIndirect(Gfx::PShaderBuffer buffer, uint64 offset, uint32 drawCount, uint32 stride) 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; PGraphicsPipeline boundPipeline;
PIndexBuffer boundIndexBuffer; PIndexBuffer boundIndexBuffer;
MTL::RenderCommandEncoder* encoder; MTL::RenderCommandEncoder* encoder;
MTL::Buffer* constantsBuffer;
std::string name; std::string name;
}; };
DEFINE_REF(RenderCommand) DEFINE_REF(RenderCommand)
@@ -93,7 +92,6 @@ class ComputeCommand : public Gfx::ComputeCommand {
PComputePipeline boundPipeline; PComputePipeline boundPipeline;
MTL::CommandBuffer* commandBuffer; MTL::CommandBuffer* commandBuffer;
MTL::ComputeCommandEncoder* encoder; MTL::ComputeCommandEncoder* encoder;
MTL::Buffer* constantsBuffer;
std::string name; std::string name;
}; };
DEFINE_REF(ComputeCommand) DEFINE_REF(ComputeCommand)
+21 -16
View File
@@ -24,19 +24,29 @@ using namespace Seele::Metal;
Command::Command(PGraphics graphics, MTL::CommandBuffer* cmdBuffer) Command::Command(PGraphics graphics, MTL::CommandBuffer* cmdBuffer)
: graphics(graphics), completed(new Event(graphics)), cmdBuffer(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) { void Command::beginRenderPass(PRenderPass renderPass) {
if (blitEncoder) { if (blitEncoder) {
blitEncoder->endEncoding(); blitEncoder->endEncoding();
blitEncoder->release();
blitEncoder = nullptr; blitEncoder = nullptr;
} }
renderPass->updateRenderPass(); renderPass->updateRenderPass();
parallelEncoder = cmdBuffer->parallelRenderCommandEncoder(renderPass->getDescriptor()); parallelEncoder = cmdBuffer->parallelRenderCommandEncoder(renderPass->getDescriptor());
parallelEncoder->setLabel(NS::String::string(renderPass->getName().c_str(), NS::ASCIIStringEncoding));
} }
void Command::endRenderPass() { void Command::endRenderPass() {
parallelEncoder->endEncoding(); parallelEncoder->endEncoding();
parallelEncoder->release();
parallelEncoder = nullptr; parallelEncoder = nullptr;
} }
@@ -46,6 +56,8 @@ void Command::end(PEvent signal) {
assert(!parallelEncoder); assert(!parallelEncoder);
if (blitEncoder) { if (blitEncoder) {
blitEncoder->endEncoding(); blitEncoder->endEncoding();
blitEncoder->release();
blitEncoder = nullptr;
} }
if (signal != nullptr) { if (signal != nullptr) {
cmdBuffer->encodeSignalEvent(signal->getHandle(), 1); 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(MTL::RenderCommandEncoder* encoder, const std::string& name) : encoder(encoder), name(name) {}
RenderCommand::~RenderCommand() {} RenderCommand::~RenderCommand() { encoder->release(); }
void RenderCommand::end() { encoder->endEncoding(); } void RenderCommand::end() { encoder->endEncoding(); }
@@ -81,9 +93,7 @@ void RenderCommand::setViewport(Gfx::PViewport viewport) {
void RenderCommand::bindPipeline(Gfx::PGraphicsPipeline pipeline) { void RenderCommand::bindPipeline(Gfx::PGraphicsPipeline pipeline) {
boundPipeline = pipeline.cast<GraphicsPipeline>(); boundPipeline = pipeline.cast<GraphicsPipeline>();
encoder->setRenderPipelineState(boundPipeline->getHandle()); encoder->setRenderPipelineState(boundPipeline->getHandle());
if (boundPipeline->getPipelineLayout()->hasPushConstants()) { encoder->setDepthStencilState(boundPipeline->depth);
constantsBuffer = boundPipeline->graphics->getDevice()->newBuffer(boundPipeline->getPipelineLayout()->getPushConstantsSize(), 0);
}
} }
void RenderCommand::bindPipeline(Gfx::PRayTracingPipeline pipeline) {} void RenderCommand::bindPipeline(Gfx::PRayTracingPipeline pipeline) {}
@@ -150,19 +160,18 @@ void RenderCommand::bindVertexBuffer(const Array<Gfx::PVertexBuffer>& buffers) {
void RenderCommand::bindIndexBuffer(Gfx::PIndexBuffer gfxIndexBuffer) { boundIndexBuffer = gfxIndexBuffer.cast<IndexBuffer>(); } void RenderCommand::bindIndexBuffer(Gfx::PIndexBuffer gfxIndexBuffer) { boundIndexBuffer = gfxIndexBuffer.cast<IndexBuffer>(); }
void RenderCommand::pushConstants(Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size, const void* data) { 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"); uint pushIndex = boundPipeline->getPipelineLayout()->findParameter("pOffsets");
if (stage & Gfx::SE_SHADER_STAGE_VERTEX_BIT) { 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) { 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) { 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) { 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) ComputeCommand::ComputeCommand(MTL::CommandBuffer* cmdBuffer, const std::string& name)
: commandBuffer(cmdBuffer), encoder(cmdBuffer->computeCommandEncoder()), name(name) {} : commandBuffer(cmdBuffer), encoder(cmdBuffer->computeCommandEncoder()), name(name) {}
ComputeCommand::~ComputeCommand() {} ComputeCommand::~ComputeCommand() { encoder->release(); commandBuffer->release(); }
void ComputeCommand::end() { void ComputeCommand::end() {
encoder->endEncoding(); encoder->endEncoding();
@@ -201,9 +210,6 @@ void ComputeCommand::end() {
void ComputeCommand::bindPipeline(Gfx::PComputePipeline pipeline) { void ComputeCommand::bindPipeline(Gfx::PComputePipeline pipeline) {
boundPipeline = pipeline.cast<ComputePipeline>(); boundPipeline = pipeline.cast<ComputePipeline>();
encoder->setComputePipelineState(boundPipeline->getHandle()); encoder->setComputePipelineState(boundPipeline->getHandle());
if (boundPipeline->getPipelineLayout()->hasPushConstants()) {
constantsBuffer = boundPipeline->graphics->getDevice()->newBuffer(boundPipeline->getPipelineLayout()->getPushConstantsSize(), 0);
}
} }
void ComputeCommand::bindDescriptor(Gfx::PDescriptorSet set) { void ComputeCommand::bindDescriptor(Gfx::PDescriptorSet set) {
@@ -248,9 +254,8 @@ void ComputeCommand::bindDescriptor(const Array<Gfx::PDescriptorSet>& sets) {
} }
void ComputeCommand::pushConstants(Gfx::SeShaderStageFlags, uint32 offset, uint32 size, const void* data) { void ComputeCommand::pushConstants(Gfx::SeShaderStageFlags, uint32 offset, uint32 size, const void* data) {
std::memcpy(constantsBuffer->contents(), data, size);
uint pushIndex = boundPipeline->getPipelineLayout()->findParameter("pMipParam"); 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) { void ComputeCommand::dispatch(uint32 threadX, uint32 threadY, uint32 threadZ) {
+19 -9
View File
@@ -26,7 +26,7 @@ using namespace Seele::Metal;
DescriptorLayout::DescriptorLayout(PGraphics graphics, const std::string& name) : Gfx::DescriptorLayout(name), graphics(graphics) {} DescriptorLayout::DescriptorLayout(PGraphics graphics, const std::string& name) : Gfx::DescriptorLayout(name), graphics(graphics) {}
DescriptorLayout::~DescriptorLayout() {} DescriptorLayout::~DescriptorLayout() { arguments->release(); }
void DescriptorLayout::create() { void DescriptorLayout::create() {
pool = new DescriptorPool(graphics, this); pool = new DescriptorPool(graphics, this);
@@ -36,14 +36,14 @@ void DescriptorLayout::create() {
for (uint32 i = 0; i < descriptorBindings.size(); ++i) { for (uint32 i = 0; i < descriptorBindings.size(); ++i) {
if (descriptorBindings[i].descriptorType != Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER) { if (descriptorBindings[i].descriptorType != Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER) {
plainDescriptor = false; 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{ variableMapping[descriptorBindings[i].name] = DescriptorMapping{
.index = mappingCounter, .index = mappingCounter,
.constantSize = descriptorBindings[i].uniformLength, .constantSize = descriptorBindings[i].uniformLength,
@@ -53,6 +53,7 @@ void DescriptorLayout::create() {
} }
numResources = mappingCounter; numResources = mappingCounter;
arguments = NS::Array::array((NS::Object**)objects, descriptorBindings.size()); arguments = NS::Array::array((NS::Object**)objects, descriptorBindings.size());
delete[] objects;
} }
MTL::ArgumentEncoder* DescriptorLayout::createEncoder() { return graphics->getDevice()->newArgumentEncoder(arguments); } MTL::ArgumentEncoder* DescriptorLayout::createEncoder() { return graphics->getDevice()->newArgumentEncoder(arguments); }
@@ -79,9 +80,18 @@ void DescriptorPool::reset() {}
DescriptorSet::DescriptorSet(PGraphics graphics, PDescriptorPool owner) DescriptorSet::DescriptorSet(PGraphics graphics, PDescriptorPool owner)
: Gfx::DescriptorSet(owner->getLayout()), CommandBoundResource(graphics), graphics(graphics), owner(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() { void DescriptorSet::reset() {
uniformWrites.clear(); uniformWrites.clear();
+1
View File
@@ -21,6 +21,7 @@ class GraphicsPipeline : public Gfx::GraphicsPipeline {
constexpr MTL::PrimitiveType getPrimitive() const { return primitiveType; } constexpr MTL::PrimitiveType getPrimitive() const { return primitiveType; }
PGraphics graphics; PGraphics graphics;
MTL::RenderPipelineState* state; MTL::RenderPipelineState* state;
MTL::DepthStencilState* depth;
MTL::PrimitiveType primitiveType; MTL::PrimitiveType primitiveType;
MTL::Function* taskFunction = nullptr; MTL::Function* taskFunction = nullptr;
Array<uint32> taskSets; Array<uint32> taskSets;
+10 -1
View File
@@ -86,7 +86,11 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::LegacyPipelineCreateInfo cr
desc->setBlendingEnabled(false); desc->setBlendingEnabled(false);
pipelineDescriptor->colorAttachments()->setObject(desc, c); pipelineDescriptor->colorAttachments()->setObject(desc, c);
} }
MTL::DepthStencilDescriptor* depthDescriptor = MTL::DepthStencilDescriptor::alloc()->init();
if (createInfo.renderPass->getLayout().depthAttachment.getTexture() != nullptr) { if (createInfo.renderPass->getLayout().depthAttachment.getTexture() != nullptr) {
depthDescriptor->setDepthWriteEnabled(createInfo.depthStencilState.depthWriteEnable);
depthDescriptor->setDepthCompareFunction(cast(createInfo.depthStencilState.depthCompareOp));
pipelineDescriptor->setDepthAttachmentPixelFormat( pipelineDescriptor->setDepthAttachmentPixelFormat(
cast(createInfo.renderPass->getLayout().depthAttachment.getTexture().cast<Texture2D>()->getFormat())); cast(createInfo.renderPass->getLayout().depthAttachment.getTexture().cast<Texture2D>()->getFormat()));
} }
@@ -94,7 +98,10 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::LegacyPipelineCreateInfo cr
pipelineDescriptor->setAlphaToOneEnabled(createInfo.multisampleState.alphaToOneEnable); pipelineDescriptor->setAlphaToOneEnabled(createInfo.multisampleState.alphaToOneEnable);
pipelineDescriptor->setRasterSampleCount(createInfo.multisampleState.samples); pipelineDescriptor->setRasterSampleCount(createInfo.multisampleState.samples);
pipelineDescriptor->setRasterizationEnabled(!createInfo.rasterizationState.rasterizerDiscardEnable); pipelineDescriptor->setRasterizationEnabled(!createInfo.rasterizationState.rasterizerDiscardEnable);
MTL::DepthStencilState* depthState = graphics->getDevice()->newDepthStencilState(depthDescriptor);
depthDescriptor->release();
uint32 hash = pipelineDescriptor->hash(); uint32 hash = pipelineDescriptor->hash();
if (graphicsPipelines.contains(hash)) { if (graphicsPipelines.contains(hash)) {
@@ -145,10 +152,12 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::LegacyPipelineCreateInfo cr
} }
pipelineDescriptor->release(); pipelineDescriptor->release();
graphicsPipelines[hash]->vertexSets = vertexSets; graphicsPipelines[hash]->vertexSets = vertexSets;
graphicsPipelines[hash]->vertexFunction = vertexFunction; graphicsPipelines[hash]->vertexFunction = vertexFunction;
graphicsPipelines[hash]->fragmentSets = fragmentSets; graphicsPipelines[hash]->fragmentSets = fragmentSets;
graphicsPipelines[hash]->fragmentFunction = fragmentFunction; graphicsPipelines[hash]->fragmentFunction = fragmentFunction;
graphicsPipelines[hash]->depth = depthState;
return graphicsPipelines[hash]; return graphicsPipelines[hash];
} }
+3 -1
View File
@@ -12,12 +12,14 @@ class RenderPass : public Gfx::RenderPass {
virtual ~RenderPass(); virtual ~RenderPass();
void updateRenderPass(); void updateRenderPass();
MTL::RenderPassDescriptor* getDescriptor() const { return renderPass; } MTL::RenderPassDescriptor* getDescriptor() const { return renderPass; }
const std::string& getName() const { return name; }
private: private:
PGraphics graphics; PGraphics graphics;
Gfx::PViewport viewport; Gfx::PViewport viewport;
MTL::RenderPassDescriptor* renderPass; MTL::RenderPassDescriptor* renderPass;
std::string name;
}; };
DEFINE_REF(RenderPass) DEFINE_REF(RenderPass)
} // namespace Metal } // namespace Metal
} // namespace Seele } // namespace Seele
+15 -5
View File
@@ -7,9 +7,9 @@
using namespace Seele; using namespace Seele;
using namespace Seele::Metal; using namespace Seele::Metal;
RenderPass::RenderPass(PGraphics graphics, Gfx::RenderTargetLayout layout, Array<Gfx::SubPassDependency> dependencies, RenderPass::RenderPass(PGraphics graphics, Gfx::RenderTargetLayout _layout, Array<Gfx::SubPassDependency> dependencies,
Gfx::PViewport viewport, const std::string& name) 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 = MTL::RenderPassDescriptor::renderPassDescriptor();
renderPass->setRenderTargetArrayLength(1); renderPass->setRenderTargetArrayLength(1);
renderPass->setRenderTargetWidth(viewport->getWidth()); renderPass->setRenderTargetWidth(viewport->getWidth());
@@ -27,7 +27,12 @@ RenderPass::RenderPass(PGraphics graphics, Gfx::RenderTargetLayout layout, Array
if (!layout.resolveAttachments.empty()) { if (!layout.resolveAttachments.empty()) {
const auto& resolve = layout.resolveAttachments[i]; const auto& resolve = layout.resolveAttachments[i];
desc->setResolveLevel(0); 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<TextureBase>()->getImage()); desc->setResolveTexture(resolve.getTexture().cast<TextureBase>()->getImage());
} }
} }
@@ -38,8 +43,13 @@ RenderPass::RenderPass(PGraphics graphics, Gfx::RenderTargetLayout layout, Array
depth->setStoreAction(cast(layout.depthAttachment.getStoreOp())); depth->setStoreAction(cast(layout.depthAttachment.getStoreOp()));
if (layout.depthResolveAttachment.getTexture() != nullptr) { 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<TextureBase>()->getImage()); depth->setResolveTexture(layout.depthResolveAttachment.getTexture().cast<TextureBase>()->getImage());
depth->setStoreAction(MTL::StoreActionStoreAndMultisampleResolve);
} }
} }
// TODO: stencil // TODO: stencil
@@ -56,4 +66,4 @@ void RenderPass::updateRenderPass() {
auto depth = renderPass->depthAttachment(); auto depth = renderPass->depthAttachment();
depth->setTexture(layout.depthAttachment.getTexture().cast<TextureBase>()->getImage()); depth->setTexture(layout.depthAttachment.getTexture().cast<TextureBase>()->getImage());
} }
} }
+1 -2
View File
@@ -24,7 +24,6 @@ class TextureHandle {
uint32 height; uint32 height;
uint32 depth; uint32 depth;
uint32 arrayCount; uint32 arrayCount;
uint32 layerCount;
uint32 mipLevels; uint32 mipLevels;
uint32 samples; uint32 samples;
Gfx::SeFormat format; Gfx::SeFormat format;
@@ -140,4 +139,4 @@ class TextureCube : public Gfx::TextureCube, public TextureBase {
}; };
DEFINE_REF(TextureCube) DEFINE_REF(TextureCube)
} // namespace Metal } // namespace Metal
} // namespace Seele } // namespace Seele
+27 -7
View File
@@ -3,6 +3,7 @@
#include "Graphics/Enums.h" #include "Graphics/Enums.h"
#include "Graphics/Initializer.h" #include "Graphics/Initializer.h"
#include "Graphics/Metal/Graphics.h" #include "Graphics/Metal/Graphics.h"
#include "Command.h"
#include "Metal/MTLTexture.hpp" #include "Metal/MTLTexture.hpp"
#include "Metal/MTLTypes.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) 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), : 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) { usage(createInfo.usage), layout(Gfx::SE_IMAGE_LAYOUT_UNDEFINED), ownsImage(existingImage == nullptr) {
if (createInfo.useMip) { if (createInfo.useMip) {
mipLevels = static_cast<uint32_t>(std::floor(std::log2(std::max(width, height)))) + 1; mipLevels = static_cast<uint32_t>(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->setTextureType(type);
descriptor->setSampleCount(samples); descriptor->setSampleCount(samples);
descriptor->setUsage(mtlUsage); 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 = graphics->getDevice()->newTexture(descriptor);
texture->setLabel(NS::String::string(createInfo.name.c_str(), NS::ASCIIStringEncoding));
descriptor->release(); descriptor->release();
} }
// if(createInfo.sourceData.data != nullptr) if(createInfo.sourceData.data != nullptr)
// { {
// MTL::Region region(0, 0, 0, width, height, depth); MTL::Buffer* stagingBuffer = graphics->getDevice()->newBuffer(createInfo.sourceData.size, MTL::ResourceStorageModeShared);
// texture->replaceRegion(region, 0, createInfo.sourceData.data, std::memcpy(stagingBuffer->contents(), createInfo.sourceData.data, createInfo.sourceData.size);
// createInfo.sourceData.size / (depth * height)); 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() { TextureHandle::~TextureHandle() {
+10 -9
View File
@@ -87,11 +87,11 @@ Window::Window(PGraphics graphics, const WindowCreateInfo& createInfo) : graphic
metalWindow = glfwGetCocoaWindow(handle); metalWindow = glfwGetCocoaWindow(handle);
metalLayer = [CAMetalLayer layer]; metalLayer = [CAMetalLayer layer];
metalLayer.device = (__bridge id<MTLDevice>)graphics->getDevice(); metalLayer.device = (__bridge id<MTLDevice>)graphics->getDevice();
metalLayer.pixelFormat = MTLPixelFormatBGRA8Unorm; metalLayer.pixelFormat = MTLPixelFormatBGRA8Unorm_sRGB;
metalLayer.drawableSize = CGSizeMake(createInfo.width, createInfo.height); metalLayer.drawableSize = CGSizeMake(createInfo.width, createInfo.height);
metalWindow.contentView.layer = metalLayer; metalWindow.contentView.layer = metalLayer;
metalWindow.contentView.wantsLayer = YES; metalWindow.contentView.wantsLayer = YES;
framebufferFormat = Gfx::SE_FORMAT_B8G8R8A8_UNORM; framebufferFormat = Gfx::SE_FORMAT_B8G8R8A8_SRGB;
drawable = (__bridge CA::MetalDrawable*)[metalLayer nextDrawable]; drawable = (__bridge CA::MetalDrawable*)[metalLayer nextDrawable];
createBackBuffer(); createBackBuffer();
@@ -104,8 +104,6 @@ void Window::show() { glfwShowWindow(windowHandle); }
void Window::pollInput() { glfwPollEvents(); } void Window::pollInput() { glfwPollEvents(); }
void Window::beginFrame() { void Window::beginFrame() {
drawable = (__bridge CA::MetalDrawable*)[metalLayer nextDrawable];
createBackBuffer();
static double start = glfwGetTime(); static double start = glfwGetTime();
double end = glfwGetTime(); double end = glfwGetTime();
currentFrameDelta = end - start; currentFrameDelta = end - start;
@@ -114,9 +112,12 @@ void Window::beginFrame() {
} }
void Window::endFrame() { void Window::endFrame() {
graphics->waitDeviceIdle();
graphics->getQueue()->getCommands()->present(drawable); graphics->getQueue()->getCommands()->present(drawable);
graphics->getQueue()->submitCommands(); graphics->getQueue()->submitCommands();
currentFrameIndex++; currentFrameIndex++;
drawable = (__bridge CA::MetalDrawable*)[metalLayer nextDrawable];
createBackBuffer();
} }
void Window::onWindowCloseEvent() {} void Window::onWindowCloseEvent() {}
@@ -156,17 +157,17 @@ void Window::resize(int width, int height) {
} }
paused = true; paused = true;
metalLayer.drawableSize = CGSizeMake(width, height); metalLayer.drawableSize = CGSizeMake(width, height);
drawable->release(); [drawable release];
framebufferWidth = width; framebufferWidth = width;
framebufferHeight = height; framebufferHeight = height;
// Deallocate the textures if they have been created // Deallocate the textures if they have been created
drawable = (__bridge CA::MetalDrawable*)[[metalLayer nextDrawable] autorelease]; drawable = (__bridge CA::MetalDrawable*)[metalLayer nextDrawable];
createBackBuffer(); createBackBuffer();
resizeCallback(width, height); resizeCallback(width, height);
} }
void Window::createBackBuffer() { void Window::createBackBuffer() {
MTL::Texture* buf = drawable->texture(); MTL::Texture* buf = (__bridge MTL::Texture*)[drawable texture];
backBuffer = new Texture2D(graphics, backBuffer = new Texture2D(graphics,
TextureCreateInfo{ TextureCreateInfo{
.width = static_cast<uint32>(buf->width()), .width = static_cast<uint32>(buf->width()),
@@ -186,8 +187,8 @@ Viewport::Viewport(PWindow owner, const ViewportCreateInfo& createInfo) : Gfx::V
viewport.height = sizeY; viewport.height = sizeY;
viewport.originX = offsetX; viewport.originX = offsetX;
viewport.originY = offsetY; viewport.originY = offsetY;
viewport.znear = 0.0f; viewport.znear = 1.0f;
viewport.zfar = 1.0f; viewport.zfar = 0.0f;
} }
Viewport::~Viewport() {} Viewport::~Viewport() {}
+6 -2
View File
@@ -259,7 +259,6 @@ void BasePass::render() {
graphics->executeCommands(std::move(skyboxCommand)); graphics->executeCommands(std::move(skyboxCommand));
} }
graphics->endRenderPass(); graphics->endRenderPass();
graphics->waitDeviceIdle();
/* /*
// Transparent rendering // Transparent rendering
{ {
@@ -416,13 +415,18 @@ void BasePass::publishOutputs() {
msDepthAttachment = msDepthAttachment =
Gfx::RenderTargetAttachment(msBasePassDepth, Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 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); 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, 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 = msColorAttachment =
Gfx::RenderTargetAttachment(msBasePassColor, Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 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); 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_COLOR", colorAttachment);
resources->registerRenderPassOutput("BASEPASS_DEPTH", depthAttachment); resources->registerRenderPassOutput("BASEPASS_DEPTH", depthAttachment);
+55 -55
View File
@@ -95,62 +95,62 @@ TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType, const
.pObjectName = name.c_str(), .pObjectName = name.c_str(),
}; };
vkSetDebugUtilsObjectNameEXT(graphics->getDevice(), &nameInfo); vkSetDebugUtilsObjectNameEXT(graphics->getDevice(), &nameInfo);
ownsImage = true; ownsImage = true;const DataSource& sourceData = createInfo.sourceData;
} if (sourceData.size > 0) {
const DataSource& sourceData = createInfo.sourceData; changeLayout(Gfx::SE_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_ACCESS_NONE, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
if (sourceData.size > 0) { VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
changeLayout(Gfx::SE_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_ACCESS_NONE, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, void* data;
VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); VkBufferCreateInfo stagingInfo = {
void* data; .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
VkBufferCreateInfo stagingInfo = { .pNext = nullptr,
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, .flags = 0,
.pNext = nullptr, .size = sourceData.size,
.flags = 0, .usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
.size = sourceData.size, .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
.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,
VmaAllocationCreateInfo alloc = { .usage = VMA_MEMORY_USAGE_AUTO,
.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);
OBufferAllocation stagingAlloc = vmaMapMemory(graphics->getAllocator(), stagingAlloc->allocation, &data);
new BufferAllocation(graphics, fmt::format("{}Staging", createInfo.name), stagingInfo, alloc, Gfx::QueueType::TRANSFER); std::memcpy(data, sourceData.data, sourceData.size);
vmaMapMemory(graphics->getAllocator(), stagingAlloc->allocation, &data); vmaUnmapMemory(graphics->getAllocator(), stagingAlloc->allocation);
std::memcpy(data, sourceData.data, sourceData.size);
vmaUnmapMemory(graphics->getAllocator(), stagingAlloc->allocation); PCommandPool commandPool = graphics->getQueueCommands(owner);
VkBufferImageCopy region = {
PCommandPool commandPool = graphics->getQueueCommands(owner); .bufferOffset = 0,
VkBufferImageCopy region = { .bufferRowLength = 0,
.bufferOffset = 0, .bufferImageHeight = 0,
.bufferRowLength = 0, .imageSubresource =
.bufferImageHeight = 0, {
.imageSubresource = .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
{ .mipLevel = 0,
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, .baseArrayLayer = 0,
.mipLevel = 0, .layerCount = arrayCount * layerCount,
.baseArrayLayer = 0, },
.layerCount = arrayCount * layerCount, .imageOffset =
}, {
.imageOffset = .x = 0,
{ .y = 0,
.x = 0, .z = 0,
.y = 0, },
.z = 0, .imageExtent = {.width = width, .height = height, .depth = depth},
}, };
.imageExtent = {.width = width, .height = height, .depth = depth},
}; vkCmdCopyBufferToImage(commandPool->getCommands()->getHandle(), stagingAlloc->buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1, &region);
vkCmdCopyBufferToImage(commandPool->getCommands()->getHandle(), stagingAlloc->buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1, &region); commandPool->getCommands()->bindResource(PBufferAllocation(stagingAlloc));
generateMipmaps();
commandPool->getCommands()->bindResource(PBufferAllocation(stagingAlloc)); // When loading a texture from a file, we will almost always use it as a texture map for fragment shaders
generateMipmaps(); changeLayout(Gfx::SE_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_ACCESS_TRANSFER_READ_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
// When loading a texture from a file, we will almost always use it as a texture map for fragment shaders VK_ACCESS_SHADER_READ_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
changeLayout(Gfx::SE_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_ACCESS_TRANSFER_READ_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, graphics->getDestructionManager()->queueResourceForDestruction(std::move(stagingAlloc));
VK_ACCESS_SHADER_READ_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); }
graphics->getDestructionManager()->queueResourceForDestruction(std::move(stagingAlloc));
} }
VkImageViewCreateInfo viewInfo = { VkImageViewCreateInfo viewInfo = {
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
.pNext = nullptr, .pNext = nullptr,