Split postprocess pipeline creation to its own files

This commit is contained in:
Magnus Norddahl 2023-05-16 23:14:14 +02:00 committed by Christoph Oelckers
parent 17f8027cc9
commit 0bb6b2c298
8 changed files with 193 additions and 152 deletions

View file

@ -750,6 +750,7 @@ set (VULKAN_SOURCES
common/rendering/vulkan/samplers/vk_samplers.cpp
common/rendering/vulkan/descriptorsets/vk_descriptorset.cpp
common/rendering/vulkan/pipelines/vk_renderpass.cpp
common/rendering/vulkan/pipelines/vk_pprenderpass.cpp
common/rendering/vulkan/shaders/vk_shader.cpp
common/rendering/vulkan/shaders/vk_ppshader.cpp
common/rendering/vulkan/textures/vk_hwtexture.cpp

View file

@ -32,6 +32,7 @@
#include "vulkan/buffers/vk_buffer.h"
#include "vulkan/buffers/vk_streambuffer.h"
#include "vulkan/commands/vk_commandbuffer.h"
#include "vulkan/pipelines/vk_pprenderpass.h"
#include <zvulkan/vulkanbuilders.h>
#include "flatvertices.h"
#include "hw_viewpointuniforms.h"

View file

@ -0,0 +1,136 @@
/*
** 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_pprenderpass.h"
#include "vulkan/vk_renderstate.h"
#include "vulkan/vk_renderdevice.h"
#include "vulkan/shaders/vk_ppshader.h"
#include "vulkan/textures/vk_renderbuffers.h"
#include <zvulkan/vulkanbuilders.h>
VkPPRenderPassSetup::VkPPRenderPassSetup(VulkanRenderDevice* fb, const VkPPRenderPassKey& key) : fb(fb)
{
CreateDescriptorLayout(key);
CreatePipelineLayout(key);
CreateRenderPass(key);
CreatePipeline(key);
}
void VkPPRenderPassSetup::CreateDescriptorLayout(const VkPPRenderPassKey& key)
{
DescriptorSetLayoutBuilder builder;
for (int i = 0; i < key.InputTextures; i++)
builder.AddBinding(i, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
if (key.ShadowMapBuffers)
{
builder.AddBinding(4, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
builder.AddBinding(5, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
builder.AddBinding(6, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
}
builder.DebugName("VkPPRenderPassSetup.DescriptorLayout");
DescriptorLayout = builder.Create(fb->GetDevice());
}
void VkPPRenderPassSetup::CreatePipelineLayout(const VkPPRenderPassKey& key)
{
PipelineLayoutBuilder builder;
builder.AddSetLayout(DescriptorLayout.get());
if (key.Uniforms > 0)
builder.AddPushConstantRange(VK_SHADER_STAGE_FRAGMENT_BIT, 0, key.Uniforms);
builder.DebugName("VkPPRenderPassSetup.PipelineLayout");
PipelineLayout = builder.Create(fb->GetDevice());
}
void VkPPRenderPassSetup::CreatePipeline(const VkPPRenderPassKey& key)
{
GraphicsPipelineBuilder builder;
builder.Cache(fb->GetRenderPassManager()->GetCache());
builder.AddVertexShader(key.Shader->VertexShader.get());
builder.AddFragmentShader(key.Shader->FragmentShader.get());
builder.AddDynamicState(VK_DYNAMIC_STATE_VIEWPORT);
builder.AddDynamicState(VK_DYNAMIC_STATE_SCISSOR);
// Note: the actual values are ignored since we use dynamic viewport+scissor states
builder.Viewport(0.0f, 0.0f, 320.0f, 200.0f);
builder.Scissor(0, 0, 320, 200);
if (key.StencilTest != WhichDepthStencil::None)
{
builder.AddDynamicState(VK_DYNAMIC_STATE_STENCIL_REFERENCE);
builder.DepthStencilEnable(false, false, true);
builder.Stencil(VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_COMPARE_OP_EQUAL, 0xffffffff, 0xffffffff, 0);
}
builder.Topology(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP);
BlendMode(builder, key.BlendMode);
builder.RasterizationSamples(key.Samples);
builder.Layout(PipelineLayout.get());
builder.RenderPass(RenderPass.get());
builder.DebugName("VkPPRenderPassSetup.Pipeline");
Pipeline = builder.Create(fb->GetDevice());
}
void VkPPRenderPassSetup::CreateRenderPass(const VkPPRenderPassKey& key)
{
RenderPassBuilder builder;
if (key.SwapChain)
builder.AddAttachment(key.OutputFormat, key.Samples, VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
else
builder.AddAttachment(key.OutputFormat, key.Samples, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
if (key.StencilTest == WhichDepthStencil::Scene)
{
builder.AddDepthStencilAttachment(
fb->GetBuffers()->SceneDepthStencilFormat, key.Samples,
VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
}
if (key.StencilTest == WhichDepthStencil::Pipeline)
{
builder.AddDepthStencilAttachment(
fb->GetBuffers()->PipelineDepthStencilFormat, 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);
}
builder.AddSubpass();
builder.AddSubpassColorAttachmentRef(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
if (key.StencilTest != WhichDepthStencil::None)
{
builder.AddSubpassDepthStencilAttachmentRef(1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
builder.AddExternalSubpassDependency(
VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_SHADER_READ_BIT);
}
else
{
builder.AddExternalSubpassDependency(
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_SHADER_READ_BIT);
}
builder.DebugName("VkPPRenderPassSetup.RenderPass");
RenderPass = builder.Create(fb->GetDevice());
}

View file

@ -0,0 +1,48 @@
#pragma once
#include "zvulkan/vulkanobjects.h"
#include "hwrenderer/postprocessing/hw_postprocess.h"
#include <string.h>
#include <map>
class VulkanRenderDevice;
class VkPPShader;
enum class WhichDepthStencil;
class VkPPRenderPassKey
{
public:
VkPPShader* Shader;
int Uniforms;
int InputTextures;
PPBlendMode BlendMode;
VkFormat OutputFormat;
int SwapChain;
int ShadowMapBuffers;
WhichDepthStencil StencilTest;
VkSampleCountFlagBits Samples;
bool operator<(const VkPPRenderPassKey& other) const { return memcmp(this, &other, sizeof(VkPPRenderPassKey)) < 0; }
bool operator==(const VkPPRenderPassKey& other) const { return memcmp(this, &other, sizeof(VkPPRenderPassKey)) == 0; }
bool operator!=(const VkPPRenderPassKey& other) const { return memcmp(this, &other, sizeof(VkPPRenderPassKey)) != 0; }
};
class VkPPRenderPassSetup
{
public:
VkPPRenderPassSetup(VulkanRenderDevice* fb, const VkPPRenderPassKey& key);
std::unique_ptr<VulkanDescriptorSetLayout> DescriptorLayout;
std::unique_ptr<VulkanPipelineLayout> PipelineLayout;
std::unique_ptr<VulkanRenderPass> RenderPass;
std::unique_ptr<VulkanPipeline> Pipeline;
private:
void CreateDescriptorLayout(const VkPPRenderPassKey& key);
void CreatePipelineLayout(const VkPPRenderPassKey& key);
void CreatePipeline(const VkPPRenderPassKey& key);
void CreateRenderPass(const VkPPRenderPassKey& key);
VulkanRenderDevice* fb = nullptr;
};

View file

@ -21,6 +21,7 @@
*/
#include "vk_renderpass.h"
#include "vk_pprenderpass.h"
#include "vulkan/vk_renderstate.h"
#include "vulkan/vk_renderdevice.h"
#include "vulkan/accelstructs/vk_raytrace.h"
@ -28,7 +29,6 @@
#include "vulkan/textures/vk_renderbuffers.h"
#include "vulkan/samplers/vk_samplers.h"
#include "vulkan/shaders/vk_shader.h"
#include "vulkan/shaders/vk_ppshader.h"
#include "vulkan/buffers/vk_hwbuffer.h"
#include <zvulkan/vulkanbuilders.h>
#include "flatvertices.h"
@ -326,116 +326,6 @@ std::unique_ptr<VulkanPipeline> VkRenderPassSetup::CreatePipeline(const VkPipeli
/////////////////////////////////////////////////////////////////////////////
VkPPRenderPassSetup::VkPPRenderPassSetup(VulkanRenderDevice* fb, const VkPPRenderPassKey& key) : fb(fb)
{
CreateDescriptorLayout(key);
CreatePipelineLayout(key);
CreateRenderPass(key);
CreatePipeline(key);
}
void VkPPRenderPassSetup::CreateDescriptorLayout(const VkPPRenderPassKey& key)
{
DescriptorSetLayoutBuilder builder;
for (int i = 0; i < key.InputTextures; i++)
builder.AddBinding(i, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
if (key.ShadowMapBuffers)
{
builder.AddBinding(4, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
builder.AddBinding(5, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
builder.AddBinding(6, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
}
builder.DebugName("VkPPRenderPassSetup.DescriptorLayout");
DescriptorLayout = builder.Create(fb->GetDevice());
}
void VkPPRenderPassSetup::CreatePipelineLayout(const VkPPRenderPassKey& key)
{
PipelineLayoutBuilder builder;
builder.AddSetLayout(DescriptorLayout.get());
if (key.Uniforms > 0)
builder.AddPushConstantRange(VK_SHADER_STAGE_FRAGMENT_BIT, 0, key.Uniforms);
builder.DebugName("VkPPRenderPassSetup.PipelineLayout");
PipelineLayout = builder.Create(fb->GetDevice());
}
void VkPPRenderPassSetup::CreatePipeline(const VkPPRenderPassKey& key)
{
GraphicsPipelineBuilder builder;
builder.Cache(fb->GetRenderPassManager()->GetCache());
builder.AddVertexShader(key.Shader->VertexShader.get());
builder.AddFragmentShader(key.Shader->FragmentShader.get());
builder.AddDynamicState(VK_DYNAMIC_STATE_VIEWPORT);
builder.AddDynamicState(VK_DYNAMIC_STATE_SCISSOR);
// Note: the actual values are ignored since we use dynamic viewport+scissor states
builder.Viewport(0.0f, 0.0f, 320.0f, 200.0f);
builder.Scissor(0, 0, 320, 200);
if (key.StencilTest != WhichDepthStencil::None)
{
builder.AddDynamicState(VK_DYNAMIC_STATE_STENCIL_REFERENCE);
builder.DepthStencilEnable(false, false, true);
builder.Stencil(VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_COMPARE_OP_EQUAL, 0xffffffff, 0xffffffff, 0);
}
builder.Topology(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP);
BlendMode(builder, key.BlendMode);
builder.RasterizationSamples(key.Samples);
builder.Layout(PipelineLayout.get());
builder.RenderPass(RenderPass.get());
builder.DebugName("VkPPRenderPassSetup.Pipeline");
Pipeline = builder.Create(fb->GetDevice());
}
void VkPPRenderPassSetup::CreateRenderPass(const VkPPRenderPassKey& key)
{
RenderPassBuilder builder;
if (key.SwapChain)
builder.AddAttachment(key.OutputFormat, key.Samples, VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
else
builder.AddAttachment(key.OutputFormat, key.Samples, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
if (key.StencilTest == WhichDepthStencil::Scene)
{
builder.AddDepthStencilAttachment(
fb->GetBuffers()->SceneDepthStencilFormat, key.Samples,
VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
}
if (key.StencilTest == WhichDepthStencil::Pipeline)
{
builder.AddDepthStencilAttachment(
fb->GetBuffers()->PipelineDepthStencilFormat, 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);
}
builder.AddSubpass();
builder.AddSubpassColorAttachmentRef(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
if (key.StencilTest != WhichDepthStencil::None)
{
builder.AddSubpassDepthStencilAttachmentRef(1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
builder.AddExternalSubpassDependency(
VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_SHADER_READ_BIT);
}
else
{
builder.AddExternalSubpassDependency(
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_SHADER_READ_BIT);
}
builder.DebugName("VkPPRenderPassSetup.RenderPass");
RenderPass = builder.Create(fb->GetDevice());
}
/////////////////////////////////////////////////////////////////////////////
GraphicsPipelineBuilder& BlendMode(GraphicsPipelineBuilder& builder, const FRenderStyle& style)
{
// Just in case Vulkan doesn't do this optimization itself

View file

@ -11,8 +11,10 @@
#include <map>
class VulkanRenderDevice;
class VkPPShader;
class GraphicsPipelineBuilder;
class VkPPShader;
class VkPPRenderPassKey;
class VkPPRenderPassSetup;
class VkPipelineKey
{
@ -94,45 +96,6 @@ public:
int UseVertexData;
};
enum class WhichDepthStencil;
class VkPPRenderPassKey
{
public:
VkPPShader* Shader;
int Uniforms;
int InputTextures;
PPBlendMode BlendMode;
VkFormat OutputFormat;
int SwapChain;
int ShadowMapBuffers;
WhichDepthStencil StencilTest;
VkSampleCountFlagBits Samples;
bool operator<(const VkPPRenderPassKey& other) const { return memcmp(this, &other, sizeof(VkPPRenderPassKey)) < 0; }
bool operator==(const VkPPRenderPassKey& other) const { return memcmp(this, &other, sizeof(VkPPRenderPassKey)) == 0; }
bool operator!=(const VkPPRenderPassKey& other) const { return memcmp(this, &other, sizeof(VkPPRenderPassKey)) != 0; }
};
class VkPPRenderPassSetup
{
public:
VkPPRenderPassSetup(VulkanRenderDevice* fb, const VkPPRenderPassKey& key);
std::unique_ptr<VulkanDescriptorSetLayout> DescriptorLayout;
std::unique_ptr<VulkanPipelineLayout> PipelineLayout;
std::unique_ptr<VulkanRenderPass> RenderPass;
std::unique_ptr<VulkanPipeline> Pipeline;
private:
void CreateDescriptorLayout(const VkPPRenderPassKey& key);
void CreatePipelineLayout(const VkPPRenderPassKey& key);
void CreatePipeline(const VkPPRenderPassKey& key);
void CreateRenderPass(const VkPPRenderPassKey& key);
VulkanRenderDevice* fb = nullptr;
};
GraphicsPipelineBuilder& BlendMode(GraphicsPipelineBuilder& builder, const FRenderStyle& style);
class VkRenderPassManager

View file

@ -27,6 +27,7 @@
#include "vulkan/framebuffers/vk_framebuffer.h"
#include "vulkan/shaders/vk_shader.h"
#include "vulkan/commands/vk_commandbuffer.h"
#include "vulkan/pipelines/vk_pprenderpass.h"
#include <zvulkan/vulkanswapchain.h>
#include <zvulkan/vulkanbuilders.h>
#include "hw_cvars.h"

View file

@ -29,10 +29,11 @@
#include "vulkan/shaders/vk_ppshader.h"
#include "vulkan/textures/vk_pptexture.h"
#include "vulkan/textures/vk_renderbuffers.h"
#include "vulkan/samplers/vk_samplers.h"
#include "vulkan/textures/vk_texture.h"
#include "vulkan/samplers/vk_samplers.h"
#include "vulkan/framebuffers/vk_framebuffer.h"
#include "vulkan/descriptorsets/vk_descriptorset.h"
#include "vulkan/pipelines/vk_pprenderpass.h"
#include <zvulkan/vulkanswapchain.h>
#include "flatvertices.h"