diff --git a/src/common/rendering/vulkan/renderer/vk_descriptorset.cpp b/src/common/rendering/vulkan/renderer/vk_descriptorset.cpp index c07f9753db..1e9f610202 100644 --- a/src/common/rendering/vulkan/renderer/vk_descriptorset.cpp +++ b/src/common/rendering/vulkan/renderer/vk_descriptorset.cpp @@ -27,6 +27,7 @@ #include "vulkan/textures/vk_samplers.h" #include "vulkan/textures/vk_renderbuffers.h" #include "vulkan/textures/vk_hwtexture.h" +#include "vulkan/textures/vk_texture.h" #include "vulkan/system/vk_builders.h" #include "vulkan/system/vk_framebuffer.h" #include "vulkan/system/vk_hwbuffer.h" @@ -123,13 +124,12 @@ void VkDescriptorSetManager::ResetHWTextureSets() for (auto mat : Materials) mat->DeleteDescriptors(); - auto& deleteList = fb->GetCommands()->FrameDeleteList; - + auto deleteList = fb->GetCommands()->DrawDeleteList.get(); for (auto& desc : TextureDescriptorPools) { - deleteList.DescriptorPools.push_back(std::move(desc)); + deleteList->Add(std::move(desc)); } - deleteList.Descriptors.push_back(std::move(NullTextureDescriptorSet)); + deleteList->Add(std::move(NullTextureDescriptorSet)); NullTextureDescriptorSet.reset(); TextureDescriptorPools.clear(); @@ -222,3 +222,57 @@ void VkDescriptorSetManager::RemoveMaterial(VkMaterial* texture) texture->fb = nullptr; Materials.erase(texture->it); } + +VulkanDescriptorSet* VkDescriptorSetManager::GetInput(VkPPRenderPassSetup* passSetup, const TArray& textures, bool bindShadowMapBuffers) +{ + auto descriptors = AllocatePPDescriptorSet(passSetup->DescriptorLayout.get()); + descriptors->SetDebugName("VkPostprocess.descriptors"); + + WriteDescriptors write; + VkImageTransition imageTransition; + + for (unsigned int index = 0; index < textures.Size(); index++) + { + const PPTextureInput& input = textures[index]; + VulkanSampler* sampler = fb->GetSamplerManager()->Get(input.Filter, input.Wrap); + VkTextureImage* tex = fb->GetTextureManager()->GetTexture(input.Type, input.Texture); + + write.addCombinedImageSampler(descriptors.get(), index, tex->DepthOnlyView ? tex->DepthOnlyView.get() : tex->View.get(), sampler, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); + imageTransition.addImage(tex, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, false); + } + + if (bindShadowMapBuffers) + { + write.addBuffer(descriptors.get(), LIGHTNODES_BINDINGPOINT, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, fb->GetBufferManager()->LightNodes->mBuffer.get()); + write.addBuffer(descriptors.get(), LIGHTLINES_BINDINGPOINT, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, fb->GetBufferManager()->LightLines->mBuffer.get()); + write.addBuffer(descriptors.get(), LIGHTLIST_BINDINGPOINT, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, fb->GetBufferManager()->LightList->mBuffer.get()); + } + + write.updateSets(fb->device); + imageTransition.execute(fb->GetCommands()->GetDrawCommands()); + + VulkanDescriptorSet* set = descriptors.get(); + fb->GetCommands()->DrawDeleteList->Add(std::move(descriptors)); + return set; +} + +std::unique_ptr VkDescriptorSetManager::AllocatePPDescriptorSet(VulkanDescriptorSetLayout* layout) +{ + if (PPDescriptorPool) + { + auto descriptors = PPDescriptorPool->tryAllocate(layout); + if (descriptors) + return descriptors; + + fb->GetCommands()->DrawDeleteList->Add(std::move(PPDescriptorPool)); + } + + DescriptorPoolBuilder builder; + builder.addPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 200); + builder.addPoolSize(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 4); + builder.setMaxSets(100); + PPDescriptorPool = builder.create(fb->device); + PPDescriptorPool->SetDebugName("PPDescriptorPool"); + + return PPDescriptorPool->allocate(layout); +} diff --git a/src/common/rendering/vulkan/renderer/vk_descriptorset.h b/src/common/rendering/vulkan/renderer/vk_descriptorset.h index 1c4c564a15..3e4c63faeb 100644 --- a/src/common/rendering/vulkan/renderer/vk_descriptorset.h +++ b/src/common/rendering/vulkan/renderer/vk_descriptorset.h @@ -6,6 +6,8 @@ class VulkanFrameBuffer; class VkMaterial; +class PPTextureInput; +class VkPPRenderPassSetup; class VkDescriptorSetManager { @@ -28,6 +30,8 @@ public: std::unique_ptr AllocateTextureDescriptorSet(int numLayers); + VulkanDescriptorSet* GetInput(VkPPRenderPassSetup* passSetup, const TArray& textures, bool bindShadowMapBuffers); + VulkanImageView* GetNullTextureView() { return NullTextureView.get(); } void AddMaterial(VkMaterial* texture); @@ -38,6 +42,8 @@ private: void CreateFixedSet(); void CreateNullTexture(); + std::unique_ptr AllocatePPDescriptorSet(VulkanDescriptorSetLayout* layout); + VulkanFrameBuffer* fb = nullptr; std::unique_ptr DynamicSetLayout; @@ -47,6 +53,8 @@ private: std::unique_ptr DynamicDescriptorPool; std::unique_ptr FixedDescriptorPool; + std::unique_ptr PPDescriptorPool; + int TextureDescriptorSetsLeft = 0; int TextureDescriptorsLeft = 0; std::vector> TextureDescriptorPools; diff --git a/src/common/rendering/vulkan/renderer/vk_postprocess.cpp b/src/common/rendering/vulkan/renderer/vk_postprocess.cpp index b3f5897784..e719ffcd70 100644 --- a/src/common/rendering/vulkan/renderer/vk_postprocess.cpp +++ b/src/common/rendering/vulkan/renderer/vk_postprocess.cpp @@ -286,28 +286,6 @@ void VkPostprocess::UpdateShadowMap() } } -std::unique_ptr VkPostprocess::AllocateDescriptorSet(VulkanDescriptorSetLayout *layout) -{ - if (mDescriptorPool) - { - auto descriptors = mDescriptorPool->tryAllocate(layout); - if (descriptors) - return descriptors; - - 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(fb->device); - mDescriptorPool->SetDebugName("VkPostprocess.mDescriptorPool"); - - return mDescriptorPool->allocate(layout); -} - void VkPostprocess::NextEye(int eyeCount) { } - diff --git a/src/common/rendering/vulkan/renderer/vk_postprocess.h b/src/common/rendering/vulkan/renderer/vk_postprocess.h index 955f0a1b4e..bd284f7b36 100644 --- a/src/common/rendering/vulkan/renderer/vk_postprocess.h +++ b/src/common/rendering/vulkan/renderer/vk_postprocess.h @@ -38,14 +38,13 @@ public: void BlitCurrentToImage(VkTextureImage *image, VkImageLayout finallayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); void DrawPresentTexture(const IntRect &box, bool applyGamma, bool screenshot); + int GetCurrentPipelineImage() const { return mCurrentPipelineImage; } + private: void NextEye(int eyeCount); - std::unique_ptr AllocateDescriptorSet(VulkanDescriptorSetLayout *layout); - VulkanFrameBuffer* fb = nullptr; - std::unique_ptr mDescriptorPool; int mCurrentPipelineImage = 0; friend class VkPPRenderState; diff --git a/src/common/rendering/vulkan/renderer/vk_pprenderstate.cpp b/src/common/rendering/vulkan/renderer/vk_pprenderstate.cpp index 498e653977..757f50350c 100644 --- a/src/common/rendering/vulkan/renderer/vk_pprenderstate.cpp +++ b/src/common/rendering/vulkan/renderer/vk_pprenderstate.cpp @@ -30,7 +30,9 @@ #include "vulkan/textures/vk_pptexture.h" #include "vulkan/textures/vk_renderbuffers.h" #include "vulkan/textures/vk_samplers.h" +#include "vulkan/textures/vk_texture.h" #include "vulkan/renderer/vk_renderstate.h" +#include "vulkan/renderer/vk_descriptorset.h" #include "flatvertices.h" VkPPRenderState::VkPPRenderState(VulkanFrameBuffer* fb) : fb(fb) @@ -49,19 +51,17 @@ void VkPPRenderState::PopGroup() void VkPPRenderState::Draw() { - auto pp = fb->GetPostprocess(); - fb->GetRenderState()->EndRenderPass(); VkPPRenderPassKey key; key.BlendMode = BlendMode; key.InputTextures = Textures.Size(); key.Uniforms = Uniforms.Data.Size(); - key.Shader = GetVkShader(Shader); + key.Shader = fb->GetShaderManager()->GetVkShader(Shader); key.SwapChain = (Output.Type == PPTextureType::SwapChain); key.ShadowMapBuffers = ShadowMapBuffers; if (Output.Type == PPTextureType::PPTexture) - key.OutputFormat = GetVkTexture(Output.Texture)->Format; + key.OutputFormat = fb->GetTextureManager()->GetTextureFormat(Output.Texture); else if (Output.Type == PPTextureType::SwapChain) key.OutputFormat = fb->GetCommands()->swapChain->swapChainFormat.format; else if (Output.Type == PPTextureType::ShadowMap) @@ -83,14 +83,15 @@ void VkPPRenderState::Draw() auto passSetup = fb->GetRenderPassManager()->GetPPRenderPass(key); int framebufferWidth = 0, framebufferHeight = 0; - VulkanDescriptorSet *input = GetInput(passSetup, Textures, ShadowMapBuffers); - VulkanFramebuffer *output = GetOutput(passSetup, Output, key.StencilTest, framebufferWidth, framebufferHeight); + VulkanDescriptorSet *input = fb->GetDescriptorSetManager()->GetInput(passSetup, Textures, ShadowMapBuffers); + VulkanFramebuffer *output = fb->GetBuffers()->GetOutput(passSetup, Output, key.StencilTest, framebufferWidth, framebufferHeight); RenderScreenQuad(passSetup, input, output, framebufferWidth, framebufferHeight, Viewport.left, Viewport.top, Viewport.width, Viewport.height, Uniforms.Data.Data(), Uniforms.Data.Size(), key.StencilTest); // Advance to next PP texture if our output was sent there if (Output.Type == PPTextureType::NextPipelineTexture) { + auto pp = fb->GetPostprocess(); pp->mCurrentPipelineImage = (pp->mCurrentPipelineImage + 1) % VkRenderBuffers::NumPipelineImages; } } @@ -135,141 +136,3 @@ void VkPPRenderState::RenderScreenQuad(VkPPRenderPassSetup *passSetup, VulkanDes cmdbuffer->draw(3, 1, FFlatVertexBuffer::PRESENT_INDEX, 0); cmdbuffer->endRenderPass(); } - -VulkanDescriptorSet *VkPPRenderState::GetInput(VkPPRenderPassSetup *passSetup, const TArray &textures, bool bindShadowMapBuffers) -{ - auto descriptors = fb->GetPostprocess()->AllocateDescriptorSet(passSetup->DescriptorLayout.get()); - descriptors->SetDebugName("VkPostprocess.descriptors"); - - WriteDescriptors write; - VkImageTransition imageTransition; - - for (unsigned int index = 0; index < textures.Size(); index++) - { - const PPTextureInput &input = textures[index]; - VulkanSampler *sampler = fb->GetSamplerManager()->Get(input.Filter, input.Wrap); - VkTextureImage *tex = GetTexture(input.Type, input.Texture); - - write.addCombinedImageSampler(descriptors.get(), index, tex->DepthOnlyView ? tex->DepthOnlyView.get() : tex->View.get(), sampler, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); - imageTransition.addImage(tex, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, false); - } - - if (bindShadowMapBuffers) - { - write.addBuffer(descriptors.get(), LIGHTNODES_BINDINGPOINT, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, fb->GetBufferManager()->LightNodes->mBuffer.get()); - write.addBuffer(descriptors.get(), LIGHTLINES_BINDINGPOINT, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, fb->GetBufferManager()->LightLines->mBuffer.get()); - write.addBuffer(descriptors.get(), LIGHTLIST_BINDINGPOINT, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, fb->GetBufferManager()->LightList->mBuffer.get()); - } - - write.updateSets(fb->device); - imageTransition.execute(fb->GetCommands()->GetDrawCommands()); - - VulkanDescriptorSet *set = descriptors.get(); - fb->GetCommands()->FrameDeleteList.Descriptors.push_back(std::move(descriptors)); - return set; -} - -VulkanFramebuffer *VkPPRenderState::GetOutput(VkPPRenderPassSetup *passSetup, const PPOutput &output, bool stencilTest, int &framebufferWidth, int &framebufferHeight) -{ - VkTextureImage *tex = GetTexture(output.Type, output.Texture); - - VkImageView view; - std::unique_ptr *framebufferptr = nullptr; - int w, h; - if (tex) - { - VkImageTransition imageTransition; - 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->GetCommands()->GetDrawCommands()); - - view = tex->View->view; - w = tex->Image->width; - h = tex->Image->height; - framebufferptr = &tex->PPFramebuffer; - } - else - { - 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; - if (!framebuffer) - { - FramebufferBuilder builder; - builder.setRenderPass(passSetup->RenderPass.get()); - builder.setSize(w, h); - builder.addAttachment(view); - if (stencilTest) - builder.addAttachment(fb->GetBuffers()->SceneDepthStencil.View.get()); - framebuffer = builder.create(fb->device); - } - - framebufferWidth = w; - framebufferHeight = h; - return framebuffer.get(); -} - -VkTextureImage *VkPPRenderState::GetTexture(const PPTextureType &type, PPTexture *pptexture) -{ - if (type == PPTextureType::CurrentPipelineTexture || type == PPTextureType::NextPipelineTexture) - { - int idx = fb->GetPostprocess()->mCurrentPipelineImage; - if (type == PPTextureType::NextPipelineTexture) - idx = (idx + 1) % VkRenderBuffers::NumPipelineImages; - - return &fb->GetBuffers()->PipelineImage[idx]; - } - else if (type == PPTextureType::PPTexture) - { - auto vktex = GetVkTexture(pptexture); - return &vktex->TexImage; - } - else if (type == PPTextureType::SceneColor) - { - return &fb->GetBuffers()->SceneColor; - } - else if (type == PPTextureType::SceneNormal) - { - return &fb->GetBuffers()->SceneNormal; - } - else if (type == PPTextureType::SceneFog) - { - return &fb->GetBuffers()->SceneFog; - } - else if (type == PPTextureType::SceneDepth) - { - return &fb->GetBuffers()->SceneDepthStencil; - } - else if (type == PPTextureType::ShadowMap) - { - return &fb->GetBuffers()->Shadowmap; - } - else if (type == PPTextureType::SwapChain) - { - return nullptr; - } - else - { - I_FatalError("VkPPRenderState::GetTexture not implemented yet for this texture type"); - return nullptr; - } -} - -VkPPShader *VkPPRenderState::GetVkShader(PPShader *shader) -{ - if (!shader->Backend) - shader->Backend = std::make_unique(fb, shader); - return static_cast(shader->Backend.get()); -} - -VkPPTexture *VkPPRenderState::GetVkTexture(PPTexture *texture) -{ - if (!texture->Backend) - texture->Backend = std::make_unique(fb, texture); - return static_cast(texture->Backend.get()); -} diff --git a/src/common/rendering/vulkan/renderer/vk_pprenderstate.h b/src/common/rendering/vulkan/renderer/vk_pprenderstate.h index a2d50f9df1..36102cc01c 100644 --- a/src/common/rendering/vulkan/renderer/vk_pprenderstate.h +++ b/src/common/rendering/vulkan/renderer/vk_pprenderstate.h @@ -23,13 +23,5 @@ public: private: void 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); - VulkanDescriptorSet *GetInput(VkPPRenderPassSetup *passSetup, const TArray &textures, bool bindShadowMapBuffers); - VulkanFramebuffer *GetOutput(VkPPRenderPassSetup *passSetup, const PPOutput &output, bool stencilTest, int &framebufferWidth, int &framebufferHeight); - - VkPPShader *GetVkShader(PPShader *shader); - VkPPTexture *GetVkTexture(PPTexture *texture); - - VkTextureImage *GetTexture(const PPTextureType &type, PPTexture *tex); - VulkanFrameBuffer* fb = nullptr; }; diff --git a/src/common/rendering/vulkan/renderer/vk_raytrace.cpp b/src/common/rendering/vulkan/renderer/vk_raytrace.cpp index 9e3d22ed81..c7f2961f73 100644 --- a/src/common/rendering/vulkan/renderer/vk_raytrace.cpp +++ b/src/common/rendering/vulkan/renderer/vk_raytrace.cpp @@ -81,20 +81,18 @@ VulkanAccelerationStructure* VkRaytrace::GetAccelStruct() void VkRaytrace::Reset() { - 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(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)); + auto deletelist = fb->GetCommands()->DrawDeleteList.get(); + deletelist->Add(std::move(vertexBuffer)); + deletelist->Add(std::move(indexBuffer)); + deletelist->Add(std::move(transferBuffer)); + deletelist->Add(std::move(blScratchBuffer)); + deletelist->Add(std::move(blAccelStructBuffer)); + deletelist->Add(std::move(blAccelStruct)); + deletelist->Add(std::move(tlTransferBuffer)); + deletelist->Add(std::move(tlScratchBuffer)); + deletelist->Add(std::move(tlInstanceBuffer)); + deletelist->Add(std::move(tlAccelStructBuffer)); + deletelist->Add(std::move(tlAccelStruct)); } void VkRaytrace::CreateVulkanObjects() diff --git a/src/common/rendering/vulkan/shaders/vk_shader.cpp b/src/common/rendering/vulkan/shaders/vk_shader.cpp index ff8348a74c..6e1f9a8ae1 100644 --- a/src/common/rendering/vulkan/shaders/vk_shader.cpp +++ b/src/common/rendering/vulkan/shaders/vk_shader.cpp @@ -21,7 +21,9 @@ */ #include "vk_shader.h" +#include "vk_ppshader.h" #include "vulkan/system/vk_builders.h" +#include "vulkan/system/vk_framebuffer.h" #include "hw_shaderpatcher.h" #include "filesystem.h" #include "engineerrors.h" @@ -111,7 +113,7 @@ bool VkShaderManager::CompileNextShader() return false; } -VkShaderManager::VkShaderManager(VulkanDevice *device) : device(device) +VkShaderManager::VkShaderManager(VulkanFrameBuffer* fb) : fb(fb) { ShInitialize(); CompileNextShader(); @@ -329,13 +331,13 @@ std::unique_ptr VkShaderManager::LoadVertShader(FString shadername code << "#define NPOT_EMULATION\n"; #endif code << shaderBindings; - if (!device->UsedDeviceFeatures.shaderClipDistance) code << "#define NO_CLIPDISTANCE_SUPPORT\n"; + if (!fb->device->UsedDeviceFeatures.shaderClipDistance) code << "#define NO_CLIPDISTANCE_SUPPORT\n"; code << "#line 1\n"; code << LoadPrivateShaderLump(vert_lump).GetChars() << "\n"; ShaderBuilder builder; builder.setVertexShader(code); - return builder.create(shadername.GetChars(), device); + return builder.create(shadername.GetChars(), fb->device); } std::unique_ptr VkShaderManager::LoadFragShader(FString shadername, const char *frag_lump, const char *material_lump, const char *light_lump, const char *defines, bool alphatest, bool gbufferpass) @@ -351,7 +353,7 @@ std::unique_ptr VkShaderManager::LoadFragShader(FString shadername code << shaderBindings; FString placeholder = "\n"; - if (!device->UsedDeviceFeatures.shaderClipDistance) code << "#define NO_CLIPDISTANCE_SUPPORT\n"; + if (!fb->device->UsedDeviceFeatures.shaderClipDistance) code << "#define NO_CLIPDISTANCE_SUPPORT\n"; if (!alphatest) code << "#define NO_ALPHATEST\n"; if (gbufferpass) code << "#define GBUFFER_PASS\n"; @@ -425,12 +427,12 @@ std::unique_ptr VkShaderManager::LoadFragShader(FString shadername ShaderBuilder builder; builder.setFragmentShader(code); - return builder.create(shadername.GetChars(), device); + return builder.create(shadername.GetChars(), fb->device); } FString VkShaderManager::GetTargetGlslVersion() { - if (device->ApiVersion == VK_API_VERSION_1_2) + if (fb->device->ApiVersion == VK_API_VERSION_1_2) { return "#version 460\n#extension GL_EXT_ray_query : enable\n"; } @@ -456,3 +458,10 @@ FString VkShaderManager::LoadPrivateShaderLump(const char *lumpname) FileData data = fileSystem.ReadFile(lump); return data.GetString(); } + +VkPPShader* VkShaderManager::GetVkShader(PPShader* shader) +{ + if (!shader->Backend) + shader->Backend = std::make_unique(fb, shader); + return static_cast(shader->Backend.get()); +} diff --git a/src/common/rendering/vulkan/shaders/vk_shader.h b/src/common/rendering/vulkan/shaders/vk_shader.h index 0b610ca330..4c365f176b 100644 --- a/src/common/rendering/vulkan/shaders/vk_shader.h +++ b/src/common/rendering/vulkan/shaders/vk_shader.h @@ -10,8 +10,11 @@ #define SHADER_MIN_REQUIRED_TEXTURE_LAYERS 8 +class VulkanFrameBuffer; class VulkanDevice; class VulkanShader; +class VkPPShader; +class PPShader; struct MatricesUBO { @@ -60,13 +63,15 @@ public: class VkShaderManager { public: - VkShaderManager(VulkanDevice *device); + VkShaderManager(VulkanFrameBuffer* fb); ~VkShaderManager(); VkShaderProgram *GetEffect(int effect, EPassType passType); VkShaderProgram *Get(unsigned int eff, bool alphateston, EPassType passType); bool CompileNextShader(); + VkPPShader* GetVkShader(PPShader* shader); + private: std::unique_ptr LoadVertShader(FString shadername, const char *vert_lump, const char *defines); std::unique_ptr LoadFragShader(FString shadername, const char *frag_lump, const char *material_lump, const char *light_lump, const char *defines, bool alphatest, bool gbufferpass); @@ -75,7 +80,7 @@ private: FString LoadPublicShaderLump(const char *lumpname); FString LoadPrivateShaderLump(const char *lumpname); - VulkanDevice *device; + VulkanFrameBuffer* fb = nullptr; std::vector mMaterialShaders[MAX_PASS_TYPES]; std::vector mMaterialShadersNAT[MAX_PASS_TYPES]; diff --git a/src/common/rendering/vulkan/system/vk_commandbuffer.cpp b/src/common/rendering/vulkan/system/vk_commandbuffer.cpp index 1523d8c0f8..1694fe0173 100644 --- a/src/common/rendering/vulkan/system/vk_commandbuffer.cpp +++ b/src/common/rendering/vulkan/system/vk_commandbuffer.cpp @@ -143,14 +143,14 @@ void VkCommandBufferManager::FlushCommands(bool finish, bool lastsubmit, bool up { mTransferCommands->end(); commands[count++] = mTransferCommands.get(); - FrameDeleteList.CommandBuffers.push_back(std::move(mTransferCommands)); + TransferDeleteList->Add(std::move(mTransferCommands)); } if (!uploadOnly && mDrawCommands) { mDrawCommands->end(); commands[count++] = mDrawCommands.get(); - FrameDeleteList.CommandBuffers.push_back(std::move(mDrawCommands)); + DrawDeleteList->Add(std::move(mDrawCommands)); } FlushCommands(commands, count, finish, lastsubmit); @@ -202,20 +202,9 @@ void VkCommandBufferManager::WaitForCommands(bool finish, bool uploadOnly) void VkCommandBufferManager::DeleteFrameObjects(bool uploadOnly) { - FrameTextureUpload.Buffers.clear(); - FrameTextureUpload.TotalSize = 0; - + TransferDeleteList = std::make_unique(); 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(); - } + DrawDeleteList = std::make_unique(); } void VkCommandBufferManager::PushGroup(const FString& name) diff --git a/src/common/rendering/vulkan/system/vk_commandbuffer.h b/src/common/rendering/vulkan/system/vk_commandbuffer.h index 1caa163482..0b86f0cbee 100644 --- a/src/common/rendering/vulkan/system/vk_commandbuffer.h +++ b/src/common/rendering/vulkan/system/vk_commandbuffer.h @@ -28,22 +28,30 @@ public: class DeleteList { public: + std::vector> Buffers; + std::vector> Samplers; std::vector> Images; std::vector> ImageViews; std::vector> Framebuffers; - std::vector> Buffers; std::vector> AccelStructs; - std::vector> Descriptors; std::vector> DescriptorPools; + std::vector> Descriptors; std::vector> CommandBuffers; - std::vector< std::unique_ptr> Samplers; - } FrameDeleteList; - - struct - { - std::vector> Buffers; size_t TotalSize = 0; - } FrameTextureUpload; + + void Add(std::unique_ptr obj) { TotalSize += obj->size; Buffers.push_back(std::move(obj)); } + void Add(std::unique_ptr obj) { Samplers.push_back(std::move(obj)); } + void Add(std::unique_ptr obj) { Images.push_back(std::move(obj)); } + void Add(std::unique_ptr obj) { ImageViews.push_back(std::move(obj)); } + void Add(std::unique_ptr obj) { Framebuffers.push_back(std::move(obj)); } + void Add(std::unique_ptr obj) { AccelStructs.push_back(std::move(obj)); } + void Add(std::unique_ptr obj) { DescriptorPools.push_back(std::move(obj)); } + void Add(std::unique_ptr obj) { Descriptors.push_back(std::move(obj)); } + void Add(std::unique_ptr obj) { CommandBuffers.push_back(std::move(obj)); } + }; + + std::unique_ptr TransferDeleteList = std::make_unique(); + std::unique_ptr DrawDeleteList = std::make_unique(); void DeleteFrameObjects(bool uploadOnly = false); diff --git a/src/common/rendering/vulkan/system/vk_framebuffer.cpp b/src/common/rendering/vulkan/system/vk_framebuffer.cpp index caa8d75028..fc22af0e3c 100644 --- a/src/common/rendering/vulkan/system/vk_framebuffer.cpp +++ b/src/common/rendering/vulkan/system/vk_framebuffer.cpp @@ -138,7 +138,7 @@ void VulkanFrameBuffer::InitializeState() mViewpoints = new HWViewpointBuffer; mLights = new FLightBuffer(); - mShaderManager.reset(new VkShaderManager(device)); + mShaderManager.reset(new VkShaderManager(this)); mDescriptorSetManager->Init(); #ifdef __APPLE__ mRenderState.reset(new VkRenderStateMolten(this)); @@ -472,8 +472,7 @@ void VulkanFrameBuffer::InitLightmap(int LMTextureSize, int LMTextureCount, TArr barrier.addImage(&lightmap, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, false, 0, count); barrier.execute(cmdbuffer); - GetCommands()->FrameTextureUpload.Buffers.push_back(std::move(stagingBuffer)); - GetCommands()->FrameTextureUpload.TotalSize += totalSize; + GetCommands()->TransferDeleteList->Add(std::move(stagingBuffer)); LMTextureData.Reset(); // We no longer need this, release the memory } diff --git a/src/common/rendering/vulkan/system/vk_hwbuffer.cpp b/src/common/rendering/vulkan/system/vk_hwbuffer.cpp index 8f3db8a982..f6b19a6f3c 100644 --- a/src/common/rendering/vulkan/system/vk_hwbuffer.cpp +++ b/src/common/rendering/vulkan/system/vk_hwbuffer.cpp @@ -50,9 +50,9 @@ void VkHardwareBuffer::Reset() map = nullptr; } if (mBuffer) - fb->GetCommands()->FrameDeleteList.Buffers.push_back(std::move(mBuffer)); + fb->GetCommands()->DrawDeleteList->Add(std::move(mBuffer)); if (mStaging) - fb->GetCommands()->FrameDeleteList.Buffers.push_back(std::move(mStaging)); + fb->GetCommands()->TransferDeleteList->Add(std::move(mStaging)); } } @@ -63,12 +63,12 @@ void VkHardwareBuffer::SetData(size_t size, const void *data, BufferUsageType us // 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->GetCommands()->FrameDeleteList.Buffers.push_back(std::move(mBuffer)); + fb->GetCommands()->DrawDeleteList->Add(std::move(mBuffer)); mBuffer = {}; } if (mStaging) { - fb->GetCommands()->FrameDeleteList.Buffers.push_back(std::move(mStaging)); + fb->GetCommands()->TransferDeleteList->Add(std::move(mStaging)); mStaging = {}; } diff --git a/src/common/rendering/vulkan/textures/vk_hwtexture.cpp b/src/common/rendering/vulkan/textures/vk_hwtexture.cpp index ce3dd7b052..ab79e25034 100644 --- a/src/common/rendering/vulkan/textures/vk_hwtexture.cpp +++ b/src/common/rendering/vulkan/textures/vk_hwtexture.cpp @@ -182,9 +182,8 @@ void VkHardwareTexture::CreateTexture(int w, int h, int pixelsize, VkFormat form if (mipmap) mImage.GenerateMipmaps(cmdbuffer); // If we queued more than 64 MB of data already: wait until the uploads finish before continuing - fb->GetCommands()->FrameTextureUpload.Buffers.push_back(std::move(stagingBuffer)); - fb->GetCommands()->FrameTextureUpload.TotalSize += totalSize; - if (fb->GetCommands()->FrameTextureUpload.TotalSize > 64 * 1024 * 1024) + fb->GetCommands()->TransferDeleteList->Add(std::move(stagingBuffer)); + if (fb->GetCommands()->TransferDeleteList->TotalSize > 64 * 1024 * 1024) fb->GetCommands()->WaitForCommands(false, true); } @@ -319,13 +318,11 @@ void VkMaterial::DeleteDescriptors() { if (fb) { - auto& deleteList = fb->GetCommands()->FrameDeleteList; - + auto deleteList = fb->GetCommands()->DrawDeleteList.get(); for (auto& it : mDescriptorSets) { - deleteList.Descriptors.push_back(std::move(it.descriptor)); + deleteList->Add(std::move(it.descriptor)); } - mDescriptorSets.clear(); } } diff --git a/src/common/rendering/vulkan/textures/vk_imagetransition.h b/src/common/rendering/vulkan/textures/vk_imagetransition.h index 4c6cde514e..11d6c4e433 100644 --- a/src/common/rendering/vulkan/textures/vk_imagetransition.h +++ b/src/common/rendering/vulkan/textures/vk_imagetransition.h @@ -14,14 +14,14 @@ public: { AspectMask = VK_IMAGE_ASPECT_COLOR_BIT; Layout = VK_IMAGE_LAYOUT_UNDEFINED; - auto& deletelist = fb->GetCommands()->FrameDeleteList; - deletelist.Framebuffers.push_back(std::move(PPFramebuffer)); + auto deletelist = fb->GetCommands()->DrawDeleteList.get(); + deletelist->Add(std::move(PPFramebuffer)); for (auto &it : RSFramebuffers) - deletelist.Framebuffers.push_back(std::move(it.second)); + deletelist->Add(std::move(it.second)); RSFramebuffers.clear(); - deletelist.ImageViews.push_back(std::move(DepthOnlyView)); - deletelist.ImageViews.push_back(std::move(View)); - deletelist.Images.push_back(std::move(Image)); + deletelist->Add(std::move(DepthOnlyView)); + deletelist->Add(std::move(View)); + deletelist->Add(std::move(Image)); } void GenerateMipmaps(VulkanCommandBuffer *cmdbuffer); diff --git a/src/common/rendering/vulkan/textures/vk_pptexture.cpp b/src/common/rendering/vulkan/textures/vk_pptexture.cpp index f6de4fa6ed..4ca9717580 100644 --- a/src/common/rendering/vulkan/textures/vk_pptexture.cpp +++ b/src/common/rendering/vulkan/textures/vk_pptexture.cpp @@ -108,6 +108,6 @@ void VkPPTexture::Reset() { TexImage.Reset(fb); if (Staging) - fb->GetCommands()->FrameDeleteList.Buffers.push_back(std::move(Staging)); + fb->GetCommands()->DrawDeleteList->Add(std::move(Staging)); } } diff --git a/src/common/rendering/vulkan/textures/vk_renderbuffers.cpp b/src/common/rendering/vulkan/textures/vk_renderbuffers.cpp index 4c9fd2beb8..2d9e8d4e7f 100644 --- a/src/common/rendering/vulkan/textures/vk_renderbuffers.cpp +++ b/src/common/rendering/vulkan/textures/vk_renderbuffers.cpp @@ -22,11 +22,12 @@ #include "vk_renderbuffers.h" #include "vulkan/renderer/vk_postprocess.h" -#include "vulkan/textures/vk_renderbuffers.h" +#include "vulkan/textures/vk_texture.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 "vulkan/system/vk_swapchain.h" #include "hw_cvars.h" VkRenderBuffers::VkRenderBuffers(VulkanFrameBuffer* fb) : fb(fb) @@ -282,3 +283,48 @@ void VkRenderBuffers::CreateLightmapSampler() LightmapSampler->SetDebugName("VkRenderBuffers.LightmapSampler"); } } + +VulkanFramebuffer* VkRenderBuffers::GetOutput(VkPPRenderPassSetup* passSetup, const PPOutput& output, bool stencilTest, int& framebufferWidth, int& framebufferHeight) +{ + VkTextureImage* tex = fb->GetTextureManager()->GetTexture(output.Type, output.Texture); + + VkImageView view; + std::unique_ptr* framebufferptr = nullptr; + int w, h; + if (tex) + { + VkImageTransition imageTransition; + 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->GetCommands()->GetDrawCommands()); + + view = tex->View->view; + w = tex->Image->width; + h = tex->Image->height; + framebufferptr = &tex->PPFramebuffer; + } + else + { + 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; + if (!framebuffer) + { + FramebufferBuilder builder; + builder.setRenderPass(passSetup->RenderPass.get()); + builder.setSize(w, h); + builder.addAttachment(view); + if (stencilTest) + builder.addAttachment(fb->GetBuffers()->SceneDepthStencil.View.get()); + framebuffer = builder.create(fb->device); + } + + framebufferWidth = w; + framebufferHeight = h; + return framebuffer.get(); +} diff --git a/src/common/rendering/vulkan/textures/vk_renderbuffers.h b/src/common/rendering/vulkan/textures/vk_renderbuffers.h index 93626f4d91..dd89d235fb 100644 --- a/src/common/rendering/vulkan/textures/vk_renderbuffers.h +++ b/src/common/rendering/vulkan/textures/vk_renderbuffers.h @@ -5,6 +5,8 @@ #include "vulkan/textures/vk_imagetransition.h" class VulkanFrameBuffer; +class VkPPRenderPassSetup; +class PPOutput; class VkRenderBuffers { @@ -37,6 +39,8 @@ public: VkTextureImage Lightmap; std::unique_ptr LightmapSampler; + VulkanFramebuffer* GetOutput(VkPPRenderPassSetup* passSetup, const PPOutput& output, bool stencilTest, int& framebufferWidth, int& framebufferHeight); + private: void CreatePipeline(int width, int height); void CreateScene(int width, int height, VkSampleCountFlagBits samples); diff --git a/src/common/rendering/vulkan/textures/vk_samplers.cpp b/src/common/rendering/vulkan/textures/vk_samplers.cpp index b0ef4b5187..96a14e8775 100644 --- a/src/common/rendering/vulkan/textures/vk_samplers.cpp +++ b/src/common/rendering/vulkan/textures/vk_samplers.cpp @@ -143,7 +143,7 @@ void VkSamplerManager::DeleteHWSamplers() for (auto& sampler : mSamplers) { if (sampler) - fb->GetCommands()->FrameDeleteList.Samplers.push_back(std::move(sampler)); + fb->GetCommands()->DrawDeleteList->Add(std::move(sampler)); } } diff --git a/src/common/rendering/vulkan/textures/vk_texture.cpp b/src/common/rendering/vulkan/textures/vk_texture.cpp index 021774369b..b1ddc8659e 100644 --- a/src/common/rendering/vulkan/textures/vk_texture.cpp +++ b/src/common/rendering/vulkan/textures/vk_texture.cpp @@ -23,6 +23,8 @@ #include "vk_texture.h" #include "vk_hwtexture.h" #include "vk_pptexture.h" +#include "vk_renderbuffers.h" +#include "vulkan/renderer/vk_postprocess.h" VkTextureManager::VkTextureManager(VulkanFrameBuffer* fb) : fb(fb) { @@ -59,3 +61,61 @@ void VkTextureManager::RemovePPTexture(VkPPTexture* texture) texture->fb = nullptr; PPTextures.erase(texture->it); } + +VkTextureImage* VkTextureManager::GetTexture(const PPTextureType& type, PPTexture* pptexture) +{ + if (type == PPTextureType::CurrentPipelineTexture || type == PPTextureType::NextPipelineTexture) + { + int idx = fb->GetPostprocess()->GetCurrentPipelineImage(); + if (type == PPTextureType::NextPipelineTexture) + idx = (idx + 1) % VkRenderBuffers::NumPipelineImages; + + return &fb->GetBuffers()->PipelineImage[idx]; + } + else if (type == PPTextureType::PPTexture) + { + auto vktex = GetVkTexture(pptexture); + return &vktex->TexImage; + } + else if (type == PPTextureType::SceneColor) + { + return &fb->GetBuffers()->SceneColor; + } + else if (type == PPTextureType::SceneNormal) + { + return &fb->GetBuffers()->SceneNormal; + } + else if (type == PPTextureType::SceneFog) + { + return &fb->GetBuffers()->SceneFog; + } + else if (type == PPTextureType::SceneDepth) + { + return &fb->GetBuffers()->SceneDepthStencil; + } + else if (type == PPTextureType::ShadowMap) + { + return &fb->GetBuffers()->Shadowmap; + } + else if (type == PPTextureType::SwapChain) + { + return nullptr; + } + else + { + I_FatalError("VkPPRenderState::GetTexture not implemented yet for this texture type"); + return nullptr; + } +} + +VkFormat VkTextureManager::GetTextureFormat(PPTexture* texture) +{ + return GetVkTexture(texture)->Format; +} + +VkPPTexture* VkTextureManager::GetVkTexture(PPTexture* texture) +{ + if (!texture->Backend) + texture->Backend = std::make_unique(fb, texture); + return static_cast(texture->Backend.get()); +} diff --git a/src/common/rendering/vulkan/textures/vk_texture.h b/src/common/rendering/vulkan/textures/vk_texture.h index e4abe3c94d..c31c631fbe 100644 --- a/src/common/rendering/vulkan/textures/vk_texture.h +++ b/src/common/rendering/vulkan/textures/vk_texture.h @@ -8,6 +8,9 @@ class VulkanFrameBuffer; class VkHardwareTexture; class VkMaterial; class VkPPTexture; +class VkTextureImage; +enum class PPTextureType; +class PPTexture; class VkTextureManager { @@ -15,6 +18,9 @@ public: VkTextureManager(VulkanFrameBuffer* fb); ~VkTextureManager(); + VkTextureImage* GetTexture(const PPTextureType& type, PPTexture* tex); + VkFormat GetTextureFormat(PPTexture* texture); + void AddTexture(VkHardwareTexture* texture); void RemoveTexture(VkHardwareTexture* texture); @@ -22,6 +28,8 @@ public: void RemovePPTexture(VkPPTexture* texture); private: + VkPPTexture* GetVkTexture(PPTexture* texture); + VulkanFrameBuffer* fb = nullptr; std::list Textures;