From 69cfadf41143fc1f3c700ceec1a2de7e66c492c6 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Sat, 11 Jun 2022 03:27:18 +0200 Subject: [PATCH] Manage buffers in VkBufferManager --- .../vulkan/renderer/vk_descriptorset.cpp | 9 +- .../vulkan/renderer/vk_pprenderstate.cpp | 7 +- .../vulkan/renderer/vk_renderstate.cpp | 3 +- .../vulkan/renderer/vk_streambuffer.cpp | 31 +----- .../vulkan/renderer/vk_streambuffer.h | 16 --- .../rendering/vulkan/system/vk_buffer.cpp | 98 +++++++++++++++++++ .../rendering/vulkan/system/vk_buffer.h | 47 +++++++++ .../vulkan/system/vk_framebuffer.cpp | 50 +--------- .../rendering/vulkan/system/vk_framebuffer.h | 16 +-- .../rendering/vulkan/system/vk_hwbuffer.cpp | 47 +++------ .../rendering/vulkan/system/vk_hwbuffer.h | 20 ++-- 11 files changed, 190 insertions(+), 154 deletions(-) diff --git a/src/common/rendering/vulkan/renderer/vk_descriptorset.cpp b/src/common/rendering/vulkan/renderer/vk_descriptorset.cpp index dee835759..c07f9753d 100644 --- a/src/common/rendering/vulkan/renderer/vk_descriptorset.cpp +++ b/src/common/rendering/vulkan/renderer/vk_descriptorset.cpp @@ -31,6 +31,7 @@ #include "vulkan/system/vk_framebuffer.h" #include "vulkan/system/vk_hwbuffer.h" #include "vulkan/system/vk_commandbuffer.h" +#include "vulkan/system/vk_buffer.h" #include "flatvertices.h" #include "hw_viewpointuniforms.h" #include "v_2ddrawer.h" @@ -75,9 +76,9 @@ void VkDescriptorSetManager::CreateDynamicSet() void VkDescriptorSetManager::UpdateDynamicSet() { WriteDescriptors update; - update.addBuffer(DynamicSet.get(), 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, fb->ViewpointUBO->mBuffer.get(), 0, sizeof(HWViewpointUniforms)); - update.addBuffer(DynamicSet.get(), 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, fb->MatrixBuffer->UniformBuffer->mBuffer.get(), 0, sizeof(MatricesUBO)); - update.addBuffer(DynamicSet.get(), 2, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, fb->StreamBuffer->UniformBuffer->mBuffer.get(), 0, sizeof(StreamUBO)); + update.addBuffer(DynamicSet.get(), 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, fb->GetBufferManager()->ViewpointUBO->mBuffer.get(), 0, sizeof(HWViewpointUniforms)); + update.addBuffer(DynamicSet.get(), 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, fb->GetBufferManager()->MatrixBuffer->UniformBuffer->mBuffer.get(), 0, sizeof(MatricesUBO)); + update.addBuffer(DynamicSet.get(), 2, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, fb->GetBufferManager()->StreamBuffer->UniformBuffer->mBuffer.get(), 0, sizeof(StreamUBO)); update.updateSets(fb->device); } @@ -111,7 +112,7 @@ void VkDescriptorSetManager::UpdateFixedSet() WriteDescriptors update; update.addCombinedImageSampler(FixedSet.get(), 0, fb->GetBuffers()->Shadowmap.View.get(), fb->GetBuffers()->ShadowmapSampler.get(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); update.addCombinedImageSampler(FixedSet.get(), 1, fb->GetBuffers()->Lightmap.View.get(), fb->GetBuffers()->LightmapSampler.get(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); - update.addBuffer(FixedSet.get(), 2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, fb->LightBufferSSO->mBuffer.get()); + update.addBuffer(FixedSet.get(), 2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, fb->GetBufferManager()->LightBufferSSO->mBuffer.get()); if (fb->device->SupportsDeviceExtension(VK_KHR_RAY_QUERY_EXTENSION_NAME)) update.addAccelerationStructure(FixedSet.get(), 3, fb->GetRaytrace()->GetAccelStruct()); update.updateSets(fb->device); diff --git a/src/common/rendering/vulkan/renderer/vk_pprenderstate.cpp b/src/common/rendering/vulkan/renderer/vk_pprenderstate.cpp index 78f3477c9..498e65397 100644 --- a/src/common/rendering/vulkan/renderer/vk_pprenderstate.cpp +++ b/src/common/rendering/vulkan/renderer/vk_pprenderstate.cpp @@ -25,6 +25,7 @@ #include "vulkan/system/vk_framebuffer.h" #include "vulkan/system/vk_commandbuffer.h" #include "vulkan/system/vk_swapchain.h" +#include "vulkan/system/vk_buffer.h" #include "vulkan/shaders/vk_ppshader.h" #include "vulkan/textures/vk_pptexture.h" #include "vulkan/textures/vk_renderbuffers.h" @@ -155,9 +156,9 @@ VulkanDescriptorSet *VkPPRenderState::GetInput(VkPPRenderPassSetup *passSetup, c if (bindShadowMapBuffers) { - write.addBuffer(descriptors.get(), LIGHTNODES_BINDINGPOINT, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, fb->LightNodes->mBuffer.get()); - write.addBuffer(descriptors.get(), LIGHTLINES_BINDINGPOINT, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, fb->LightLines->mBuffer.get()); - write.addBuffer(descriptors.get(), LIGHTLIST_BINDINGPOINT, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, fb->LightList->mBuffer.get()); + write.addBuffer(descriptors.get(), LIGHTNODES_BINDINGPOINT, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, fb->GetBufferManager()->LightNodes->mBuffer.get()); + write.addBuffer(descriptors.get(), LIGHTLINES_BINDINGPOINT, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, fb->GetBufferManager()->LightLines->mBuffer.get()); + write.addBuffer(descriptors.get(), LIGHTLIST_BINDINGPOINT, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, fb->GetBufferManager()->LightList->mBuffer.get()); } write.updateSets(fb->device); diff --git a/src/common/rendering/vulkan/renderer/vk_renderstate.cpp b/src/common/rendering/vulkan/renderer/vk_renderstate.cpp index 60b192eae..6d1a1ab01 100644 --- a/src/common/rendering/vulkan/renderer/vk_renderstate.cpp +++ b/src/common/rendering/vulkan/renderer/vk_renderstate.cpp @@ -24,6 +24,7 @@ #include "vulkan/system/vk_framebuffer.h" #include "vulkan/system/vk_builders.h" #include "vulkan/system/vk_commandbuffer.h" +#include "vulkan/system/vk_buffer.h" #include "vulkan/renderer/vk_renderpass.h" #include "vulkan/renderer/vk_descriptorset.h" #include "vulkan/textures/vk_renderbuffers.h" @@ -586,7 +587,7 @@ void VkRenderStateMolten::Draw(int dt, int index, int count, bool apply) if (dt == DT_TriangleFan) { IIndexBuffer *oldIndexBuffer = mIndexBuffer; - mIndexBuffer = fb->FanToTrisIndexBuffer.get(); + mIndexBuffer = fb->GetBufferManager()->FanToTrisIndexBuffer.get(); if (apply || mNeedApply) Apply(DT_Triangles); diff --git a/src/common/rendering/vulkan/renderer/vk_streambuffer.cpp b/src/common/rendering/vulkan/renderer/vk_streambuffer.cpp index 4bd1f86f1..b2bc402dd 100644 --- a/src/common/rendering/vulkan/renderer/vk_streambuffer.cpp +++ b/src/common/rendering/vulkan/renderer/vk_streambuffer.cpp @@ -23,37 +23,12 @@ #include "vk_renderstate.h" #include "vulkan/system/vk_framebuffer.h" #include "vulkan/system/vk_builders.h" +#include "vulkan/system/vk_buffer.h" #include "vulkan/renderer/vk_streambuffer.h" -VkStreamBuffer::VkStreamBuffer(VulkanFrameBuffer* fb, size_t structSize, size_t count) -{ - mBlockSize = static_cast((structSize + screen->uniformblockalignment - 1) / screen->uniformblockalignment * screen->uniformblockalignment); - - UniformBuffer = (VkHardwareDataBuffer*)fb->CreateDataBuffer(-1, false, false); - UniformBuffer->SetData(mBlockSize * count, nullptr, BufferUsageType::Persistent); -} - -VkStreamBuffer::~VkStreamBuffer() -{ - delete UniformBuffer; -} - -uint32_t VkStreamBuffer::NextStreamDataBlock() -{ - mStreamDataOffset += mBlockSize; - if (mStreamDataOffset + (size_t)mBlockSize >= UniformBuffer->Size()) - { - mStreamDataOffset = 0; - return 0xffffffff; - } - return mStreamDataOffset; -} - -///////////////////////////////////////////////////////////////////////////// - VkStreamBufferWriter::VkStreamBufferWriter(VulkanFrameBuffer* fb) { - mBuffer = fb->StreamBuffer; + mBuffer = fb->GetBufferManager()->StreamBuffer; } bool VkStreamBufferWriter::Write(const StreamData& data) @@ -82,7 +57,7 @@ void VkStreamBufferWriter::Reset() VkMatrixBufferWriter::VkMatrixBufferWriter(VulkanFrameBuffer* fb) { - mBuffer = fb->MatrixBuffer; + mBuffer = fb->GetBufferManager()->MatrixBuffer; mIdentityMatrix.loadIdentity(); } diff --git a/src/common/rendering/vulkan/renderer/vk_streambuffer.h b/src/common/rendering/vulkan/renderer/vk_streambuffer.h index 2cb21bbb6..749bc46e8 100644 --- a/src/common/rendering/vulkan/renderer/vk_streambuffer.h +++ b/src/common/rendering/vulkan/renderer/vk_streambuffer.h @@ -40,19 +40,3 @@ private: VSMatrix mIdentityMatrix; uint32_t mOffset = 0; }; - -class VkStreamBuffer -{ -public: - VkStreamBuffer(VulkanFrameBuffer* fb, size_t structSize, size_t count); - ~VkStreamBuffer(); - - uint32_t NextStreamDataBlock(); - void Reset() { mStreamDataOffset = 0; } - - VkHardwareDataBuffer* UniformBuffer = nullptr; - -private: - uint32_t mBlockSize = 0; - uint32_t mStreamDataOffset = 0; -}; diff --git a/src/common/rendering/vulkan/system/vk_buffer.cpp b/src/common/rendering/vulkan/system/vk_buffer.cpp index 90b18dd61..1ae8cc65b 100644 --- a/src/common/rendering/vulkan/system/vk_buffer.cpp +++ b/src/common/rendering/vulkan/system/vk_buffer.cpp @@ -21,6 +21,9 @@ */ #include "vk_buffer.h" +#include "vk_hwbuffer.h" +#include "vulkan/renderer/vk_streambuffer.h" +#include "hwrenderer/data/shaderuniforms.h" VkBufferManager::VkBufferManager(VulkanFrameBuffer* fb) : fb(fb) { @@ -28,4 +31,99 @@ VkBufferManager::VkBufferManager(VulkanFrameBuffer* fb) : fb(fb) VkBufferManager::~VkBufferManager() { + delete MatrixBuffer; + delete StreamBuffer; +} + +void VkBufferManager::Init() +{ + MatrixBuffer = new VkStreamBuffer(this, sizeof(MatricesUBO), 50000); + StreamBuffer = new VkStreamBuffer(this, sizeof(StreamUBO), 300); + + CreateFanToTrisIndexBuffer(); +} + +void VkBufferManager::AddBuffer(VkHardwareBuffer* buffer) +{ + buffer->it = Buffers.insert(Buffers.end(), buffer); +} + +void VkBufferManager::RemoveBuffer(VkHardwareBuffer* buffer) +{ + buffer->Reset(); + buffer->fb = nullptr; + Buffers.erase(buffer->it); + + for (VkHardwareDataBuffer** knownbuf : { &ViewpointUBO, &LightBufferSSO, &LightNodes, &LightLines, &LightList }) + { + if (buffer == *knownbuf) *knownbuf = nullptr; + } +} + +IVertexBuffer* VkBufferManager::CreateVertexBuffer() +{ + return new VkHardwareVertexBuffer(fb); +} + +IIndexBuffer* VkBufferManager::CreateIndexBuffer() +{ + return new VkHardwareIndexBuffer(fb); +} + +IDataBuffer* VkBufferManager::CreateDataBuffer(int bindingpoint, bool ssbo, bool needsresize) +{ + auto buffer = new VkHardwareDataBuffer(fb, bindingpoint, ssbo, needsresize); + + switch (bindingpoint) + { + case LIGHTBUF_BINDINGPOINT: LightBufferSSO = buffer; break; + case VIEWPOINT_BINDINGPOINT: ViewpointUBO = buffer; break; + case LIGHTNODES_BINDINGPOINT: LightNodes = buffer; break; + case LIGHTLINES_BINDINGPOINT: LightLines = buffer; break; + case LIGHTLIST_BINDINGPOINT: LightList = buffer; break; + case POSTPROCESS_BINDINGPOINT: break; + default: break; + } + + return buffer; +} + +void VkBufferManager::CreateFanToTrisIndexBuffer() +{ + TArray data; + for (int i = 2; i < 1000; i++) + { + data.Push(0); + data.Push(i - 1); + data.Push(i); + } + + FanToTrisIndexBuffer.reset(CreateIndexBuffer()); + FanToTrisIndexBuffer->SetData(sizeof(uint32_t) * data.Size(), data.Data(), BufferUsageType::Static); +} + +///////////////////////////////////////////////////////////////////////////// + +VkStreamBuffer::VkStreamBuffer(VkBufferManager* buffers, size_t structSize, size_t count) +{ + mBlockSize = static_cast((structSize + screen->uniformblockalignment - 1) / screen->uniformblockalignment * screen->uniformblockalignment); + + UniformBuffer = (VkHardwareDataBuffer*)buffers->CreateDataBuffer(-1, false, false); + UniformBuffer->SetData(mBlockSize * count, nullptr, BufferUsageType::Persistent); +} + +VkStreamBuffer::~VkStreamBuffer() +{ + delete UniformBuffer; +} + +uint32_t VkStreamBuffer::NextStreamDataBlock() +{ + mStreamDataOffset += mBlockSize; + if (mStreamDataOffset + (size_t)mBlockSize >= UniformBuffer->Size()) + { + mStreamDataOffset = 0; + return 0xffffffff; + } + return mStreamDataOffset; } diff --git a/src/common/rendering/vulkan/system/vk_buffer.h b/src/common/rendering/vulkan/system/vk_buffer.h index ccf751c6a..210f8307c 100644 --- a/src/common/rendering/vulkan/system/vk_buffer.h +++ b/src/common/rendering/vulkan/system/vk_buffer.h @@ -2,8 +2,15 @@ #pragma once #include "vulkan/system/vk_objects.h" +#include class VulkanFrameBuffer; +class VkHardwareBuffer; +class VkHardwareDataBuffer; +class VkStreamBuffer; +class IIndexBuffer; +class IVertexBuffer; +class IDataBuffer; class VkBufferManager { @@ -11,6 +18,46 @@ public: VkBufferManager(VulkanFrameBuffer* fb); ~VkBufferManager(); + void Init(); + + IVertexBuffer* CreateVertexBuffer(); + IIndexBuffer* CreateIndexBuffer(); + IDataBuffer* CreateDataBuffer(int bindingpoint, bool ssbo, bool needsresize); + + void AddBuffer(VkHardwareBuffer* buffer); + void RemoveBuffer(VkHardwareBuffer* buffer); + + VkHardwareDataBuffer* ViewpointUBO = nullptr; + VkHardwareDataBuffer* LightBufferSSO = nullptr; + VkHardwareDataBuffer* LightNodes = nullptr; + VkHardwareDataBuffer* LightLines = nullptr; + VkHardwareDataBuffer* LightList = nullptr; + + VkStreamBuffer* MatrixBuffer = nullptr; + VkStreamBuffer* StreamBuffer = nullptr; + + std::unique_ptr FanToTrisIndexBuffer; + private: + void CreateFanToTrisIndexBuffer(); + VulkanFrameBuffer* fb = nullptr; + + std::list Buffers; +}; + +class VkStreamBuffer +{ +public: + VkStreamBuffer(VkBufferManager* buffers, size_t structSize, size_t count); + ~VkStreamBuffer(); + + uint32_t NextStreamDataBlock(); + void Reset() { mStreamDataOffset = 0; } + + VkHardwareDataBuffer* UniformBuffer = nullptr; + +private: + uint32_t mBlockSize = 0; + uint32_t mStreamDataOffset = 0; }; diff --git a/src/common/rendering/vulkan/system/vk_framebuffer.cpp b/src/common/rendering/vulkan/system/vk_framebuffer.cpp index 754810f01..caa8d7502 100644 --- a/src/common/rendering/vulkan/system/vk_framebuffer.cpp +++ b/src/common/rendering/vulkan/system/vk_framebuffer.cpp @@ -85,12 +85,6 @@ VulkanFrameBuffer::~VulkanFrameBuffer() { vkDeviceWaitIdle(device->device); // make sure the GPU is no longer using any objects before RAII tears them down - // All descriptors must be destroyed before the descriptor pool in renderpass manager is destroyed - VkHardwareBuffer::ResetAll(); - PPResource::ResetAll(); - - delete MatrixBuffer; - delete StreamBuffer; delete mVertexData; delete mSkyData; delete mViewpoints; @@ -128,6 +122,7 @@ void VulkanFrameBuffer::InitializeState() mSamplerManager.reset(new VkSamplerManager(this)); mTextureManager.reset(new VkTextureManager(this)); mBufferManager.reset(new VkBufferManager(this)); + mBufferManager->Init(); mScreenBuffers.reset(new VkRenderBuffers(this)); mSaveBuffers.reset(new VkRenderBuffers(this)); @@ -143,12 +138,6 @@ void VulkanFrameBuffer::InitializeState() mViewpoints = new HWViewpointBuffer; mLights = new FLightBuffer(); - CreateFanToTrisIndexBuffer(); - - // To do: move this to HW renderer interface maybe? - MatrixBuffer = new VkStreamBuffer(this, sizeof(MatricesUBO), 50000); - StreamBuffer = new VkStreamBuffer(this, sizeof(StreamUBO), 300); - mShaderManager.reset(new VkShaderManager(device)); mDescriptorSetManager->Init(); #ifdef __APPLE__ @@ -231,11 +220,9 @@ const char* VulkanFrameBuffer::DeviceName() const return props.deviceName; } - void VulkanFrameBuffer::SetVSync(bool vsync) { - // This is handled in VulkanSwapChain::AcquireImage. - cur_vsync = vsync; + mVSync = vsync; } void VulkanFrameBuffer::PrecacheMaterial(FMaterial *mat, int translation) @@ -267,30 +254,17 @@ FMaterial* VulkanFrameBuffer::CreateMaterial(FGameTexture* tex, int scaleflags) IVertexBuffer *VulkanFrameBuffer::CreateVertexBuffer() { - return new VkHardwareVertexBuffer(); + return GetBufferManager()->CreateVertexBuffer(); } IIndexBuffer *VulkanFrameBuffer::CreateIndexBuffer() { - return new VkHardwareIndexBuffer(); + return GetBufferManager()->CreateIndexBuffer(); } IDataBuffer *VulkanFrameBuffer::CreateDataBuffer(int bindingpoint, bool ssbo, bool needsresize) { - auto buffer = new VkHardwareDataBuffer(bindingpoint, ssbo, needsresize); - - switch (bindingpoint) - { - case LIGHTBUF_BINDINGPOINT: LightBufferSSO = buffer; break; - case VIEWPOINT_BINDINGPOINT: ViewpointUBO = buffer; break; - case LIGHTNODES_BINDINGPOINT: LightNodes = buffer; break; - case LIGHTLINES_BINDINGPOINT: LightLines = buffer; break; - case LIGHTLIST_BINDINGPOINT: LightList = buffer; break; - case POSTPROCESS_BINDINGPOINT: break; - default: break; - } - - return buffer; + return GetBufferManager()->CreateDataBuffer(bindingpoint, ssbo, needsresize); } void VulkanFrameBuffer::SetTextureFilterMode() @@ -556,20 +530,6 @@ void VulkanFrameBuffer::PrintStartupLog() Printf("Min. uniform buffer offset alignment: %" PRIu64 "\n", limits.minUniformBufferOffsetAlignment); } -void VulkanFrameBuffer::CreateFanToTrisIndexBuffer() -{ - TArray data; - for (int i = 2; i < 1000; i++) - { - data.Push(0); - data.Push(i - 1); - data.Push(i); - } - - FanToTrisIndexBuffer.reset(CreateIndexBuffer()); - FanToTrisIndexBuffer->SetData(sizeof(uint32_t) * data.Size(), data.Data(), BufferUsageType::Static); -} - void VulkanFrameBuffer::SetLevelMesh(hwrenderer::LevelMesh* mesh) { mRaytrace->SetLevelMesh(mesh); diff --git a/src/common/rendering/vulkan/system/vk_framebuffer.h b/src/common/rendering/vulkan/system/vk_framebuffer.h index 2729b1f57..40ed75633 100644 --- a/src/common/rendering/vulkan/system/vk_framebuffer.h +++ b/src/common/rendering/vulkan/system/vk_framebuffer.h @@ -44,17 +44,6 @@ public: unsigned int GetLightBufferBlockSize() const; - VkHardwareDataBuffer *ViewpointUBO = nullptr; - VkHardwareDataBuffer *LightBufferSSO = nullptr; - VkStreamBuffer *MatrixBuffer = nullptr; - VkStreamBuffer *StreamBuffer = nullptr; - - VkHardwareDataBuffer *LightNodes = nullptr; - VkHardwareDataBuffer *LightLines = nullptr; - VkHardwareDataBuffer *LightList = nullptr; - - std::unique_ptr FanToTrisIndexBuffer; - VulkanFrameBuffer(void *hMonitor, bool fullscreen, VulkanDevice *dev); ~VulkanFrameBuffer(); bool IsVulkan() override { return true; } @@ -92,7 +81,7 @@ public: TArray GetScreenshotBuffer(int &pitch, ESSType &color_type, float &gamma) override; - bool GetVSync() { return cur_vsync; } + bool GetVSync() { return mVSync; } void SetVSync(bool vsync) override; void Draw2D() override; @@ -102,7 +91,6 @@ public: private: void RenderTextureView(FCanvasTexture* tex, std::function renderFunc) override; void PrintStartupLog(); - void CreateFanToTrisIndexBuffer(); void CopyScreenToBuffer(int w, int h, uint8_t *data) override; std::unique_ptr mCommands; @@ -120,7 +108,7 @@ private: VkRenderBuffers *mActiveRenderBuffers = nullptr; - bool cur_vsync = false; + bool mVSync = false; }; inline VulkanFrameBuffer *GetVulkanFrameBuffer() { return static_cast(screen); } diff --git a/src/common/rendering/vulkan/system/vk_hwbuffer.cpp b/src/common/rendering/vulkan/system/vk_hwbuffer.cpp index c388e9b36..8f3db8a98 100644 --- a/src/common/rendering/vulkan/system/vk_hwbuffer.cpp +++ b/src/common/rendering/vulkan/system/vk_hwbuffer.cpp @@ -24,31 +24,31 @@ #include "vk_builders.h" #include "vk_framebuffer.h" #include "vk_commandbuffer.h" +#include "vk_buffer.h" #include "vulkan/renderer/vk_renderstate.h" #include "vulkan/renderer/vk_descriptorset.h" #include "engineerrors.h" -VkHardwareBuffer *VkHardwareBuffer::First = nullptr; - -VkHardwareBuffer::VkHardwareBuffer() +VkHardwareBuffer::VkHardwareBuffer(VulkanFrameBuffer* fb) : fb(fb) { - Next = First; - First = this; - if (Next) Next->Prev = this; + fb->GetBufferManager()->AddBuffer(this); } VkHardwareBuffer::~VkHardwareBuffer() { - if (Next) Next->Prev = Prev; - if (Prev) Prev->Next = Next; - else First = Next; + if (fb) + fb->GetBufferManager()->RemoveBuffer(this); +} - if (mBuffer && map) - mBuffer->Unmap(); - - auto fb = GetVulkanFrameBuffer(); +void VkHardwareBuffer::Reset() +{ if (fb) { + if (mBuffer && map) + { + mBuffer->Unmap(); + map = nullptr; + } if (mBuffer) fb->GetCommands()->FrameDeleteList.Buffers.push_back(std::move(mBuffer)); if (mStaging) @@ -56,24 +56,8 @@ VkHardwareBuffer::~VkHardwareBuffer() } } -void VkHardwareBuffer::ResetAll() -{ - for (VkHardwareBuffer *cur = VkHardwareBuffer::First; cur; cur = cur->Next) - cur->Reset(); -} - -void VkHardwareBuffer::Reset() -{ - if (mBuffer && map) - mBuffer->Unmap(); - mBuffer.reset(); - mStaging.reset(); -} - void VkHardwareBuffer::SetData(size_t size, const void *data, BufferUsageType usage) { - auto fb = GetVulkanFrameBuffer(); - size_t bufsize = max(size, (size_t)16); // For supporting zero byte buffers // If SetData is called multiple times we have to keep the old buffers alive as there might still be draw commands referencing them @@ -156,7 +140,6 @@ void VkHardwareBuffer::SetSubData(size_t offset, size_t size, const void *data) { size = max(size, (size_t)16); // For supporting zero byte buffers - auto fb = GetVulkanFrameBuffer(); if (mStaging) { void *dst = mStaging->Map(offset, size); @@ -177,8 +160,6 @@ void VkHardwareBuffer::Resize(size_t newsize) { newsize = max(newsize, (size_t)16); // For supporting zero byte buffers - auto fb = GetVulkanFrameBuffer(); - // Grab old buffer size_t oldsize = buffersize; std::unique_ptr oldBuffer = std::move(mBuffer); @@ -256,7 +237,7 @@ void VkHardwareBuffer::Unlock() void VkHardwareVertexBuffer::SetFormat(int numBindingPoints, int numAttributes, size_t stride, const FVertexBufferAttribute *attrs) { - VertexFormat = GetVulkanFrameBuffer()->GetRenderPassManager()->GetVertexFormat(numBindingPoints, numAttributes, stride, attrs); + VertexFormat = fb->GetRenderPassManager()->GetVertexFormat(numBindingPoints, numAttributes, stride, attrs); } ///////////////////////////////////////////////////////////////////////////// diff --git a/src/common/rendering/vulkan/system/vk_hwbuffer.h b/src/common/rendering/vulkan/system/vk_hwbuffer.h index 33a4c7933..9eedf6c46 100644 --- a/src/common/rendering/vulkan/system/vk_hwbuffer.h +++ b/src/common/rendering/vulkan/system/vk_hwbuffer.h @@ -3,6 +3,7 @@ #include "hwrenderer/data/buffers.h" #include "vk_objects.h" #include "tarray.h" +#include #ifdef _MSC_VER // silence bogus warning C4250: 'VkHardwareVertexBuffer': inherits 'VkHardwareBuffer::VkHardwareBuffer::SetData' via dominance @@ -10,13 +11,14 @@ #pragma warning(disable:4250) #endif +class VulkanFrameBuffer; + class VkHardwareBuffer : virtual public IBuffer { public: - VkHardwareBuffer(); + VkHardwareBuffer(VulkanFrameBuffer* fb); ~VkHardwareBuffer(); - static void ResetAll(); void Reset(); void SetData(size_t size, const void *data, BufferUsageType usage) override; @@ -29,22 +31,20 @@ public: void *Lock(unsigned int size) override; void Unlock() override; + VulkanFrameBuffer* fb = nullptr; + std::list::iterator it; + VkBufferUsageFlags mBufferType = 0; std::unique_ptr mBuffer; std::unique_ptr mStaging; bool mPersistent = false; TArray mStaticUpload; - -private: - static VkHardwareBuffer *First; - VkHardwareBuffer *Prev = nullptr; - VkHardwareBuffer *Next = nullptr; }; class VkHardwareVertexBuffer : public IVertexBuffer, public VkHardwareBuffer { public: - VkHardwareVertexBuffer() { mBufferType = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; } + VkHardwareVertexBuffer(VulkanFrameBuffer* fb) : VkHardwareBuffer(fb) { mBufferType = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; } void SetFormat(int numBindingPoints, int numAttributes, size_t stride, const FVertexBufferAttribute *attrs) override; int VertexFormat = -1; @@ -53,13 +53,13 @@ public: class VkHardwareIndexBuffer : public IIndexBuffer, public VkHardwareBuffer { public: - VkHardwareIndexBuffer() { mBufferType = VK_BUFFER_USAGE_INDEX_BUFFER_BIT; } + VkHardwareIndexBuffer(VulkanFrameBuffer* fb) : VkHardwareBuffer(fb) { mBufferType = VK_BUFFER_USAGE_INDEX_BUFFER_BIT; } }; class VkHardwareDataBuffer : public IDataBuffer, public VkHardwareBuffer { public: - VkHardwareDataBuffer(int bindingpoint, bool ssbo, bool needresize) : bindingpoint(bindingpoint) + VkHardwareDataBuffer(VulkanFrameBuffer* fb, int bindingpoint, bool ssbo, bool needresize) : VkHardwareBuffer(fb), bindingpoint(bindingpoint) { mBufferType = ssbo ? VK_BUFFER_USAGE_STORAGE_BUFFER_BIT : VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; if (needresize)