diff --git a/res/shaders/MeshletBasePass.slang b/res/shaders/MeshletBasePass.slang index c9163be..a5800f4 100644 --- a/res/shaders/MeshletBasePass.slang +++ b/res/shaders/MeshletBasePass.slang @@ -51,7 +51,7 @@ void taskMain( { uint m = mesh.meshletOffset + i; MeshletDescription meshlet = pScene.meshletInfos[m]; - //if(meshlet.boundingBox.insideFrustum(localToClip, viewFrustum)) + if(meshlet.boundingBox.insideFrustum(localToClip, viewFrustum)) { uint index; InterlockedAdd(head, 1, index); diff --git a/src/Engine/Graphics/Resources.h b/src/Engine/Graphics/Resources.h index 5c992e7..b02e830 100644 --- a/src/Engine/Graphics/Resources.h +++ b/src/Engine/Graphics/Resources.h @@ -10,7 +10,7 @@ #ifndef ENABLE_VALIDATION -#define ENABLE_VALIDATION 0 +#define ENABLE_VALIDATION 1 #endif namespace Seele diff --git a/src/Engine/Graphics/VertexData.cpp b/src/Engine/Graphics/VertexData.cpp index 69deac8..c951c53 100644 --- a/src/Engine/Graphics/VertexData.cpp +++ b/src/Engine/Graphics/VertexData.cpp @@ -100,11 +100,11 @@ void VertexData::loadMesh(MeshId id, Array loadedIndices, Array { uint32 numMeshlets = std::min(512, loadedMeshlets.size() - currentMesh); uint32 meshletOffset = meshlets.size(); - //AABB meshAABB; + AABB meshAABB; for (uint32 i = 0; i < numMeshlets; ++i) { Meshlet& m = loadedMeshlets[currentMesh + i]; - //meshAABB = meshAABB.combine(m.boundingBox); + meshAABB = meshAABB.combine(m.boundingBox); uint32 vertexOffset = vertexIndices.size(); vertexIndices.resize(vertexOffset + m.numVertices); std::memcpy(vertexIndices.data() + vertexOffset, m.uniqueVertices, m.numVertices * sizeof(uint32)); @@ -121,6 +121,7 @@ void VertexData::loadMesh(MeshId id, Array loadedIndices, Array }); } meshData[id].add(MeshData{ + .boundingBox = meshAABB, .numMeshlets = numMeshlets, .meshletOffset = meshletOffset, .indicesOffset = (uint32)meshOffsets[id], diff --git a/src/Engine/Graphics/Vulkan/Allocator.cpp b/src/Engine/Graphics/Vulkan/Allocator.cpp index 250395d..c1973fa 100644 --- a/src/Engine/Graphics/Vulkan/Allocator.cpp +++ b/src/Engine/Graphics/Vulkan/Allocator.cpp @@ -134,6 +134,10 @@ void Allocation::markFree(PSubAllocation allocation) } activeAllocations.remove(allocation, false); bytesUsed -= allocation->allocatedSize; + //if (activeAllocations.size() == 0) + //{ + // pool->free(this); + //} } void Allocation::flushMemory() @@ -203,7 +207,7 @@ OSubAllocation Allocator::allocate(const VkMemoryRequirements2 &memRequirements2 OSubAllocation suballoc = alloc->getSuballocation(requirements.size, requirements.alignment); if (suballoc != nullptr) { - return std::move(suballoc); + return suballoc; } } } @@ -216,18 +220,15 @@ OSubAllocation Allocator::allocate(const VkMemoryRequirements2 &memRequirements2 return heaps[heapIndex].allocations.back()->getSuballocation(requirements.size, requirements.alignment); } -void Allocator::free() +void Allocator::free(PAllocation allocation) { for (uint32 heapIndex = 0; heapIndex < heaps.size(); ++heapIndex) { for (uint32 alloc = 0; alloc < heaps[heapIndex].allocations.size(); ++alloc) { - if (heaps[heapIndex].allocations[alloc]->bytesUsed == 0) + if (heaps[heapIndex].allocations[alloc] == allocation) { - heaps[heapIndex].inUse -= heaps[heapIndex].allocations[alloc]->bytesAllocated; - std::cout << "Heap " << heapIndex << ": " << (float)heaps[heapIndex].inUse / heaps[heapIndex].maxSize * 100 << "%" << std::endl; heaps[heapIndex].allocations.removeAt(alloc, false); - alloc--; } } } @@ -259,7 +260,7 @@ uint32 Allocator::findMemoryType(uint32 typeFilter, VkMemoryPropertyFlags proper } StagingBuffer::StagingBuffer(PGraphics graphics, OSubAllocation allocation, VkBuffer buffer, VkDeviceSize size, Gfx::QueueType owner) - : QueueOwnedResource(graphics->getFamilyMapping(), owner) + : owner(owner) , graphics(graphics) , allocation(std::move(allocation)) , buffer(buffer) @@ -270,9 +271,9 @@ StagingBuffer::StagingBuffer(PGraphics graphics, OSubAllocation allocation, VkBu StagingBuffer::~StagingBuffer() { graphics->getDestructionManager()->queueBuffer( - graphics->getQueueCommands(currentOwner)->getCommands(), buffer); + graphics->getQueueCommands(owner)->getCommands(), buffer); graphics->getDestructionManager()->queueAllocation( - graphics->getQueueCommands(currentOwner)->getCommands(), std::move(allocation)); + graphics->getQueueCommands(owner)->getCommands(), std::move(allocation)); } void* StagingBuffer::map() @@ -300,28 +301,6 @@ VkDeviceSize StagingBuffer::getOffset() const return allocation->getOffset(); } -void StagingBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) -{ - assert(false); -} -void StagingBuffer::executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, - Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) -{ - PCommand commandBuffer = graphics->getQueueCommands(currentOwner)->getCommands(); - VkBufferMemoryBarrier barrier = { - .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, - .pNext = nullptr, - .srcAccessMask = srcAccess, - .dstAccessMask = dstAccess, - .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, - .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, - .buffer = buffer, - .offset = 0, - .size = size, - }; - vkCmdPipelineBarrier(commandBuffer->getHandle(), srcStage, dstStage, 0, 0, nullptr, 1, &barrier, 0, nullptr); -} - StagingManager::StagingManager(PGraphics graphics, PAllocator pool) : graphics(graphics), pool(pool) { @@ -333,8 +312,18 @@ StagingManager::~StagingManager() OStagingBuffer StagingManager::create(uint64 size, Gfx::QueueType owner) { + //vkDeviceWaitIdle(graphics->getDevice()); //std::cout << "Creating new stagingbuffer" << std::endl; - uint32 queueIndex = graphics->getFamilyMapping().getQueueTypeFamilyIndex(Gfx::QueueType::DEDICATED_TRANSFER); + for (uint32 i = 0; i < freeBuffers.size(); ++i) + { + if (size <= freeBuffers[i]->getSize() && owner == freeBuffers[i]->getOwner()) + { + OStagingBuffer result = std::move(freeBuffers[i]); + freeBuffers.removeAt(i); + return result; + } + } + uint32 queueIndex = graphics->getFamilyMapping().getQueueTypeFamilyIndex(owner); VkBufferCreateInfo stagingBufferCreateInfo = { .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, .pNext = nullptr, @@ -375,3 +364,8 @@ OStagingBuffer StagingManager::create(uint64 size, Gfx::QueueType owner) return stagingBuffer; } + +void StagingManager::release(OStagingBuffer buffer) +{ + freeBuffers.add(std::move(buffer)); +} diff --git a/src/Engine/Graphics/Vulkan/Allocator.h b/src/Engine/Graphics/Vulkan/Allocator.h index 589a2f6..8869a9e 100644 --- a/src/Engine/Graphics/Vulkan/Allocator.h +++ b/src/Engine/Graphics/Vulkan/Allocator.h @@ -49,6 +49,8 @@ class Allocation public: Allocation(PGraphics graphics, PAllocator pool, VkDeviceSize size, uint8 memoryTypeIndex, VkMemoryPropertyFlags properties, VkMemoryDedicatedAllocateInfo *dedicatedInfo = nullptr); + Allocation(const Allocation& other) = delete; + Allocation& operator=(const Allocation& other) = delete; ~Allocation(); OSubAllocation getSuballocation(VkDeviceSize size, VkDeviceSize alignment); void markFree(PSubAllocation alloc); @@ -122,7 +124,7 @@ public: return allocate(requirements, props, &allocInfo); } - void free(); + void free(PAllocation allocation); void print(); private: static constexpr VkDeviceSize DEFAULT_ALLOCATION = 16 * 1024 * 1024; // 16MB @@ -143,7 +145,7 @@ private: VkPhysicalDeviceMemoryProperties memProperties; }; DEFINE_REF(Allocator) -class StagingBuffer : public Gfx::QueueOwnedResource +class StagingBuffer { public: StagingBuffer(PGraphics graphics, OSubAllocation allocation, VkBuffer buffer, VkDeviceSize size, Gfx::QueueType owner); @@ -161,10 +163,12 @@ public: { return size; } + constexpr Gfx::QueueType getOwner() const + { + return owner; + } private: - virtual void executeOwnershipBarrier(Gfx::QueueType newOwner) override; - virtual void executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, - Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) override; + Gfx::QueueType owner; OSubAllocation allocation; PGraphics graphics; VkBuffer buffer; @@ -178,10 +182,11 @@ public: StagingManager(PGraphics graphics, PAllocator pool); ~StagingManager(); OStagingBuffer create(uint64 size, Gfx::QueueType owner); - + void release(OStagingBuffer buffer); private: PGraphics graphics; PAllocator pool; + Array freeBuffers; }; DEFINE_REF(StagingManager) } // namespace Vulkan diff --git a/src/Engine/Graphics/Vulkan/Buffer.cpp b/src/Engine/Graphics/Vulkan/Buffer.cpp index 6744549..4aa6c16 100644 --- a/src/Engine/Graphics/Vulkan/Buffer.cpp +++ b/src/Engine/Graphics/Vulkan/Buffer.cpp @@ -255,6 +255,7 @@ void Buffer::unmap() vkCmdCopyBuffer(cmdHandle, stagingBuffer->getHandle(), buffers[currentBuffer].buffer, 1, ®ion); } //requestOwnershipTransfer(pending.prevQueue); + graphics->getStagingManager()->release(std::move(pending.stagingBuffer)); pendingBuffers.erase(this); } } @@ -278,6 +279,10 @@ UniformBuffer::UniformBuffer(PGraphics graphics, const UniformBufferCreateInfo & UniformBuffer::~UniformBuffer() { + if (dedicatedStagingBuffer != nullptr) + { + graphics->getStagingManager()->release(std::move(dedicatedStagingBuffer)); + } } bool UniformBuffer::updateContents(const DataSource &sourceData) @@ -365,6 +370,10 @@ ShaderBuffer::ShaderBuffer(PGraphics graphics, const ShaderBufferCreateInfo &sou ShaderBuffer::~ShaderBuffer() { + if (dedicatedStagingBuffer != nullptr) + { + graphics->getStagingManager()->release(std::move(dedicatedStagingBuffer)); + } } bool ShaderBuffer::updateContents(const DataSource &sourceData) diff --git a/src/Engine/Graphics/Vulkan/Descriptor.cpp b/src/Engine/Graphics/Vulkan/Descriptor.cpp index 0f8551f..34db576 100644 --- a/src/Engine/Graphics/Vulkan/Descriptor.cpp +++ b/src/Engine/Graphics/Vulkan/Descriptor.cpp @@ -346,13 +346,6 @@ DescriptorPool::DescriptorPool(PGraphics graphics, DescriptorLayout &layout) DescriptorPool::~DescriptorPool() { - for (uint32 setIndex = 0; setIndex < cachedHandles.size(); ++setIndex) - { - if (cachedHandles[setIndex] != nullptr && cachedHandles[setIndex]->setHandle != VK_NULL_HANDLE) - { - graphics->getDestructionManager()->queueDescriptorSet(graphics->getGraphicsCommands()->getCommands(), Pair(cachedHandles[setIndex]->setHandle, poolHandle)); - } - } graphics->getDestructionManager()->queueDescriptorPool(graphics->getGraphicsCommands()->getCommands(), poolHandle); if(nextAlloc) { diff --git a/src/Engine/Graphics/Vulkan/Resources.cpp b/src/Engine/Graphics/Vulkan/Resources.cpp index b9783e1..d0afbe4 100644 --- a/src/Engine/Graphics/Vulkan/Resources.cpp +++ b/src/Engine/Graphics/Vulkan/Resources.cpp @@ -46,16 +46,21 @@ bool Fence::isSignaled() { return true; } - VkResult res = vkGetFenceStatus(graphics->getDevice(), fence); - if (res == VK_SUCCESS) + VkResult r = vkGetFenceStatus(graphics->getDevice(), fence); + if (r == VK_SUCCESS) { signaled = true; return true; } - if (res == VK_NOT_READY) + if (r == VK_NOT_READY) { return false; } + else + { + VK_CHECK(r); + return false; + } } void Fence::reset() @@ -124,11 +129,6 @@ void DestructionManager::queueDescriptorPool(PCommand cmd, VkDescriptorPool pool pools[cmd].add(pool); } -void DestructionManager::queueDescriptorSet(PCommand cmd, Pair set) -{ - sets[cmd].add(set); -} - void DestructionManager::queueAllocation(PCommand cmd, OSubAllocation alloc) { allocs[cmd].add(std::move(alloc)); @@ -152,10 +152,6 @@ void DestructionManager::notifyCmdComplete(PCommand cmd) { vkDestroySemaphore(graphics->getDevice(), sem, nullptr); } - for (auto [set, pool] : sets[cmd]) - { - vkFreeDescriptorSets(graphics->getDevice(), pool, 1, &set); - } for (auto pool : pools[cmd]) { vkDestroyDescriptorPool(graphics->getDevice(), pool, nullptr); @@ -168,7 +164,7 @@ void DestructionManager::notifyCmdComplete(PCommand cmd) images[cmd].clear(); views[cmd].clear(); sems[cmd].clear(); + pools[cmd].clear(); renderPasses[cmd].clear(); allocs[cmd].clear(); - //graphics->getAllocator()->free(); } diff --git a/src/Engine/Graphics/Vulkan/Resources.h b/src/Engine/Graphics/Vulkan/Resources.h index d70a289..b034689 100644 --- a/src/Engine/Graphics/Vulkan/Resources.h +++ b/src/Engine/Graphics/Vulkan/Resources.h @@ -63,7 +63,6 @@ public: void queueSemaphore(PCommand cmd, VkSemaphore sem); void queueRenderPass(PCommand cmd, VkRenderPass renderPass); void queueDescriptorPool(PCommand cmd, VkDescriptorPool pool); - void queueDescriptorSet(PCommand cmd, Pair set); void queueAllocation(PCommand cmd, OSubAllocation alloc); void notifyCmdComplete(PCommand cmdbuffer); private: @@ -74,7 +73,6 @@ private: Map> sems; Map> renderPasses; Map> pools; - Map>> sets; Map> allocs; }; DEFINE_REF(DestructionManager) diff --git a/src/Engine/Graphics/Vulkan/Texture.cpp b/src/Engine/Graphics/Vulkan/Texture.cpp index 4d7e806..defdca7 100644 --- a/src/Engine/Graphics/Vulkan/Texture.cpp +++ b/src/Engine/Graphics/Vulkan/Texture.cpp @@ -157,6 +157,7 @@ TextureBase::TextureBase(PGraphics graphics, VkImageViewType viewType, // 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); + graphics->getStagingManager()->release(std::move(staging)); } else if(usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) { diff --git a/src/Engine/Graphics/Vulkan/Window.cpp b/src/Engine/Graphics/Vulkan/Window.cpp index e5e8e79..efbb7f5 100644 --- a/src/Engine/Graphics/Vulkan/Window.cpp +++ b/src/Engine/Graphics/Vulkan/Window.cpp @@ -97,9 +97,13 @@ Window::~Window() glfwDestroyWindow(static_cast(windowHandle)); } -void Window::beginFrame() +void Window::pollInput() { glfwPollEvents(); +} + +void Window::beginFrame() +{ vkAcquireNextImageKHR(graphics->getDevice(), swapchain, std::numeric_limits::max(), imageAvailableSemaphores[currentSemaphoreIndex]->getHandle(), VK_NULL_HANDLE, ¤tImageIndex); swapChainTextures[currentImageIndex]->changeLayout(Gfx::SE_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); graphics->getGraphicsCommands()->getCommands()->waitForSemaphore(VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, imageAvailableSemaphores[currentSemaphoreIndex]); @@ -210,6 +214,12 @@ void Window::close() void Window::resize(int width, int height) { + if (width == 0 || height == 0) + { + paused = true; + return; + } + paused = false; querySurface(); chooseSwapSurfaceFormat(); framebufferFormat = cast(format.format); diff --git a/src/Engine/Graphics/Vulkan/Window.h b/src/Engine/Graphics/Vulkan/Window.h index 8b24376..a750770 100644 --- a/src/Engine/Graphics/Vulkan/Window.h +++ b/src/Engine/Graphics/Vulkan/Window.h @@ -13,6 +13,7 @@ class Window : public Gfx::Window public: Window(PGraphics graphics, const WindowCreateInfo &createInfo); virtual ~Window(); + virtual void pollInput() override; virtual void beginFrame() override; virtual void endFrame() override; virtual Gfx::PTexture2D getBackBuffer() override; diff --git a/src/Engine/Graphics/Window.cpp b/src/Engine/Graphics/Window.cpp index 4759608..7b558d5 100644 --- a/src/Engine/Graphics/Window.cpp +++ b/src/Engine/Graphics/Window.cpp @@ -31,7 +31,7 @@ Matrix4 Viewport::getProjectionMatrix() const { if (fieldOfView > 0.0f) { - return glm::perspective(fieldOfView, sizeX / static_cast(sizeY), 0.1f, 1000.0f); + return glm::perspective(fieldOfView, sizeX / static_cast(sizeY), 0.1f, 10000.0f); } else { diff --git a/src/Engine/Graphics/Window.h b/src/Engine/Graphics/Window.h index 276d6c3..6041032 100644 --- a/src/Engine/Graphics/Window.h +++ b/src/Engine/Graphics/Window.h @@ -11,6 +11,7 @@ class Window public: Window(); virtual ~Window(); + virtual void pollInput() = 0; virtual void beginFrame() = 0; virtual void endFrame() = 0; virtual void onWindowCloseEvent() = 0; @@ -34,11 +35,15 @@ public: { return framebufferHeight; } - + constexpr bool isPaused() const + { + return paused; + } protected: SeFormat framebufferFormat; uint32 framebufferWidth; uint32 framebufferHeight; + bool paused = false; }; DEFINE_REF(Window) diff --git a/src/Engine/Window/GameView.cpp b/src/Engine/Window/GameView.cpp index 7ce637c..47faa29 100644 --- a/src/Engine/Window/GameView.cpp +++ b/src/Engine/Window/GameView.cpp @@ -69,16 +69,13 @@ void GameView::render() Component::Camera cam; scene->view([&cam](Component::Camera& c) { if (c.mainCamera) - cam = c; + cam = c; }); renderGraph.render(cam); } void GameView::applyArea(URect rect) { - viewport = graphics->createViewport(owner->getGfxHandle(), ViewportCreateInfo{ - .dimensions = rect, - }); renderGraph.updateViewport(viewport); } diff --git a/src/Engine/Window/GameView.h b/src/Engine/Window/GameView.h index 12956e2..b7e4a18 100644 --- a/src/Engine/Window/GameView.h +++ b/src/Engine/Window/GameView.h @@ -25,10 +25,10 @@ public: virtual void prepareRender() override; virtual void render() override; - virtual void applyArea(URect rect) override; void reloadGame(); -private: +protected: + virtual void applyArea(URect rect) override; OScene scene; GameInterface gameInterface; RenderGraph< diff --git a/src/Engine/Window/View.cpp b/src/Engine/Window/View.cpp index ae15c10..e903090 100644 --- a/src/Engine/Window/View.cpp +++ b/src/Engine/Window/View.cpp @@ -7,6 +7,7 @@ using namespace Seele; View::View(Gfx::PGraphics graphics, PWindow window, const ViewportCreateInfo &viewportInfo, std::string name) : graphics(graphics) , owner(window) + , createInfo(viewportInfo) , name(name) { viewport = graphics->createViewport(owner->getGfxHandle(), viewportInfo); @@ -18,7 +19,14 @@ View::~View() { } -void View::setFocused() +void View::resize(URect area) +{ + createInfo.dimensions = area; + viewport = graphics->createViewport(owner->getGfxHandle(), createInfo); + applyArea(area); +} + +void View::setFocused() { owner->setFocused(this); } diff --git a/src/Engine/Window/View.h b/src/Engine/Window/View.h index 207e0ed..d81280b 100644 --- a/src/Engine/Window/View.h +++ b/src/Engine/Window/View.h @@ -17,14 +17,16 @@ public: virtual void prepareRender() = 0; virtual void render() = 0; - virtual void applyArea(URect area) = 0; + void resize(URect area); void setFocused(); const std::string& getName(); protected: + virtual void applyArea(URect area) = 0; Gfx::PGraphics graphics; Gfx::OViewport viewport; + ViewportCreateInfo createInfo; PWindow owner; std::string name; diff --git a/src/Engine/Window/Window.cpp b/src/Engine/Window/Window.cpp index eae0338..fb9b730 100644 --- a/src/Engine/Window/Window.cpp +++ b/src/Engine/Window/Window.cpp @@ -20,6 +20,11 @@ void Window::addView(PView view) views.add(view); } +void Window::pollInputs() +{ + gfxHandle->pollInput(); +} + void Window::render() { gfxHandle->beginFrame(); @@ -61,7 +66,7 @@ void Window::onResize(uint32 width, uint32 height) for (auto& view : views) { // TODO: some sort of layouting algorithm should do this - view->applyArea(URect{ + view->resize(URect{ .size = UVector2(width, height), .offset = UVector2(0, 0), }); diff --git a/src/Engine/Window/Window.h b/src/Engine/Window/Window.h index 85a9246..6736087 100644 --- a/src/Engine/Window/Window.h +++ b/src/Engine/Window/Window.h @@ -12,10 +12,15 @@ public: Window(PWindowManager owner, Gfx::OWindow handle); ~Window(); void addView(PView view); + void pollInputs(); void render(); Gfx::PWindow getGfxHandle(); void setFocused(PView view); void onResize(uint32 width, uint32 height); + constexpr bool isPaused() const + { + return gfxHandle->isPaused(); + } protected: PWindowManager owner; Array views; diff --git a/src/Engine/Window/WindowManager.cpp b/src/Engine/Window/WindowManager.cpp index c0c17ae..d609154 100644 --- a/src/Engine/Window/WindowManager.cpp +++ b/src/Engine/Window/WindowManager.cpp @@ -22,6 +22,9 @@ void WindowManager::render() { for (auto& window : windows) { + window->pollInputs(); + if (window->isPaused()) + continue; window->render(); } }