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>
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) {
if (pred(_data[i])) {
return iterator(&_data[i]);
@@ -292,8 +292,11 @@ template <typename T, typename Allocator = std::pmr::polymorphic_allocator<T>> s
}
template <class Pred>
requires std::predicate<Pred, value_type>
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 <typename T, typename Allocator = std::pmr::polymorphic_allocator<T>> 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) {
+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,
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) {
+1 -3
View File
@@ -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)
+21 -16
View File
@@ -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<GraphicsPipeline>();
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<Gfx::PVertexBuffer>& buffers) {
void RenderCommand::bindIndexBuffer(Gfx::PIndexBuffer gfxIndexBuffer) { boundIndexBuffer = gfxIndexBuffer.cast<IndexBuffer>(); }
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<ComputePipeline>();
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<Gfx::PDescriptorSet>& 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) {
+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() {}
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();
+1
View File
@@ -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<uint32> taskSets;
+10 -1
View File
@@ -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<Texture2D>()->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];
}
+3 -1
View File
@@ -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
} // namespace Seele
+15 -5
View File
@@ -7,9 +7,9 @@
using namespace Seele;
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::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<TextureBase>()->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<TextureBase>()->getImage());
depth->setStoreAction(MTL::StoreActionStoreAndMultisampleResolve);
}
}
// TODO: stencil
@@ -56,4 +66,4 @@ void RenderPass::updateRenderPass() {
auto depth = renderPass->depthAttachment();
depth->setTexture(layout.depthAttachment.getTexture().cast<TextureBase>()->getImage());
}
}
}
+1 -2
View File
@@ -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
} // namespace Seele
+27 -7
View File
@@ -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<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->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() {
+10 -9
View File
@@ -87,11 +87,11 @@ Window::Window(PGraphics graphics, const WindowCreateInfo& createInfo) : graphic
metalWindow = glfwGetCocoaWindow(handle);
metalLayer = [CAMetalLayer layer];
metalLayer.device = (__bridge id<MTLDevice>)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<uint32>(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() {}
+6 -2
View File
@@ -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);
+55 -55
View File
@@ -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, &region);
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, &region);
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,