mirror of
https://github.com/ZDoom/ZDRay.git
synced 2024-11-21 19:50:54 +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)
|
||||
{
|
||||
mCommandPool = CommandPoolBuilder()
|
||||
.QueueFamily(fb->GetDevice()->GraphicsFamily)
|
||||
.DebugName("mCommandPool")
|
||||
.Create(fb->GetDevice());
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
return TransferCommands.get();
|
||||
}
|
||||
|
||||
VulkanCommandBuffer* VkCommandBufferManager::GetDrawCommands()
|
||||
{
|
||||
return DrawCommands.get();
|
||||
if (!mTransferCommands)
|
||||
{
|
||||
mTransferCommands = mCommandPool->createBuffer();
|
||||
mTransferCommands->begin();
|
||||
}
|
||||
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)
|
||||
{
|
||||
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 "zvulkan/vulkanobjects.h"
|
||||
#include "zvulkan/vulkanbuilders.h"
|
||||
#include "textureid.h"
|
||||
#include <stdexcept>
|
||||
|
||||
|
@ -45,7 +46,6 @@ public:
|
|||
void SubmitAndWait();
|
||||
|
||||
VulkanCommandBuffer* GetTransferCommands();
|
||||
VulkanCommandBuffer* GetDrawCommands();
|
||||
|
||||
void PushGroup(VulkanCommandBuffer* cmdbuffer, const FString& name) { }
|
||||
void PopGroup(VulkanCommandBuffer* cmdbuffer) { }
|
||||
|
@ -82,8 +82,9 @@ public:
|
|||
|
||||
private:
|
||||
VulkanRenderDevice* fb = nullptr;
|
||||
std::unique_ptr<VulkanCommandBuffer> TransferCommands;
|
||||
std::unique_ptr<VulkanCommandBuffer> DrawCommands;
|
||||
std::unique_ptr<VulkanCommandPool> mCommandPool;
|
||||
std::unique_ptr<VulkanCommandBuffer> mTransferCommands;
|
||||
std::unique_ptr<VulkanCommandBuffer> mDrawCommands;
|
||||
};
|
||||
|
||||
class VkTextureImage
|
||||
|
@ -111,8 +112,12 @@ class VkTextureManager
|
|||
public:
|
||||
VkTextureManager(VulkanRenderDevice* fb);
|
||||
|
||||
void CreateLightmap(int newLMTextureSize, int newLMTextureCount);
|
||||
void DownloadLightmap(int arrayIndex, TArray<uint16_t>& buffer);
|
||||
|
||||
VkTextureImage Lightmap;
|
||||
int LMTextureSize = 1024;
|
||||
int LMTextureSize = 0;
|
||||
int LMTextureCount = 0;
|
||||
|
||||
private:
|
||||
VulkanRenderDevice* fb = nullptr;
|
||||
|
@ -123,11 +128,24 @@ class VkDescriptorSetManager
|
|||
public:
|
||||
VkDescriptorSetManager(VulkanRenderDevice* fb);
|
||||
|
||||
VulkanDescriptorSetLayout* GetBindlessSetLayout() { return nullptr; }
|
||||
VulkanDescriptorSet* GetBindlessDescriptorSet() { return nullptr; }
|
||||
VulkanDescriptorSetLayout* GetBindlessSetLayout() { return BindlessDescriptorSetLayout.get(); }
|
||||
VulkanDescriptorSet* GetBindlessDescriptorSet() { return BindlessDescriptorSet.get(); }
|
||||
|
||||
void UpdateBindlessDescriptorSet();
|
||||
int AddBindlessTextureIndex(VulkanImageView* imageview, VulkanSampler* sampler);
|
||||
|
||||
private:
|
||||
void CreateBindlessDescriptorSet();
|
||||
|
||||
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); }
|
||||
|
|
Loading…
Reference in a new issue