From 478ef05a0a3fbcfe1fab4e80e2923d3704081c42 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Thu, 21 Feb 2019 12:31:14 +0100 Subject: [PATCH] - create vulkan buffer objects implementation --- src/CMakeLists.txt | 1 + src/rendering/vulkan/system/vk_buffers.cpp | 119 ++++++++++++++++++ src/rendering/vulkan/system/vk_buffers.h | 55 ++++++++ src/rendering/vulkan/system/vk_device.cpp | 2 +- .../vulkan/system/vk_framebuffer.cpp | 53 ++++++-- src/rendering/vulkan/system/vk_framebuffer.h | 21 +++- 6 files changed, 237 insertions(+), 14 deletions(-) create mode 100644 src/rendering/vulkan/system/vk_buffers.cpp create mode 100644 src/rendering/vulkan/system/vk_buffers.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 780fd2eda..21d521f88 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -897,6 +897,7 @@ set( FASTMATH_SOURCES rendering/vulkan/system/vk_swapchain.cpp rendering/vulkan/system/vk_builders.cpp rendering/vulkan/system/vk_framebuffer.cpp + rendering/vulkan/system/vk_buffers.cpp rendering/vulkan/textures/vk_samplers.cpp rendering/vulkan/textures/vk_hwtexture.cpp rendering/vulkan/thirdparty/volk/volk.c diff --git a/src/rendering/vulkan/system/vk_buffers.cpp b/src/rendering/vulkan/system/vk_buffers.cpp new file mode 100644 index 000000000..6726ff326 --- /dev/null +++ b/src/rendering/vulkan/system/vk_buffers.cpp @@ -0,0 +1,119 @@ + +#include "vk_buffers.h" +#include "vk_builders.h" +#include "vk_framebuffer.h" +#include "doomerrors.h" + +void VKBuffer::SetData(size_t size, const void *data, bool staticdata) +{ + auto fb = GetVulkanFrameBuffer(); + + mPersistent = screen->BuffersArePersistent() && !staticdata; + + if (staticdata) + { + BufferBuilder builder; + builder.setUsage(VK_BUFFER_USAGE_TRANSFER_DST_BIT | mBufferType, VMA_MEMORY_USAGE_GPU_ONLY); + builder.setSize(size); + mBuffer = builder.create(fb->device); + + builder.setUsage(VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VMA_MEMORY_USAGE_CPU_ONLY); + mStaging = builder.create(fb->device); + + void *dst = mStaging->Map(0, size); + memcpy(dst, data, size); + mStaging->Unmap(); + + fb->GetUploadCommands()->copyBuffer(mStaging.get(), mBuffer.get()); + } + else + { + BufferBuilder builder; + builder.setUsage(mBufferType, VMA_MEMORY_USAGE_CPU_TO_GPU); + builder.setSize(size); + mBuffer = builder.create(fb->device); + + if (mPersistent) + { + map = mBuffer->Map(0, size); + } + else if (data) + { + void *dst = mBuffer->Map(0, size); + memcpy(dst, data, size); + mBuffer->Unmap(); + } + } + buffersize = size; +} + +void VKBuffer::SetSubData(size_t offset, size_t size, const void *data) +{ + auto fb = GetVulkanFrameBuffer(); + if (mStaging) + { + void *dst = mStaging->Map(offset, size); + memcpy(dst, data, size); + mStaging->Unmap(); + + fb->GetUploadCommands()->copyBuffer(mStaging.get(), mBuffer.get(), offset, offset, size); + } + else + { + void *dst = mBuffer->Map(offset, size); + memcpy(dst, data, size); + mBuffer->Unmap(); + } +} + +void VKBuffer::Resize(size_t newsize) +{ + I_FatalError("VKBuffer::Resize not implemented\n"); +} + +void VKBuffer::Map() +{ + if (!mPersistent) + map = mBuffer->Map(0, mBuffer->size); +} + +void VKBuffer::Unmap() +{ + if (!mPersistent) + { + mBuffer->Unmap(); + map = nullptr; + } +} + +void *VKBuffer::Lock(unsigned int size) +{ + if (!mPersistent) + map = mBuffer->Map(0, size); + return map; +} + +void VKBuffer::Unlock() +{ + if (!mPersistent) + { + mBuffer->Unmap(); + map = nullptr; + } +} + +///////////////////////////////////////////////////////////////////////////// + +void VKVertexBuffer::SetFormat(int numBindingPoints, int numAttributes, size_t stride, const FVertexBufferAttribute *attrs) +{ +} + +///////////////////////////////////////////////////////////////////////////// + +void VKDataBuffer::BindRange(size_t start, size_t length) +{ +} + +void VKDataBuffer::BindBase() +{ +} diff --git a/src/rendering/vulkan/system/vk_buffers.h b/src/rendering/vulkan/system/vk_buffers.h new file mode 100644 index 000000000..276b8f6b0 --- /dev/null +++ b/src/rendering/vulkan/system/vk_buffers.h @@ -0,0 +1,55 @@ +#pragma once + +#include "hwrenderer/data/buffers.h" +#include "vk_objects.h" + +#ifdef _MSC_VER +// silence bogus warning C4250: 'VKVertexBuffer': inherits 'VKBuffer::VKBuffer::SetData' via dominance +// According to internet infos, the warning is erroneously emitted in this case. +#pragma warning(disable:4250) +#endif + +class VKBuffer : virtual public IBuffer +{ +public: + ~VKBuffer() { if (map) Unmap(); } + + void SetData(size_t size, const void *data, bool staticdata) override; + void SetSubData(size_t offset, size_t size, const void *data) override; + void Resize(size_t newsize) override; + + void Map() override; + void Unmap() override; + + void *Lock(unsigned int size) override; + void Unlock() override; + + VkBufferUsageFlags mBufferType = 0; + std::unique_ptr mBuffer; + std::unique_ptr mStaging; + bool mPersistent; +}; + +class VKVertexBuffer : public IVertexBuffer, public VKBuffer +{ +public: + VKVertexBuffer() { mBufferType = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; } + void SetFormat(int numBindingPoints, int numAttributes, size_t stride, const FVertexBufferAttribute *attrs) override; +}; + +class VKIndexBuffer : public IIndexBuffer, public VKBuffer +{ +public: + VKIndexBuffer() { mBufferType = VK_BUFFER_USAGE_INDEX_BUFFER_BIT; } +}; + +class VKDataBuffer : public IDataBuffer, public VKBuffer +{ +public: + VKDataBuffer(int bindingpoint, bool ssbo) : bindingpoint(bindingpoint) { mBufferType = ssbo ? VK_BUFFER_USAGE_STORAGE_BUFFER_BIT : VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; } + + void BindRange(size_t start, size_t length) override; + void BindBase() override; + + int bindingpoint; +}; diff --git a/src/rendering/vulkan/system/vk_device.cpp b/src/rendering/vulkan/system/vk_device.cpp index 8816b39db..1ded967de 100644 --- a/src/rendering/vulkan/system/vk_device.cpp +++ b/src/rendering/vulkan/system/vk_device.cpp @@ -364,7 +364,7 @@ void VulkanDevice::createDevice() void VulkanDevice::createAllocator() { VmaAllocatorCreateInfo allocinfo = {}; - allocinfo.flags = VMA_ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT; + // allocinfo.flags = VMA_ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT; // To do: enable this for better performance allocinfo.physicalDevice = physicalDevice; allocinfo.device = device; allocinfo.preferredLargeHeapBlockSize = 64 * 1024 * 1024; diff --git a/src/rendering/vulkan/system/vk_framebuffer.cpp b/src/rendering/vulkan/system/vk_framebuffer.cpp index 4e9521f07..0b886f8bd 100644 --- a/src/rendering/vulkan/system/vk_framebuffer.cpp +++ b/src/rendering/vulkan/system/vk_framebuffer.cpp @@ -30,8 +30,14 @@ #include "hwrenderer/utility/hw_clock.h" #include "hwrenderer/utility/hw_vrmodes.h" +#include "hwrenderer/models/hw_models.h" +#include "hwrenderer/scene/hw_skydome.h" +#include "hwrenderer/data/hw_viewpointbuffer.h" +#include "hwrenderer/data/flatvertices.h" +#include "hwrenderer/dynlights/hw_lightbuffer.h" #include "vk_framebuffer.h" +#include "vk_buffers.h" #include "vulkan/textures/vk_samplers.h" #include "vulkan/system/vk_builders.h" #include "vulkan/system/vk_swapchain.h" @@ -57,9 +63,15 @@ VulkanFrameBuffer::~VulkanFrameBuffer() void VulkanFrameBuffer::InitializeState() { + mGraphicsCommandPool.reset(new VulkanCommandPool(device, device->graphicsFamily)); + + mVertexData = new FFlatVertexBuffer(GetWidth(), GetHeight()); + mSkyData = new FSkyVertexBuffer; + mViewpoints = new GLViewpointBuffer; + mLights = new FLightBuffer(); + ShInitialize(); mSamplerManager.reset(new VkSamplerManager(device)); - mGraphicsCommandPool.reset(new VulkanCommandPool(device, device->graphicsFamily)); #if 0 { @@ -176,17 +188,29 @@ void VulkanFrameBuffer::CleanForRestart() FModelRenderer *VulkanFrameBuffer::CreateModelRenderer(int mli) { + I_FatalError("VulkanFrameBuffer::CreateModelRenderer not implemented\n"); return nullptr; } +IShaderProgram *VulkanFrameBuffer::CreateShaderProgram() +{ + I_FatalError("VulkanFrameBuffer::CreateShaderProgram not implemented\n"); + return nullptr; +} + +IVertexBuffer *VulkanFrameBuffer::CreateVertexBuffer() +{ + return new VKVertexBuffer(); +} + +IIndexBuffer *VulkanFrameBuffer::CreateIndexBuffer() +{ + return new VKIndexBuffer(); +} + IDataBuffer *VulkanFrameBuffer::CreateDataBuffer(int bindingpoint, bool ssbo) { - return nullptr; -} - -IShaderProgram *VulkanFrameBuffer::CreateShaderProgram() -{ - return nullptr; + return new VKDataBuffer(bindingpoint, ssbo); } void VulkanFrameBuffer::UnbindTexUnit(int no) @@ -212,3 +236,18 @@ void VulkanFrameBuffer::BeginFrame() void VulkanFrameBuffer::Draw2D() { } + +VulkanCommandBuffer *VulkanFrameBuffer::GetUploadCommands() +{ + if (!mUploadCommands) + { + mUploadCommands = mGraphicsCommandPool->createBuffer(); + mUploadCommands->begin(); + } + return mUploadCommands.get(); +} + +VulkanCommandBuffer *VulkanFrameBuffer::GetDrawCommands() +{ + return mPresentCommands.get(); +} diff --git a/src/rendering/vulkan/system/vk_framebuffer.h b/src/rendering/vulkan/system/vk_framebuffer.h index 94e2e8886..7cec67cc2 100644 --- a/src/rendering/vulkan/system/vk_framebuffer.h +++ b/src/rendering/vulkan/system/vk_framebuffer.h @@ -13,10 +13,9 @@ class VulkanFrameBuffer : public SystemBaseFrameBuffer public: VulkanDevice *device; - std::unique_ptr mSamplerManager; - std::unique_ptr mGraphicsCommandPool; - std::unique_ptr mUploadCommands; - std::unique_ptr mPresentCommands; + + VulkanCommandBuffer *GetUploadCommands(); + VulkanCommandBuffer *GetDrawCommands(); VulkanFrameBuffer(void *hMonitor, bool fullscreen, VulkanDevice *dev); ~VulkanFrameBuffer(); @@ -30,13 +29,16 @@ public: uint32_t GetCaps() override; void WriteSavePic(player_t *player, FileWriter *file, int width, int height) override; sector_t *RenderView(player_t *player) override; - FModelRenderer *CreateModelRenderer(int mli) override; void UnbindTexUnit(int no) override; void TextureFilterChanged() override; void BeginFrame() override; void BlurScene(float amount) override; - IDataBuffer *CreateDataBuffer(int bindingpoint, bool ssbo) override; + + FModelRenderer *CreateModelRenderer(int mli) override; IShaderProgram *CreateShaderProgram() override; + IVertexBuffer *CreateVertexBuffer() override; + IIndexBuffer *CreateIndexBuffer() override; + IDataBuffer *CreateDataBuffer(int bindingpoint, bool ssbo) override; /* bool WipeStartScreen(int type); @@ -50,8 +52,15 @@ public: void Draw2D() override; private: + std::unique_ptr mSamplerManager; + std::unique_ptr mGraphicsCommandPool; + std::unique_ptr mUploadCommands; + std::unique_ptr mPresentCommands; + int camtexcount = 0; int lastSwapWidth = 0; int lastSwapHeight = 0; }; + +inline VulkanFrameBuffer *GetVulkanFrameBuffer() { return static_cast(screen); }