- create vulkan buffer objects implementation

This commit is contained in:
Magnus Norddahl 2019-02-21 12:31:14 +01:00
parent fc79cd1280
commit 478ef05a0a
6 changed files with 237 additions and 14 deletions

View file

@ -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

View file

@ -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()
{
}

View file

@ -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<VulkanBuffer> mBuffer;
std::unique_ptr<VulkanBuffer> 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;
};

View file

@ -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;

View file

@ -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();
}

View file

@ -13,10 +13,9 @@ class VulkanFrameBuffer : public SystemBaseFrameBuffer
public:
VulkanDevice *device;
std::unique_ptr<VkSamplerManager> mSamplerManager;
std::unique_ptr<VulkanCommandPool> mGraphicsCommandPool;
std::unique_ptr<VulkanCommandBuffer> mUploadCommands;
std::unique_ptr<VulkanCommandBuffer> 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<VkSamplerManager> mSamplerManager;
std::unique_ptr<VulkanCommandPool> mGraphicsCommandPool;
std::unique_ptr<VulkanCommandBuffer> mUploadCommands;
std::unique_ptr<VulkanCommandBuffer> mPresentCommands;
int camtexcount = 0;
int lastSwapWidth = 0;
int lastSwapHeight = 0;
};
inline VulkanFrameBuffer *GetVulkanFrameBuffer() { return static_cast<VulkanFrameBuffer*>(screen); }