From c0c2743e897f395e280353075974ed216105c159 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Fri, 8 Mar 2019 02:24:54 +0100 Subject: [PATCH] - add multisample support - fix BlurScene - create the gbuffers needed by ssao --- .../vulkan/renderer/vk_postprocess.cpp | 14 ++- .../vulkan/renderer/vk_renderbuffers.cpp | 104 ++++++++++++++++-- .../vulkan/renderer/vk_renderbuffers.h | 16 ++- src/rendering/vulkan/system/vk_builders.h | 6 + 4 files changed, 120 insertions(+), 20 deletions(-) diff --git a/src/rendering/vulkan/renderer/vk_postprocess.cpp b/src/rendering/vulkan/renderer/vk_postprocess.cpp index 1374f7918..e95c6c339 100644 --- a/src/rendering/vulkan/renderer/vk_postprocess.cpp +++ b/src/rendering/vulkan/renderer/vk_postprocess.cpp @@ -78,7 +78,7 @@ void VkPostprocess::BlitSceneToTexture() barrier0.addImage(buffers->PipelineImage[mCurrentPipelineImage].get(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT); barrier0.execute(cmdbuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); - if (buffers->SceneSamples > 1) + if (buffers->GetSceneSamples() != VK_SAMPLE_COUNT_1_BIT) { VkImageResolve resolve = {}; resolve.srcOffset = { 0, 0, 0 }; @@ -193,6 +193,9 @@ void VkPostprocess::AmbientOccludeScene(float m5) void VkPostprocess::BlurScene(float gameinfobluramount) { + auto fb = GetVulkanFrameBuffer(); + hw_postprocess.SceneWidth = fb->GetBuffers()->GetSceneWidth(); + hw_postprocess.SceneHeight = fb->GetBuffers()->GetSceneHeight(); hw_postprocess.gameinfobluramount = gameinfobluramount; hw_postprocess.DeclareShaders(); @@ -223,8 +226,8 @@ void VkPostprocess::BeginFrame() if (!mDescriptorPool) { DescriptorPoolBuilder builder; - builder.addPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 50); - builder.setMaxSets(50); + builder.addPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 100); + builder.setMaxSets(100); mDescriptorPool = builder.create(GetVulkanFrameBuffer()->device); } } @@ -378,7 +381,10 @@ void VkPostprocess::RenderEffect(const FString &name) key.InputTextures = step.Textures.Size(); key.Uniforms = step.Uniforms.Data.Size(); key.Shader = mShaders[step.ShaderName].get(); - key.OutputFormat = (step.Output.Type == PPTextureType::PPTexture) ? mTextures[step.Output.Texture]->Format : VK_FORMAT_R16G16B16A16_SFLOAT; + if (step.Output.Type == PPTextureType::PPTexture) + key.OutputFormat = mTextures[step.Output.Texture]->Format; + else + key.OutputFormat = VK_FORMAT_R16G16B16A16_SFLOAT; auto &passSetup = mRenderPassSetup[key]; if (!passSetup) diff --git a/src/rendering/vulkan/renderer/vk_renderbuffers.cpp b/src/rendering/vulkan/renderer/vk_renderbuffers.cpp index 810040082..21235c617 100644 --- a/src/rendering/vulkan/renderer/vk_renderbuffers.cpp +++ b/src/rendering/vulkan/renderer/vk_renderbuffers.cpp @@ -15,9 +15,32 @@ VkRenderBuffers::~VkRenderBuffers() { } +VkSampleCountFlagBits VkRenderBuffers::GetBestSampleCount() +{ + auto fb = GetVulkanFrameBuffer(); + const auto &limits = fb->device->deviceProperties.limits; + VkSampleCountFlags deviceSampleCounts = limits.sampledImageColorSampleCounts & limits.sampledImageDepthSampleCounts & limits.sampledImageStencilSampleCounts; + + int requestedSamples = clamp((int)gl_multisample, 0, 64); + + int samples = 1; + VkSampleCountFlags bit = VK_SAMPLE_COUNT_1_BIT; + VkSampleCountFlags best = bit; + while (samples < requestedSamples) + { + if (deviceSampleCounts & bit) + { + best = bit; + } + samples <<= 1; + bit <<= 1; + } + return (VkSampleCountFlagBits)best; +} + void VkRenderBuffers::BeginFrame(int width, int height, int sceneWidth, int sceneHeight) { - int samples = clamp((int)gl_multisample, 0, mMaxSamples); + VkSampleCountFlagBits samples = GetBestSampleCount(); if (width != mWidth || height != mHeight || mSamples != samples) { @@ -68,15 +91,38 @@ void VkRenderBuffers::CreatePipeline(int width, int height) barrier.execute(fb->GetDrawCommands(), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT); } -void VkRenderBuffers::CreateScene(int width, int height, int samples) +void VkRenderBuffers::CreateScene(int width, int height, VkSampleCountFlagBits samples) { auto fb = GetVulkanFrameBuffer(); SceneColorView.reset(); SceneDepthStencilView.reset(); SceneDepthView.reset(); + SceneNormalView.reset(); + SceneFogView.reset(); SceneColor.reset(); SceneDepthStencil.reset(); + SceneNormal.reset(); + SceneFog.reset(); + + CreateSceneColor(width, height, samples); + CreateSceneDepthStencil(width, height, samples); + CreateSceneNormal(width, height, samples); + CreateSceneFog(width, height, samples); + + PipelineBarrier barrier; + barrier.addImage(SceneColor.get(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 0, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT); + barrier.addImage(SceneDepthStencil.get(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 0, VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT); + barrier.addImage(SceneNormal.get(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 0, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT); + barrier.addImage(SceneFog.get(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 0, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT); + barrier.execute(fb->GetDrawCommands(), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT); + + SceneColorLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; +} + +void VkRenderBuffers::CreateSceneColor(int width, int height, VkSampleCountFlagBits samples) +{ + auto fb = GetVulkanFrameBuffer(); ImageBuilder builder; builder.setSize(width, height); @@ -84,6 +130,18 @@ void VkRenderBuffers::CreateScene(int width, int height, int samples) builder.setUsage(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT); SceneColor = builder.create(fb->device); + ImageViewBuilder viewbuilder; + viewbuilder.setImage(SceneColor.get(), VK_FORMAT_R16G16B16A16_SFLOAT); + SceneColorView = viewbuilder.create(fb->device); +} + +void VkRenderBuffers::CreateSceneDepthStencil(int width, int height, VkSampleCountFlagBits samples) +{ + auto fb = GetVulkanFrameBuffer(); + + ImageBuilder builder; + builder.setSize(width, height); + builder.setSamples(samples); builder.setFormat(SceneDepthStencilFormat); builder.setUsage(VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT); if (!builder.isFormatSupported(fb->device)) @@ -98,19 +156,41 @@ void VkRenderBuffers::CreateScene(int width, int height, int samples) SceneDepthStencil = builder.create(fb->device); ImageViewBuilder viewbuilder; - viewbuilder.setImage(SceneColor.get(), VK_FORMAT_R16G16B16A16_SFLOAT); - SceneColorView = viewbuilder.create(fb->device); - viewbuilder.setImage(SceneDepthStencil.get(), SceneDepthStencilFormat, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT); SceneDepthStencilView = viewbuilder.create(fb->device); viewbuilder.setImage(SceneDepthStencil.get(), SceneDepthStencilFormat, VK_IMAGE_ASPECT_DEPTH_BIT); SceneDepthView = viewbuilder.create(fb->device); - - PipelineBarrier barrier; - barrier.addImage(SceneColor.get(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 0, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT); - barrier.addImage(SceneDepthStencil.get(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 0, VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT); - barrier.execute(fb->GetDrawCommands(), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT); - - SceneColorLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; +} + +void VkRenderBuffers::CreateSceneFog(int width, int height, VkSampleCountFlagBits samples) +{ + auto fb = GetVulkanFrameBuffer(); + + ImageBuilder builder; + builder.setSize(width, height); + builder.setSamples(samples); + builder.setFormat(VK_FORMAT_R8G8B8A8_UNORM); + builder.setUsage(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT); + SceneFog = builder.create(fb->device); + + ImageViewBuilder viewbuilder; + viewbuilder.setImage(SceneFog.get(), VK_FORMAT_R8G8B8A8_UNORM); + SceneFogView = viewbuilder.create(fb->device); +} + +void VkRenderBuffers::CreateSceneNormal(int width, int height, VkSampleCountFlagBits samples) +{ + auto fb = GetVulkanFrameBuffer(); + + ImageBuilder builder; + builder.setSize(width, height); + builder.setSamples(samples); + builder.setFormat(VK_FORMAT_A2R10G10B10_UNORM_PACK32); + builder.setUsage(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT); + SceneNormal = builder.create(fb->device); + + ImageViewBuilder viewbuilder; + viewbuilder.setImage(SceneNormal.get(), VK_FORMAT_A2R10G10B10_UNORM_PACK32); + SceneNormalView = viewbuilder.create(fb->device); } diff --git a/src/rendering/vulkan/renderer/vk_renderbuffers.h b/src/rendering/vulkan/renderer/vk_renderbuffers.h index 819236d8c..19d602148 100644 --- a/src/rendering/vulkan/renderer/vk_renderbuffers.h +++ b/src/rendering/vulkan/renderer/vk_renderbuffers.h @@ -15,15 +15,19 @@ public: int GetHeight() const { return mHeight; } int GetSceneWidth() const { return mSceneWidth; } int GetSceneHeight() const { return mSceneHeight; } + VkSampleCountFlagBits GetSceneSamples() const { return mSamples; } std::unique_ptr SceneColor; std::unique_ptr SceneDepthStencil; + std::unique_ptr SceneNormal; + std::unique_ptr SceneFog; std::unique_ptr SceneColorView; std::unique_ptr SceneDepthStencilView; std::unique_ptr SceneDepthView; + std::unique_ptr SceneNormalView; + std::unique_ptr SceneFogView; VkFormat SceneDepthStencilFormat = VK_FORMAT_D24_UNORM_S8_UINT; VkImageLayout SceneColorLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - int SceneSamples = 1; static const int NumPipelineImages = 2; std::unique_ptr PipelineImage[NumPipelineImages]; @@ -32,12 +36,16 @@ public: private: void CreatePipeline(int width, int height); - void CreateScene(int width, int height, int samples); + void CreateScene(int width, int height, VkSampleCountFlagBits samples); + void CreateSceneColor(int width, int height, VkSampleCountFlagBits samples); + void CreateSceneDepthStencil(int width, int height, VkSampleCountFlagBits samples); + void CreateSceneFog(int width, int height, VkSampleCountFlagBits samples); + void CreateSceneNormal(int width, int height, VkSampleCountFlagBits samples); + VkSampleCountFlagBits GetBestSampleCount(); int mWidth = 0; int mHeight = 0; int mSceneWidth = 0; int mSceneHeight = 0; - int mSamples = 0; - int mMaxSamples = 16; + VkSampleCountFlagBits mSamples = VK_SAMPLE_COUNT_1_BIT; }; diff --git a/src/rendering/vulkan/system/vk_builders.h b/src/rendering/vulkan/system/vk_builders.h index c3c871fbb..5b9906723 100644 --- a/src/rendering/vulkan/system/vk_builders.h +++ b/src/rendering/vulkan/system/vk_builders.h @@ -39,6 +39,7 @@ public: ImageBuilder(); void setSize(int width, int height, int miplevels = 1); + void setSamples(VkSampleCountFlagBits samples); void setFormat(VkFormat format); void setUsage(VkImageUsageFlags imageUsage, VmaMemoryUsage memoryUsage = VMA_MEMORY_USAGE_GPU_ONLY, VmaAllocationCreateFlags allocFlags = 0); void setLinearTiling(); @@ -344,6 +345,11 @@ inline void ImageBuilder::setSize(int width, int height, int mipLevels) imageInfo.mipLevels = mipLevels; } +inline void ImageBuilder::setSamples(VkSampleCountFlagBits samples) +{ + imageInfo.samples = samples; +} + inline void ImageBuilder::setFormat(VkFormat format) { imageInfo.format = format;