From ecd2dc6300d0a41c8a19c67762346f80fa03298e Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Thu, 9 Jun 2022 22:21:04 +0200 Subject: [PATCH] Move command buffers out of vk_framebuffer and into its own manager class --- src/CMakeLists.txt | 3 +- .../vulkan/renderer/vk_descriptorset.cpp | 7 +- .../vulkan/renderer/vk_postprocess.cpp | 59 ++-- .../rendering/vulkan/renderer/vk_raytrace.cpp | 42 +-- .../vulkan/renderer/vk_renderpass.cpp | 2 +- .../vulkan/renderer/vk_renderstate.cpp | 7 +- .../rendering/vulkan/system/vk_buffers.cpp | 17 +- .../vulkan/system/vk_commandbuffer.cpp | 279 ++++++++++++++++++ .../vulkan/system/vk_commandbuffer.h | 83 ++++++ .../vulkan/system/vk_framebuffer.cpp | 267 ++--------------- .../rendering/vulkan/system/vk_framebuffer.h | 67 +---- .../rendering/vulkan/system/vk_swapchain.cpp | 18 +- .../rendering/vulkan/system/vk_swapchain.h | 9 +- .../vulkan/textures/vk_hwtexture.cpp | 30 +- .../vk_renderbuffers.cpp | 14 +- .../{renderer => textures}/vk_renderbuffers.h | 0 16 files changed, 492 insertions(+), 412 deletions(-) create mode 100644 src/common/rendering/vulkan/system/vk_commandbuffer.cpp create mode 100644 src/common/rendering/vulkan/system/vk_commandbuffer.h rename src/common/rendering/vulkan/{renderer => textures}/vk_renderbuffers.cpp (96%) rename src/common/rendering/vulkan/{renderer => textures}/vk_renderbuffers.h (100%) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 645f3fc7a7..8a75c354cb 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -797,18 +797,19 @@ set (VULKAN_SOURCES common/rendering/vulkan/system/vk_swapchain.cpp common/rendering/vulkan/system/vk_builders.cpp common/rendering/vulkan/system/vk_framebuffer.cpp + common/rendering/vulkan/system/vk_commandbuffer.cpp common/rendering/vulkan/system/vk_buffers.cpp common/rendering/vulkan/renderer/vk_renderstate.cpp common/rendering/vulkan/renderer/vk_renderpass.cpp 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 common/rendering/vulkan/textures/vk_hwtexture.cpp common/rendering/vulkan/textures/vk_imagetransition.cpp + common/rendering/vulkan/textures/vk_renderbuffers.cpp common/rendering/vulkan/thirdparty/volk/volk.c common/rendering/vulkan/thirdparty/vk_mem_alloc/vk_mem_alloc.cpp ) diff --git a/src/common/rendering/vulkan/renderer/vk_descriptorset.cpp b/src/common/rendering/vulkan/renderer/vk_descriptorset.cpp index af837df9a4..479a992f4e 100644 --- a/src/common/rendering/vulkan/renderer/vk_descriptorset.cpp +++ b/src/common/rendering/vulkan/renderer/vk_descriptorset.cpp @@ -22,13 +22,14 @@ #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/textures/vk_renderbuffers.h" #include "vulkan/system/vk_builders.h" #include "vulkan/system/vk_framebuffer.h" #include "vulkan/system/vk_buffers.h" +#include "vulkan/system/vk_commandbuffer.h" #include "flatvertices.h" #include "hw_viewpointuniforms.h" #include "v_2ddrawer.h" @@ -121,7 +122,7 @@ void VkDescriptorSetManager::TextureSetPoolReset() { if (auto fb = GetVulkanFrameBuffer()) { - auto& deleteList = fb->FrameDeleteList; + auto& deleteList = fb->GetCommands()->FrameDeleteList; for (auto& desc : TextureDescriptorPools) { @@ -153,7 +154,7 @@ void VkDescriptorSetManager::CreateNullTexture() 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); + barrier.execute(fb->GetCommands()->GetTransferCommands(), VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); } VulkanDescriptorSet* VkDescriptorSetManager::GetNullTextureDescriptorSet() diff --git a/src/common/rendering/vulkan/renderer/vk_postprocess.cpp b/src/common/rendering/vulkan/renderer/vk_postprocess.cpp index dd8a22e955..f7676af10e 100644 --- a/src/common/rendering/vulkan/renderer/vk_postprocess.cpp +++ b/src/common/rendering/vulkan/renderer/vk_postprocess.cpp @@ -21,13 +21,14 @@ */ #include "vk_postprocess.h" -#include "vk_renderbuffers.h" #include "vulkan/shaders/vk_shader.h" #include "vulkan/system/vk_builders.h" #include "vulkan/system/vk_framebuffer.h" #include "vulkan/system/vk_buffers.h" #include "vulkan/system/vk_swapchain.h" +#include "vulkan/system/vk_commandbuffer.h" #include "vulkan/renderer/vk_renderstate.h" +#include "vulkan/textures/vk_renderbuffers.h" #include "vulkan/textures/vk_imagetransition.h" #include "hw_cvars.h" #include "hwrenderer/postprocessing/hw_postprocess.h" @@ -55,7 +56,7 @@ void VkPostprocess::SetActiveRenderTarget() VkImageTransition imageTransition; imageTransition.addImage(&buffers->PipelineImage[mCurrentPipelineImage], VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, false); - imageTransition.execute(fb->GetDrawCommands()); + imageTransition.execute(fb->GetCommands()->GetDrawCommands()); fb->GetRenderState()->SetRenderTarget(&buffers->PipelineImage[mCurrentPipelineImage], nullptr, buffers->GetWidth(), buffers->GetHeight(), VK_FORMAT_R16G16B16A16_SFLOAT, VK_SAMPLE_COUNT_1_BIT); } @@ -81,14 +82,14 @@ void VkPostprocess::BlitSceneToPostprocess() fb->GetRenderState()->EndRenderPass(); auto buffers = fb->GetBuffers(); - auto cmdbuffer = fb->GetDrawCommands(); + auto cmdbuffer = fb->GetCommands()->GetDrawCommands(); mCurrentPipelineImage = 0; VkImageTransition imageTransition; imageTransition.addImage(&buffers->SceneColor, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, false); imageTransition.addImage(&buffers->PipelineImage[mCurrentPipelineImage], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, true); - imageTransition.execute(fb->GetDrawCommands()); + imageTransition.execute(fb->GetCommands()->GetDrawCommands()); if (buffers->GetSceneSamples() != VK_SAMPLE_COUNT_1_BIT) { @@ -143,7 +144,7 @@ void VkPostprocess::ImageTransitionScene(bool undefinedSrcLayout) imageTransition.addImage(&buffers->SceneFog, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, undefinedSrcLayout); imageTransition.addImage(&buffers->SceneNormal, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, undefinedSrcLayout); imageTransition.addImage(&buffers->SceneDepthStencil, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, undefinedSrcLayout); - imageTransition.execute(fb->GetDrawCommands()); + imageTransition.execute(fb->GetCommands()->GetDrawCommands()); } void VkPostprocess::BlitCurrentToImage(VkTextureImage *dstimage, VkImageLayout finallayout) @@ -153,7 +154,7 @@ void VkPostprocess::BlitCurrentToImage(VkTextureImage *dstimage, VkImageLayout f fb->GetRenderState()->EndRenderPass(); auto srcimage = &fb->GetBuffers()->PipelineImage[mCurrentPipelineImage]; - auto cmdbuffer = fb->GetDrawCommands(); + auto cmdbuffer = fb->GetCommands()->GetDrawCommands(); VkImageTransition imageTransition0; imageTransition0.addImage(srcimage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, false); @@ -221,7 +222,7 @@ void VkPostprocess::DrawPresentTexture(const IntRect &box, bool applyGamma, bool uniforms.Offset = { 0.0f, 1.0f }; } - if (applyGamma && fb->swapChain->IsHdrModeActive() && !screenshot) + if (applyGamma && fb->GetCommands()->swapChain->IsHdrModeActive() && !screenshot) { uniforms.HdrMode = 1; } @@ -290,7 +291,7 @@ void VkPostprocess::UpdateShadowMap() VkImageTransition imageTransition; imageTransition.addImage(&buffers->Shadowmap, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, false); - imageTransition.execute(fb->GetDrawCommands()); + imageTransition.execute(fb->GetCommands()->GetDrawCommands()); screen->mShadowMap.FinishUpdate(); } @@ -304,7 +305,7 @@ std::unique_ptr VkPostprocess::AllocateDescriptorSet(Vulkan if (descriptors) return descriptors; - GetVulkanFrameBuffer()->FrameDeleteList.DescriptorPools.push_back(std::move(mDescriptorPool)); + GetVulkanFrameBuffer()->GetCommands()->FrameDeleteList.DescriptorPools.push_back(std::move(mDescriptorPool)); } DescriptorPoolBuilder builder; @@ -390,7 +391,7 @@ VkPPTexture::VkPPTexture(PPTexture *texture) VkImageTransition barrier0; barrier0.addImage(&TexImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, true); - barrier0.execute(fb->GetTransferCommands()); + barrier0.execute(fb->GetCommands()->GetTransferCommands()); void *data = Staging->Map(0, totalsize); memcpy(data, texture->Data.get(), totalsize); @@ -402,17 +403,17 @@ VkPPTexture::VkPPTexture(PPTexture *texture) region.imageExtent.depth = 1; region.imageExtent.width = texture->Width; region.imageExtent.height = texture->Height; - fb->GetTransferCommands()->copyBufferToImage(Staging->buffer, TexImage.Image->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion); + fb->GetCommands()->GetTransferCommands()->copyBufferToImage(Staging->buffer, TexImage.Image->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion); VkImageTransition barrier1; barrier1.addImage(&TexImage, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, false); - barrier1.execute(fb->GetTransferCommands()); + barrier1.execute(fb->GetCommands()->GetTransferCommands()); } else { VkImageTransition barrier; barrier.addImage(&TexImage, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, true); - barrier.execute(fb->GetTransferCommands()); + barrier.execute(fb->GetCommands()->GetTransferCommands()); } } @@ -420,11 +421,11 @@ VkPPTexture::~VkPPTexture() { if (auto fb = GetVulkanFrameBuffer()) { - if (TexImage.Image) fb->FrameDeleteList.Images.push_back(std::move(TexImage.Image)); - if (TexImage.View) fb->FrameDeleteList.ImageViews.push_back(std::move(TexImage.View)); - if (TexImage.DepthOnlyView) fb->FrameDeleteList.ImageViews.push_back(std::move(TexImage.DepthOnlyView)); - if (TexImage.PPFramebuffer) fb->FrameDeleteList.Framebuffers.push_back(std::move(TexImage.PPFramebuffer)); - if (Staging) fb->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)); } } @@ -468,12 +469,12 @@ FString VkPPShader::LoadShaderCode(const FString &lumpName, const FString &defin void VkPPRenderState::PushGroup(const FString &name) { - GetVulkanFrameBuffer()->PushGroup(name); + GetVulkanFrameBuffer()->GetCommands()->PushGroup(name); } void VkPPRenderState::PopGroup() { - GetVulkanFrameBuffer()->PopGroup(); + GetVulkanFrameBuffer()->GetCommands()->PopGroup(); } void VkPPRenderState::Draw() @@ -493,7 +494,7 @@ void VkPPRenderState::Draw() if (Output.Type == PPTextureType::PPTexture) key.OutputFormat = GetVkTexture(Output.Texture)->Format; else if (Output.Type == PPTextureType::SwapChain) - key.OutputFormat = GetVulkanFrameBuffer()->swapChain->swapChainFormat.format; + key.OutputFormat = GetVulkanFrameBuffer()->GetCommands()->swapChain->swapChainFormat.format; else if (Output.Type == PPTextureType::ShadowMap) key.OutputFormat = VK_FORMAT_R32_SFLOAT; else @@ -530,7 +531,7 @@ 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->GetDrawCommands(); + auto cmdbuffer = fb->GetCommands()->GetDrawCommands(); VkViewport viewport = { }; viewport.x = (float)x; @@ -597,10 +598,10 @@ VulkanDescriptorSet *VkPPRenderState::GetInput(VkPPRenderPassSetup *passSetup, c } write.updateSets(fb->device); - imageTransition.execute(fb->GetDrawCommands()); + imageTransition.execute(fb->GetCommands()->GetDrawCommands()); VulkanDescriptorSet *set = descriptors.get(); - fb->FrameDeleteList.Descriptors.push_back(std::move(descriptors)); + fb->GetCommands()->FrameDeleteList.Descriptors.push_back(std::move(descriptors)); return set; } @@ -619,7 +620,7 @@ VulkanFramebuffer *VkPPRenderState::GetOutput(VkPPRenderPassSetup *passSetup, co imageTransition.addImage(tex, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, output.Type == PPTextureType::NextPipelineTexture); if (stencilTest) imageTransition.addImage(&fb->GetBuffers()->SceneDepthStencil, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, false); - imageTransition.execute(fb->GetDrawCommands()); + imageTransition.execute(fb->GetCommands()->GetDrawCommands()); view = tex->View->view; w = tex->Image->width; @@ -628,10 +629,10 @@ VulkanFramebuffer *VkPPRenderState::GetOutput(VkPPRenderPassSetup *passSetup, co } else { - view = fb->swapChain->swapChainImageViews[fb->presentImageIndex]; - framebufferptr = &fb->swapChain->framebuffers[fb->presentImageIndex]; - w = fb->swapChain->actualExtent.width; - h = fb->swapChain->actualExtent.height; + view = fb->GetCommands()->swapChain->swapChainImageViews[fb->GetCommands()->presentImageIndex]; + framebufferptr = &fb->GetCommands()->swapChain->framebuffers[fb->GetCommands()->presentImageIndex]; + w = fb->GetCommands()->swapChain->actualExtent.width; + h = fb->GetCommands()->swapChain->actualExtent.height; } auto &framebuffer = *framebufferptr; diff --git a/src/common/rendering/vulkan/renderer/vk_raytrace.cpp b/src/common/rendering/vulkan/renderer/vk_raytrace.cpp index a385538963..f89fbc1e92 100644 --- a/src/common/rendering/vulkan/renderer/vk_raytrace.cpp +++ b/src/common/rendering/vulkan/renderer/vk_raytrace.cpp @@ -23,6 +23,7 @@ #include "vk_raytrace.h" #include "vulkan/system/vk_builders.h" #include "vulkan/system/vk_framebuffer.h" +#include "vulkan/system/vk_commandbuffer.h" #include "doom_levelmesh.h" void VkRaytrace::SetLevelMesh(hwrenderer::LevelMesh* mesh) @@ -79,19 +80,20 @@ void VkRaytrace::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)); + 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)); - fb->FrameDeleteList.Buffers.push_back(std::move(blScratchBuffer)); - fb->FrameDeleteList.Buffers.push_back(std::move(blAccelStructBuffer)); - fb->FrameDeleteList.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)); - 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)); + 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)); } } @@ -134,14 +136,14 @@ void VkRaytrace::CreateVertexAndIndexBuffers() indexBuffer = ibuilder.create(GetVulkanFrameBuffer()->device); indexBuffer->SetDebugName("indexBuffer"); - GetVulkanFrameBuffer()->GetTransferCommands()->copyBuffer(transferBuffer.get(), vertexBuffer.get(), vertexoffset); - GetVulkanFrameBuffer()->GetTransferCommands()->copyBuffer(transferBuffer.get(), indexBuffer.get(), indexoffset); + GetVulkanFrameBuffer()->GetCommands()->GetTransferCommands()->copyBuffer(transferBuffer.get(), vertexBuffer.get(), vertexoffset); + GetVulkanFrameBuffer()->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()->GetTransferCommands()->pipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, 0, 1, &barrier, 0, nullptr, 0, nullptr); + GetVulkanFrameBuffer()->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() @@ -212,13 +214,13 @@ void VkRaytrace::CreateBottomLevelAccelerationStructure() buildInfo.dstAccelerationStructure = blAccelStruct->accelstruct; buildInfo.scratchData.deviceAddress = scratchAddress; VkAccelerationStructureBuildRangeInfoKHR* rangeInfos[] = { &rangeInfo }; - GetVulkanFrameBuffer()->GetTransferCommands()->buildAccelerationStructures(1, &buildInfo, rangeInfos); + GetVulkanFrameBuffer()->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()->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); + 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); } void VkRaytrace::CreateTopLevelAccelerationStructure() @@ -252,13 +254,13 @@ void VkRaytrace::CreateTopLevelAccelerationStructure() tlInstanceBuffer = instbufbuilder.create(GetVulkanFrameBuffer()->device); tlInstanceBuffer->SetDebugName("tlInstanceBuffer"); - GetVulkanFrameBuffer()->GetTransferCommands()->copyBuffer(tlTransferBuffer.get(), tlInstanceBuffer.get()); + GetVulkanFrameBuffer()->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()->GetTransferCommands()->pipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, 0, 1, &barrier, 0, nullptr, 0, nullptr); + GetVulkanFrameBuffer()->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; @@ -317,10 +319,10 @@ void VkRaytrace::CreateTopLevelAccelerationStructure() buildInfo.scratchData.deviceAddress = scratchAddress; VkAccelerationStructureBuildRangeInfoKHR* rangeInfos[] = { &rangeInfo }; - GetVulkanFrameBuffer()->GetTransferCommands()->buildAccelerationStructures(1, &buildInfo, rangeInfos); + GetVulkanFrameBuffer()->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()->GetTransferCommands(), VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); + finishbuildbarrier.execute(GetVulkanFrameBuffer()->GetCommands()->GetTransferCommands(), VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); } diff --git a/src/common/rendering/vulkan/renderer/vk_renderpass.cpp b/src/common/rendering/vulkan/renderer/vk_renderpass.cpp index 85d876c380..672272d8fa 100644 --- a/src/common/rendering/vulkan/renderer/vk_renderpass.cpp +++ b/src/common/rendering/vulkan/renderer/vk_renderpass.cpp @@ -21,10 +21,10 @@ */ #include "vk_renderpass.h" -#include "vk_renderbuffers.h" #include "vk_renderstate.h" #include "vk_descriptorset.h" #include "vk_raytrace.h" +#include "vulkan/textures/vk_renderbuffers.h" #include "vulkan/textures/vk_samplers.h" #include "vulkan/shaders/vk_shader.h" #include "vulkan/system/vk_builders.h" diff --git a/src/common/rendering/vulkan/renderer/vk_renderstate.cpp b/src/common/rendering/vulkan/renderer/vk_renderstate.cpp index bac7e41d0c..6306ef2e51 100644 --- a/src/common/rendering/vulkan/renderer/vk_renderstate.cpp +++ b/src/common/rendering/vulkan/renderer/vk_renderstate.cpp @@ -23,9 +23,10 @@ #include "vk_renderstate.h" #include "vulkan/system/vk_framebuffer.h" #include "vulkan/system/vk_builders.h" +#include "vulkan/system/vk_commandbuffer.h" #include "vulkan/renderer/vk_renderpass.h" -#include "vulkan/renderer/vk_renderbuffers.h" #include "vulkan/renderer/vk_descriptorset.h" +#include "vulkan/textures/vk_renderbuffers.h" #include "vulkan/textures/vk_hwtexture.h" #include "hw_skydome.h" @@ -183,7 +184,7 @@ void VkRenderState::Apply(int dt) mApplyCount++; if (mApplyCount >= vk_submit_size) { - GetVulkanFrameBuffer()->FlushCommands(false); + GetVulkanFrameBuffer()->GetCommands()->FlushCommands(false); mApplyCount = 0; } @@ -252,7 +253,7 @@ void VkRenderState::ApplyRenderPass(int dt) if (!inRenderPass) { - mCommandBuffer = GetVulkanFrameBuffer()->GetDrawCommands(); + mCommandBuffer = GetVulkanFrameBuffer()->GetCommands()->GetDrawCommands(); mScissorChanged = true; mViewportChanged = true; mStencilRefChanged = true; diff --git a/src/common/rendering/vulkan/system/vk_buffers.cpp b/src/common/rendering/vulkan/system/vk_buffers.cpp index 1a1227c569..0c6a52dcff 100644 --- a/src/common/rendering/vulkan/system/vk_buffers.cpp +++ b/src/common/rendering/vulkan/system/vk_buffers.cpp @@ -23,6 +23,7 @@ #include "vk_buffers.h" #include "vk_builders.h" #include "vk_framebuffer.h" +#include "vk_commandbuffer.h" #include "vulkan/renderer/vk_renderstate.h" #include "vulkan/renderer/vk_descriptorset.h" #include "engineerrors.h" @@ -49,9 +50,9 @@ VKBuffer::~VKBuffer() if (fb) { if (mBuffer) - fb->FrameDeleteList.Buffers.push_back(std::move(mBuffer)); + fb->GetCommands()->FrameDeleteList.Buffers.push_back(std::move(mBuffer)); if (mStaging) - fb->FrameDeleteList.Buffers.push_back(std::move(mStaging)); + fb->GetCommands()->FrameDeleteList.Buffers.push_back(std::move(mStaging)); } } @@ -78,12 +79,12 @@ void VKBuffer::SetData(size_t size, const void *data, BufferUsageType usage) // If SetData is called multiple times we have to keep the old buffers alive as there might still be draw commands referencing them if (mBuffer) { - fb->FrameDeleteList.Buffers.push_back(std::move(mBuffer)); + fb->GetCommands()->FrameDeleteList.Buffers.push_back(std::move(mBuffer)); mBuffer = {}; } if (mStaging) { - fb->FrameDeleteList.Buffers.push_back(std::move(mStaging)); + fb->GetCommands()->FrameDeleteList.Buffers.push_back(std::move(mStaging)); mStaging = {}; } @@ -110,7 +111,7 @@ void VKBuffer::SetData(size_t size, const void *data, BufferUsageType usage) mStaging->Unmap(); } - fb->GetTransferCommands()->copyBuffer(mStaging.get(), mBuffer.get()); + fb->GetCommands()->GetTransferCommands()->copyBuffer(mStaging.get(), mBuffer.get()); } else if (usage == BufferUsageType::Persistent) { @@ -162,7 +163,7 @@ void VKBuffer::SetSubData(size_t offset, size_t size, const void *data) memcpy(dst, data, size); mStaging->Unmap(); - fb->GetTransferCommands()->copyBuffer(mStaging.get(), mBuffer.get(), offset, offset, size); + fb->GetCommands()->GetTransferCommands()->copyBuffer(mStaging.get(), mBuffer.get(), offset, offset, size); } else { @@ -195,8 +196,8 @@ void VKBuffer::Resize(size_t newsize) buffersize = newsize; // Transfer data from old to new - fb->GetTransferCommands()->copyBuffer(oldBuffer.get(), mBuffer.get(), 0, 0, oldsize); - fb->WaitForCommands(false); + fb->GetCommands()->GetTransferCommands()->copyBuffer(oldBuffer.get(), mBuffer.get(), 0, 0, oldsize); + fb->GetCommands()->WaitForCommands(false); fb->GetDescriptorSetManager()->UpdateDynamicSet(); // Old buffer may be part of the dynamic set // Fetch pointer to new buffer diff --git a/src/common/rendering/vulkan/system/vk_commandbuffer.cpp b/src/common/rendering/vulkan/system/vk_commandbuffer.cpp new file mode 100644 index 0000000000..1523d8c0f8 --- /dev/null +++ b/src/common/rendering/vulkan/system/vk_commandbuffer.cpp @@ -0,0 +1,279 @@ +/* +** 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_commandbuffer.h" +#include "vk_framebuffer.h" +#include "vk_swapchain.h" +#include "vk_builders.h" +#include "vulkan/renderer/vk_renderstate.h" +#include "vulkan/renderer/vk_postprocess.h" +#include "hw_clock.h" +#include "v_video.h" + +extern int rendered_commandbuffers; +int current_rendered_commandbuffers; + +extern bool gpuStatActive; +extern bool keepGpuStatActive; +extern FString gpuStatOutput; + +VkCommandBufferManager::VkCommandBufferManager(VulkanFrameBuffer* fb) : fb(fb) +{ + mCommandPool.reset(new VulkanCommandPool(fb->device, fb->device->graphicsFamily)); + + swapChain = std::make_unique(fb->device); + mSwapChainImageAvailableSemaphore.reset(new VulkanSemaphore(fb->device)); + mRenderFinishedSemaphore.reset(new VulkanSemaphore(fb->device)); + + for (auto& semaphore : mSubmitSemaphore) + semaphore.reset(new VulkanSemaphore(fb->device)); + + for (auto& fence : mSubmitFence) + fence.reset(new VulkanFence(fb->device)); + + for (int i = 0; i < maxConcurrentSubmitCount; i++) + mSubmitWaitFences[i] = mSubmitFence[i]->fence; + + if (fb->device->graphicsTimeQueries) + { + QueryPoolBuilder querybuilder; + querybuilder.setQueryType(VK_QUERY_TYPE_TIMESTAMP, MaxTimestampQueries); + mTimestampQueryPool = querybuilder.create(fb->device); + + GetDrawCommands()->resetQueryPool(mTimestampQueryPool.get(), 0, MaxTimestampQueries); + } +} + +VkCommandBufferManager::~VkCommandBufferManager() +{ +} + +VulkanCommandBuffer* VkCommandBufferManager::GetTransferCommands() +{ + if (!mTransferCommands) + { + mTransferCommands = mCommandPool->createBuffer(); + mTransferCommands->SetDebugName("VulkanFrameBuffer.mTransferCommands"); + mTransferCommands->begin(); + } + return mTransferCommands.get(); +} + +VulkanCommandBuffer* VkCommandBufferManager::GetDrawCommands() +{ + if (!mDrawCommands) + { + mDrawCommands = mCommandPool->createBuffer(); + mDrawCommands->SetDebugName("VulkanFrameBuffer.mDrawCommands"); + mDrawCommands->begin(); + } + return mDrawCommands.get(); +} + +void VkCommandBufferManager::BeginFrame() +{ + if (mNextTimestampQuery > 0) + { + GetDrawCommands()->resetQueryPool(mTimestampQueryPool.get(), 0, mNextTimestampQuery); + mNextTimestampQuery = 0; + } +} + +void VkCommandBufferManager::FlushCommands(VulkanCommandBuffer** commands, size_t count, bool finish, bool lastsubmit) +{ + int currentIndex = mNextSubmit % maxConcurrentSubmitCount; + + if (mNextSubmit >= maxConcurrentSubmitCount) + { + vkWaitForFences(fb->device->device, 1, &mSubmitFence[currentIndex]->fence, VK_TRUE, std::numeric_limits::max()); + vkResetFences(fb->device->device, 1, &mSubmitFence[currentIndex]->fence); + } + + QueueSubmit submit; + + for (size_t i = 0; i < count; i++) + submit.addCommandBuffer(commands[i]); + + if (mNextSubmit > 0) + submit.addWait(VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, mSubmitSemaphore[(mNextSubmit - 1) % maxConcurrentSubmitCount].get()); + + if (finish && presentImageIndex != 0xffffffff) + { + submit.addWait(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, mSwapChainImageAvailableSemaphore.get()); + submit.addSignal(mRenderFinishedSemaphore.get()); + } + + if (!lastsubmit) + submit.addSignal(mSubmitSemaphore[currentIndex].get()); + + submit.execute(fb->device, fb->device->graphicsQueue, mSubmitFence[currentIndex].get()); + mNextSubmit++; +} + +void VkCommandBufferManager::FlushCommands(bool finish, bool lastsubmit, bool uploadOnly) +{ + if (!uploadOnly) + fb->GetRenderState()->EndRenderPass(); + + if ((!uploadOnly && mDrawCommands) || mTransferCommands) + { + VulkanCommandBuffer* commands[2]; + size_t count = 0; + + if (mTransferCommands) + { + mTransferCommands->end(); + commands[count++] = mTransferCommands.get(); + FrameDeleteList.CommandBuffers.push_back(std::move(mTransferCommands)); + } + + if (!uploadOnly && mDrawCommands) + { + mDrawCommands->end(); + commands[count++] = mDrawCommands.get(); + FrameDeleteList.CommandBuffers.push_back(std::move(mDrawCommands)); + } + + FlushCommands(commands, count, finish, lastsubmit); + + current_rendered_commandbuffers += (int)count; + } +} + +void VkCommandBufferManager::WaitForCommands(bool finish, bool uploadOnly) +{ + if (finish) + { + Finish.Reset(); + Finish.Clock(); + + presentImageIndex = swapChain->AcquireImage(fb->GetClientWidth(), fb->GetClientHeight(), fb->GetVSync(), mSwapChainImageAvailableSemaphore.get()); + if (presentImageIndex != 0xffffffff) + fb->GetPostprocess()->DrawPresentTexture(fb->mOutputLetterbox, true, false); + } + + FlushCommands(finish, true, uploadOnly); + + if (finish) + { + fb->FPSLimit(); + + if (presentImageIndex != 0xffffffff) + swapChain->QueuePresent(presentImageIndex, mRenderFinishedSemaphore.get()); + } + + int numWaitFences = min(mNextSubmit, (int)maxConcurrentSubmitCount); + + if (numWaitFences > 0) + { + vkWaitForFences(fb->device->device, numWaitFences, mSubmitWaitFences, VK_TRUE, std::numeric_limits::max()); + vkResetFences(fb->device->device, numWaitFences, mSubmitWaitFences); + } + + DeleteFrameObjects(uploadOnly); + mNextSubmit = 0; + + if (finish) + { + Finish.Unclock(); + rendered_commandbuffers = current_rendered_commandbuffers; + current_rendered_commandbuffers = 0; + } +} + +void VkCommandBufferManager::DeleteFrameObjects(bool uploadOnly) +{ + FrameTextureUpload.Buffers.clear(); + FrameTextureUpload.TotalSize = 0; + + if (!uploadOnly) + { + FrameDeleteList.AccelStructs.clear(); + FrameDeleteList.Images.clear(); + FrameDeleteList.ImageViews.clear(); + FrameDeleteList.Framebuffers.clear(); + FrameDeleteList.Buffers.clear(); + FrameDeleteList.Descriptors.clear(); + FrameDeleteList.DescriptorPools.clear(); + FrameDeleteList.CommandBuffers.clear(); + } +} + +void VkCommandBufferManager::PushGroup(const FString& name) +{ + if (!gpuStatActive) + return; + + if (mNextTimestampQuery < MaxTimestampQueries && fb->device->graphicsTimeQueries) + { + TimestampQuery q; + q.name = name; + q.startIndex = mNextTimestampQuery++; + q.endIndex = 0; + GetDrawCommands()->writeTimestamp(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, mTimestampQueryPool.get(), q.startIndex); + mGroupStack.push_back(timeElapsedQueries.size()); + timeElapsedQueries.push_back(q); + } +} + +void VkCommandBufferManager::PopGroup() +{ + if (!gpuStatActive || mGroupStack.empty()) + return; + + TimestampQuery& q = timeElapsedQueries[mGroupStack.back()]; + mGroupStack.pop_back(); + + if (mNextTimestampQuery < MaxTimestampQueries && fb->device->graphicsTimeQueries) + { + q.endIndex = mNextTimestampQuery++; + GetDrawCommands()->writeTimestamp(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, mTimestampQueryPool.get(), q.endIndex); + } +} + +void VkCommandBufferManager::UpdateGpuStats() +{ + uint64_t timestamps[MaxTimestampQueries]; + if (mNextTimestampQuery > 0) + mTimestampQueryPool->getResults(0, mNextTimestampQuery, sizeof(uint64_t) * mNextTimestampQuery, timestamps, sizeof(uint64_t), VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT); + + double timestampPeriod = fb->device->PhysicalDevice.Properties.limits.timestampPeriod; + + gpuStatOutput = ""; + for (auto& q : timeElapsedQueries) + { + if (q.endIndex <= q.startIndex) + continue; + + int64_t timeElapsed = max(static_cast(timestamps[q.endIndex] - timestamps[q.startIndex]), (int64_t)0); + double timeNS = timeElapsed * timestampPeriod; + + FString out; + out.Format("%s=%04.2f ms\n", q.name.GetChars(), timeNS / 1000000.0f); + gpuStatOutput += out; + } + timeElapsedQueries.clear(); + mGroupStack.clear(); + + gpuStatActive = keepGpuStatActive; + keepGpuStatActive = false; +} diff --git a/src/common/rendering/vulkan/system/vk_commandbuffer.h b/src/common/rendering/vulkan/system/vk_commandbuffer.h new file mode 100644 index 0000000000..71c12e9268 --- /dev/null +++ b/src/common/rendering/vulkan/system/vk_commandbuffer.h @@ -0,0 +1,83 @@ +#pragma once + +#include "vk_device.h" +#include "vk_objects.h" + +class VulkanFrameBuffer; + +class VkCommandBufferManager +{ +public: + VkCommandBufferManager(VulkanFrameBuffer* fb); + ~VkCommandBufferManager(); + + void BeginFrame(); + + VulkanCommandBuffer* GetTransferCommands(); + VulkanCommandBuffer* GetDrawCommands(); + + void FlushCommands(bool finish, bool lastsubmit = false, bool uploadOnly = false); + + void WaitForCommands(bool finish) { WaitForCommands(finish, false); } + void WaitForCommands(bool finish, bool uploadOnly); + + void PushGroup(const FString& name); + void PopGroup(); + void UpdateGpuStats(); + + class DeleteList + { + public: + std::vector> Images; + std::vector> ImageViews; + std::vector> Framebuffers; + std::vector> Buffers; + std::vector> AccelStructs; + std::vector> Descriptors; + std::vector> DescriptorPools; + std::vector> CommandBuffers; + } FrameDeleteList; + + struct + { + std::vector> Buffers; + size_t TotalSize = 0; + } FrameTextureUpload; + + void DeleteFrameObjects(bool uploadOnly = false); + + std::unique_ptr swapChain; + uint32_t presentImageIndex = 0xffffffff; + +private: + void FlushCommands(VulkanCommandBuffer** commands, size_t count, bool finish, bool lastsubmit); + + VulkanFrameBuffer* fb = nullptr; + + std::unique_ptr mCommandPool; + + std::unique_ptr mTransferCommands; + std::unique_ptr mDrawCommands; + + enum { maxConcurrentSubmitCount = 8 }; + std::unique_ptr mSubmitSemaphore[maxConcurrentSubmitCount]; + std::unique_ptr mSubmitFence[maxConcurrentSubmitCount]; + VkFence mSubmitWaitFences[maxConcurrentSubmitCount]; + int mNextSubmit = 0; + + std::unique_ptr mSwapChainImageAvailableSemaphore; + std::unique_ptr mRenderFinishedSemaphore; + + struct TimestampQuery + { + FString name; + uint32_t startIndex; + uint32_t endIndex; + }; + + enum { MaxTimestampQueries = 100 }; + std::unique_ptr mTimestampQueryPool; + int mNextTimestampQuery = 0; + std::vector mGroupStack; + std::vector timeElapsedQueries; +}; diff --git a/src/common/rendering/vulkan/system/vk_framebuffer.cpp b/src/common/rendering/vulkan/system/vk_framebuffer.cpp index 626a7b807a..99a8d296ca 100644 --- a/src/common/rendering/vulkan/system/vk_framebuffer.cpp +++ b/src/common/rendering/vulkan/system/vk_framebuffer.cpp @@ -49,13 +49,14 @@ #include "vulkan/renderer/vk_descriptorset.h" #include "vulkan/renderer/vk_streambuffer.h" #include "vulkan/renderer/vk_postprocess.h" -#include "vulkan/renderer/vk_renderbuffers.h" #include "vulkan/renderer/vk_raytrace.h" #include "vulkan/shaders/vk_shader.h" +#include "vulkan/textures/vk_renderbuffers.h" #include "vulkan/textures/vk_samplers.h" #include "vulkan/textures/vk_hwtexture.h" #include "vulkan/system/vk_builders.h" #include "vulkan/system/vk_swapchain.h" +#include "vulkan/system/vk_commandbuffer.h" #include "engineerrors.h" #include "c_dispatch.h" @@ -64,13 +65,6 @@ EXTERN_CVAR(Int, gl_tonemap) EXTERN_CVAR(Int, screenblocks) EXTERN_CVAR(Bool, cl_capfps) -extern int rendered_commandbuffers; -int current_rendered_commandbuffers; - -extern bool gpuStatActive; -extern bool keepGpuStatActive; -extern FString gpuStatOutput; - CCMD(vk_memstats) { VmaStats stats = {}; @@ -83,19 +77,6 @@ VulkanFrameBuffer::VulkanFrameBuffer(void *hMonitor, bool fullscreen, VulkanDevi Super(hMonitor, fullscreen) { device = dev; - - swapChain = std::make_unique(device); - mSwapChainImageAvailableSemaphore.reset(new VulkanSemaphore(device)); - mRenderFinishedSemaphore.reset(new VulkanSemaphore(device)); - - for (auto &semaphore : mSubmitSemaphore) - semaphore.reset(new VulkanSemaphore(device)); - - for (auto &fence : mSubmitFence) - fence.reset(new VulkanFence(device)); - - for (int i = 0; i < maxConcurrentSubmitCount; i++) - mSubmitWaitFences[i] = mSubmitFence[i]->fence; } VulkanFrameBuffer::~VulkanFrameBuffer() @@ -121,7 +102,7 @@ VulkanFrameBuffer::~VulkanFrameBuffer() screen = tmp; - DeleteFrameObjects(); + mCommands->DeleteFrameObjects(); } void VulkanFrameBuffer::InitializeState() @@ -147,7 +128,7 @@ void VulkanFrameBuffer::InitializeState() uniformblockalignment = (unsigned int)device->PhysicalDevice.Properties.limits.minUniformBufferOffsetAlignment; maxuniformblock = device->PhysicalDevice.Properties.limits.maxUniformBufferRange; - mCommandPool.reset(new VulkanCommandPool(device, device->graphicsFamily)); + mCommands.reset(new VkCommandBufferManager(this)); mScreenBuffers.reset(new VkRenderBuffers()); mSaveBuffers.reset(new VkRenderBuffers()); @@ -177,15 +158,6 @@ void VulkanFrameBuffer::InitializeState() #else mRenderState.reset(new VkRenderState()); #endif - - if (device->graphicsTimeQueries) - { - QueryPoolBuilder querybuilder; - querybuilder.setQueryType(VK_QUERY_TYPE_TIMESTAMP, MaxTimestampQueries); - mTimestampQueryPool = querybuilder.create(device); - - GetDrawCommands()->resetQueryPool(mTimestampQueryPool.get(), 0, MaxTimestampQueries); - } } void VulkanFrameBuffer::Update() @@ -205,8 +177,8 @@ void VulkanFrameBuffer::Update() Flush3D.Unclock(); - WaitForCommands(true); - UpdateGpuStats(); + mCommands->WaitForCommands(true); + mCommands->UpdateGpuStats(); Super::Update(); } @@ -216,126 +188,6 @@ bool VulkanFrameBuffer::CompileNextShader() return mShaderManager->CompileNextShader(); } -void VulkanFrameBuffer::DeleteFrameObjects(bool uploadOnly) -{ - FrameTextureUpload.Buffers.clear(); - FrameTextureUpload.TotalSize = 0; - - if (!uploadOnly) - { - FrameDeleteList.AccelStructs.clear(); - FrameDeleteList.Images.clear(); - FrameDeleteList.ImageViews.clear(); - FrameDeleteList.Framebuffers.clear(); - FrameDeleteList.Buffers.clear(); - FrameDeleteList.Descriptors.clear(); - FrameDeleteList.DescriptorPools.clear(); - FrameDeleteList.CommandBuffers.clear(); - } -} - -void VulkanFrameBuffer::FlushCommands(VulkanCommandBuffer **commands, size_t count, bool finish, bool lastsubmit) -{ - int currentIndex = mNextSubmit % maxConcurrentSubmitCount; - - if (mNextSubmit >= maxConcurrentSubmitCount) - { - vkWaitForFences(device->device, 1, &mSubmitFence[currentIndex]->fence, VK_TRUE, std::numeric_limits::max()); - vkResetFences(device->device, 1, &mSubmitFence[currentIndex]->fence); - } - - QueueSubmit submit; - - for (size_t i = 0; i < count; i++) - submit.addCommandBuffer(commands[i]); - - if (mNextSubmit > 0) - submit.addWait(VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, mSubmitSemaphore[(mNextSubmit - 1) % maxConcurrentSubmitCount].get()); - - if (finish && presentImageIndex != 0xffffffff) - { - submit.addWait(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, mSwapChainImageAvailableSemaphore.get()); - submit.addSignal(mRenderFinishedSemaphore.get()); - } - - if (!lastsubmit) - submit.addSignal(mSubmitSemaphore[currentIndex].get()); - - submit.execute(device, device->graphicsQueue, mSubmitFence[currentIndex].get()); - mNextSubmit++; -} - -void VulkanFrameBuffer::FlushCommands(bool finish, bool lastsubmit, bool uploadOnly) -{ - if (!uploadOnly) - mRenderState->EndRenderPass(); - - if ((!uploadOnly && mDrawCommands) || mTransferCommands) - { - VulkanCommandBuffer *commands[2]; - size_t count = 0; - - if (mTransferCommands) - { - mTransferCommands->end(); - commands[count++] = mTransferCommands.get(); - FrameDeleteList.CommandBuffers.push_back(std::move(mTransferCommands)); - } - - if (!uploadOnly && mDrawCommands) - { - mDrawCommands->end(); - commands[count++] = mDrawCommands.get(); - FrameDeleteList.CommandBuffers.push_back(std::move(mDrawCommands)); - } - - FlushCommands(commands, count, finish, lastsubmit); - - current_rendered_commandbuffers += (int)count; - } -} - -void VulkanFrameBuffer::WaitForCommands(bool finish, bool uploadOnly) -{ - if (finish) - { - Finish.Reset(); - Finish.Clock(); - - presentImageIndex = swapChain->AcquireImage(GetClientWidth(), GetClientHeight(), mSwapChainImageAvailableSemaphore.get()); - if (presentImageIndex != 0xffffffff) - mPostprocess->DrawPresentTexture(mOutputLetterbox, true, false); - } - - FlushCommands(finish, true, uploadOnly); - - if (finish) - { - FPSLimit(); - - if (presentImageIndex != 0xffffffff) - swapChain->QueuePresent(presentImageIndex, mRenderFinishedSemaphore.get()); - } - - int numWaitFences = min(mNextSubmit, (int)maxConcurrentSubmitCount); - - if (numWaitFences > 0) - { - vkWaitForFences(device->device, numWaitFences, mSubmitWaitFences, VK_TRUE, std::numeric_limits::max()); - vkResetFences(device->device, numWaitFences, mSubmitWaitFences); - } - - DeleteFrameObjects(uploadOnly); - mNextSubmit = 0; - - if (finish) - { - Finish.Unclock(); - rendered_commandbuffers = current_rendered_commandbuffers; - current_rendered_commandbuffers = 0; - } -} - void VulkanFrameBuffer::RenderTextureView(FCanvasTexture* tex, std::function renderFunc) { auto BaseLayer = static_cast(tex->GetHardwareTexture(0, 0)); @@ -347,7 +199,7 @@ void VulkanFrameBuffer::RenderTextureView(FCanvasTexture* tex, std::functionGetDrawCommands()); mRenderState->SetRenderTarget(image, depthStencil->View.get(), image->Image->width, image->Image->height, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT); @@ -362,7 +214,7 @@ void VulkanFrameBuffer::RenderTextureView(FCanvasTexture* tex, std::functionGetDrawCommands()); mRenderState->SetRenderTarget(&GetBuffers()->SceneColor, GetBuffers()->SceneDepthStencil.View.get(), GetBuffers()->GetWidth(), GetBuffers()->GetHeight(), VK_FORMAT_R16G16B16A16_SFLOAT, GetBuffers()->GetSceneSamples()); @@ -523,10 +375,10 @@ void VulkanFrameBuffer::CopyScreenToBuffer(int w, int h, uint8_t *data) region.imageExtent.depth = 1; region.imageSubresource.layerCount = 1; region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - GetDrawCommands()->copyImageToBuffer(image.Image->image, image.Layout, staging->buffer, 1, ®ion); + mCommands->GetDrawCommands()->copyImageToBuffer(image.Image->image, image.Layout, staging->buffer, 1, ®ion); // Submit command buffers and wait for device to finish the work - WaitForCommands(false); + mCommands->WaitForCommands(false); // Map and convert from rgba8 to rgb8 uint8_t *dest = (uint8_t*)data; @@ -552,7 +404,6 @@ void VulkanFrameBuffer::SetActiveRenderTarget() mPostprocess->SetActiveRenderTarget(); } - TArray VulkanFrameBuffer::GetScreenshotBuffer(int &pitch, ESSType &color_type, float &gamma) { int w = SCREENWIDTH; @@ -585,11 +436,7 @@ void VulkanFrameBuffer::BeginFrame() mDescriptorSetManager->UpdateFixedSet(); mDescriptorSetManager->UpdateDynamicSet(); - if (mNextTimestampQuery > 0) - { - GetDrawCommands()->resetQueryPool(mTimestampQueryPool.get(), 0, mNextTimestampQuery); - mNextTimestampQuery = 0; - } + mCommands->BeginFrame(); } void VulkanFrameBuffer::InitLightmap(int LMTextureSize, int LMTextureCount, TArray& LMTextureData) @@ -604,8 +451,8 @@ void VulkanFrameBuffer::InitLightmap(int LMTextureSize, int LMTextureCount, TArr if (lightmap.Image) { - FrameDeleteList.Images.push_back(std::move(lightmap.Image)); - FrameDeleteList.ImageViews.push_back(std::move(lightmap.View)); + GetCommands()->FrameDeleteList.Images.push_back(std::move(lightmap.Image)); + GetCommands()->FrameDeleteList.ImageViews.push_back(std::move(lightmap.View)); lightmap.reset(); } @@ -622,7 +469,7 @@ void VulkanFrameBuffer::InitLightmap(int LMTextureSize, int LMTextureCount, TArr lightmap.View = viewbuilder.create(device); lightmap.View->SetDebugName("VkRenderBuffers.LightmapView"); - auto cmdbuffer = GetTransferCommands(); + auto cmdbuffer = GetCommands()->GetTransferCommands(); int totalSize = w * h * count * pixelsize; @@ -660,98 +507,21 @@ void VulkanFrameBuffer::InitLightmap(int LMTextureSize, int LMTextureCount, TArr barrier.addImage(&lightmap, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, false, 0, count); barrier.execute(cmdbuffer); - FrameTextureUpload.Buffers.push_back(std::move(stagingBuffer)); - FrameTextureUpload.TotalSize += totalSize; + GetCommands()->FrameTextureUpload.Buffers.push_back(std::move(stagingBuffer)); + GetCommands()->FrameTextureUpload.TotalSize += totalSize; LMTextureData.Reset(); // We no longer need this, release the memory } } -void VulkanFrameBuffer::PushGroup(const FString &name) -{ - if (!gpuStatActive) - return; - - if (mNextTimestampQuery < VulkanFrameBuffer::MaxTimestampQueries && device->graphicsTimeQueries) - { - TimestampQuery q; - q.name = name; - q.startIndex = mNextTimestampQuery++; - q.endIndex = 0; - GetDrawCommands()->writeTimestamp(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, mTimestampQueryPool.get(), q.startIndex); - mGroupStack.push_back(timeElapsedQueries.size()); - timeElapsedQueries.push_back(q); - } -} - -void VulkanFrameBuffer::PopGroup() -{ - if (!gpuStatActive || mGroupStack.empty()) - return; - - TimestampQuery &q = timeElapsedQueries[mGroupStack.back()]; - mGroupStack.pop_back(); - - if (mNextTimestampQuery < VulkanFrameBuffer::MaxTimestampQueries && device->graphicsTimeQueries) - { - q.endIndex = mNextTimestampQuery++; - GetDrawCommands()->writeTimestamp(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, mTimestampQueryPool.get(), q.endIndex); - } -} - -void VulkanFrameBuffer::UpdateGpuStats() -{ - uint64_t timestamps[MaxTimestampQueries]; - if (mNextTimestampQuery > 0) - mTimestampQueryPool->getResults(0, mNextTimestampQuery, sizeof(uint64_t) * mNextTimestampQuery, timestamps, sizeof(uint64_t), VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT); - - double timestampPeriod = device->PhysicalDevice.Properties.limits.timestampPeriod; - - gpuStatOutput = ""; - for (auto &q : timeElapsedQueries) - { - if (q.endIndex <= q.startIndex) - continue; - - int64_t timeElapsed = max(static_cast(timestamps[q.endIndex] - timestamps[q.startIndex]), (int64_t)0); - double timeNS = timeElapsed * timestampPeriod; - - FString out; - out.Format("%s=%04.2f ms\n", q.name.GetChars(), timeNS / 1000000.0f); - gpuStatOutput += out; - } - timeElapsedQueries.clear(); - mGroupStack.clear(); - - gpuStatActive = keepGpuStatActive; - keepGpuStatActive = false; -} - void VulkanFrameBuffer::Draw2D() { ::Draw2D(twod, *mRenderState); } -VulkanCommandBuffer *VulkanFrameBuffer::GetTransferCommands() +void VulkanFrameBuffer::WaitForCommands(bool finish) { - if (!mTransferCommands) - { - mTransferCommands = mCommandPool->createBuffer(); - mTransferCommands->SetDebugName("VulkanFrameBuffer.mTransferCommands"); - mTransferCommands->begin(); - } - return mTransferCommands.get(); -} - -VulkanCommandBuffer *VulkanFrameBuffer::GetDrawCommands() -{ - if (!mDrawCommands) - { - mDrawCommands = mCommandPool->createBuffer(); - mDrawCommands->SetDebugName("VulkanFrameBuffer.mDrawCommands"); - mDrawCommands->begin(); - } - return mDrawCommands.get(); + mCommands->WaitForCommands(finish); } unsigned int VulkanFrameBuffer::GetLightBufferBlockSize() const @@ -830,7 +600,6 @@ void VulkanFrameBuffer::ImageTransitionScene(bool unknown) mPostprocess->ImageTransitionScene(unknown); } - FRenderState* VulkanFrameBuffer::RenderState() { return mRenderState.get(); diff --git a/src/common/rendering/vulkan/system/vk_framebuffer.h b/src/common/rendering/vulkan/system/vk_framebuffer.h index 2463ff8c21..5e58d58766 100644 --- a/src/common/rendering/vulkan/system/vk_framebuffer.h +++ b/src/common/rendering/vulkan/system/vk_framebuffer.h @@ -7,6 +7,7 @@ struct FRenderViewpoint; class VkSamplerManager; class VkShaderManager; +class VkCommandBufferManager; class VkDescriptorSetManager; class VkRenderPassManager; class VkRaytrace; @@ -25,12 +26,8 @@ class VulkanFrameBuffer : public SystemBaseFrameBuffer public: VulkanDevice *device; - std::unique_ptr swapChain; - uint32_t presentImageIndex = 0xffffffff; - bool cur_vsync; - VulkanCommandBuffer *GetTransferCommands(); - VulkanCommandBuffer *GetDrawCommands(); + VkCommandBufferManager* GetCommands() { return mCommands.get(); } VkShaderManager *GetShaderManager() { return mShaderManager.get(); } VkSamplerManager *GetSamplerManager() { return mSamplerManager.get(); } VkDescriptorSetManager* GetDescriptorSetManager() { return mDescriptorSetManager.get(); } @@ -41,8 +38,6 @@ public: VkRenderBuffers *GetBuffers() { return mActiveRenderBuffers; } FRenderState* RenderState() override; - void FlushCommands(bool finish, bool lastsubmit = false, bool uploadOnly = false); - unsigned int GetLightBufferBlockSize() const; VKDataBuffer *ViewpointUBO = nullptr; @@ -56,25 +51,6 @@ public: std::unique_ptr FanToTrisIndexBuffer; - class DeleteList - { - public: - std::vector> Images; - std::vector> ImageViews; - std::vector> Framebuffers; - std::vector> Buffers; - std::vector> AccelStructs; - std::vector> Descriptors; - std::vector> DescriptorPools; - std::vector> CommandBuffers; - } FrameDeleteList; - - struct - { - std::vector> Buffers; - size_t TotalSize = 0; - } FrameTextureUpload; - VulkanFrameBuffer(void *hMonitor, bool fullscreen, VulkanDevice *dev); ~VulkanFrameBuffer(); bool IsVulkan() override { return true; } @@ -112,27 +88,20 @@ public: TArray GetScreenshotBuffer(int &pitch, ESSType &color_type, float &gamma) override; + bool GetVSync() { return cur_vsync; } void SetVSync(bool vsync) override; void Draw2D() override; - void WaitForCommands(bool finish) override { WaitForCommands(finish, false); } - void WaitForCommands(bool finish, bool uploadOnly); - - void PushGroup(const FString &name); - void PopGroup(); - void UpdateGpuStats(); - IntRect SetupTextureView(FCanvasTexture* tex); - void FinishTextureView(FCanvasTexture* tex); + void WaitForCommands(bool finish) override; private: void RenderTextureView(FCanvasTexture* tex, std::function renderFunc) override; void PrintStartupLog(); void CreateFanToTrisIndexBuffer(); void CopyScreenToBuffer(int w, int h, uint8_t *data) override; - void DeleteFrameObjects(bool uploadOnly = false); - void FlushCommands(VulkanCommandBuffer **commands, size_t count, bool finish, bool lastsubmit); + std::unique_ptr mCommands; std::unique_ptr mShaderManager; std::unique_ptr mSamplerManager; std::unique_ptr mScreenBuffers; @@ -141,35 +110,11 @@ private: std::unique_ptr mDescriptorSetManager; std::unique_ptr mRenderPassManager; std::unique_ptr mRaytrace; - std::unique_ptr mCommandPool; - std::unique_ptr mTransferCommands; std::unique_ptr mRenderState; - std::unique_ptr mDrawCommands; - - enum { maxConcurrentSubmitCount = 8}; - std::unique_ptr mSubmitSemaphore[maxConcurrentSubmitCount]; - std::unique_ptr mSubmitFence[maxConcurrentSubmitCount]; - VkFence mSubmitWaitFences[maxConcurrentSubmitCount]; - int mNextSubmit = 0; - - std::unique_ptr mSwapChainImageAvailableSemaphore; - std::unique_ptr mRenderFinishedSemaphore; - VkRenderBuffers *mActiveRenderBuffers = nullptr; - struct TimestampQuery - { - FString name; - uint32_t startIndex; - uint32_t endIndex; - }; - - enum { MaxTimestampQueries = 100 }; - std::unique_ptr mTimestampQueryPool; - int mNextTimestampQuery = 0; - std::vector mGroupStack; - std::vector timeElapsedQueries; + bool cur_vsync = false; }; inline VulkanFrameBuffer *GetVulkanFrameBuffer() { return static_cast(screen); } diff --git a/src/common/rendering/vulkan/system/vk_swapchain.cpp b/src/common/rendering/vulkan/system/vk_swapchain.cpp index 789259695b..fd21c462e5 100644 --- a/src/common/rendering/vulkan/system/vk_swapchain.cpp +++ b/src/common/rendering/vulkan/system/vk_swapchain.cpp @@ -41,12 +41,11 @@ VulkanSwapChain::~VulkanSwapChain() ReleaseResources(); } -uint32_t VulkanSwapChain::AcquireImage(int width, int height, VulkanSemaphore *semaphore, VulkanFence *fence) +uint32_t VulkanSwapChain::AcquireImage(int width, int height, bool vsync, VulkanSemaphore *semaphore, VulkanFence *fence) { - auto vsync = static_cast(screen)->cur_vsync; if (lastSwapWidth != width || lastSwapHeight != height || lastVsync != vsync || lastHdr != vk_hdr || !swapChain) { - Recreate(); + Recreate(vsync); lastSwapWidth = width; lastSwapHeight = height; lastVsync = vsync; @@ -77,7 +76,7 @@ uint32_t VulkanSwapChain::AcquireImage(int width, int height, VulkanSemaphore *s } else if (result == VK_ERROR_OUT_OF_DATE_KHR) { - Recreate(); + Recreate(vsync); } else if (result == VK_NOT_READY || result == VK_TIMEOUT) { @@ -133,13 +132,13 @@ void VulkanSwapChain::QueuePresent(uint32_t imageIndex, VulkanSemaphore *semapho } } -void VulkanSwapChain::Recreate() +void VulkanSwapChain::Recreate(bool vsync) { ReleaseViews(); swapChainImages.clear(); VkSwapchainKHR oldSwapChain = swapChain; - CreateSwapChain(oldSwapChain); + CreateSwapChain(vsync, oldSwapChain); if (oldSwapChain) vkDestroySwapchainKHR(device->device, oldSwapChain, nullptr); @@ -150,10 +149,10 @@ void VulkanSwapChain::Recreate() } } -bool VulkanSwapChain::CreateSwapChain(VkSwapchainKHR oldSwapChain) +bool VulkanSwapChain::CreateSwapChain(bool vsync, VkSwapchainKHR oldSwapChain) { SelectFormat(); - SelectPresentMode(); + SelectPresentMode(vsync); int width, height; I_GetVulkanDrawableSize(&width, &height); @@ -301,7 +300,7 @@ void VulkanSwapChain::SelectFormat() swapChainFormat = surfaceFormats.front(); } -void VulkanSwapChain::SelectPresentMode() +void VulkanSwapChain::SelectPresentMode(bool vsync) { std::vector presentModes = GetPresentModes(); @@ -309,7 +308,6 @@ void VulkanSwapChain::SelectPresentMode() VulkanError("No surface present modes supported"); swapChainPresentMode = VK_PRESENT_MODE_FIFO_KHR; - auto vsync = static_cast(screen)->cur_vsync; if (vsync) { bool supportsFifoRelaxed = std::find(presentModes.begin(), presentModes.end(), VK_PRESENT_MODE_FIFO_RELAXED_KHR) != presentModes.end(); diff --git a/src/common/rendering/vulkan/system/vk_swapchain.h b/src/common/rendering/vulkan/system/vk_swapchain.h index 51de648673..cbb5ab6983 100644 --- a/src/common/rendering/vulkan/system/vk_swapchain.h +++ b/src/common/rendering/vulkan/system/vk_swapchain.h @@ -12,11 +12,9 @@ public: VulkanSwapChain(VulkanDevice *device); ~VulkanSwapChain(); - uint32_t AcquireImage(int width, int height, VulkanSemaphore *semaphore = nullptr, VulkanFence *fence = nullptr); + uint32_t AcquireImage(int width, int height, bool vsync, VulkanSemaphore *semaphore = nullptr, VulkanFence *fence = nullptr); void QueuePresent(uint32_t imageIndex, VulkanSemaphore *semaphore = nullptr); - void Recreate(); - bool IsHdrModeActive() const; VkSwapchainKHR swapChain = VK_NULL_HANDLE; @@ -30,9 +28,10 @@ public: VkExtent2D actualExtent; private: + void Recreate(bool vsync); void SelectFormat(); - void SelectPresentMode(); - bool CreateSwapChain(VkSwapchainKHR oldSwapChain = VK_NULL_HANDLE); + void SelectPresentMode(bool vsync); + bool CreateSwapChain(bool vsync, VkSwapchainKHR oldSwapChain = VK_NULL_HANDLE); void CreateViews(); void GetImages(); void ReleaseResources(); diff --git a/src/common/rendering/vulkan/textures/vk_hwtexture.cpp b/src/common/rendering/vulkan/textures/vk_hwtexture.cpp index 49d3f37af1..3a0565fbc7 100644 --- a/src/common/rendering/vulkan/textures/vk_hwtexture.cpp +++ b/src/common/rendering/vulkan/textures/vk_hwtexture.cpp @@ -28,10 +28,11 @@ #include "vulkan/system/vk_objects.h" #include "vulkan/system/vk_builders.h" #include "vulkan/system/vk_framebuffer.h" +#include "vulkan/system/vk_commandbuffer.h" #include "vulkan/textures/vk_samplers.h" +#include "vulkan/textures/vk_renderbuffers.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" #include "vk_hwtexture.h" @@ -70,7 +71,7 @@ void VkHardwareTexture::Reset() mappedSWFB = nullptr; } - auto &deleteList = fb->FrameDeleteList; + auto &deleteList = fb->GetCommands()->FrameDeleteList; if (mImage.Image) deleteList.Images.push_back(std::move(mImage.Image)); if (mImage.View) deleteList.ImageViews.push_back(std::move(mImage.View)); for (auto &it : mImage.RSFramebuffers) deleteList.Framebuffers.push_back(std::move(it.second)); @@ -117,7 +118,7 @@ VkTextureImage *VkHardwareTexture::GetDepthStencil(FTexture *tex) VkImageTransition barrier; barrier.addImage(&mDepthStencil, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, true); - barrier.execute(fb->GetTransferCommands()); + barrier.execute(fb->GetCommands()->GetTransferCommands()); } return &mDepthStencil; } @@ -150,7 +151,7 @@ void VkHardwareTexture::CreateImage(FTexture *tex, int translation, int flags) mImage.View = viewbuilder.create(fb->device); mImage.View->SetDebugName("VkHardwareTexture.mImageView"); - auto cmdbuffer = fb->GetTransferCommands(); + auto cmdbuffer = fb->GetCommands()->GetTransferCommands(); VkImageTransition imageTransition; imageTransition.addImage(&mImage, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, true); @@ -189,7 +190,7 @@ void VkHardwareTexture::CreateTexture(int w, int h, int pixelsize, VkFormat form mImage.View = viewbuilder.create(fb->device); mImage.View->SetDebugName("VkHardwareTexture.mImageView"); - auto cmdbuffer = fb->GetTransferCommands(); + auto cmdbuffer = fb->GetCommands()->GetTransferCommands(); VkImageTransition imageTransition; imageTransition.addImage(&mImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, true); @@ -203,14 +204,13 @@ void VkHardwareTexture::CreateTexture(int w, int h, int pixelsize, VkFormat form region.imageExtent.height = h; cmdbuffer->copyBufferToImage(stagingBuffer->buffer, mImage.Image->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion); - fb->FrameTextureUpload.Buffers.push_back(std::move(stagingBuffer)); - if (mipmap) mImage.GenerateMipmaps(cmdbuffer); // If we queued more than 64 MB of data already: wait until the uploads finish before continuing - fb->FrameTextureUpload.TotalSize += totalSize; - if (fb->FrameTextureUpload.TotalSize > 64 * 1024 * 1024) - fb->WaitForCommands(false, true); + fb->GetCommands()->FrameTextureUpload.Buffers.push_back(std::move(stagingBuffer)); + fb->GetCommands()->FrameTextureUpload.TotalSize += totalSize; + if (fb->GetCommands()->FrameTextureUpload.TotalSize > 64 * 1024 * 1024) + fb->GetCommands()->WaitForCommands(false, true); } int VkHardwareTexture::GetMipLevels(int w, int h) @@ -256,7 +256,7 @@ void VkHardwareTexture::AllocateBuffer(int w, int h, int texelsize) mImage.View = viewbuilder.create(fb->device); mImage.View->SetDebugName("VkHardwareTexture.mImageView"); - auto cmdbuffer = fb->GetTransferCommands(); + auto cmdbuffer = fb->GetCommands()->GetTransferCommands(); VkImageTransition imageTransition; imageTransition.addImage(&mImage, VK_IMAGE_LAYOUT_GENERAL, true); @@ -311,7 +311,7 @@ void VkHardwareTexture::CreateWipeTexture(int w, int h, const char *name) VkImageTransition transition0; transition0.addImage(&mImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, true); - transition0.execute(fb->GetTransferCommands()); + transition0.execute(fb->GetCommands()->GetTransferCommands()); VkImageSubresourceRange range = {}; range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; @@ -323,11 +323,11 @@ void VkHardwareTexture::CreateWipeTexture(int w, int h, const char *name) value.float32[1] = 0.0f; value.float32[2] = 0.0f; value.float32[3] = 1.0f; - fb->GetTransferCommands()->clearColorImage(mImage.Image->image, mImage.Layout, &value, 1, &range); + fb->GetCommands()->GetTransferCommands()->clearColorImage(mImage.Image->image, mImage.Layout, &value, 1, &range); VkImageTransition transition1; transition1.addImage(&mImage, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, false); - transition1.execute(fb->GetTransferCommands()); + transition1.execute(fb->GetCommands()->GetTransferCommands()); } } @@ -354,7 +354,7 @@ void VkMaterial::DeleteDescriptors() { if (auto fb = GetVulkanFrameBuffer()) { - auto& deleteList = fb->FrameDeleteList; + auto& deleteList = fb->GetCommands()->FrameDeleteList; for (auto& it : mDescriptorSets) { diff --git a/src/common/rendering/vulkan/renderer/vk_renderbuffers.cpp b/src/common/rendering/vulkan/textures/vk_renderbuffers.cpp similarity index 96% rename from src/common/rendering/vulkan/renderer/vk_renderbuffers.cpp rename to src/common/rendering/vulkan/textures/vk_renderbuffers.cpp index 7409a78b8f..2cd3ef6738 100644 --- a/src/common/rendering/vulkan/renderer/vk_renderbuffers.cpp +++ b/src/common/rendering/vulkan/textures/vk_renderbuffers.cpp @@ -21,14 +21,14 @@ */ #include "vk_renderbuffers.h" -#include "vk_renderpass.h" -#include "vk_postprocess.h" +#include "vulkan/renderer/vk_postprocess.h" +#include "vulkan/textures/vk_renderbuffers.h" #include "vulkan/shaders/vk_shader.h" #include "vulkan/system/vk_builders.h" #include "vulkan/system/vk_framebuffer.h" +#include "vulkan/system/vk_commandbuffer.h" #include "hw_cvars.h" - VkRenderBuffers::VkRenderBuffers() { } @@ -113,7 +113,7 @@ void VkRenderBuffers::CreatePipeline(int width, int height) barrier.addImage(&PipelineImage[i], VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, true); } - barrier.execute(fb->GetDrawCommands()); + barrier.execute(fb->GetCommands()->GetDrawCommands()); } void VkRenderBuffers::CreateScene(int width, int height, VkSampleCountFlagBits samples) @@ -135,7 +135,7 @@ void VkRenderBuffers::CreateScene(int width, int height, VkSampleCountFlagBits s barrier.addImage(&SceneDepthStencil, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, true); barrier.addImage(&SceneNormal, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, true); barrier.addImage(&SceneFog, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, true); - barrier.execute(fb->GetDrawCommands()); + barrier.execute(fb->GetCommands()->GetDrawCommands()); } void VkRenderBuffers::CreateSceneColor(int width, int height, VkSampleCountFlagBits samples) @@ -252,7 +252,7 @@ void VkRenderBuffers::CreateShadowmap() VkImageTransition barrier; barrier.addImage(&Shadowmap, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, true); - barrier.execute(fb->GetDrawCommands()); + barrier.execute(fb->GetCommands()->GetDrawCommands()); if (!ShadowmapSampler) { @@ -287,7 +287,7 @@ void VkRenderBuffers::CreateLightmapSampler() VkImageTransition barrier; barrier.addImage(&Lightmap, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, true); - barrier.execute(fb->GetDrawCommands()); + barrier.execute(fb->GetCommands()->GetDrawCommands()); } if (!LightmapSampler) diff --git a/src/common/rendering/vulkan/renderer/vk_renderbuffers.h b/src/common/rendering/vulkan/textures/vk_renderbuffers.h similarity index 100% rename from src/common/rendering/vulkan/renderer/vk_renderbuffers.h rename to src/common/rendering/vulkan/textures/vk_renderbuffers.h