mirror of
https://github.com/ZDoom/ZDRay.git
synced 2024-11-25 05:11:20 +00:00
Implement a basic VulkanRenderDevice
This commit is contained in:
parent
3572d81010
commit
0b09fa9793
2 changed files with 148 additions and 12 deletions
|
@ -50,20 +50,37 @@ VulkanRenderDevice::~VulkanRenderDevice()
|
||||||
|
|
||||||
VkCommandBufferManager::VkCommandBufferManager(VulkanRenderDevice* fb) : fb(fb)
|
VkCommandBufferManager::VkCommandBufferManager(VulkanRenderDevice* fb) : fb(fb)
|
||||||
{
|
{
|
||||||
|
mCommandPool = CommandPoolBuilder()
|
||||||
|
.QueueFamily(fb->GetDevice()->GraphicsFamily)
|
||||||
|
.DebugName("mCommandPool")
|
||||||
|
.Create(fb->GetDevice());
|
||||||
}
|
}
|
||||||
|
|
||||||
void VkCommandBufferManager::SubmitAndWait()
|
void VkCommandBufferManager::SubmitAndWait()
|
||||||
{
|
{
|
||||||
|
if (mTransferCommands)
|
||||||
|
{
|
||||||
|
mTransferCommands->end();
|
||||||
|
|
||||||
|
QueueSubmit()
|
||||||
|
.AddCommandBuffer(mTransferCommands.get())
|
||||||
|
.Execute(fb->GetDevice(), fb->GetDevice()->GraphicsQueue);
|
||||||
|
|
||||||
|
vkDeviceWaitIdle(fb->GetDevice()->device);
|
||||||
|
}
|
||||||
|
|
||||||
|
TransferDeleteList = std::make_unique<DeleteList>();
|
||||||
|
DrawDeleteList = std::make_unique<DeleteList>();
|
||||||
}
|
}
|
||||||
|
|
||||||
VulkanCommandBuffer* VkCommandBufferManager::GetTransferCommands()
|
VulkanCommandBuffer* VkCommandBufferManager::GetTransferCommands()
|
||||||
{
|
{
|
||||||
return TransferCommands.get();
|
if (!mTransferCommands)
|
||||||
}
|
{
|
||||||
|
mTransferCommands = mCommandPool->createBuffer();
|
||||||
VulkanCommandBuffer* VkCommandBufferManager::GetDrawCommands()
|
mTransferCommands->begin();
|
||||||
{
|
}
|
||||||
return DrawCommands.get();
|
return mTransferCommands.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -72,8 +89,109 @@ VkTextureManager::VkTextureManager(VulkanRenderDevice* fb) : fb(fb)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VkTextureManager::CreateLightmap(int newLMTextureSize, int newLMTextureCount)
|
||||||
|
{
|
||||||
|
if (LMTextureSize == newLMTextureSize && LMTextureCount == newLMTextureCount + 1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
LMTextureSize = newLMTextureSize;
|
||||||
|
LMTextureCount = newLMTextureCount + 1; // the extra texture is for the dynamic lightmap
|
||||||
|
|
||||||
|
int w = newLMTextureSize;
|
||||||
|
int h = newLMTextureSize;
|
||||||
|
int count = newLMTextureCount;
|
||||||
|
int pixelsize = 8;
|
||||||
|
|
||||||
|
Lightmap.Reset(fb);
|
||||||
|
|
||||||
|
Lightmap.Image = ImageBuilder()
|
||||||
|
.Size(w, h, 1, LMTextureCount)
|
||||||
|
.Format(VK_FORMAT_R16G16B16A16_SFLOAT)
|
||||||
|
.Usage(VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)
|
||||||
|
.DebugName("VkRenderBuffers.Lightmap")
|
||||||
|
.Create(fb->GetDevice());
|
||||||
|
|
||||||
|
PipelineBarrier()
|
||||||
|
.AddImage(Lightmap.Image.get(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, 0, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, LMTextureCount)
|
||||||
|
.Execute(fb->GetCommands()->GetTransferCommands(), 0, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VkTextureManager::DownloadLightmap(int arrayIndex, TArray<uint16_t>& buffer)
|
||||||
|
{
|
||||||
|
unsigned int totalSize = LMTextureSize * LMTextureSize;
|
||||||
|
buffer.Resize(totalSize);
|
||||||
|
|
||||||
|
auto stagingBuffer = BufferBuilder()
|
||||||
|
.Size(totalSize * sizeof(uint16_t))
|
||||||
|
.Usage(VK_BUFFER_USAGE_TRANSFER_DST_BIT, VMA_MEMORY_USAGE_CPU_ONLY)
|
||||||
|
.DebugName("DownloadLightmap")
|
||||||
|
.Create(fb->GetDevice());
|
||||||
|
|
||||||
|
auto cmdbuffer = fb->GetCommands()->GetTransferCommands();
|
||||||
|
|
||||||
|
PipelineBarrier()
|
||||||
|
.AddImage(Lightmap.Image.get(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_ACCESS_SHADER_READ_BIT, VK_ACCESS_TRANSFER_READ_BIT, VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, arrayIndex, 1)
|
||||||
|
.Execute(cmdbuffer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
|
||||||
|
|
||||||
|
VkBufferImageCopy region = {};
|
||||||
|
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||||
|
region.imageSubresource.baseArrayLayer = arrayIndex;
|
||||||
|
region.imageSubresource.layerCount = 1;
|
||||||
|
region.imageSubresource.mipLevel = 0;
|
||||||
|
region.imageExtent.width = LMTextureSize;
|
||||||
|
region.imageExtent.height = LMTextureSize;
|
||||||
|
region.imageExtent.depth = 1;
|
||||||
|
cmdbuffer->copyImageToBuffer(Lightmap.Image->image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, stagingBuffer->buffer, 1, ®ion);
|
||||||
|
|
||||||
|
PipelineBarrier()
|
||||||
|
.AddImage(Lightmap.Image.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_ACCESS_TRANSFER_READ_BIT, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, arrayIndex, 1)
|
||||||
|
.Execute(cmdbuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||||
|
|
||||||
|
fb->GetCommands()->SubmitAndWait();
|
||||||
|
|
||||||
|
uint16_t* srcdata = (uint16_t*)stagingBuffer->Map(0, totalSize * sizeof(uint16_t));
|
||||||
|
memcpy(buffer.Data(), srcdata, totalSize * sizeof(uint16_t));
|
||||||
|
stagingBuffer->Unmap();
|
||||||
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
VkDescriptorSetManager::VkDescriptorSetManager(VulkanRenderDevice* fb) : fb(fb)
|
VkDescriptorSetManager::VkDescriptorSetManager(VulkanRenderDevice* fb) : fb(fb)
|
||||||
{
|
{
|
||||||
|
CreateBindlessDescriptorSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
void VkDescriptorSetManager::CreateBindlessDescriptorSet()
|
||||||
|
{
|
||||||
|
BindlessDescriptorPool = DescriptorPoolBuilder()
|
||||||
|
.Flags(VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT_EXT)
|
||||||
|
.AddPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, MaxBindlessTextures)
|
||||||
|
.MaxSets(MaxBindlessTextures)
|
||||||
|
.DebugName("BindlessDescriptorPool")
|
||||||
|
.Create(fb->GetDevice());
|
||||||
|
|
||||||
|
BindlessDescriptorSetLayout = DescriptorSetLayoutBuilder()
|
||||||
|
.Flags(VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT)
|
||||||
|
.AddBinding(
|
||||||
|
0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
||||||
|
MaxBindlessTextures,
|
||||||
|
VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||||
|
VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT_EXT | VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT | VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT)
|
||||||
|
.DebugName("BindlessDescriptorSetLayout")
|
||||||
|
.Create(fb->GetDevice());
|
||||||
|
|
||||||
|
BindlessDescriptorSet = BindlessDescriptorPool->allocate(BindlessDescriptorSetLayout.get(), MaxBindlessTextures);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VkDescriptorSetManager::UpdateBindlessDescriptorSet()
|
||||||
|
{
|
||||||
|
WriteBindless.Execute(fb->GetDevice());
|
||||||
|
WriteBindless = WriteDescriptors();
|
||||||
|
}
|
||||||
|
|
||||||
|
int VkDescriptorSetManager::AddBindlessTextureIndex(VulkanImageView* imageview, VulkanSampler* sampler)
|
||||||
|
{
|
||||||
|
int index = NextBindlessIndex++;
|
||||||
|
WriteBindless.AddCombinedImageSampler(BindlessDescriptorSet.get(), 0, index, imageview, sampler, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||||
|
return index;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include "framework/zstring.h"
|
#include "framework/zstring.h"
|
||||||
#include "zvulkan/vulkanobjects.h"
|
#include "zvulkan/vulkanobjects.h"
|
||||||
|
#include "zvulkan/vulkanbuilders.h"
|
||||||
#include "textureid.h"
|
#include "textureid.h"
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
|
@ -45,7 +46,6 @@ public:
|
||||||
void SubmitAndWait();
|
void SubmitAndWait();
|
||||||
|
|
||||||
VulkanCommandBuffer* GetTransferCommands();
|
VulkanCommandBuffer* GetTransferCommands();
|
||||||
VulkanCommandBuffer* GetDrawCommands();
|
|
||||||
|
|
||||||
void PushGroup(VulkanCommandBuffer* cmdbuffer, const FString& name) { }
|
void PushGroup(VulkanCommandBuffer* cmdbuffer, const FString& name) { }
|
||||||
void PopGroup(VulkanCommandBuffer* cmdbuffer) { }
|
void PopGroup(VulkanCommandBuffer* cmdbuffer) { }
|
||||||
|
@ -82,8 +82,9 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
VulkanRenderDevice* fb = nullptr;
|
VulkanRenderDevice* fb = nullptr;
|
||||||
std::unique_ptr<VulkanCommandBuffer> TransferCommands;
|
std::unique_ptr<VulkanCommandPool> mCommandPool;
|
||||||
std::unique_ptr<VulkanCommandBuffer> DrawCommands;
|
std::unique_ptr<VulkanCommandBuffer> mTransferCommands;
|
||||||
|
std::unique_ptr<VulkanCommandBuffer> mDrawCommands;
|
||||||
};
|
};
|
||||||
|
|
||||||
class VkTextureImage
|
class VkTextureImage
|
||||||
|
@ -111,8 +112,12 @@ class VkTextureManager
|
||||||
public:
|
public:
|
||||||
VkTextureManager(VulkanRenderDevice* fb);
|
VkTextureManager(VulkanRenderDevice* fb);
|
||||||
|
|
||||||
|
void CreateLightmap(int newLMTextureSize, int newLMTextureCount);
|
||||||
|
void DownloadLightmap(int arrayIndex, TArray<uint16_t>& buffer);
|
||||||
|
|
||||||
VkTextureImage Lightmap;
|
VkTextureImage Lightmap;
|
||||||
int LMTextureSize = 1024;
|
int LMTextureSize = 0;
|
||||||
|
int LMTextureCount = 0;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
VulkanRenderDevice* fb = nullptr;
|
VulkanRenderDevice* fb = nullptr;
|
||||||
|
@ -123,11 +128,24 @@ class VkDescriptorSetManager
|
||||||
public:
|
public:
|
||||||
VkDescriptorSetManager(VulkanRenderDevice* fb);
|
VkDescriptorSetManager(VulkanRenderDevice* fb);
|
||||||
|
|
||||||
VulkanDescriptorSetLayout* GetBindlessSetLayout() { return nullptr; }
|
VulkanDescriptorSetLayout* GetBindlessSetLayout() { return BindlessDescriptorSetLayout.get(); }
|
||||||
VulkanDescriptorSet* GetBindlessDescriptorSet() { return nullptr; }
|
VulkanDescriptorSet* GetBindlessDescriptorSet() { return BindlessDescriptorSet.get(); }
|
||||||
|
|
||||||
|
void UpdateBindlessDescriptorSet();
|
||||||
|
int AddBindlessTextureIndex(VulkanImageView* imageview, VulkanSampler* sampler);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void CreateBindlessDescriptorSet();
|
||||||
|
|
||||||
VulkanRenderDevice* fb = nullptr;
|
VulkanRenderDevice* fb = nullptr;
|
||||||
|
|
||||||
|
std::unique_ptr<VulkanDescriptorPool> BindlessDescriptorPool;
|
||||||
|
std::unique_ptr<VulkanDescriptorSet> BindlessDescriptorSet;
|
||||||
|
std::unique_ptr<VulkanDescriptorSetLayout> BindlessDescriptorSetLayout;
|
||||||
|
WriteDescriptors WriteBindless;
|
||||||
|
int NextBindlessIndex = 0;
|
||||||
|
|
||||||
|
static const int MaxBindlessTextures = 16536;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline void I_FatalError(const char* reason) { throw std::runtime_error(reason); }
|
inline void I_FatalError(const char* reason) { throw std::runtime_error(reason); }
|
||||||
|
|
Loading…
Reference in a new issue