Move descriptor sets from VkRenderPassManager into a new class called VkDescriptorSetManager

This commit is contained in:
Magnus Norddahl 2022-06-06 21:30:55 +02:00 committed by Christoph Oelckers
parent e26fb04adf
commit 8517c9713a
13 changed files with 344 additions and 250 deletions

View file

@ -803,6 +803,7 @@ set (VULKAN_SOURCES
common/rendering/vulkan/renderer/vk_streambuffer.cpp
common/rendering/vulkan/renderer/vk_postprocess.cpp
common/rendering/vulkan/renderer/vk_renderbuffers.cpp
common/rendering/vulkan/renderer/vk_descriptorset.cpp
common/rendering/vulkan/renderer/vk_raytrace.cpp
common/rendering/vulkan/shaders/vk_shader.cpp
common/rendering/vulkan/textures/vk_samplers.cpp

View file

@ -0,0 +1,213 @@
/*
** Vulkan backend
** Copyright (c) 2016-2020 Magnus Norddahl
**
** This software is provided 'as-is', without any express or implied
** warranty. In no event will the authors be held liable for any damages
** arising from the use of this software.
**
** Permission is granted to anyone to use this software for any purpose,
** including commercial applications, and to alter it and redistribute it
** freely, subject to the following restrictions:
**
** 1. The origin of this software must not be misrepresented; you must not
** claim that you wrote the original software. If you use this software
** in a product, an acknowledgment in the product documentation would be
** appreciated but is not required.
** 2. Altered source versions must be plainly marked as such, and must not be
** misrepresented as being the original software.
** 3. This notice may not be removed or altered from any source distribution.
**
*/
#include "vk_descriptorset.h"
#include "vk_streambuffer.h"
#include "vk_renderbuffers.h"
#include "vk_raytrace.h"
#include "vulkan/shaders/vk_shader.h"
#include "vulkan/textures/vk_samplers.h"
#include "vulkan/system/vk_builders.h"
#include "vulkan/system/vk_framebuffer.h"
#include "vulkan/system/vk_buffers.h"
#include "flatvertices.h"
#include "hw_viewpointuniforms.h"
#include "v_2ddrawer.h"
VkDescriptorSetManager::VkDescriptorSetManager()
{
}
VkDescriptorSetManager::~VkDescriptorSetManager()
{
}
void VkDescriptorSetManager::Init()
{
CreateFixedSet();
CreateDynamicSet();
CreateNullTexture();
}
void VkDescriptorSetManager::CreateDynamicSet()
{
DescriptorSetLayoutBuilder builder;
builder.addBinding(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT);
builder.addBinding(1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT);
builder.addBinding(2, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT);
DynamicSetLayout = builder.create(GetVulkanFrameBuffer()->device);
DynamicSetLayout->SetDebugName("VkDescriptorSetManager.DynamicSetLayout");
DescriptorPoolBuilder poolbuilder;
poolbuilder.addPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 3);
poolbuilder.setMaxSets(1);
DynamicDescriptorPool = poolbuilder.create(GetVulkanFrameBuffer()->device);
DynamicDescriptorPool->SetDebugName("VkDescriptorSetManager.DynamicDescriptorPool");
DynamicSet = DynamicDescriptorPool->allocate(DynamicSetLayout.get());
if (!DynamicSet)
I_FatalError("CreateDynamicSet failed.\n");
}
void VkDescriptorSetManager::UpdateDynamicSet()
{
auto fb = GetVulkanFrameBuffer();
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.updateSets(fb->device);
}
void VkDescriptorSetManager::CreateFixedSet()
{
DescriptorSetLayoutBuilder builder;
builder.addBinding(0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
builder.addBinding(1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
builder.addBinding(2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
if (GetVulkanFrameBuffer()->device->SupportsDeviceExtension(VK_KHR_RAY_QUERY_EXTENSION_NAME))
builder.addBinding(3, VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
FixedSetLayout = builder.create(GetVulkanFrameBuffer()->device);
FixedSetLayout->SetDebugName("VkDescriptorSetManager.FixedSetLayout");
DescriptorPoolBuilder poolbuilder;
poolbuilder.addPoolSize(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1);
poolbuilder.addPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 2);
if (GetVulkanFrameBuffer()->device->SupportsDeviceExtension(VK_KHR_RAY_QUERY_EXTENSION_NAME))
poolbuilder.addPoolSize(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, 1);
poolbuilder.setMaxSets(1);
FixedDescriptorPool = poolbuilder.create(GetVulkanFrameBuffer()->device);
FixedDescriptorPool->SetDebugName("VkDescriptorSetManager.FixedDescriptorPool");
FixedSet = FixedDescriptorPool->allocate(FixedSetLayout.get());
if (!FixedSet)
I_FatalError("CreateFixedSet failed.\n");
}
void VkDescriptorSetManager::UpdateFixedSet()
{
auto fb = GetVulkanFrameBuffer();
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());
if (fb->device->SupportsDeviceExtension(VK_KHR_RAY_QUERY_EXTENSION_NAME))
update.addAccelerationStructure(FixedSet.get(), 3, fb->GetRaytrace()->GetAccelStruct());
update.updateSets(fb->device);
}
void VkDescriptorSetManager::TextureSetPoolReset()
{
if (auto fb = GetVulkanFrameBuffer())
{
auto& deleteList = fb->FrameDeleteList;
for (auto& desc : TextureDescriptorPools)
{
deleteList.DescriptorPools.push_back(std::move(desc));
}
deleteList.Descriptors.push_back(std::move(NullTextureDescriptorSet));
}
NullTextureDescriptorSet.reset();
TextureDescriptorPools.clear();
TextureDescriptorSetsLeft = 0;
TextureDescriptorsLeft = 0;
}
void VkDescriptorSetManager::CreateNullTexture()
{
auto fb = GetVulkanFrameBuffer();
ImageBuilder imgbuilder;
imgbuilder.setFormat(VK_FORMAT_R8G8B8A8_UNORM);
imgbuilder.setSize(1, 1);
imgbuilder.setUsage(VK_IMAGE_USAGE_SAMPLED_BIT);
NullTexture = imgbuilder.create(fb->device);
NullTexture->SetDebugName("VkDescriptorSetManager.NullTexture");
ImageViewBuilder viewbuilder;
viewbuilder.setImage(NullTexture.get(), VK_FORMAT_R8G8B8A8_UNORM);
NullTextureView = viewbuilder.create(fb->device);
NullTextureView->SetDebugName("VkDescriptorSetManager.NullTextureView");
PipelineBarrier barrier;
barrier.addImage(NullTexture.get(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, 0, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_ASPECT_COLOR_BIT);
barrier.execute(fb->GetTransferCommands(), VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
}
VulkanDescriptorSet* VkDescriptorSetManager::GetNullTextureDescriptorSet()
{
if (!NullTextureDescriptorSet)
{
NullTextureDescriptorSet = AllocateTextureDescriptorSet(SHADER_MIN_REQUIRED_TEXTURE_LAYERS);
auto fb = GetVulkanFrameBuffer();
WriteDescriptors update;
for (int i = 0; i < SHADER_MIN_REQUIRED_TEXTURE_LAYERS; i++)
{
update.addCombinedImageSampler(NullTextureDescriptorSet.get(), i, NullTextureView.get(), fb->GetSamplerManager()->Get(CLAMP_XY_NOMIP), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
}
update.updateSets(fb->device);
}
return NullTextureDescriptorSet.get();
}
std::unique_ptr<VulkanDescriptorSet> VkDescriptorSetManager::AllocateTextureDescriptorSet(int numLayers)
{
if (TextureDescriptorSetsLeft == 0 || TextureDescriptorsLeft < numLayers)
{
TextureDescriptorSetsLeft = 1000;
TextureDescriptorsLeft = 2000;
DescriptorPoolBuilder builder;
builder.addPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, TextureDescriptorsLeft);
builder.setMaxSets(TextureDescriptorSetsLeft);
TextureDescriptorPools.push_back(builder.create(GetVulkanFrameBuffer()->device));
TextureDescriptorPools.back()->SetDebugName("VkDescriptorSetManager.TextureDescriptorPool");
}
TextureDescriptorSetsLeft--;
TextureDescriptorsLeft -= numLayers;
return TextureDescriptorPools.back()->allocate(GetTextureSetLayout(numLayers));
}
VulkanDescriptorSetLayout* VkDescriptorSetManager::GetTextureSetLayout(int numLayers)
{
if (TextureSetLayouts.size() < (size_t)numLayers)
TextureSetLayouts.resize(numLayers);
auto& layout = TextureSetLayouts[numLayers - 1];
if (layout)
return layout.get();
DescriptorSetLayoutBuilder builder;
for (int i = 0; i < numLayers; i++)
{
builder.addBinding(i, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
}
layout = builder.create(GetVulkanFrameBuffer()->device);
layout->SetDebugName("VkDescriptorSetManager.TextureSetLayout");
return layout.get();
}

View file

@ -0,0 +1,51 @@
#pragma once
#include "vulkan/system/vk_objects.h"
class VkDescriptorSetManager
{
public:
VkDescriptorSetManager();
~VkDescriptorSetManager();
void Init();
void UpdateFixedSet();
void UpdateDynamicSet();
void TextureSetPoolReset();
VulkanDescriptorSetLayout* GetDynamicSetLayout() { return DynamicSetLayout.get(); }
VulkanDescriptorSetLayout* GetFixedSetLayout() { return FixedSetLayout.get(); }
VulkanDescriptorSetLayout* GetTextureSetLayout(int numLayers);
VulkanDescriptorSet* GetDynamicDescriptorSet() { return DynamicSet.get(); }
VulkanDescriptorSet* GetFixedDescriptorSet() { return FixedSet.get(); }
VulkanDescriptorSet* GetNullTextureDescriptorSet();
std::unique_ptr<VulkanDescriptorSet> AllocateTextureDescriptorSet(int numLayers);
VulkanImageView* GetNullTextureView() { return NullTextureView.get(); }
private:
void CreateDynamicSet();
void CreateFixedSet();
void CreateNullTexture();
std::unique_ptr<VulkanDescriptorSetLayout> DynamicSetLayout;
std::unique_ptr<VulkanDescriptorSetLayout> FixedSetLayout;
std::vector<std::unique_ptr<VulkanDescriptorSetLayout>> TextureSetLayouts;
std::unique_ptr<VulkanDescriptorPool> DynamicDescriptorPool;
std::unique_ptr<VulkanDescriptorPool> FixedDescriptorPool;
int TextureDescriptorSetsLeft = 0;
int TextureDescriptorsLeft = 0;
std::vector<std::unique_ptr<VulkanDescriptorPool>> TextureDescriptorPools;
std::unique_ptr<VulkanDescriptorSet> DynamicSet;
std::unique_ptr<VulkanDescriptorSet> FixedSet;
std::unique_ptr<VulkanDescriptorSet> NullTextureDescriptorSet;
std::unique_ptr<VulkanImage> NullTexture;
std::unique_ptr<VulkanImageView> NullTextureView;
};

View file

@ -76,19 +76,23 @@ VulkanAccelerationStructure* VkRaytrace::GetAccelStruct()
void VkRaytrace::Reset()
{
vertexBuffer.reset();
indexBuffer.reset();
transferBuffer.reset();
auto fb = GetVulkanFrameBuffer();
if (fb)
{
fb->FrameDeleteList.Buffers.push_back(std::move(vertexBuffer));
fb->FrameDeleteList.Buffers.push_back(std::move(indexBuffer));
fb->FrameDeleteList.Buffers.push_back(std::move(transferBuffer));
blScratchBuffer.reset();
blAccelStructBuffer.reset();
blAccelStruct.reset();
fb->FrameDeleteList.Buffers.push_back(std::move(blScratchBuffer));
fb->FrameDeleteList.Buffers.push_back(std::move(blAccelStructBuffer));
fb->FrameDeleteList.AccelStructs.push_back(std::move(blAccelStruct));
tlTransferBuffer.reset();
tlScratchBuffer.reset();
tlInstanceBuffer.reset();
tlAccelStructBuffer.reset();
tlAccelStruct.reset();
fb->FrameDeleteList.Buffers.push_back(std::move(tlTransferBuffer));
fb->FrameDeleteList.Buffers.push_back(std::move(tlScratchBuffer));
fb->FrameDeleteList.Buffers.push_back(std::move(tlInstanceBuffer));
fb->FrameDeleteList.Buffers.push_back(std::move(tlAccelStructBuffer));
fb->FrameDeleteList.AccelStructs.push_back(std::move(tlAccelStruct));
}
}
void VkRaytrace::CreateVulkanObjects()

View file

@ -23,6 +23,7 @@
#include "vk_renderpass.h"
#include "vk_renderbuffers.h"
#include "vk_renderstate.h"
#include "vk_descriptorset.h"
#include "vk_raytrace.h"
#include "vulkan/textures/vk_samplers.h"
#include "vulkan/shaders/vk_shader.h"
@ -39,15 +40,6 @@ VkRenderPassManager::VkRenderPassManager()
VkRenderPassManager::~VkRenderPassManager()
{
DynamicSet.reset(); // Needed since it must come before destruction of DynamicDescriptorPool
}
void VkRenderPassManager::Init()
{
CreateDynamicSetLayout();
CreateDescriptorPool();
CreateDynamicSet();
CreateNullTexture();
}
void VkRenderPassManager::RenderBuffersReset()
@ -55,23 +47,6 @@ void VkRenderPassManager::RenderBuffersReset()
RenderPassSetup.clear();
}
void VkRenderPassManager::TextureSetPoolReset()
{
if (auto fb = GetVulkanFrameBuffer())
{
auto &deleteList = fb->FrameDeleteList;
for (auto &desc : TextureDescriptorPools)
{
deleteList.DescriptorPools.push_back(std::move(desc));
}
}
NullTextureDescriptorSet.reset();
TextureDescriptorPools.clear();
TextureDescriptorSetsLeft = 0;
TextureDescriptorsLeft = 0;
}
VkRenderPassSetup *VkRenderPassManager::GetRenderPass(const VkRenderPassKey &key)
{
auto &item = RenderPassSetup[key];
@ -123,40 +98,6 @@ VkVertexFormat *VkRenderPassManager::GetVertexFormat(int index)
return &VertexFormats[index];
}
void VkRenderPassManager::CreateDynamicSetLayout()
{
DescriptorSetLayoutBuilder builder;
builder.addBinding(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT);
builder.addBinding(1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
builder.addBinding(2, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT);
builder.addBinding(3, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT);
builder.addBinding(4, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
builder.addBinding(5, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
if (GetVulkanFrameBuffer()->device->SupportsDeviceExtension(VK_KHR_RAY_QUERY_EXTENSION_NAME))
builder.addBinding(6, VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
DynamicSetLayout = builder.create(GetVulkanFrameBuffer()->device);
DynamicSetLayout->SetDebugName("VkRenderPassManager.DynamicSetLayout");
}
VulkanDescriptorSetLayout *VkRenderPassManager::GetTextureSetLayout(int numLayers)
{
if (TextureSetLayouts.size() < (size_t)numLayers)
TextureSetLayouts.resize(numLayers);
auto &layout = TextureSetLayouts[numLayers - 1];
if (layout)
return layout.get();
DescriptorSetLayoutBuilder builder;
for (int i = 0; i < numLayers; i++)
{
builder.addBinding(i, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
}
layout = builder.create(GetVulkanFrameBuffer()->device);
layout->SetDebugName("VkRenderPassManager.TextureSetLayout");
return layout.get();
}
VulkanPipelineLayout* VkRenderPassManager::GetPipelineLayout(int numLayers)
{
if (PipelineLayouts.size() <= (size_t)numLayers)
@ -166,120 +107,19 @@ VulkanPipelineLayout* VkRenderPassManager::GetPipelineLayout(int numLayers)
if (layout)
return layout.get();
auto descriptors = GetVulkanFrameBuffer()->GetDescriptorSetManager();
PipelineLayoutBuilder builder;
builder.addSetLayout(DynamicSetLayout.get());
builder.addSetLayout(descriptors->GetFixedSetLayout());
builder.addSetLayout(descriptors->GetDynamicSetLayout());
if (numLayers != 0)
builder.addSetLayout(GetTextureSetLayout(numLayers));
builder.addSetLayout(descriptors->GetTextureSetLayout(numLayers));
builder.addPushConstantRange(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(PushConstants));
layout = builder.create(GetVulkanFrameBuffer()->device);
layout->SetDebugName("VkRenderPassManager.PipelineLayout");
return layout.get();
}
void VkRenderPassManager::CreateDescriptorPool()
{
DescriptorPoolBuilder builder;
builder.addPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 3);
builder.addPoolSize(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1);
builder.addPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 2);
if (GetVulkanFrameBuffer()->device->SupportsDeviceExtension(VK_KHR_RAY_QUERY_EXTENSION_NAME))
builder.addPoolSize(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, 1);
builder.setMaxSets(1);
DynamicDescriptorPool = builder.create(GetVulkanFrameBuffer()->device);
DynamicDescriptorPool->SetDebugName("VkRenderPassManager.DynamicDescriptorPool");
}
void VkRenderPassManager::CreateDynamicSet()
{
DynamicSet = DynamicDescriptorPool->allocate(DynamicSetLayout.get());
if (!DynamicSet)
I_FatalError("CreateDynamicSet failed.\n");
}
void VkRenderPassManager::CreateNullTexture()
{
auto fb = GetVulkanFrameBuffer();
ImageBuilder imgbuilder;
imgbuilder.setFormat(VK_FORMAT_R8G8B8A8_UNORM);
imgbuilder.setSize(1, 1);
imgbuilder.setUsage(VK_IMAGE_USAGE_SAMPLED_BIT);
NullTexture = imgbuilder.create(fb->device);
NullTexture->SetDebugName("VkRenderPassManager.NullTexture");
ImageViewBuilder viewbuilder;
viewbuilder.setImage(NullTexture.get(), VK_FORMAT_R8G8B8A8_UNORM);
NullTextureView = viewbuilder.create(fb->device);
NullTextureView->SetDebugName("VkRenderPassManager.NullTextureView");
PipelineBarrier barrier;
barrier.addImage(NullTexture.get(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, 0, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_ASPECT_COLOR_BIT);
barrier.execute(fb->GetTransferCommands(), VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
}
VulkanDescriptorSet* VkRenderPassManager::GetNullTextureDescriptorSet()
{
if (!NullTextureDescriptorSet)
{
NullTextureDescriptorSet = AllocateTextureDescriptorSet(SHADER_MIN_REQUIRED_TEXTURE_LAYERS);
auto fb = GetVulkanFrameBuffer();
WriteDescriptors update;
for (int i = 0; i < SHADER_MIN_REQUIRED_TEXTURE_LAYERS; i++)
{
update.addCombinedImageSampler(NullTextureDescriptorSet.get(), i, NullTextureView.get(), fb->GetSamplerManager()->Get(CLAMP_XY_NOMIP), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
}
update.updateSets(fb->device);
}
return NullTextureDescriptorSet.get();
}
VulkanImageView* VkRenderPassManager::GetNullTextureView()
{
return NullTextureView.get();
}
void VkRenderPassManager::UpdateDynamicSet()
{
auto fb = GetVulkanFrameBuffer();
// In some rare cases drawing commands may already have been created before VulkanFrameBuffer::BeginFrame is called.
// Make sure there there are no active command buffers using DynamicSet when we update it:
fb->GetRenderState()->EndRenderPass();
fb->WaitForCommands(false);
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_STORAGE_BUFFER, fb->LightBufferSSO->mBuffer.get());
update.addBuffer(DynamicSet.get(), 2, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, fb->MatrixBuffer->UniformBuffer->mBuffer.get(), 0, sizeof(MatricesUBO));
update.addBuffer(DynamicSet.get(), 3, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, fb->StreamBuffer->UniformBuffer->mBuffer.get(), 0, sizeof(StreamUBO));
update.addCombinedImageSampler(DynamicSet.get(), 4, fb->GetBuffers()->Shadowmap.View.get(), fb->GetBuffers()->ShadowmapSampler.get(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
update.addCombinedImageSampler(DynamicSet.get(), 5, fb->GetBuffers()->Lightmap.View.get(), fb->GetBuffers()->LightmapSampler.get(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
if (GetVulkanFrameBuffer()->device->SupportsDeviceExtension(VK_KHR_RAY_QUERY_EXTENSION_NAME))
update.addAccelerationStructure(DynamicSet.get(), 6, fb->GetRaytrace()->GetAccelStruct());
update.updateSets(fb->device);
}
std::unique_ptr<VulkanDescriptorSet> VkRenderPassManager::AllocateTextureDescriptorSet(int numLayers)
{
if (TextureDescriptorSetsLeft == 0 || TextureDescriptorsLeft < numLayers)
{
TextureDescriptorSetsLeft = 1000;
TextureDescriptorsLeft = 2000;
DescriptorPoolBuilder builder;
builder.addPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, TextureDescriptorsLeft);
builder.setMaxSets(TextureDescriptorSetsLeft);
TextureDescriptorPools.push_back(builder.create(GetVulkanFrameBuffer()->device));
TextureDescriptorPools.back()->SetDebugName("VkRenderPassManager.TextureDescriptorPool");
}
TextureDescriptorSetsLeft--;
TextureDescriptorsLeft -= numLayers;
return TextureDescriptorPools.back()->allocate(GetTextureSetLayout(numLayers));
}
/////////////////////////////////////////////////////////////////////////////
VkRenderPassSetup::VkRenderPassSetup(const VkRenderPassKey &key) : PassKey(key)
@ -403,12 +243,7 @@ std::unique_ptr<VulkanPipeline> VkRenderPassSetup::CreatePipeline(const VkPipeli
builder.addDynamicState(VK_DYNAMIC_STATE_VIEWPORT);
builder.addDynamicState(VK_DYNAMIC_STATE_SCISSOR);
// builder.addDynamicState(VK_DYNAMIC_STATE_LINE_WIDTH);
builder.addDynamicState(VK_DYNAMIC_STATE_DEPTH_BIAS);
// builder.addDynamicState(VK_DYNAMIC_STATE_BLEND_CONSTANTS);
// builder.addDynamicState(VK_DYNAMIC_STATE_DEPTH_BOUNDS);
// builder.addDynamicState(VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK);
// builder.addDynamicState(VK_DYNAMIC_STATE_STENCIL_WRITE_MASK);
builder.addDynamicState(VK_DYNAMIC_STATE_STENCIL_REFERENCE);
// Note: the actual values are ignored since we use dynamic viewport+scissor states

View file

@ -80,44 +80,15 @@ public:
VkRenderPassManager();
~VkRenderPassManager();
void Init();
void RenderBuffersReset();
void UpdateDynamicSet();
void TextureSetPoolReset();
VkRenderPassSetup *GetRenderPass(const VkRenderPassKey &key);
int GetVertexFormat(int numBindingPoints, int numAttributes, size_t stride, const FVertexBufferAttribute *attrs);
VkVertexFormat *GetVertexFormat(int index);
std::unique_ptr<VulkanDescriptorSet> AllocateTextureDescriptorSet(int numLayers);
VulkanPipelineLayout* GetPipelineLayout(int numLayers);
VulkanDescriptorSet* GetNullTextureDescriptorSet();
VulkanImageView* GetNullTextureView();
std::unique_ptr<VulkanDescriptorSetLayout> DynamicSetLayout;
std::map<VkRenderPassKey, std::unique_ptr<VkRenderPassSetup>> RenderPassSetup;
std::unique_ptr<VulkanDescriptorSet> DynamicSet;
private:
void CreateDynamicSetLayout();
void CreateDescriptorPool();
void CreateDynamicSet();
void CreateNullTexture();
VulkanDescriptorSetLayout *GetTextureSetLayout(int numLayers);
int TextureDescriptorSetsLeft = 0;
int TextureDescriptorsLeft = 0;
std::vector<std::unique_ptr<VulkanDescriptorPool>> TextureDescriptorPools;
std::unique_ptr<VulkanDescriptorPool> DynamicDescriptorPool;
std::vector<std::unique_ptr<VulkanDescriptorSetLayout>> TextureSetLayouts;
std::map<VkRenderPassKey, std::unique_ptr<VkRenderPassSetup>> RenderPassSetup;
std::vector<std::unique_ptr<VulkanPipelineLayout>> PipelineLayouts;
std::vector<VkVertexFormat> VertexFormats;
std::unique_ptr<VulkanImage> NullTexture;
std::unique_ptr<VulkanImageView> NullTextureView;
std::unique_ptr<VulkanDescriptorSet> NullTextureDescriptorSet;
};

View file

@ -25,6 +25,7 @@
#include "vulkan/system/vk_builders.h"
#include "vulkan/renderer/vk_renderpass.h"
#include "vulkan/renderer/vk_renderbuffers.h"
#include "vulkan/renderer/vk_descriptorset.h"
#include "vulkan/textures/vk_hwtexture.h"
#include "hw_skydome.h"
@ -265,6 +266,11 @@ void VkRenderState::ApplyRenderPass(int dt)
mCommandBuffer->bindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, mPassSetup->GetPipeline(pipelineKey));
mPipelineKey = pipelineKey;
}
if (!inRenderPass)
{
mCommandBuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, GetVulkanFrameBuffer()->GetRenderPassManager()->GetPipelineLayout(mPipelineKey.NumTextureLayers), 0, GetVulkanFrameBuffer()->GetDescriptorSetManager()->GetFixedDescriptorSet());
}
}
void VkRenderState::ApplyStencilRef()
@ -432,12 +438,13 @@ void VkRenderState::ApplyMaterial()
{
auto fb = GetVulkanFrameBuffer();
auto passManager = fb->GetRenderPassManager();
auto descriptors = fb->GetDescriptorSetManager();
if (mMaterial.mMaterial && mMaterial.mMaterial->Source()->isHardwareCanvas()) static_cast<FCanvasTexture*>(mMaterial.mMaterial->Source()->GetTexture())->NeedUpdate();
VulkanDescriptorSet* descriptorset = mMaterial.mMaterial ? static_cast<VkMaterial*>(mMaterial.mMaterial)->GetDescriptorSet(mMaterial) : passManager->GetNullTextureDescriptorSet();
VulkanDescriptorSet* descriptorset = mMaterial.mMaterial ? static_cast<VkMaterial*>(mMaterial.mMaterial)->GetDescriptorSet(mMaterial) : descriptors->GetNullTextureDescriptorSet();
mCommandBuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, passManager->GetPipelineLayout(mPipelineKey.NumTextureLayers), 1, descriptorset);
mCommandBuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, passManager->GetPipelineLayout(mPipelineKey.NumTextureLayers), 2, descriptorset);
mMaterial.mChanged = false;
}
}
@ -450,9 +457,10 @@ void VkRenderState::ApplyDynamicSet()
if (mViewpointOffset != mLastViewpointOffset || matrixOffset != mLastMatricesOffset || streamDataOffset != mLastStreamDataOffset)
{
auto passManager = fb->GetRenderPassManager();
auto descriptors = fb->GetDescriptorSetManager();
uint32_t offsets[3] = { mViewpointOffset, matrixOffset, streamDataOffset };
mCommandBuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, passManager->GetPipelineLayout(mPipelineKey.NumTextureLayers), 0, passManager->DynamicSet.get(), 3, offsets);
mCommandBuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, passManager->GetPipelineLayout(mPipelineKey.NumTextureLayers), 1, descriptors->GetDynamicDescriptorSet(), 3, offsets);
mLastViewpointOffset = mViewpointOffset;
mLastMatricesOffset = matrixOffset;

View file

@ -148,8 +148,21 @@ VkShaderProgram *VkShaderManager::Get(unsigned int eff, bool alphateston, EPassT
static const char *shaderBindings = R"(
layout(set = 0, binding = 0) uniform sampler2D ShadowMap;
layout(set = 0, binding = 1) uniform sampler2DArray LightMap;
// light buffers
layout(set = 0, binding = 2, std430) buffer LightBufferSSO
{
vec4 lights[];
};
#ifdef SUPPORTS_RAYTRACING
layout(set = 0, binding = 3) uniform accelerationStructureEXT TopLevelAS;
#endif
// This must match the HWViewpointUniforms struct
layout(set = 0, binding = 0, std140) uniform ViewpointUBO {
layout(set = 1, binding = 0, std140) uniform ViewpointUBO {
mat4 ProjectionMatrix;
mat4 ViewMatrix;
mat4 NormalViewMatrix;
@ -165,13 +178,7 @@ static const char *shaderBindings = R"(
int uShadowmapFilter;
};
// light buffers
layout(set = 0, binding = 1, std430) buffer LightBufferSSO
{
vec4 lights[];
};
layout(set = 0, binding = 2, std140) uniform MatricesUBO {
layout(set = 1, binding = 1, std140) uniform MatricesUBO {
mat4 ModelMatrix;
mat4 NormalModelMatrix;
mat4 TextureMatrix;
@ -210,26 +217,22 @@ static const char *shaderBindings = R"(
vec4 padding1, padding2, padding3;
};
layout(set = 0, binding = 3, std140) uniform StreamUBO {
layout(set = 1, binding = 2, std140) uniform StreamUBO {
StreamData data[MAX_STREAM_DATA];
};
layout(set = 0, binding = 4) uniform sampler2D ShadowMap;
layout(set = 0, binding = 5) uniform sampler2DArray LightMap;
layout(set = 0, binding = 6) uniform accelerationStructureEXT TopLevelAS;
// textures
layout(set = 1, binding = 0) uniform sampler2D tex;
layout(set = 1, binding = 1) uniform sampler2D texture2;
layout(set = 1, binding = 2) uniform sampler2D texture3;
layout(set = 1, binding = 3) uniform sampler2D texture4;
layout(set = 1, binding = 4) uniform sampler2D texture5;
layout(set = 1, binding = 5) uniform sampler2D texture6;
layout(set = 1, binding = 6) uniform sampler2D texture7;
layout(set = 1, binding = 7) uniform sampler2D texture8;
layout(set = 1, binding = 8) uniform sampler2D texture9;
layout(set = 1, binding = 9) uniform sampler2D texture10;
layout(set = 1, binding = 10) uniform sampler2D texture11;
layout(set = 2, binding = 0) uniform sampler2D tex;
layout(set = 2, binding = 1) uniform sampler2D texture2;
layout(set = 2, binding = 2) uniform sampler2D texture3;
layout(set = 2, binding = 3) uniform sampler2D texture4;
layout(set = 2, binding = 4) uniform sampler2D texture5;
layout(set = 2, binding = 5) uniform sampler2D texture6;
layout(set = 2, binding = 6) uniform sampler2D texture7;
layout(set = 2, binding = 7) uniform sampler2D texture8;
layout(set = 2, binding = 8) uniform sampler2D texture9;
layout(set = 2, binding = 9) uniform sampler2D texture10;
layout(set = 2, binding = 10) uniform sampler2D texture11;
// This must match the PushConstants struct
layout(push_constant) uniform PushConstants

View file

@ -24,7 +24,7 @@
#include "vk_builders.h"
#include "vk_framebuffer.h"
#include "vulkan/renderer/vk_renderstate.h"
#include "vulkan/renderer/vk_renderpass.h"
#include "vulkan/renderer/vk_descriptorset.h"
#include "engineerrors.h"
VKBuffer *VKBuffer::First = nullptr;
@ -197,12 +197,10 @@ void VKBuffer::Resize(size_t newsize)
// Transfer data from old to new
fb->GetTransferCommands()->copyBuffer(oldBuffer.get(), mBuffer.get(), 0, 0, oldsize);
fb->WaitForCommands(false);
fb->GetDescriptorSetManager()->UpdateDynamicSet(); // Old buffer may be part of the dynamic set
// Fetch pointer to new buffer
map = mBuffer->Map(0, newsize);
// Old buffer may be part of the dynamic set
fb->GetRenderPassManager()->UpdateDynamicSet();
}
void VKBuffer::Map()

View file

@ -46,6 +46,7 @@
#include "vk_buffers.h"
#include "vulkan/renderer/vk_renderstate.h"
#include "vulkan/renderer/vk_renderpass.h"
#include "vulkan/renderer/vk_descriptorset.h"
#include "vulkan/renderer/vk_streambuffer.h"
#include "vulkan/renderer/vk_postprocess.h"
#include "vulkan/renderer/vk_renderbuffers.h"
@ -153,6 +154,7 @@ void VulkanFrameBuffer::InitializeState()
mActiveRenderBuffers = mScreenBuffers.get();
mPostprocess.reset(new VkPostprocess());
mDescriptorSetManager.reset(new VkDescriptorSetManager());
mRenderPassManager.reset(new VkRenderPassManager());
mRaytrace.reset(new VkRaytrace());
@ -169,7 +171,7 @@ void VulkanFrameBuffer::InitializeState()
mShaderManager.reset(new VkShaderManager(device));
mSamplerManager.reset(new VkSamplerManager(device));
mRenderPassManager->Init();
mDescriptorSetManager->Init();
#ifdef __APPLE__
mRenderState.reset(new VkRenderStateMolten());
#else
@ -221,6 +223,7 @@ void VulkanFrameBuffer::DeleteFrameObjects(bool uploadOnly)
if (!uploadOnly)
{
FrameDeleteList.AccelStructs.clear();
FrameDeleteList.Images.clear();
FrameDeleteList.ImageViews.clear();
FrameDeleteList.Framebuffers.clear();
@ -577,7 +580,10 @@ void VulkanFrameBuffer::BeginFrame()
mScreenBuffers->BeginFrame(screen->mScreenViewport.width, screen->mScreenViewport.height, screen->mSceneViewport.width, screen->mSceneViewport.height);
mSaveBuffers->BeginFrame(SAVEPICWIDTH, SAVEPICHEIGHT, SAVEPICWIDTH, SAVEPICHEIGHT);
mRenderState->BeginFrame();
mRenderPassManager->UpdateDynamicSet();
WaitForCommands(false);
mDescriptorSetManager->UpdateFixedSet();
mDescriptorSetManager->UpdateDynamicSet();
if (mNextTimestampQuery > 0)
{

View file

@ -7,6 +7,7 @@
struct FRenderViewpoint;
class VkSamplerManager;
class VkShaderManager;
class VkDescriptorSetManager;
class VkRenderPassManager;
class VkRaytrace;
class VkRenderState;
@ -32,6 +33,7 @@ public:
VulkanCommandBuffer *GetDrawCommands();
VkShaderManager *GetShaderManager() { return mShaderManager.get(); }
VkSamplerManager *GetSamplerManager() { return mSamplerManager.get(); }
VkDescriptorSetManager* GetDescriptorSetManager() { return mDescriptorSetManager.get(); }
VkRenderPassManager *GetRenderPassManager() { return mRenderPassManager.get(); }
VkRaytrace* GetRaytrace() { return mRaytrace.get(); }
VkRenderState *GetRenderState() { return mRenderState.get(); }
@ -61,6 +63,7 @@ public:
std::vector<std::unique_ptr<VulkanImageView>> ImageViews;
std::vector<std::unique_ptr<VulkanFramebuffer>> Framebuffers;
std::vector<std::unique_ptr<VulkanBuffer>> Buffers;
std::vector<std::unique_ptr<VulkanAccelerationStructure>> AccelStructs;
std::vector<std::unique_ptr<VulkanDescriptorSet>> Descriptors;
std::vector<std::unique_ptr<VulkanDescriptorPool>> DescriptorPools;
std::vector<std::unique_ptr<VulkanCommandBuffer>> CommandBuffers;
@ -135,6 +138,7 @@ private:
std::unique_ptr<VkRenderBuffers> mScreenBuffers;
std::unique_ptr<VkRenderBuffers> mSaveBuffers;
std::unique_ptr<VkPostprocess> mPostprocess;
std::unique_ptr<VkDescriptorSetManager> mDescriptorSetManager;
std::unique_ptr<VkRenderPassManager> mRenderPassManager;
std::unique_ptr<VkRaytrace> mRaytrace;
std::unique_ptr<VulkanCommandPool> mCommandPool;

View file

@ -29,7 +29,7 @@
#include "vulkan/system/vk_builders.h"
#include "vulkan/system/vk_framebuffer.h"
#include "vulkan/textures/vk_samplers.h"
#include "vulkan/renderer/vk_renderpass.h"
#include "vulkan/renderer/vk_descriptorset.h"
#include "vulkan/renderer/vk_postprocess.h"
#include "vulkan/renderer/vk_renderbuffers.h"
#include "vulkan/shaders/vk_shader.h"
@ -372,7 +372,7 @@ void VkMaterial::ResetAllDescriptors()
auto fb = GetVulkanFrameBuffer();
if (fb)
fb->GetRenderPassManager()->TextureSetPoolReset();
fb->GetDescriptorSetManager()->TextureSetPoolReset();
}
VulkanDescriptorSet* VkMaterial::GetDescriptorSet(const FMaterialState& state)
@ -392,7 +392,7 @@ VulkanDescriptorSet* VkMaterial::GetDescriptorSet(const FMaterialState& state)
int numLayers = NumLayers();
auto fb = GetVulkanFrameBuffer();
auto descriptor = fb->GetRenderPassManager()->AllocateTextureDescriptorSet(max(numLayers, SHADER_MIN_REQUIRED_TEXTURE_LAYERS));
auto descriptor = fb->GetDescriptorSetManager()->AllocateTextureDescriptorSet(max(numLayers, SHADER_MIN_REQUIRED_TEXTURE_LAYERS));
descriptor->SetDebugName("VkHardwareTexture.mDescriptorSets");
@ -424,7 +424,7 @@ VulkanDescriptorSet* VkMaterial::GetDescriptorSet(const FMaterialState& state)
numLayers = 3;
}
auto dummyImage = fb->GetRenderPassManager()->GetNullTextureView();
auto dummyImage = fb->GetDescriptorSetManager()->GetNullTextureView();
for (int i = numLayers; i < SHADER_MIN_REQUIRED_TEXTURE_LAYERS; i++)
{
update.addCombinedImageSampler(descriptor.get(), i, dummyImage, sampler, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);