- create a render pass for each blend setup

This commit is contained in:
Magnus Norddahl 2019-03-01 00:42:51 +01:00
parent e472050f36
commit 7f3e473f56
5 changed files with 83 additions and 15 deletions

View file

@ -23,7 +23,7 @@ void VkRenderPassManager::BeginFrame()
{ {
auto fb = GetVulkanFrameBuffer(); auto fb = GetVulkanFrameBuffer();
RenderPassSetup.reset(); RenderPassSetup.clear();
SceneColorView.reset(); SceneColorView.reset();
SceneDepthStencilView.reset(); SceneDepthStencilView.reset();
SceneDepthView.reset(); SceneDepthView.reset();
@ -49,11 +49,17 @@ void VkRenderPassManager::BeginFrame()
viewbuilder.setImage(SceneDepthStencil.get(), VK_FORMAT_D24_UNORM_S8_UINT, VK_IMAGE_ASPECT_DEPTH_BIT); viewbuilder.setImage(SceneDepthStencil.get(), VK_FORMAT_D24_UNORM_S8_UINT, VK_IMAGE_ASPECT_DEPTH_BIT);
SceneDepthView = viewbuilder.create(fb->device); SceneDepthView = viewbuilder.create(fb->device);
RenderPassSetup.reset(new VkRenderPassSetup());
} }
} }
VkRenderPassSetup *VkRenderPassManager::GetRenderPass(const VkRenderPassKey &key)
{
auto &item = RenderPassSetup[key];
if (!item)
item.reset(new VkRenderPassSetup(key));
return item.get();
}
void VkRenderPassManager::CreateDynamicSetLayout() void VkRenderPassManager::CreateDynamicSetLayout()
{ {
DescriptorSetLayoutBuilder builder; DescriptorSetLayoutBuilder builder;
@ -114,24 +120,24 @@ void VkRenderPassManager::CreateDynamicSet()
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
VkRenderPassSetup::VkRenderPassSetup() VkRenderPassSetup::VkRenderPassSetup(const VkRenderPassKey &key)
{ {
CreateRenderPass(); CreateRenderPass();
CreatePipeline(); CreatePipeline(key);
CreateFramebuffer(); CreateFramebuffer();
} }
void VkRenderPassSetup::CreateRenderPass() void VkRenderPassSetup::CreateRenderPass()
{ {
RenderPassBuilder builder; RenderPassBuilder builder;
builder.addRgba16fAttachment(true, VK_IMAGE_LAYOUT_GENERAL); builder.addRgba16fAttachment(false, VK_IMAGE_LAYOUT_GENERAL);
builder.addSubpass(); builder.addSubpass();
builder.addSubpassColorAttachmentRef(0, VK_IMAGE_LAYOUT_GENERAL); builder.addSubpassColorAttachmentRef(0, VK_IMAGE_LAYOUT_GENERAL);
builder.addExternalSubpassDependency(); builder.addExternalSubpassDependency();
RenderPass = builder.create(GetVulkanFrameBuffer()->device); RenderPass = builder.create(GetVulkanFrameBuffer()->device);
} }
void VkRenderPassSetup::CreatePipeline() void VkRenderPassSetup::CreatePipeline(const VkRenderPassKey &key)
{ {
auto fb = GetVulkanFrameBuffer(); auto fb = GetVulkanFrameBuffer();
GraphicsPipelineBuilder builder; GraphicsPipelineBuilder builder;
@ -169,7 +175,35 @@ void VkRenderPassSetup::CreatePipeline()
builder.setViewport(0.0f, 0.0f, (float)SCREENWIDTH, (float)SCREENHEIGHT); builder.setViewport(0.0f, 0.0f, (float)SCREENWIDTH, (float)SCREENHEIGHT);
builder.setScissor(0, 0, SCREENWIDTH, SCREENHEIGHT); builder.setScissor(0, 0, SCREENWIDTH, SCREENHEIGHT);
builder.setAlphaBlendMode();
static const int blendstyles[] = {
VK_BLEND_FACTOR_ZERO,
VK_BLEND_FACTOR_ONE,
VK_BLEND_FACTOR_SRC_ALPHA,
VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
VK_BLEND_FACTOR_SRC_COLOR,
VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR,
VK_BLEND_FACTOR_DST_COLOR,
VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR,
};
static const int renderops[] = {
0, VK_BLEND_OP_ADD, VK_BLEND_OP_SUBTRACT, VK_BLEND_OP_REVERSE_SUBTRACT, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
};
int srcblend = blendstyles[key.RenderStyle.SrcAlpha%STYLEALPHA_MAX];
int dstblend = blendstyles[key.RenderStyle.DestAlpha%STYLEALPHA_MAX];
int blendequation = renderops[key.RenderStyle.BlendOp & 15];
if (blendequation == -1) // This was a fuzz style.
{
srcblend = VK_BLEND_FACTOR_DST_COLOR;
dstblend = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
blendequation = VK_BLEND_OP_ADD;
}
builder.setBlendMode((VkBlendOp)blendequation, (VkBlendFactor)srcblend, (VkBlendFactor)dstblend);
builder.setLayout(fb->GetRenderPassManager()->PipelineLayout.get()); builder.setLayout(fb->GetRenderPassManager()->PipelineLayout.get());
builder.setRenderPass(RenderPass.get()); builder.setRenderPass(RenderPass.get());
Pipeline = builder.create(fb->device); Pipeline = builder.create(fb->device);

View file

@ -2,20 +2,33 @@
#pragma once #pragma once
#include "vulkan/system/vk_objects.h" #include "vulkan/system/vk_objects.h"
#include "r_data/renderstyle.h"
#include <map>
class VKDataBuffer; class VKDataBuffer;
class VkRenderPassKey
{
public:
FRenderStyle RenderStyle;
bool operator<(const VkRenderPassKey &other) const
{
return RenderStyle.AsDWORD < other.RenderStyle.AsDWORD;
}
};
class VkRenderPassSetup class VkRenderPassSetup
{ {
public: public:
VkRenderPassSetup(); VkRenderPassSetup(const VkRenderPassKey &key);
std::unique_ptr<VulkanRenderPass> RenderPass; std::unique_ptr<VulkanRenderPass> RenderPass;
std::unique_ptr<VulkanPipeline> Pipeline; std::unique_ptr<VulkanPipeline> Pipeline;
std::unique_ptr<VulkanFramebuffer> Framebuffer; std::unique_ptr<VulkanFramebuffer> Framebuffer;
private: private:
void CreatePipeline(); void CreatePipeline(const VkRenderPassKey &key);
void CreateRenderPass(); void CreateRenderPass();
void CreateFramebuffer(); void CreateFramebuffer();
}; };
@ -26,12 +39,13 @@ public:
VkRenderPassManager(); VkRenderPassManager();
void BeginFrame(); void BeginFrame();
VkRenderPassSetup *GetRenderPass(const VkRenderPassKey &key);
std::unique_ptr<VulkanDescriptorSetLayout> DynamicSetLayout; std::unique_ptr<VulkanDescriptorSetLayout> DynamicSetLayout;
std::unique_ptr<VulkanDescriptorSetLayout> TextureSetLayout; std::unique_ptr<VulkanDescriptorSetLayout> TextureSetLayout;
std::unique_ptr<VulkanPipelineLayout> PipelineLayout; std::unique_ptr<VulkanPipelineLayout> PipelineLayout;
std::unique_ptr<VulkanDescriptorPool> DescriptorPool; std::unique_ptr<VulkanDescriptorPool> DescriptorPool;
std::unique_ptr<VkRenderPassSetup> RenderPassSetup; std::map<VkRenderPassKey, std::unique_ptr<VkRenderPassSetup>> RenderPassSetup;
std::unique_ptr<VulkanImage> SceneColor; std::unique_ptr<VulkanImage> SceneColor;
std::unique_ptr<VulkanImage> SceneDepthStencil; std::unique_ptr<VulkanImage> SceneDepthStencil;

View file

@ -144,9 +144,14 @@ void VkRenderState::Apply(int dt)
{ {
auto fb = GetVulkanFrameBuffer(); auto fb = GetVulkanFrameBuffer();
auto passManager = fb->GetRenderPassManager(); auto passManager = fb->GetRenderPassManager();
auto passSetup = passManager->RenderPassSetup.get();
bool changingRenderPass = false; // To do: decide if the state matches current bound renderpass // Find a render pass that matches our state
VkRenderPassKey passKey;
passKey.RenderStyle = mRenderStyle;
VkRenderPassSetup *passSetup = passManager->GetRenderPass(passKey);
// Is this the one we already have or do we need to change render pass?
bool changingRenderPass = (passSetup != mRenderPassSetup);
if (!mCommandBuffer) if (!mCommandBuffer)
{ {
@ -166,10 +171,9 @@ void VkRenderState::Apply(int dt)
beginInfo.setRenderPass(passSetup->RenderPass.get()); beginInfo.setRenderPass(passSetup->RenderPass.get());
beginInfo.setRenderArea(0, 0, SCREENWIDTH, SCREENHEIGHT); beginInfo.setRenderArea(0, 0, SCREENWIDTH, SCREENHEIGHT);
beginInfo.setFramebuffer(passSetup->Framebuffer.get()); beginInfo.setFramebuffer(passSetup->Framebuffer.get());
beginInfo.addClearColor(0.0f, 0.0f, 0.0f, 1.0f);
beginInfo.addClearDepthStencil(1.0f, 0);
mCommandBuffer->beginRenderPass(beginInfo); mCommandBuffer->beginRenderPass(beginInfo);
mCommandBuffer->bindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, passSetup->Pipeline.get()); mCommandBuffer->bindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, passSetup->Pipeline.get());
mRenderPassSetup = passSetup;
} }
if (mScissorChanged) if (mScissorChanged)
@ -382,6 +386,7 @@ void VkRenderState::EndRenderPass()
{ {
mCommandBuffer->endRenderPass(); mCommandBuffer->endRenderPass();
mCommandBuffer = nullptr; mCommandBuffer = nullptr;
mRenderPassSetup = nullptr;
// To do: move this elsewhere or rename this function to make it clear this can only happen at the end of a frame // To do: move this elsewhere or rename this function to make it clear this can only happen at the end of a frame
mMatricesOffset = 0; mMatricesOffset = 0;

View file

@ -10,6 +10,8 @@
#include "hwrenderer/scene/hw_renderstate.h" #include "hwrenderer/scene/hw_renderstate.h"
#include "hwrenderer/textures/hw_material.h" #include "hwrenderer/textures/hw_material.h"
class VkRenderPassSetup;
class VkRenderState : public FRenderState class VkRenderState : public FRenderState
{ {
public: public:
@ -47,6 +49,7 @@ private:
bool mLastDepthClamp = true; bool mLastDepthClamp = true;
VulkanCommandBuffer *mCommandBuffer = nullptr; VulkanCommandBuffer *mCommandBuffer = nullptr;
VkRenderPassSetup *mRenderPassSetup = nullptr;
bool mDescriptorsChanged = true; bool mDescriptorsChanged = true;
int mScissorX = 0, mScissorY = 0, mScissorWidth = -1, mScissorHeight = -1; int mScissorX = 0, mScissorY = 0, mScissorWidth = -1, mScissorHeight = -1;

View file

@ -189,6 +189,7 @@ public:
void setAdditiveBlendMode(); void setAdditiveBlendMode();
void setAlphaBlendMode(); void setAlphaBlendMode();
void setBlendMode(VkBlendOp op, VkBlendFactor src, VkBlendFactor dst);
void setSubpassColorAttachmentCount(int count); void setSubpassColorAttachmentCount(int count);
void addVertexShader(VulkanShader *shader); void addVertexShader(VulkanShader *shader);
@ -786,6 +787,17 @@ inline void GraphicsPipelineBuilder::setAlphaBlendMode()
colorBlendAttachment.alphaBlendOp = VK_BLEND_OP_ADD; colorBlendAttachment.alphaBlendOp = VK_BLEND_OP_ADD;
} }
inline void GraphicsPipelineBuilder::setBlendMode(VkBlendOp op, VkBlendFactor src, VkBlendFactor dst)
{
colorBlendAttachment.blendEnable = VK_TRUE;
colorBlendAttachment.srcColorBlendFactor = src;
colorBlendAttachment.dstColorBlendFactor = dst;
colorBlendAttachment.colorBlendOp = op;
colorBlendAttachment.srcAlphaBlendFactor = src;
colorBlendAttachment.dstAlphaBlendFactor = dst;
colorBlendAttachment.alphaBlendOp = op;
}
inline void GraphicsPipelineBuilder::setSubpassColorAttachmentCount(int count) inline void GraphicsPipelineBuilder::setSubpassColorAttachmentCount(int count)
{ {
colorBlendAttachments.resize(count, colorBlendAttachment); colorBlendAttachments.resize(count, colorBlendAttachment);