Begin detaching internal vulkan object lifetimes from the hardware renderer layer

This commit is contained in:
Magnus Norddahl 2022-06-10 00:50:40 +02:00 committed by Christoph Oelckers
parent 8ebad1003b
commit 8004532cba
22 changed files with 177 additions and 203 deletions

View File

@ -35,7 +35,7 @@
#include "hw_viewpointuniforms.h"
#include "v_2ddrawer.h"
VkDescriptorSetManager::VkDescriptorSetManager()
VkDescriptorSetManager::VkDescriptorSetManager(VulkanFrameBuffer* fb) : fb(fb)
{
}
@ -56,13 +56,13 @@ void VkDescriptorSetManager::CreateDynamicSet()
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 = builder.create(fb->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 = poolbuilder.create(fb->device);
DynamicDescriptorPool->SetDebugName("VkDescriptorSetManager.DynamicDescriptorPool");
DynamicSet = DynamicDescriptorPool->allocate(DynamicSetLayout.get());
@ -72,8 +72,6 @@ void VkDescriptorSetManager::CreateDynamicSet()
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));
@ -87,18 +85,18 @@ void VkDescriptorSetManager::CreateFixedSet()
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))
if (fb->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 = builder.create(fb->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))
if (fb->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 = poolbuilder.create(fb->device);
FixedDescriptorPool->SetDebugName("VkDescriptorSetManager.FixedDescriptorPool");
FixedSet = FixedDescriptorPool->allocate(FixedSetLayout.get());
@ -108,8 +106,6 @@ void VkDescriptorSetManager::CreateFixedSet()
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);
@ -121,16 +117,14 @@ void VkDescriptorSetManager::UpdateFixedSet()
void VkDescriptorSetManager::TextureSetPoolReset()
{
if (auto fb = GetVulkanFrameBuffer())
{
auto& deleteList = fb->GetCommands()->FrameDeleteList;
auto& deleteList = fb->GetCommands()->FrameDeleteList;
for (auto& desc : TextureDescriptorPools)
{
deleteList.DescriptorPools.push_back(std::move(desc));
}
deleteList.Descriptors.push_back(std::move(NullTextureDescriptorSet));
for (auto& desc : TextureDescriptorPools)
{
deleteList.DescriptorPools.push_back(std::move(desc));
}
deleteList.Descriptors.push_back(std::move(NullTextureDescriptorSet));
NullTextureDescriptorSet.reset();
TextureDescriptorPools.clear();
TextureDescriptorSetsLeft = 0;
@ -145,8 +139,6 @@ void VkDescriptorSetManager::FilterModeChanged()
void VkDescriptorSetManager::CreateNullTexture()
{
auto fb = GetVulkanFrameBuffer();
ImageBuilder imgbuilder;
imgbuilder.setFormat(VK_FORMAT_R8G8B8A8_UNORM);
imgbuilder.setSize(1, 1);
@ -170,7 +162,6 @@ VulkanDescriptorSet* VkDescriptorSetManager::GetNullTextureDescriptorSet()
{
NullTextureDescriptorSet = AllocateTextureDescriptorSet(SHADER_MIN_REQUIRED_TEXTURE_LAYERS);
auto fb = GetVulkanFrameBuffer();
WriteDescriptors update;
for (int i = 0; i < SHADER_MIN_REQUIRED_TEXTURE_LAYERS; i++)
{
@ -192,7 +183,7 @@ std::unique_ptr<VulkanDescriptorSet> VkDescriptorSetManager::AllocateTextureDesc
DescriptorPoolBuilder builder;
builder.addPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, TextureDescriptorsLeft);
builder.setMaxSets(TextureDescriptorSetsLeft);
TextureDescriptorPools.push_back(builder.create(GetVulkanFrameBuffer()->device));
TextureDescriptorPools.push_back(builder.create(fb->device));
TextureDescriptorPools.back()->SetDebugName("VkDescriptorSetManager.TextureDescriptorPool");
}
@ -215,7 +206,7 @@ VulkanDescriptorSetLayout* VkDescriptorSetManager::GetTextureSetLayout(int numLa
{
builder.addBinding(i, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
}
layout = builder.create(GetVulkanFrameBuffer()->device);
layout = builder.create(fb->device);
layout->SetDebugName("VkDescriptorSetManager.TextureSetLayout");
return layout.get();
}

View File

@ -3,10 +3,12 @@
#include "vulkan/system/vk_objects.h"
class VulkanFrameBuffer;
class VkDescriptorSetManager
{
public:
VkDescriptorSetManager();
VkDescriptorSetManager(VulkanFrameBuffer* fb);
~VkDescriptorSetManager();
void Init();
@ -32,6 +34,8 @@ private:
void CreateFixedSet();
void CreateNullTexture();
VulkanFrameBuffer* fb = nullptr;
std::unique_ptr<VulkanDescriptorSetLayout> DynamicSetLayout;
std::unique_ptr<VulkanDescriptorSetLayout> FixedSetLayout;
std::vector<std::unique_ptr<VulkanDescriptorSetLayout>> TextureSetLayouts;

View File

@ -42,7 +42,7 @@
EXTERN_CVAR(Int, gl_dither_bpc)
VkPostprocess::VkPostprocess()
VkPostprocess::VkPostprocess(VulkanFrameBuffer* fb) : fb(fb)
{
}
@ -52,7 +52,6 @@ VkPostprocess::~VkPostprocess()
void VkPostprocess::SetActiveRenderTarget()
{
auto fb = GetVulkanFrameBuffer();
auto buffers = fb->GetBuffers();
VkImageTransition imageTransition;
@ -64,11 +63,10 @@ void VkPostprocess::SetActiveRenderTarget()
void VkPostprocess::PostProcessScene(int fixedcm, float flash, const std::function<void()> &afterBloomDrawEndScene2D)
{
auto fb = GetVulkanFrameBuffer();
int sceneWidth = fb->GetBuffers()->GetSceneWidth();
int sceneHeight = fb->GetBuffers()->GetSceneHeight();
VkPPRenderState renderstate;
VkPPRenderState renderstate(fb);
hw_postprocess.Pass1(&renderstate, fixedcm, sceneWidth, sceneHeight);
SetActiveRenderTarget();
@ -78,8 +76,6 @@ void VkPostprocess::PostProcessScene(int fixedcm, float flash, const std::functi
void VkPostprocess::BlitSceneToPostprocess()
{
auto fb = GetVulkanFrameBuffer();
fb->GetRenderState()->EndRenderPass();
auto buffers = fb->GetBuffers();
@ -137,7 +133,6 @@ void VkPostprocess::BlitSceneToPostprocess()
void VkPostprocess::ImageTransitionScene(bool undefinedSrcLayout)
{
auto fb = GetVulkanFrameBuffer();
auto buffers = fb->GetBuffers();
VkImageTransition imageTransition;
@ -150,8 +145,6 @@ void VkPostprocess::ImageTransitionScene(bool undefinedSrcLayout)
void VkPostprocess::BlitCurrentToImage(VkTextureImage *dstimage, VkImageLayout finallayout)
{
auto fb = GetVulkanFrameBuffer();
fb->GetRenderState()->EndRenderPass();
auto srcimage = &fb->GetBuffers()->PipelineImage[mCurrentPipelineImage];
@ -187,9 +180,7 @@ void VkPostprocess::BlitCurrentToImage(VkTextureImage *dstimage, VkImageLayout f
void VkPostprocess::DrawPresentTexture(const IntRect &box, bool applyGamma, bool screenshot)
{
auto fb = GetVulkanFrameBuffer();
VkPPRenderState renderstate;
VkPPRenderState renderstate(fb);
if (!screenshot) // Already applied as we are actually copying the last frame here (GetScreenshotBuffer is called after swap)
hw_postprocess.customShaders.Run(&renderstate, "screen");
@ -248,11 +239,10 @@ void VkPostprocess::DrawPresentTexture(const IntRect &box, bool applyGamma, bool
void VkPostprocess::AmbientOccludeScene(float m5)
{
auto fb = GetVulkanFrameBuffer();
int sceneWidth = fb->GetBuffers()->GetSceneWidth();
int sceneHeight = fb->GetBuffers()->GetSceneHeight();
VkPPRenderState renderstate;
VkPPRenderState renderstate(fb);
hw_postprocess.ssao.Render(&renderstate, m5, sceneWidth, sceneHeight);
ImageTransitionScene(false);
@ -260,11 +250,10 @@ void VkPostprocess::AmbientOccludeScene(float m5)
void VkPostprocess::BlurScene(float gameinfobluramount)
{
auto fb = GetVulkanFrameBuffer();
int sceneWidth = fb->GetBuffers()->GetSceneWidth();
int sceneHeight = fb->GetBuffers()->GetSceneHeight();
VkPPRenderState renderstate;
VkPPRenderState renderstate(fb);
auto vrmode = VRMode::GetVRMode(true);
int eyeCount = vrmode->mEyeCount;
@ -284,10 +273,9 @@ void VkPostprocess::UpdateShadowMap()
{
if (screen->mShadowMap.PerformUpdate())
{
VkPPRenderState renderstate;
VkPPRenderState renderstate(fb);
hw_postprocess.shadowmap.Update(&renderstate);
auto fb = GetVulkanFrameBuffer();
auto buffers = fb->GetBuffers();
VkImageTransition imageTransition;
@ -306,14 +294,14 @@ std::unique_ptr<VulkanDescriptorSet> VkPostprocess::AllocateDescriptorSet(Vulkan
if (descriptors)
return descriptors;
GetVulkanFrameBuffer()->GetCommands()->FrameDeleteList.DescriptorPools.push_back(std::move(mDescriptorPool));
fb->GetCommands()->FrameDeleteList.DescriptorPools.push_back(std::move(mDescriptorPool));
}
DescriptorPoolBuilder builder;
builder.addPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 200);
builder.addPoolSize(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 4);
builder.setMaxSets(100);
mDescriptorPool = builder.create(GetVulkanFrameBuffer()->device);
mDescriptorPool = builder.create(fb->device);
mDescriptorPool->SetDebugName("VkPostprocess.mDescriptorPool");
return mDescriptorPool->allocate(layout);

View File

@ -15,11 +15,12 @@ class FString;
class VkPPShader;
class VkPPTexture;
class PipelineBarrier;
class VulkanFrameBuffer;
class VkPostprocess
{
public:
VkPostprocess();
VkPostprocess(VulkanFrameBuffer* fb);
~VkPostprocess();
void SetActiveRenderTarget();
@ -42,6 +43,8 @@ private:
std::unique_ptr<VulkanDescriptorSet> AllocateDescriptorSet(VulkanDescriptorSetLayout *layout);
VulkanFrameBuffer* fb = nullptr;
std::unique_ptr<VulkanDescriptorPool> mDescriptorPool;
int mCurrentPipelineImage = 0;

View File

@ -32,19 +32,22 @@
#include "vulkan/renderer/vk_renderstate.h"
#include "flatvertices.h"
VkPPRenderState::VkPPRenderState(VulkanFrameBuffer* fb) : fb(fb)
{
}
void VkPPRenderState::PushGroup(const FString &name)
{
GetVulkanFrameBuffer()->GetCommands()->PushGroup(name);
fb->GetCommands()->PushGroup(name);
}
void VkPPRenderState::PopGroup()
{
GetVulkanFrameBuffer()->GetCommands()->PopGroup();
fb->GetCommands()->PopGroup();
}
void VkPPRenderState::Draw()
{
auto fb = GetVulkanFrameBuffer();
auto pp = fb->GetPostprocess();
fb->GetRenderState()->EndRenderPass();
@ -59,7 +62,7 @@ void VkPPRenderState::Draw()
if (Output.Type == PPTextureType::PPTexture)
key.OutputFormat = GetVkTexture(Output.Texture)->Format;
else if (Output.Type == PPTextureType::SwapChain)
key.OutputFormat = GetVulkanFrameBuffer()->GetCommands()->swapChain->swapChainFormat.format;
key.OutputFormat = fb->GetCommands()->swapChain->swapChainFormat.format;
else if (Output.Type == PPTextureType::ShadowMap)
key.OutputFormat = VK_FORMAT_R32_SFLOAT;
else
@ -93,7 +96,6 @@ void VkPPRenderState::Draw()
void VkPPRenderState::RenderScreenQuad(VkPPRenderPassSetup *passSetup, VulkanDescriptorSet *descriptorSet, VulkanFramebuffer *framebuffer, int framebufferWidth, int framebufferHeight, int x, int y, int width, int height, const void *pushConstants, uint32_t pushConstantsSize, bool stencilTest)
{
auto fb = GetVulkanFrameBuffer();
auto cmdbuffer = fb->GetCommands()->GetDrawCommands();
VkViewport viewport = { };
@ -135,7 +137,6 @@ void VkPPRenderState::RenderScreenQuad(VkPPRenderPassSetup *passSetup, VulkanDes
VulkanDescriptorSet *VkPPRenderState::GetInput(VkPPRenderPassSetup *passSetup, const TArray<PPTextureInput> &textures, bool bindShadowMapBuffers)
{
auto fb = GetVulkanFrameBuffer();
auto descriptors = fb->GetPostprocess()->AllocateDescriptorSet(passSetup->DescriptorLayout.get());
descriptors->SetDebugName("VkPostprocess.descriptors");
@ -169,8 +170,6 @@ VulkanDescriptorSet *VkPPRenderState::GetInput(VkPPRenderPassSetup *passSetup, c
VulkanFramebuffer *VkPPRenderState::GetOutput(VkPPRenderPassSetup *passSetup, const PPOutput &output, bool stencilTest, int &framebufferWidth, int &framebufferHeight)
{
auto fb = GetVulkanFrameBuffer();
VkTextureImage *tex = GetTexture(output.Type, output.Texture);
VkImageView view;
@ -206,7 +205,7 @@ VulkanFramebuffer *VkPPRenderState::GetOutput(VkPPRenderPassSetup *passSetup, co
builder.addAttachment(view);
if (stencilTest)
builder.addAttachment(fb->GetBuffers()->SceneDepthStencil.View.get());
framebuffer = builder.create(GetVulkanFrameBuffer()->device);
framebuffer = builder.create(fb->device);
}
framebufferWidth = w;
@ -216,8 +215,6 @@ VulkanFramebuffer *VkPPRenderState::GetOutput(VkPPRenderPassSetup *passSetup, co
VkTextureImage *VkPPRenderState::GetTexture(const PPTextureType &type, PPTexture *pptexture)
{
auto fb = GetVulkanFrameBuffer();
if (type == PPTextureType::CurrentPipelineTexture || type == PPTextureType::NextPipelineTexture)
{
int idx = fb->GetPostprocess()->mCurrentPipelineImage;
@ -265,13 +262,13 @@ VkTextureImage *VkPPRenderState::GetTexture(const PPTextureType &type, PPTexture
VkPPShader *VkPPRenderState::GetVkShader(PPShader *shader)
{
if (!shader->Backend)
shader->Backend = std::make_unique<VkPPShader>(shader);
shader->Backend = std::make_unique<VkPPShader>(fb, shader);
return static_cast<VkPPShader*>(shader->Backend.get());
}
VkPPTexture *VkPPRenderState::GetVkTexture(PPTexture *texture)
{
if (!texture->Backend)
texture->Backend = std::make_unique<VkPPTexture>(texture);
texture->Backend = std::make_unique<VkPPTexture>(fb, texture);
return static_cast<VkPPTexture*>(texture->Backend.get());
}

View File

@ -8,10 +8,13 @@ class VkPPRenderPassSetup;
class VkPPShader;
class VkPPTexture;
class VkTextureImage;
class VulkanFrameBuffer;
class VkPPRenderState : public PPRenderState
{
public:
VkPPRenderState(VulkanFrameBuffer* fb);
void PushGroup(const FString &name) override;
void PopGroup() override;
@ -27,4 +30,6 @@ private:
VkPPTexture *GetVkTexture(PPTexture *texture);
VkTextureImage *GetTexture(const PPTextureType &type, PPTexture *tex);
VulkanFrameBuffer* fb = nullptr;
};

View File

@ -26,6 +26,10 @@
#include "vulkan/system/vk_commandbuffer.h"
#include "doom_levelmesh.h"
VkRaytrace::VkRaytrace(VulkanFrameBuffer* fb) : fb(fb)
{
}
void VkRaytrace::SetLevelMesh(hwrenderer::LevelMesh* mesh)
{
if (mesh != Mesh)
@ -34,7 +38,7 @@ void VkRaytrace::SetLevelMesh(hwrenderer::LevelMesh* mesh)
Mesh = mesh;
if (Mesh)
{
if (GetVulkanFrameBuffer()->device->SupportsDeviceExtension(VK_KHR_RAY_QUERY_EXTENSION_NAME))
if (fb->device->SupportsDeviceExtension(VK_KHR_RAY_QUERY_EXTENSION_NAME))
{
CreateVulkanObjects();
}
@ -77,24 +81,20 @@ VulkanAccelerationStructure* VkRaytrace::GetAccelStruct()
void VkRaytrace::Reset()
{
auto fb = GetVulkanFrameBuffer();
if (fb)
{
auto& deletelist = fb->GetCommands()->FrameDeleteList;
deletelist.Buffers.push_back(std::move(vertexBuffer));
deletelist.Buffers.push_back(std::move(indexBuffer));
deletelist.Buffers.push_back(std::move(transferBuffer));
auto& deletelist = fb->GetCommands()->FrameDeleteList;
deletelist.Buffers.push_back(std::move(vertexBuffer));
deletelist.Buffers.push_back(std::move(indexBuffer));
deletelist.Buffers.push_back(std::move(transferBuffer));
deletelist.Buffers.push_back(std::move(blScratchBuffer));
deletelist.Buffers.push_back(std::move(blAccelStructBuffer));
deletelist.AccelStructs.push_back(std::move(blAccelStruct));
deletelist.Buffers.push_back(std::move(blScratchBuffer));
deletelist.Buffers.push_back(std::move(blAccelStructBuffer));
deletelist.AccelStructs.push_back(std::move(blAccelStruct));
deletelist.Buffers.push_back(std::move(tlTransferBuffer));
deletelist.Buffers.push_back(std::move(tlScratchBuffer));
deletelist.Buffers.push_back(std::move(tlInstanceBuffer));
deletelist.Buffers.push_back(std::move(tlAccelStructBuffer));
deletelist.AccelStructs.push_back(std::move(tlAccelStruct));
}
deletelist.Buffers.push_back(std::move(tlTransferBuffer));
deletelist.Buffers.push_back(std::move(tlScratchBuffer));
deletelist.Buffers.push_back(std::move(tlInstanceBuffer));
deletelist.Buffers.push_back(std::move(tlAccelStructBuffer));
deletelist.AccelStructs.push_back(std::move(tlAccelStruct));
}
void VkRaytrace::CreateVulkanObjects()
@ -117,7 +117,7 @@ void VkRaytrace::CreateVertexAndIndexBuffers()
BufferBuilder tbuilder;
tbuilder.setUsage(VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VMA_MEMORY_USAGE_CPU_ONLY);
tbuilder.setSize(transferbuffersize);
transferBuffer = tbuilder.create(GetVulkanFrameBuffer()->device);
transferBuffer = tbuilder.create(fb->device);
transferBuffer->SetDebugName("transferBuffer");
uint8_t* data = (uint8_t*)transferBuffer->Map(0, transferbuffersize);
memcpy(data + vertexoffset, Mesh->MeshVertices.Data(), vertexbuffersize);
@ -127,34 +127,34 @@ void VkRaytrace::CreateVertexAndIndexBuffers()
BufferBuilder vbuilder;
vbuilder.setUsage(VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
vbuilder.setSize(vertexbuffersize);
vertexBuffer = vbuilder.create(GetVulkanFrameBuffer()->device);
vertexBuffer = vbuilder.create(fb->device);
vertexBuffer->SetDebugName("vertexBuffer");
BufferBuilder ibuilder;
ibuilder.setUsage(VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
ibuilder.setSize(indexbuffersize);
indexBuffer = ibuilder.create(GetVulkanFrameBuffer()->device);
indexBuffer = ibuilder.create(fb->device);
indexBuffer->SetDebugName("indexBuffer");
GetVulkanFrameBuffer()->GetCommands()->GetTransferCommands()->copyBuffer(transferBuffer.get(), vertexBuffer.get(), vertexoffset);
GetVulkanFrameBuffer()->GetCommands()->GetTransferCommands()->copyBuffer(transferBuffer.get(), indexBuffer.get(), indexoffset);
fb->GetCommands()->GetTransferCommands()->copyBuffer(transferBuffer.get(), vertexBuffer.get(), vertexoffset);
fb->GetCommands()->GetTransferCommands()->copyBuffer(transferBuffer.get(), indexBuffer.get(), indexoffset);
// Finish transfer before using it for building
VkMemoryBarrier barrier = { VK_STRUCTURE_TYPE_MEMORY_BARRIER };
barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
GetVulkanFrameBuffer()->GetCommands()->GetTransferCommands()->pipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, 0, 1, &barrier, 0, nullptr, 0, nullptr);
fb->GetCommands()->GetTransferCommands()->pipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, 0, 1, &barrier, 0, nullptr, 0, nullptr);
}
void VkRaytrace::CreateBottomLevelAccelerationStructure()
{
VkBufferDeviceAddressInfo info = { VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO };
info.buffer = vertexBuffer->buffer;
VkDeviceAddress vertexAddress = vkGetBufferDeviceAddress(GetVulkanFrameBuffer()->device->device, &info);
VkDeviceAddress vertexAddress = vkGetBufferDeviceAddress(fb->device->device, &info);
info = { VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO };
info.buffer = indexBuffer->buffer;
VkDeviceAddress indexAddress = vkGetBufferDeviceAddress(GetVulkanFrameBuffer()->device->device, &info);
VkDeviceAddress indexAddress = vkGetBufferDeviceAddress(fb->device->device, &info);
VkAccelerationStructureGeometryTrianglesDataKHR triangles = { VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_TRIANGLES_DATA_KHR };
triangles.vertexFormat = VK_FORMAT_R32G32B32_SFLOAT;
@ -182,12 +182,12 @@ void VkRaytrace::CreateBottomLevelAccelerationStructure()
uint32_t maxPrimitiveCount = rangeInfo.primitiveCount;
VkAccelerationStructureBuildSizesInfoKHR sizeInfo = { VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_SIZES_INFO_KHR };
vkGetAccelerationStructureBuildSizesKHR(GetVulkanFrameBuffer()->device->device, VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR, &buildInfo, &maxPrimitiveCount, &sizeInfo);
vkGetAccelerationStructureBuildSizesKHR(fb->device->device, VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR, &buildInfo, &maxPrimitiveCount, &sizeInfo);
BufferBuilder blbufbuilder;
blbufbuilder.setUsage(VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_STORAGE_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT);
blbufbuilder.setSize(sizeInfo.accelerationStructureSize);
blAccelStructBuffer = blbufbuilder.create(GetVulkanFrameBuffer()->device);
blAccelStructBuffer = blbufbuilder.create(fb->device);
blAccelStructBuffer->SetDebugName("blAccelStructBuffer");
VkAccelerationStructureKHR blAccelStructHandle = {};
@ -195,39 +195,39 @@ void VkRaytrace::CreateBottomLevelAccelerationStructure()
createInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR;
createInfo.buffer = blAccelStructBuffer->buffer;
createInfo.size = sizeInfo.accelerationStructureSize;
VkResult result = vkCreateAccelerationStructureKHR(GetVulkanFrameBuffer()->device->device, &createInfo, nullptr, &blAccelStructHandle);
VkResult result = vkCreateAccelerationStructureKHR(fb->device->device, &createInfo, nullptr, &blAccelStructHandle);
if (result != VK_SUCCESS)
throw std::runtime_error("vkCreateAccelerationStructureKHR failed");
blAccelStruct = std::make_unique<VulkanAccelerationStructure>(GetVulkanFrameBuffer()->device, blAccelStructHandle);
blAccelStruct = std::make_unique<VulkanAccelerationStructure>(fb->device, blAccelStructHandle);
blAccelStruct->SetDebugName("blAccelStruct");
BufferBuilder sbuilder;
sbuilder.setUsage(VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
sbuilder.setSize(sizeInfo.buildScratchSize);
blScratchBuffer = sbuilder.create(GetVulkanFrameBuffer()->device);
blScratchBuffer = sbuilder.create(fb->device);
blScratchBuffer->SetDebugName("blScratchBuffer");
info = { VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO };
info.buffer = blScratchBuffer->buffer;
VkDeviceAddress scratchAddress = vkGetBufferDeviceAddress(GetVulkanFrameBuffer()->device->device, &info);
VkDeviceAddress scratchAddress = vkGetBufferDeviceAddress(fb->device->device, &info);
buildInfo.dstAccelerationStructure = blAccelStruct->accelstruct;
buildInfo.scratchData.deviceAddress = scratchAddress;
VkAccelerationStructureBuildRangeInfoKHR* rangeInfos[] = { &rangeInfo };
GetVulkanFrameBuffer()->GetCommands()->GetTransferCommands()->buildAccelerationStructures(1, &buildInfo, rangeInfos);
fb->GetCommands()->GetTransferCommands()->buildAccelerationStructures(1, &buildInfo, rangeInfos);
// Finish building before using it as input to a toplevel accel structure
VkMemoryBarrier barrier = { VK_STRUCTURE_TYPE_MEMORY_BARRIER };
barrier.srcAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR;
barrier.dstAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR;
GetVulkanFrameBuffer()->GetCommands()->GetTransferCommands()->pipelineBarrier(VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, 0, 1, &barrier, 0, nullptr, 0, nullptr);
fb->GetCommands()->GetTransferCommands()->pipelineBarrier(VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, 0, 1, &barrier, 0, nullptr, 0, nullptr);
}
void VkRaytrace::CreateTopLevelAccelerationStructure()
{
VkAccelerationStructureDeviceAddressInfoKHR addressInfo = { VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_DEVICE_ADDRESS_INFO_KHR };
addressInfo.accelerationStructure = blAccelStruct->accelstruct;
VkDeviceAddress blAccelStructAddress = vkGetAccelerationStructureDeviceAddressKHR(GetVulkanFrameBuffer()->device->device, &addressInfo);
VkDeviceAddress blAccelStructAddress = vkGetAccelerationStructureDeviceAddressKHR(fb->device->device, &addressInfo);
VkAccelerationStructureInstanceKHR instance = {};
instance.transform.matrix[0][0] = 1.0f;
@ -242,7 +242,7 @@ void VkRaytrace::CreateTopLevelAccelerationStructure()
BufferBuilder tbuilder;
tbuilder.setUsage(VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VMA_MEMORY_USAGE_CPU_ONLY);
tbuilder.setSize(sizeof(VkAccelerationStructureInstanceKHR));
tlTransferBuffer = tbuilder.create(GetVulkanFrameBuffer()->device);
tlTransferBuffer = tbuilder.create(fb->device);
tlTransferBuffer->SetDebugName("tlTransferBuffer");
auto data = (uint8_t*)tlTransferBuffer->Map(0, sizeof(VkAccelerationStructureInstanceKHR));
memcpy(data, &instance, sizeof(VkAccelerationStructureInstanceKHR));
@ -251,20 +251,20 @@ void VkRaytrace::CreateTopLevelAccelerationStructure()
BufferBuilder instbufbuilder;
instbufbuilder.setUsage(VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
instbufbuilder.setSize(sizeof(VkAccelerationStructureInstanceKHR));
tlInstanceBuffer = instbufbuilder.create(GetVulkanFrameBuffer()->device);
tlInstanceBuffer = instbufbuilder.create(fb->device);
tlInstanceBuffer->SetDebugName("tlInstanceBuffer");
GetVulkanFrameBuffer()->GetCommands()->GetTransferCommands()->copyBuffer(tlTransferBuffer.get(), tlInstanceBuffer.get());
fb->GetCommands()->GetTransferCommands()->copyBuffer(tlTransferBuffer.get(), tlInstanceBuffer.get());
// Finish transfering before using it as input
VkMemoryBarrier barrier = { VK_STRUCTURE_TYPE_MEMORY_BARRIER };
barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
barrier.dstAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR;
GetVulkanFrameBuffer()->GetCommands()->GetTransferCommands()->pipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, 0, 1, &barrier, 0, nullptr, 0, nullptr);
fb->GetCommands()->GetTransferCommands()->pipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, 0, 1, &barrier, 0, nullptr, 0, nullptr);
VkBufferDeviceAddressInfo info = { VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO };
info.buffer = tlInstanceBuffer->buffer;
VkDeviceAddress instanceBufferAddress = vkGetBufferDeviceAddress(GetVulkanFrameBuffer()->device->device, &info);
VkDeviceAddress instanceBufferAddress = vkGetBufferDeviceAddress(fb->device->device, &info);
VkAccelerationStructureGeometryInstancesDataKHR instances = { VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_INSTANCES_DATA_KHR };
instances.data.deviceAddress = instanceBufferAddress;
@ -287,12 +287,12 @@ void VkRaytrace::CreateTopLevelAccelerationStructure()
uint32_t maxInstanceCount = 1;
VkAccelerationStructureBuildSizesInfoKHR sizeInfo = { VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_SIZES_INFO_KHR };
vkGetAccelerationStructureBuildSizesKHR(GetVulkanFrameBuffer()->device->device, VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR, &buildInfo, &maxInstanceCount, &sizeInfo);
vkGetAccelerationStructureBuildSizesKHR(fb->device->device, VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR, &buildInfo, &maxInstanceCount, &sizeInfo);
BufferBuilder tlbufbuilder;
tlbufbuilder.setUsage(VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_STORAGE_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT);
tlbufbuilder.setSize(sizeInfo.accelerationStructureSize);
tlAccelStructBuffer = tlbufbuilder.create(GetVulkanFrameBuffer()->device);
tlAccelStructBuffer = tlbufbuilder.create(fb->device);
tlAccelStructBuffer->SetDebugName("tlAccelStructBuffer");
VkAccelerationStructureKHR tlAccelStructHandle = {};
@ -300,29 +300,29 @@ void VkRaytrace::CreateTopLevelAccelerationStructure()
createInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR;
createInfo.buffer = tlAccelStructBuffer->buffer;
createInfo.size = sizeInfo.accelerationStructureSize;
VkResult result = vkCreateAccelerationStructureKHR(GetVulkanFrameBuffer()->device->device, &createInfo, nullptr, &tlAccelStructHandle);
VkResult result = vkCreateAccelerationStructureKHR(fb->device->device, &createInfo, nullptr, &tlAccelStructHandle);
if (result != VK_SUCCESS)
throw std::runtime_error("vkCreateAccelerationStructureKHR failed");
tlAccelStruct = std::make_unique<VulkanAccelerationStructure>(GetVulkanFrameBuffer()->device, tlAccelStructHandle);
tlAccelStruct = std::make_unique<VulkanAccelerationStructure>(fb->device, tlAccelStructHandle);
BufferBuilder sbuilder;
sbuilder.setUsage(VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
sbuilder.setSize(sizeInfo.buildScratchSize);
tlScratchBuffer = sbuilder.create(GetVulkanFrameBuffer()->device);
tlScratchBuffer = sbuilder.create(fb->device);
tlScratchBuffer->SetDebugName("tlScratchBuffer");
info = { VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO };
info.buffer = tlScratchBuffer->buffer;
VkDeviceAddress scratchAddress = vkGetBufferDeviceAddress(GetVulkanFrameBuffer()->device->device, &info);
VkDeviceAddress scratchAddress = vkGetBufferDeviceAddress(fb->device->device, &info);
buildInfo.dstAccelerationStructure = tlAccelStruct->accelstruct;
buildInfo.scratchData.deviceAddress = scratchAddress;
VkAccelerationStructureBuildRangeInfoKHR* rangeInfos[] = { &rangeInfo };
GetVulkanFrameBuffer()->GetCommands()->GetTransferCommands()->buildAccelerationStructures(1, &buildInfo, rangeInfos);
fb->GetCommands()->GetTransferCommands()->buildAccelerationStructures(1, &buildInfo, rangeInfos);
// Finish building the accel struct before using as input in a fragment shader
PipelineBarrier finishbuildbarrier;
finishbuildbarrier.addMemory(VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR, VK_ACCESS_SHADER_READ_BIT);
finishbuildbarrier.execute(GetVulkanFrameBuffer()->GetCommands()->GetTransferCommands(), VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
finishbuildbarrier.execute(fb->GetCommands()->GetTransferCommands(), VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
}

View File

@ -4,9 +4,13 @@
#include "vulkan/system/vk_objects.h"
#include "hw_levelmesh.h"
class VulkanFrameBuffer;
class VkRaytrace
{
public:
VkRaytrace(VulkanFrameBuffer* fb);
void SetLevelMesh(hwrenderer::LevelMesh* mesh);
VulkanAccelerationStructure* GetAccelStruct();
@ -18,6 +22,8 @@ private:
void CreateBottomLevelAccelerationStructure();
void CreateTopLevelAccelerationStructure();
VulkanFrameBuffer* fb = nullptr;
hwrenderer::LevelMesh* Mesh = nullptr;
std::unique_ptr<VulkanBuffer> vertexBuffer;

View File

@ -35,7 +35,7 @@
#include "hw_viewpointuniforms.h"
#include "v_2ddrawer.h"
VkRenderPassManager::VkRenderPassManager()
VkRenderPassManager::VkRenderPassManager(VulkanFrameBuffer* fb) : fb(fb)
{
}
@ -53,7 +53,7 @@ VkRenderPassSetup *VkRenderPassManager::GetRenderPass(const VkRenderPassKey &key
{
auto &item = RenderPassSetup[key];
if (!item)
item.reset(new VkRenderPassSetup(key));
item.reset(new VkRenderPassSetup(fb, key));
return item.get();
}
@ -109,7 +109,7 @@ VulkanPipelineLayout* VkRenderPassManager::GetPipelineLayout(int numLayers)
if (layout)
return layout.get();
auto descriptors = GetVulkanFrameBuffer()->GetDescriptorSetManager();
auto descriptors = fb->GetDescriptorSetManager();
PipelineLayoutBuilder builder;
builder.addSetLayout(descriptors->GetFixedSetLayout());
@ -117,7 +117,7 @@ VulkanPipelineLayout* VkRenderPassManager::GetPipelineLayout(int numLayers)
if (numLayers != 0)
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 = builder.create(fb->device);
layout->SetDebugName("VkRenderPassManager.PipelineLayout");
return layout.get();
}
@ -126,19 +126,19 @@ VkPPRenderPassSetup* VkRenderPassManager::GetPPRenderPass(const VkPPRenderPassKe
{
auto& passSetup = PPRenderPassSetup[key];
if (!passSetup)
passSetup.reset(new VkPPRenderPassSetup(key));
passSetup.reset(new VkPPRenderPassSetup(fb, key));
return passSetup.get();
}
/////////////////////////////////////////////////////////////////////////////
VkRenderPassSetup::VkRenderPassSetup(const VkRenderPassKey &key) : PassKey(key)
VkRenderPassSetup::VkRenderPassSetup(VulkanFrameBuffer* fb, const VkRenderPassKey &key) : PassKey(key), fb(fb)
{
}
std::unique_ptr<VulkanRenderPass> VkRenderPassSetup::CreateRenderPass(int clearTargets)
{
auto buffers = GetVulkanFrameBuffer()->GetBuffers();
auto buffers = fb->GetBuffers();
VkFormat drawBufferFormats[] = { VK_FORMAT_R16G16B16A16_SFLOAT, VK_FORMAT_R8G8B8A8_UNORM, buffers->SceneNormalFormat };
@ -184,7 +184,7 @@ std::unique_ptr<VulkanRenderPass> VkRenderPassSetup::CreateRenderPass(int clearT
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT);
}
auto renderpass = builder.create(GetVulkanFrameBuffer()->device);
auto renderpass = builder.create(fb->device);
renderpass->SetDebugName("VkRenderPassSetup.RenderPass");
return renderpass;
}
@ -206,7 +206,6 @@ VulkanPipeline *VkRenderPassSetup::GetPipeline(const VkPipelineKey &key)
std::unique_ptr<VulkanPipeline> VkRenderPassSetup::CreatePipeline(const VkPipelineKey &key)
{
auto fb = GetVulkanFrameBuffer();
GraphicsPipelineBuilder builder;
VkShaderProgram *program;
@ -297,7 +296,7 @@ std::unique_ptr<VulkanPipeline> VkRenderPassSetup::CreatePipeline(const VkPipeli
/////////////////////////////////////////////////////////////////////////////
VkPPRenderPassSetup::VkPPRenderPassSetup(const VkPPRenderPassKey& key)
VkPPRenderPassSetup::VkPPRenderPassSetup(VulkanFrameBuffer* fb, const VkPPRenderPassKey& key) : fb(fb)
{
CreateDescriptorLayout(key);
CreatePipelineLayout(key);
@ -316,7 +315,7 @@ void VkPPRenderPassSetup::CreateDescriptorLayout(const VkPPRenderPassKey& key)
builder.addBinding(LIGHTLINES_BINDINGPOINT, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
builder.addBinding(LIGHTLIST_BINDINGPOINT, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
}
DescriptorLayout = builder.create(GetVulkanFrameBuffer()->device);
DescriptorLayout = builder.create(fb->device);
DescriptorLayout->SetDebugName("VkPPRenderPassSetup.DescriptorLayout");
}
@ -326,7 +325,7 @@ void VkPPRenderPassSetup::CreatePipelineLayout(const VkPPRenderPassKey& key)
builder.addSetLayout(DescriptorLayout.get());
if (key.Uniforms > 0)
builder.addPushConstantRange(VK_SHADER_STAGE_FRAGMENT_BIT, 0, key.Uniforms);
PipelineLayout = builder.create(GetVulkanFrameBuffer()->device);
PipelineLayout = builder.create(fb->device);
PipelineLayout->SetDebugName("VkPPRenderPassSetup.PipelineLayout");
}
@ -355,7 +354,7 @@ void VkPPRenderPassSetup::CreatePipeline(const VkPPRenderPassKey& key)
builder.setRasterizationSamples(key.Samples);
builder.setLayout(PipelineLayout.get());
builder.setRenderPass(RenderPass.get());
Pipeline = builder.create(GetVulkanFrameBuffer()->device);
Pipeline = builder.create(fb->device);
Pipeline->SetDebugName("VkPPRenderPassSetup.Pipeline");
}
@ -369,7 +368,7 @@ void VkPPRenderPassSetup::CreateRenderPass(const VkPPRenderPassKey& key)
if (key.StencilTest)
{
builder.addDepthStencilAttachment(
GetVulkanFrameBuffer()->GetBuffers()->SceneDepthStencilFormat, key.Samples,
fb->GetBuffers()->SceneDepthStencilFormat, key.Samples,
VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
@ -395,6 +394,6 @@ void VkPPRenderPassSetup::CreateRenderPass(const VkPPRenderPassKey& key)
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_SHADER_READ_BIT);
}
RenderPass = builder.create(GetVulkanFrameBuffer()->device);
RenderPass = builder.create(fb->device);
RenderPass->SetDebugName("VkPPRenderPassSetup.RenderPass");
}

View File

@ -9,6 +9,7 @@
#include <string.h>
#include <map>
class VulkanFrameBuffer;
class VkPPShader;
class VkPipelineKey
@ -52,7 +53,7 @@ public:
class VkRenderPassSetup
{
public:
VkRenderPassSetup(const VkRenderPassKey &key);
VkRenderPassSetup(VulkanFrameBuffer* fb, const VkRenderPassKey &key);
VulkanRenderPass *GetRenderPass(int clearTargets);
VulkanPipeline *GetPipeline(const VkPipelineKey &key);
@ -64,6 +65,8 @@ public:
private:
std::unique_ptr<VulkanRenderPass> CreateRenderPass(int clearTargets);
std::unique_ptr<VulkanPipeline> CreatePipeline(const VkPipelineKey &key);
VulkanFrameBuffer* fb = nullptr;
};
class VkVertexFormat
@ -96,7 +99,7 @@ public:
class VkPPRenderPassSetup
{
public:
VkPPRenderPassSetup(const VkPPRenderPassKey& key);
VkPPRenderPassSetup(VulkanFrameBuffer* fb, const VkPPRenderPassKey& key);
std::unique_ptr<VulkanDescriptorSetLayout> DescriptorLayout;
std::unique_ptr<VulkanPipelineLayout> PipelineLayout;
@ -108,12 +111,14 @@ private:
void CreatePipelineLayout(const VkPPRenderPassKey& key);
void CreatePipeline(const VkPPRenderPassKey& key);
void CreateRenderPass(const VkPPRenderPassKey& key);
VulkanFrameBuffer* fb = nullptr;
};
class VkRenderPassManager
{
public:
VkRenderPassManager();
VkRenderPassManager(VulkanFrameBuffer* fb);
~VkRenderPassManager();
void RenderBuffersReset();
@ -126,6 +131,8 @@ public:
VkPPRenderPassSetup* GetPPRenderPass(const VkPPRenderPassKey& key);
private:
VulkanFrameBuffer* fb = nullptr;
std::map<VkRenderPassKey, std::unique_ptr<VkRenderPassSetup>> RenderPassSetup;
std::vector<std::unique_ptr<VulkanPipelineLayout>> PipelineLayouts;
std::vector<VkVertexFormat> VertexFormats;

View File

@ -41,7 +41,7 @@
CVAR(Int, vk_submit_size, 1000, 0);
EXTERN_CVAR(Bool, r_skipmats)
VkRenderState::VkRenderState()
VkRenderState::VkRenderState(VulkanFrameBuffer* fb) : fb(fb), mStreamBufferWriter(fb), mMatrixBufferWriter(fb)
{
Reset();
}
@ -184,7 +184,7 @@ void VkRenderState::Apply(int dt)
mApplyCount++;
if (mApplyCount >= vk_submit_size)
{
GetVulkanFrameBuffer()->GetCommands()->FlushCommands(false);
fb->GetCommands()->FlushCommands(false);
mApplyCount = 0;
}
@ -253,7 +253,7 @@ void VkRenderState::ApplyRenderPass(int dt)
if (!inRenderPass)
{
mCommandBuffer = GetVulkanFrameBuffer()->GetCommands()->GetDrawCommands();
mCommandBuffer = fb->GetCommands()->GetDrawCommands();
mScissorChanged = true;
mViewportChanged = true;
mStencilRefChanged = true;
@ -270,7 +270,7 @@ void VkRenderState::ApplyRenderPass(int dt)
if (!inRenderPass)
{
mCommandBuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, GetVulkanFrameBuffer()->GetRenderPassManager()->GetPipelineLayout(mPipelineKey.NumTextureLayers), 0, GetVulkanFrameBuffer()->GetDescriptorSetManager()->GetFixedDescriptorSet());
mCommandBuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, fb->GetRenderPassManager()->GetPipelineLayout(mPipelineKey.NumTextureLayers), 0, fb->GetDescriptorSetManager()->GetFixedDescriptorSet());
}
}
@ -340,7 +340,6 @@ void VkRenderState::ApplyViewport()
void VkRenderState::ApplyStreamData()
{
auto fb = GetVulkanFrameBuffer();
auto passManager = fb->GetRenderPassManager();
mStreamData.useVertexData = passManager->GetVertexFormat(static_cast<VKVertexBuffer*>(mVertexBuffer)->VertexFormat)->UseVertexData;
@ -398,7 +397,6 @@ void VkRenderState::ApplyPushConstants()
mPushConstants.uLightIndex = mLightIndex;
mPushConstants.uDataIndex = mStreamBufferWriter.DataIndex();
auto fb = GetVulkanFrameBuffer();
auto passManager = fb->GetRenderPassManager();
mCommandBuffer->pushConstants(passManager->GetPipelineLayout(mPipelineKey.NumTextureLayers), VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, (uint32_t)sizeof(PushConstants), &mPushConstants);
}
@ -417,7 +415,7 @@ void VkRenderState::ApplyVertexBuffers()
if ((mVertexBuffer != mLastVertexBuffer || mVertexOffsets[0] != mLastVertexOffsets[0] || mVertexOffsets[1] != mLastVertexOffsets[1]) && mVertexBuffer)
{
auto vkbuf = static_cast<VKVertexBuffer*>(mVertexBuffer);
const VkVertexFormat *format = GetVulkanFrameBuffer()->GetRenderPassManager()->GetVertexFormat(vkbuf->VertexFormat);
const VkVertexFormat *format = fb->GetRenderPassManager()->GetVertexFormat(vkbuf->VertexFormat);
VkBuffer vertexBuffers[2] = { vkbuf->mBuffer->buffer, vkbuf->mBuffer->buffer };
VkDeviceSize offsets[] = { mVertexOffsets[0] * format->Stride, mVertexOffsets[1] * format->Stride };
mCommandBuffer->bindVertexBuffers(0, 2, vertexBuffers, offsets);
@ -437,7 +435,6 @@ void VkRenderState::ApplyMaterial()
{
if (mMaterial.mChanged)
{
auto fb = GetVulkanFrameBuffer();
auto passManager = fb->GetRenderPassManager();
auto descriptors = fb->GetDescriptorSetManager();
@ -452,7 +449,6 @@ void VkRenderState::ApplyMaterial()
void VkRenderState::ApplyDynamicSet()
{
auto fb = GetVulkanFrameBuffer();
uint32_t matrixOffset = mMatrixBufferWriter.Offset();
uint32_t streamDataOffset = mStreamBufferWriter.StreamDataOffset();
if (mViewpointOffset != mLastViewpointOffset || matrixOffset != mLastMatricesOffset || streamDataOffset != mLastStreamDataOffset)
@ -471,7 +467,7 @@ void VkRenderState::ApplyDynamicSet()
void VkRenderState::WaitForStreamBuffers()
{
GetVulkanFrameBuffer()->WaitForCommands(false);
fb->WaitForCommands(false);
mApplyCount = 0;
mStreamBufferWriter.Reset();
mMatrixBufferWriter.Reset();
@ -537,8 +533,6 @@ void VkRenderState::SetRenderTarget(VkTextureImage *image, VulkanImageView *dept
void VkRenderState::BeginRenderPass(VulkanCommandBuffer *cmdbuffer)
{
auto fb = GetVulkanFrameBuffer();
VkRenderPassKey key = {};
key.DrawBufferFormat = mRenderTarget.Format;
key.Samples = mRenderTarget.Samples;
@ -561,7 +555,7 @@ void VkRenderState::BeginRenderPass(VulkanCommandBuffer *cmdbuffer)
builder.addAttachment(buffers->SceneNormal.View.get());
if (key.DepthStencil)
builder.addAttachment(mRenderTarget.DepthStencil);
framebuffer = builder.create(GetVulkanFrameBuffer()->device);
framebuffer = builder.create(fb->device);
framebuffer->SetDebugName("VkRenderPassSetup.Framebuffer");
}
@ -592,7 +586,7 @@ void VkRenderStateMolten::Draw(int dt, int index, int count, bool apply)
if (dt == DT_TriangleFan)
{
IIndexBuffer *oldIndexBuffer = mIndexBuffer;
mIndexBuffer = GetVulkanFrameBuffer()->FanToTrisIndexBuffer.get();
mIndexBuffer = fb->FanToTrisIndexBuffer.get();
if (apply || mNeedApply)
Apply(DT_Triangles);

View File

@ -11,13 +11,14 @@
#include "hw_renderstate.h"
#include "hw_material.h"
class VulkanFrameBuffer;
class VkRenderPassSetup;
class VkTextureImage;
class VkRenderState : public FRenderState
{
public:
VkRenderState();
VkRenderState(VulkanFrameBuffer* fb);
virtual ~VkRenderState() = default;
// Draw commands
@ -66,6 +67,8 @@ protected:
void BeginRenderPass(VulkanCommandBuffer *cmdbuffer);
void WaitForStreamBuffers();
VulkanFrameBuffer* fb = nullptr;
bool mDepthClamp = true;
VulkanCommandBuffer *mCommandBuffer = nullptr;
VkPipelineKey mPipelineKey = {};

View File

@ -25,11 +25,11 @@
#include "vulkan/system/vk_builders.h"
#include "vulkan/renderer/vk_streambuffer.h"
VkStreamBuffer::VkStreamBuffer(size_t structSize, size_t count)
VkStreamBuffer::VkStreamBuffer(VulkanFrameBuffer* fb, size_t structSize, size_t count)
{
mBlockSize = static_cast<uint32_t>((structSize + screen->uniformblockalignment - 1) / screen->uniformblockalignment * screen->uniformblockalignment);
UniformBuffer = (VKDataBuffer*)GetVulkanFrameBuffer()->CreateDataBuffer(-1, false, false);
UniformBuffer = (VKDataBuffer*)fb->CreateDataBuffer(-1, false, false);
UniformBuffer->SetData(mBlockSize * count, nullptr, BufferUsageType::Persistent);
}
@ -51,9 +51,9 @@ uint32_t VkStreamBuffer::NextStreamDataBlock()
/////////////////////////////////////////////////////////////////////////////
VkStreamBufferWriter::VkStreamBufferWriter()
VkStreamBufferWriter::VkStreamBufferWriter(VulkanFrameBuffer* fb)
{
mBuffer = GetVulkanFrameBuffer()->StreamBuffer;
mBuffer = fb->StreamBuffer;
}
bool VkStreamBufferWriter::Write(const StreamData& data)
@ -80,9 +80,9 @@ void VkStreamBufferWriter::Reset()
/////////////////////////////////////////////////////////////////////////////
VkMatrixBufferWriter::VkMatrixBufferWriter()
VkMatrixBufferWriter::VkMatrixBufferWriter(VulkanFrameBuffer* fb)
{
mBuffer = GetVulkanFrameBuffer()->MatrixBuffer;
mBuffer = fb->MatrixBuffer;
mIdentityMatrix.loadIdentity();
}

View File

@ -10,7 +10,7 @@ class VkMatrixBuffer;
class VkStreamBufferWriter
{
public:
VkStreamBufferWriter();
VkStreamBufferWriter(VulkanFrameBuffer* fb);
bool Write(const StreamData& data);
void Reset();
@ -27,7 +27,7 @@ private:
class VkMatrixBufferWriter
{
public:
VkMatrixBufferWriter();
VkMatrixBufferWriter(VulkanFrameBuffer* fb);
bool Write(const VSMatrix& modelMatrix, bool modelMatrixEnabled, const VSMatrix& textureMatrix, bool textureMatrixEnabled);
void Reset();
@ -44,7 +44,7 @@ private:
class VkStreamBuffer
{
public:
VkStreamBuffer(size_t structSize, size_t count);
VkStreamBuffer(VulkanFrameBuffer* fb, size_t structSize, size_t count);
~VkStreamBuffer();
uint32_t NextStreamDataBlock();

View File

@ -25,10 +25,8 @@
#include "vulkan/system/vk_builders.h"
#include "filesystem.h"
VkPPShader::VkPPShader(PPShader *shader)
VkPPShader::VkPPShader(VulkanFrameBuffer* fb, PPShader *shader)
{
auto fb = GetVulkanFrameBuffer();
FString prolog;
if (!shader->Uniforms.empty())
prolog = UniformBlockDecl::Create("Uniforms", shader->Uniforms, -1);

View File

@ -4,10 +4,12 @@
#include "hwrenderer/postprocessing/hw_postprocess.h"
#include "vulkan/system/vk_objects.h"
class VulkanFrameBuffer;
class VkPPShader : public PPShaderBackend
{
public:
VkPPShader(PPShader *shader);
VkPPShader(VulkanFrameBuffer* fb, PPShader *shader);
std::unique_ptr<VulkanShader> VertexShader;
std::unique_ptr<VulkanShader> FragmentShader;

View File

@ -83,10 +83,6 @@ VulkanFrameBuffer::~VulkanFrameBuffer()
{
vkDeviceWaitIdle(device->device); // make sure the GPU is no longer using any objects before RAII tears them down
// screen is already null at this point, but VkHardwareTexture::ResetAll needs it during clean up. Is there a better way we can do this?
auto tmp = screen;
screen = this;
// All descriptors must be destroyed before the descriptor pool in renderpass manager is destroyed
VkHardwareTexture::ResetAll();
VKBuffer::ResetAll();
@ -100,8 +96,6 @@ VulkanFrameBuffer::~VulkanFrameBuffer()
delete mLights;
mShadowMap.Reset();
screen = tmp;
mCommands->DeleteFrameObjects();
}
@ -130,14 +124,14 @@ void VulkanFrameBuffer::InitializeState()
mCommands.reset(new VkCommandBufferManager(this));
mScreenBuffers.reset(new VkRenderBuffers());
mSaveBuffers.reset(new VkRenderBuffers());
mScreenBuffers.reset(new VkRenderBuffers(this));
mSaveBuffers.reset(new VkRenderBuffers(this));
mActiveRenderBuffers = mScreenBuffers.get();
mPostprocess.reset(new VkPostprocess());
mDescriptorSetManager.reset(new VkDescriptorSetManager());
mRenderPassManager.reset(new VkRenderPassManager());
mRaytrace.reset(new VkRaytrace());
mPostprocess.reset(new VkPostprocess(this));
mDescriptorSetManager.reset(new VkDescriptorSetManager(this));
mRenderPassManager.reset(new VkRenderPassManager(this));
mRaytrace.reset(new VkRaytrace(this));
mVertexData = new FFlatVertexBuffer(GetWidth(), GetHeight());
mSkyData = new FSkyVertexBuffer;
@ -147,16 +141,16 @@ void VulkanFrameBuffer::InitializeState()
CreateFanToTrisIndexBuffer();
// To do: move this to HW renderer interface maybe?
MatrixBuffer = new VkStreamBuffer(sizeof(MatricesUBO), 50000);
StreamBuffer = new VkStreamBuffer(sizeof(StreamUBO), 300);
MatrixBuffer = new VkStreamBuffer(this, sizeof(MatricesUBO), 50000);
StreamBuffer = new VkStreamBuffer(this, sizeof(StreamUBO), 300);
mShaderManager.reset(new VkShaderManager(device));
mSamplerManager.reset(new VkSamplerManager(this));
mDescriptorSetManager->Init();
#ifdef __APPLE__
mRenderState.reset(new VkRenderStateMolten());
mRenderState.reset(new VkRenderStateMolten(this));
#else
mRenderState.reset(new VkRenderState());
mRenderState.reset(new VkRenderState(this));
#endif
}

View File

@ -24,10 +24,8 @@
#include "vulkan/system/vk_framebuffer.h"
#include "vulkan/system/vk_commandbuffer.h"
VkPPTexture::VkPPTexture(PPTexture *texture)
VkPPTexture::VkPPTexture(VulkanFrameBuffer* fb, PPTexture *texture)
{
auto fb = GetVulkanFrameBuffer();
VkFormat format;
int pixelsize;
switch (texture->Format)
@ -97,12 +95,9 @@ VkPPTexture::VkPPTexture(PPTexture *texture)
VkPPTexture::~VkPPTexture()
{
if (auto fb = GetVulkanFrameBuffer())
{
if (TexImage.Image) fb->GetCommands()->FrameDeleteList.Images.push_back(std::move(TexImage.Image));
if (TexImage.View) fb->GetCommands()->FrameDeleteList.ImageViews.push_back(std::move(TexImage.View));
if (TexImage.DepthOnlyView) fb->GetCommands()->FrameDeleteList.ImageViews.push_back(std::move(TexImage.DepthOnlyView));
if (TexImage.PPFramebuffer) fb->GetCommands()->FrameDeleteList.Framebuffers.push_back(std::move(TexImage.PPFramebuffer));
if (Staging) fb->GetCommands()->FrameDeleteList.Buffers.push_back(std::move(Staging));
}
if (TexImage.Image) fb->GetCommands()->FrameDeleteList.Images.push_back(std::move(TexImage.Image));
if (TexImage.View) fb->GetCommands()->FrameDeleteList.ImageViews.push_back(std::move(TexImage.View));
if (TexImage.DepthOnlyView) fb->GetCommands()->FrameDeleteList.ImageViews.push_back(std::move(TexImage.DepthOnlyView));
if (TexImage.PPFramebuffer) fb->GetCommands()->FrameDeleteList.Framebuffers.push_back(std::move(TexImage.PPFramebuffer));
if (Staging) fb->GetCommands()->FrameDeleteList.Buffers.push_back(std::move(Staging));
}

View File

@ -5,12 +5,16 @@
#include "vulkan/system/vk_objects.h"
#include "vulkan/textures/vk_imagetransition.h"
class VulkanFrameBuffer;
class VkPPTexture : public PPTextureBackend
{
public:
VkPPTexture(PPTexture *texture);
VkPPTexture(VulkanFrameBuffer* fb, PPTexture *texture);
~VkPPTexture();
VulkanFrameBuffer* fb = nullptr;
VkTextureImage TexImage;
std::unique_ptr<VulkanBuffer> Staging;
VkFormat Format;

View File

@ -29,7 +29,7 @@
#include "vulkan/system/vk_commandbuffer.h"
#include "hw_cvars.h"
VkRenderBuffers::VkRenderBuffers()
VkRenderBuffers::VkRenderBuffers(VulkanFrameBuffer* fb) : fb(fb)
{
}
@ -39,7 +39,6 @@ VkRenderBuffers::~VkRenderBuffers()
VkSampleCountFlagBits VkRenderBuffers::GetBestSampleCount()
{
auto fb = GetVulkanFrameBuffer();
const auto &limits = fb->device->PhysicalDevice.Properties.limits;
VkSampleCountFlags deviceSampleCounts = limits.sampledImageColorSampleCounts & limits.sampledImageDepthSampleCounts & limits.sampledImageStencilSampleCounts;
@ -66,7 +65,6 @@ void VkRenderBuffers::BeginFrame(int width, int height, int sceneWidth, int scen
if (width != mWidth || height != mHeight || mSamples != samples)
{
auto fb = GetVulkanFrameBuffer();
fb->GetRenderPassManager()->RenderBuffersReset();
}
@ -88,8 +86,6 @@ void VkRenderBuffers::BeginFrame(int width, int height, int sceneWidth, int scen
void VkRenderBuffers::CreatePipeline(int width, int height)
{
auto fb = GetVulkanFrameBuffer();
for (int i = 0; i < NumPipelineImages; i++)
{
PipelineImage[i].reset();
@ -117,8 +113,6 @@ void VkRenderBuffers::CreatePipeline(int width, int height)
void VkRenderBuffers::CreateScene(int width, int height, VkSampleCountFlagBits samples)
{
auto fb = GetVulkanFrameBuffer();
SceneColor.reset();
SceneDepthStencil.reset();
SceneNormal.reset();
@ -139,8 +133,6 @@ void VkRenderBuffers::CreateScene(int width, int height, VkSampleCountFlagBits s
void VkRenderBuffers::CreateSceneColor(int width, int height, VkSampleCountFlagBits samples)
{
auto fb = GetVulkanFrameBuffer();
ImageBuilder builder;
builder.setSize(width, height);
builder.setSamples(samples);
@ -157,8 +149,6 @@ void VkRenderBuffers::CreateSceneColor(int width, int height, VkSampleCountFlagB
void VkRenderBuffers::CreateSceneDepthStencil(int width, int height, VkSampleCountFlagBits samples)
{
auto fb = GetVulkanFrameBuffer();
ImageBuilder builder;
builder.setSize(width, height);
builder.setSamples(samples);
@ -189,8 +179,6 @@ void VkRenderBuffers::CreateSceneDepthStencil(int width, int height, VkSampleCou
void VkRenderBuffers::CreateSceneFog(int width, int height, VkSampleCountFlagBits samples)
{
auto fb = GetVulkanFrameBuffer();
ImageBuilder builder;
builder.setSize(width, height);
builder.setSamples(samples);
@ -207,8 +195,6 @@ void VkRenderBuffers::CreateSceneFog(int width, int height, VkSampleCountFlagBit
void VkRenderBuffers::CreateSceneNormal(int width, int height, VkSampleCountFlagBits samples)
{
auto fb = GetVulkanFrameBuffer();
ImageBuilder builder;
builder.setSize(width, height);
builder.setSamples(samples);
@ -235,8 +221,6 @@ void VkRenderBuffers::CreateShadowmap()
Shadowmap.reset();
auto fb = GetVulkanFrameBuffer();
ImageBuilder builder;
builder.setSize(gl_shadowmap_quality, 1024);
builder.setFormat(VK_FORMAT_R32_SFLOAT);
@ -269,8 +253,6 @@ void VkRenderBuffers::CreateLightmapSampler()
{
if (!Lightmap.Image)
{
auto fb = GetVulkanFrameBuffer();
ImageBuilder builder;
builder.setSize(1, 1);
builder.setFormat(VK_FORMAT_R16G16B16A16_SFLOAT);
@ -291,8 +273,6 @@ void VkRenderBuffers::CreateLightmapSampler()
if (!LightmapSampler)
{
auto fb = GetVulkanFrameBuffer();
SamplerBuilder builder;
builder.setMipmapMode(VK_SAMPLER_MIPMAP_MODE_LINEAR);
builder.setMinFilter(VK_FILTER_LINEAR);

View File

@ -4,10 +4,12 @@
#include "vulkan/system/vk_objects.h"
#include "vulkan/textures/vk_imagetransition.h"
class VulkanFrameBuffer;
class VkRenderBuffers
{
public:
VkRenderBuffers();
VkRenderBuffers(VulkanFrameBuffer* fb);
~VkRenderBuffers();
void BeginFrame(int width, int height, int sceneWidth, int sceneHeight);
@ -46,6 +48,8 @@ private:
void CreateLightmapSampler();
VkSampleCountFlagBits GetBestSampleCount();
VulkanFrameBuffer* fb = nullptr;
int mWidth = 0;
int mHeight = 0;
int mSceneWidth = 0;

View File

@ -159,7 +159,7 @@ VulkanSampler* VkSamplerManager::Get(PPFilterMode filter, PPWrapMode wrap)
builder.setMinFilter(filter == PPFilterMode::Nearest ? VK_FILTER_NEAREST : VK_FILTER_LINEAR);
builder.setMagFilter(filter == PPFilterMode::Nearest ? VK_FILTER_NEAREST : VK_FILTER_LINEAR);
builder.setAddressMode(wrap == PPWrapMode::Clamp ? VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE : VK_SAMPLER_ADDRESS_MODE_REPEAT);
sampler = builder.create(GetVulkanFrameBuffer()->device);
sampler = builder.create(fb->device);
sampler->SetDebugName("VkPostprocess.mSamplers");
return sampler.get();
}