diff --git a/libraries/ZVulkan/src/vulkanbuilders.cpp b/libraries/ZVulkan/src/vulkanbuilders.cpp index 35a2208bb..9e2c70c95 100644 --- a/libraries/ZVulkan/src/vulkanbuilders.cpp +++ b/libraries/ZVulkan/src/vulkanbuilders.cpp @@ -1196,9 +1196,15 @@ std::unique_ptr GraphicsPipelineBuilder::Create(VulkanDevice* de if (!libraries.empty()) { + auto subpass = pipelineInfo.subpass; + auto layout = pipelineInfo.layout; + auto renderpass = pipelineInfo.renderPass; auto flags = pipelineInfo.flags; pipelineInfo = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO }; pipelineInfo.flags = flags; + pipelineInfo.subpass = subpass; + pipelineInfo.layout = layout; + pipelineInfo.renderPass = renderpass; libraryCreate.libraryCount = (uint32_t)libraries.size(); libraryCreate.pLibraries = libraries.data(); } diff --git a/src/common/rendering/vulkan/pipelines/vk_pprenderpass.cpp b/src/common/rendering/vulkan/pipelines/vk_pprenderpass.cpp index f50501558..fd070e429 100644 --- a/src/common/rendering/vulkan/pipelines/vk_pprenderpass.cpp +++ b/src/common/rendering/vulkan/pipelines/vk_pprenderpass.cpp @@ -101,7 +101,7 @@ void VkPPRenderPassSetup::CreateRenderPass(const VkPPRenderPassKey& key) if (key.StencilTest == WhichDepthStencil::Scene) { builder.AddDepthStencilAttachment( - fb->GetBuffers()->SceneDepthStencilFormat, key.Samples, + fb->DepthStencilFormat, key.Samples, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); @@ -109,7 +109,7 @@ void VkPPRenderPassSetup::CreateRenderPass(const VkPPRenderPassKey& key) if (key.StencilTest == WhichDepthStencil::Pipeline) { builder.AddDepthStencilAttachment( - fb->GetBuffers()->PipelineDepthStencilFormat, key.Samples, + fb->DepthStencilFormat, key.Samples, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); diff --git a/src/common/rendering/vulkan/pipelines/vk_renderpass.cpp b/src/common/rendering/vulkan/pipelines/vk_renderpass.cpp index 3d88e86b2..f1e81b91c 100644 --- a/src/common/rendering/vulkan/pipelines/vk_renderpass.cpp +++ b/src/common/rendering/vulkan/pipelines/vk_renderpass.cpp @@ -422,7 +422,7 @@ VkRenderPassSetup::VkRenderPassSetup(VulkanRenderDevice* fb, const VkRenderPassK std::unique_ptr VkRenderPassSetup::CreateRenderPass(int clearTargets) { - VkFormat drawBufferFormats[] = { VK_FORMAT_R16G16B16A16_SFLOAT, VK_FORMAT_R8G8B8A8_UNORM, PassKey.NormalFormat }; + VkFormat drawBufferFormats[] = { VK_FORMAT_R16G16B16A16_SFLOAT, VK_FORMAT_R8G8B8A8_UNORM, fb->NormalFormat }; RenderPassBuilder builder; @@ -441,7 +441,7 @@ std::unique_ptr VkRenderPassSetup::CreateRenderPass(int clearT if (PassKey.DepthStencil) { builder.AddDepthStencilAttachment( - PassKey.DepthStencilFormat, (VkSampleCountFlagBits)PassKey.Samples, + fb->DepthStencilFormat, (VkSampleCountFlagBits)PassKey.Samples, (clearTargets & CT_Depth) ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, (clearTargets & CT_Stencil) ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); @@ -774,6 +774,8 @@ std::unique_ptr VkRenderPassSetup::LinkPipeline(const VkPipeline GraphicsPipelineBuilder builder; builder.Cache(fb->GetRenderPassManager()->GetCache()); + builder.Layout(fb->GetRenderPassManager()->GetPipelineLayout(key.ShaderKey.Layout.UseLevelMesh, program->Uniforms.sz)); + builder.RenderPass(GetRenderPass(0)); builder.AddLibrary(GetVertexInputLibrary(key.ShaderKey.VertexFormat, key.DrawType, key.ShaderKey.Layout.UseLevelMesh, program->Uniforms.sz)); builder.AddLibrary(GetVertexShaderLibrary(key, isUberShader)); builder.AddLibrary(GetFragmentShaderLibrary(key, isUberShader)); diff --git a/src/common/rendering/vulkan/pipelines/vk_renderpass.h b/src/common/rendering/vulkan/pipelines/vk_renderpass.h index 7f5db464a..1a692fc78 100644 --- a/src/common/rendering/vulkan/pipelines/vk_renderpass.h +++ b/src/common/rendering/vulkan/pipelines/vk_renderpass.h @@ -68,8 +68,6 @@ public: int Samples = 0; int DrawBuffers = 0; VkFormat DrawBufferFormat = VK_FORMAT_UNDEFINED; - VkFormat NormalFormat = VK_FORMAT_UNDEFINED; - VkFormat DepthStencilFormat = VK_FORMAT_UNDEFINED; bool operator<(const VkRenderPassKey &other) const { return memcmp(this, &other, sizeof(VkRenderPassKey)) < 0; } bool operator==(const VkRenderPassKey &other) const { return memcmp(this, &other, sizeof(VkRenderPassKey)) == 0; } diff --git a/src/common/rendering/vulkan/textures/vk_hwtexture.cpp b/src/common/rendering/vulkan/textures/vk_hwtexture.cpp index 40b251129..6a211278d 100644 --- a/src/common/rendering/vulkan/textures/vk_hwtexture.cpp +++ b/src/common/rendering/vulkan/textures/vk_hwtexture.cpp @@ -79,7 +79,7 @@ VkTextureImage *VkHardwareTexture::GetDepthStencil(FTexture *tex) { if (!mDepthStencil.View) { - VkFormat format = fb->GetBuffers()->SceneDepthStencilFormat; + VkFormat format = fb->DepthStencilFormat; int w = tex->GetWidth(); int h = tex->GetHeight(); diff --git a/src/common/rendering/vulkan/textures/vk_renderbuffers.cpp b/src/common/rendering/vulkan/textures/vk_renderbuffers.cpp index e9315382d..1a4a24995 100644 --- a/src/common/rendering/vulkan/textures/vk_renderbuffers.cpp +++ b/src/common/rendering/vulkan/textures/vk_renderbuffers.cpp @@ -141,31 +141,22 @@ VulkanFramebuffer* VkRenderBuffers::GetZMinMaxFramebuffer(int index) void VkRenderBuffers::CreatePipelineDepthStencil(int width, int height) { - ImageBuilder builder; - builder.Size(width, height); - builder.Format(PipelineDepthStencilFormat); - builder.Usage(VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT); - if (!builder.IsFormatSupported(fb->GetDevice())) - { - PipelineDepthStencilFormat = VK_FORMAT_D32_SFLOAT_S8_UINT; - builder.Format(PipelineDepthStencilFormat); - if (!builder.IsFormatSupported(fb->GetDevice())) - { - I_FatalError("This device does not support any of the required depth stencil image formats."); - } - } - builder.DebugName("VkRenderBuffers.PipelineDepthStencil"); + PipelineDepthStencil.Image = ImageBuilder() + .Size(width, height) + .Format(fb->DepthStencilFormat) + .Usage(VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT) + .DebugName("VkRenderBuffers.PipelineDepthStencil") + .Create(fb->GetDevice()); - PipelineDepthStencil.Image = builder.Create(fb->GetDevice()); PipelineDepthStencil.AspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; PipelineDepthStencil.View = ImageViewBuilder() - .Image(PipelineDepthStencil.Image.get(), PipelineDepthStencilFormat, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT) + .Image(PipelineDepthStencil.Image.get(), fb->DepthStencilFormat, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT) .DebugName("VkRenderBuffers.PipelineDepthStencilView") .Create(fb->GetDevice()); PipelineDepthStencil.DepthOnlyView = ImageViewBuilder() - .Image(PipelineDepthStencil.Image.get(), PipelineDepthStencilFormat, VK_IMAGE_ASPECT_DEPTH_BIT) + .Image(PipelineDepthStencil.Image.get(), fb->DepthStencilFormat, VK_IMAGE_ASPECT_DEPTH_BIT) .DebugName("VkRenderBuffers.PipelineDepthView") .Create(fb->GetDevice()); } @@ -239,32 +230,23 @@ void VkRenderBuffers::CreateSceneColor(int width, int height, VkSampleCountFlagB void VkRenderBuffers::CreateSceneDepthStencil(int width, int height, VkSampleCountFlagBits samples) { - ImageBuilder builder; - builder.Size(width, height); - builder.Samples(samples); - builder.Format(SceneDepthStencilFormat); - builder.Usage(VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT); - if (!builder.IsFormatSupported(fb->GetDevice())) - { - SceneDepthStencilFormat = VK_FORMAT_D32_SFLOAT_S8_UINT; - builder.Format(SceneDepthStencilFormat); - if (!builder.IsFormatSupported(fb->GetDevice())) - { - I_FatalError("This device does not support any of the required depth stencil image formats."); - } - } - builder.DebugName("VkRenderBuffers.SceneDepthStencil"); + SceneDepthStencil.Image = ImageBuilder() + .Size(width, height) + .Samples(samples) + .Format(fb->DepthStencilFormat) + .Usage(VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT) + .DebugName("VkRenderBuffers.SceneDepthStencil") + .Create(fb->GetDevice()); - SceneDepthStencil.Image = builder.Create(fb->GetDevice()); SceneDepthStencil.AspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; SceneDepthStencil.View = ImageViewBuilder() - .Image(SceneDepthStencil.Image.get(), SceneDepthStencilFormat, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT) + .Image(SceneDepthStencil.Image.get(), fb->DepthStencilFormat, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT) .DebugName("VkRenderBuffers.SceneDepthStencilView") .Create(fb->GetDevice()); SceneDepthStencil.DepthOnlyView = ImageViewBuilder() - .Image(SceneDepthStencil.Image.get(), SceneDepthStencilFormat, VK_IMAGE_ASPECT_DEPTH_BIT) + .Image(SceneDepthStencil.Image.get(), fb->DepthStencilFormat, VK_IMAGE_ASPECT_DEPTH_BIT) .DebugName("VkRenderBuffers.SceneDepthView") .Create(fb->GetDevice()); } @@ -341,22 +323,16 @@ void VkRenderBuffers::CreateSceneLightTiles(int width, int height) void VkRenderBuffers::CreateSceneNormal(int width, int height, VkSampleCountFlagBits samples) { - ImageBuilder builder; - builder.Size(width, height); - builder.Samples(samples); - builder.Format(SceneNormalFormat); - builder.Usage(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT); - if (!builder.IsFormatSupported(fb->GetDevice(), VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) - { - SceneNormalFormat = VK_FORMAT_R8G8B8A8_UNORM; - builder.Format(SceneNormalFormat); - } - builder.DebugName("VkRenderBuffers.SceneNormal"); - - SceneNormal.Image = builder.Create(fb->GetDevice()); + SceneNormal.Image = ImageBuilder() + .Size(width, height) + .Samples(samples) + .Format(fb->NormalFormat) + .Usage(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT) + .DebugName("VkRenderBuffers.SceneNormal") + .Create(fb->GetDevice()); SceneNormal.View = ImageViewBuilder() - .Image(SceneNormal.Image.get(), SceneNormalFormat) + .Image(SceneNormal.Image.get(), fb->NormalFormat) .DebugName("VkRenderBuffers.SceneNormalView") .Create(fb->GetDevice()); } diff --git a/src/common/rendering/vulkan/textures/vk_renderbuffers.h b/src/common/rendering/vulkan/textures/vk_renderbuffers.h index 16ce615b2..659a2b82b 100644 --- a/src/common/rendering/vulkan/textures/vk_renderbuffers.h +++ b/src/common/rendering/vulkan/textures/vk_renderbuffers.h @@ -40,10 +40,6 @@ public: VkTextureImage SceneZMinMax[6]; std::unique_ptr SceneLightTiles; - VkFormat PipelineDepthStencilFormat = VK_FORMAT_D24_UNORM_S8_UINT; - VkFormat SceneDepthStencilFormat = VK_FORMAT_D24_UNORM_S8_UINT; - VkFormat SceneNormalFormat = VK_FORMAT_A2R10G10B10_UNORM_PACK32; - static const int NumPipelineImages = 2; VkTextureImage PipelineDepthStencil; VkTextureImage PipelineImage[NumPipelineImages]; diff --git a/src/common/rendering/vulkan/vk_lightprober.cpp b/src/common/rendering/vulkan/vk_lightprober.cpp index e9a2be50a..c3c4e8ab9 100644 --- a/src/common/rendering/vulkan/vk_lightprober.cpp +++ b/src/common/rendering/vulkan/vk_lightprober.cpp @@ -114,7 +114,7 @@ void VkLightprober::CreateEnvironmentMap() .DebugName("VkLightprober.environmentMap.cubeview") .Create(fb->GetDevice()); - VkFormat format = fb->GetBuffers()->SceneDepthStencilFormat; + VkFormat format = fb->DepthStencilFormat; environmentMap.zbuffer = ImageBuilder() .Size(environmentMap.textureSize, environmentMap.textureSize) diff --git a/src/common/rendering/vulkan/vk_renderdevice.cpp b/src/common/rendering/vulkan/vk_renderdevice.cpp index 3ae62996c..e6b8f9eb0 100644 --- a/src/common/rendering/vulkan/vk_renderdevice.cpp +++ b/src/common/rendering/vulkan/vk_renderdevice.cpp @@ -199,15 +199,50 @@ VulkanRenderDevice::~VulkanRenderDevice() if (mDescriptorSetManager) mDescriptorSetManager->Deinit(); - mCommands->DeleteFrameObjects(); + if (mCommands) + mCommands->DeleteFrameObjects(); if (mTextureManager) mTextureManager->Deinit(); if (mBufferManager) mBufferManager->Deinit(); if (mShaderManager) mShaderManager->Deinit(); + if (mCommands) + mCommands->DeleteFrameObjects(); +} - mCommands->DeleteFrameObjects(); +bool VulkanRenderDevice::SupportsRenderTargetFormat(VkFormat format) +{ + if (ImageBuilder() + .Size(1024, 1024) + .Format(format) + .Usage(VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT) + .IsFormatSupported(GetDevice())) + return true; + + return ImageBuilder() + .Size(1024, 1024) + .Format(format) + .Samples(VK_SAMPLE_COUNT_4_BIT) + .Usage(VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT) + .IsFormatSupported(GetDevice()); +} + +bool VulkanRenderDevice::SupportsNormalGBufferFormat(VkFormat format) +{ + if (ImageBuilder() + .Size(1024, 1024) + .Format(format) + .Usage(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT) + .IsFormatSupported(GetDevice())) + return true; + + return ImageBuilder() + .Size(1024, 1024) + .Format(format) + .Samples(VK_SAMPLE_COUNT_4_BIT) + .Usage(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT) + .IsFormatSupported(GetDevice()); } void VulkanRenderDevice::InitializeState() @@ -231,6 +266,32 @@ void VulkanRenderDevice::InitializeState() uniformblockalignment = (unsigned int)mDevice->PhysicalDevice.Properties.Properties.limits.minUniformBufferOffsetAlignment; maxuniformblock = std::min(mDevice->PhysicalDevice.Properties.Properties.limits.maxUniformBufferRange, (uint32_t)1024 * 1024); + if (SupportsRenderTargetFormat(VK_FORMAT_D24_UNORM_S8_UINT)) + { + DepthStencilFormat = VK_FORMAT_D24_UNORM_S8_UINT; + } + else if (SupportsRenderTargetFormat(VK_FORMAT_D32_SFLOAT_S8_UINT)) + { + DepthStencilFormat = VK_FORMAT_D32_SFLOAT_S8_UINT; + } + else + { + I_FatalError("This device does not support any of the required depth stencil image formats."); + } + + if (SupportsNormalGBufferFormat(VK_FORMAT_A2R10G10B10_UNORM_PACK32)) + { + NormalFormat = VK_FORMAT_A2R10G10B10_UNORM_PACK32; + } + else if (SupportsNormalGBufferFormat(VK_FORMAT_R8G8B8A8_UNORM)) + { + NormalFormat = VK_FORMAT_R8G8B8A8_UNORM; + } + else + { + I_FatalError("This device does not support any of the required normal buffer image formats."); + } + NullMesh.reset(new LevelMesh()); levelMesh = NullMesh.get(); diff --git a/src/common/rendering/vulkan/vk_renderdevice.h b/src/common/rendering/vulkan/vk_renderdevice.h index 99f5846a5..16757cdf6 100644 --- a/src/common/rendering/vulkan/vk_renderdevice.h +++ b/src/common/rendering/vulkan/vk_renderdevice.h @@ -104,6 +104,9 @@ public: bool IsSurfaceAvailable() { return HasSurface; } + VkFormat DepthStencilFormat = VK_FORMAT_UNDEFINED; + VkFormat NormalFormat = VK_FORMAT_UNDEFINED; + private: void RenderTextureView(FCanvasTexture* tex, std::function renderFunc) override; void RenderEnvironmentMap(std::function renderFunc, TArrayView& irradianceMap, TArrayView& prefilterMap) override; @@ -111,6 +114,9 @@ private: void PrintStartupLog(); void CopyScreenToBuffer(int w, int h, uint8_t *data) override; + bool SupportsRenderTargetFormat(VkFormat format); + bool SupportsNormalGBufferFormat(VkFormat format); + bool HasSurface = false; std::shared_ptr mDevice; diff --git a/src/common/rendering/vulkan/vk_renderstate.cpp b/src/common/rendering/vulkan/vk_renderstate.cpp index 568ca1963..85d479c1c 100644 --- a/src/common/rendering/vulkan/vk_renderstate.cpp +++ b/src/common/rendering/vulkan/vk_renderstate.cpp @@ -826,8 +826,6 @@ void VkRenderState::SetRenderTarget(VkTextureImage *image, VulkanImageView *dept mRenderTarget.Height = height; mRenderTarget.Format = format; mRenderTarget.Samples = samples; - mRenderTarget.NormalFormat = buffers->SceneNormalFormat; - mRenderTarget.DepthStencilFormat = buffers->SceneDepthStencilFormat; } void VkRenderState::BeginRenderPass(VulkanCommandBuffer *cmdbuffer) @@ -837,8 +835,6 @@ void VkRenderState::BeginRenderPass(VulkanCommandBuffer *cmdbuffer) key.Samples = mRenderTarget.Samples; key.DrawBuffers = mRenderTarget.DrawBuffers; key.DepthStencil = !!mRenderTarget.DepthStencil; - key.NormalFormat = mRenderTarget.NormalFormat; - key.DepthStencilFormat = mRenderTarget.DepthStencilFormat; mPassSetup = fb->GetRenderPassManager()->GetRenderPass(key); @@ -895,8 +891,6 @@ void VkRenderState::RaytraceScene(const FVector3& cameraPos, const VSMatrix& vie key.Samples = mRenderTarget.Samples; key.DrawBuffers = mRenderTarget.DrawBuffers; key.DepthStencil = !!mRenderTarget.DepthStencil; - key.NormalFormat = mRenderTarget.NormalFormat; - key.DepthStencilFormat = mRenderTarget.DepthStencilFormat; fb->GetLevelMesh()->RaytraceScene(key, mCommandBuffer, cameraPos, viewToWorld, fovy, aspect); } diff --git a/src/common/rendering/vulkan/vk_renderstate.h b/src/common/rendering/vulkan/vk_renderstate.h index 377bac76b..4bee19175 100644 --- a/src/common/rendering/vulkan/vk_renderstate.h +++ b/src/common/rendering/vulkan/vk_renderstate.h @@ -152,8 +152,6 @@ protected: VkFormat Format = VK_FORMAT_R16G16B16A16_SFLOAT; VkSampleCountFlagBits Samples = VK_SAMPLE_COUNT_1_BIT; int DrawBuffers = 1; - VkFormat NormalFormat = VK_FORMAT_UNDEFINED; - VkFormat DepthStencilFormat = VK_FORMAT_UNDEFINED; } mRenderTarget; TArray mQueryResultsBuffer;