mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-10 23:02:08 +00:00
- use one render pass for the entire scene or until postprocess or command buffer flushing forces it to end
This commit is contained in:
parent
7e37d640dc
commit
680a6f348b
4 changed files with 59 additions and 84 deletions
|
@ -200,12 +200,11 @@ std::unique_ptr<VulkanDescriptorSet> VkRenderPassManager::AllocateTextureDescrip
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
VkRenderPassSetup::VkRenderPassSetup(const VkRenderPassKey &key)
|
VkRenderPassSetup::VkRenderPassSetup(const VkRenderPassKey &key) : PassKey(key)
|
||||||
{
|
{
|
||||||
CreateRenderPass(key);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VkRenderPassSetup::CreateRenderPass(const VkRenderPassKey &key)
|
std::unique_ptr<VulkanRenderPass> VkRenderPassSetup::CreateRenderPass(int clearTargets)
|
||||||
{
|
{
|
||||||
auto buffers = GetVulkanFrameBuffer()->GetBuffers();
|
auto buffers = GetVulkanFrameBuffer()->GetBuffers();
|
||||||
|
|
||||||
|
@ -214,31 +213,31 @@ void VkRenderPassSetup::CreateRenderPass(const VkRenderPassKey &key)
|
||||||
RenderPassBuilder builder;
|
RenderPassBuilder builder;
|
||||||
|
|
||||||
builder.addAttachment(
|
builder.addAttachment(
|
||||||
key.DrawBufferFormat, (VkSampleCountFlagBits)key.Samples,
|
PassKey.DrawBufferFormat, (VkSampleCountFlagBits)PassKey.Samples,
|
||||||
(key.ClearTargets & CT_Color) ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
|
(clearTargets & CT_Color) ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
|
||||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||||
|
|
||||||
for (int i = 1; i < key.DrawBuffers; i++)
|
for (int i = 1; i < PassKey.DrawBuffers; i++)
|
||||||
{
|
{
|
||||||
builder.addAttachment(
|
builder.addAttachment(
|
||||||
drawBufferFormats[i], buffers->GetSceneSamples(),
|
drawBufferFormats[i], buffers->GetSceneSamples(),
|
||||||
(key.ClearTargets & CT_Color) ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
|
(clearTargets & CT_Color) ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
|
||||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||||
}
|
}
|
||||||
if (key.UsesDepthStencil())
|
if (PassKey.DepthStencil)
|
||||||
{
|
{
|
||||||
builder.addDepthStencilAttachment(
|
builder.addDepthStencilAttachment(
|
||||||
buffers->SceneDepthStencilFormat, key.DrawBufferFormat == VK_FORMAT_R8G8B8A8_UNORM ? VK_SAMPLE_COUNT_1_BIT : buffers->GetSceneSamples(),
|
buffers->SceneDepthStencilFormat, PassKey.DrawBufferFormat == VK_FORMAT_R8G8B8A8_UNORM ? VK_SAMPLE_COUNT_1_BIT : buffers->GetSceneSamples(),
|
||||||
(key.ClearTargets & CT_Depth) ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
|
(clearTargets & CT_Depth) ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
|
||||||
(key.ClearTargets & CT_Stencil) ? 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);
|
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
|
||||||
}
|
}
|
||||||
builder.addSubpass();
|
builder.addSubpass();
|
||||||
for (int i = 0; i < key.DrawBuffers; i++)
|
for (int i = 0; i < PassKey.DrawBuffers; i++)
|
||||||
builder.addSubpassColorAttachmentRef(i, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
builder.addSubpassColorAttachmentRef(i, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||||
if (key.UsesDepthStencil())
|
if (PassKey.DepthStencil)
|
||||||
{
|
{
|
||||||
builder.addSubpassDepthStencilAttachmentRef(key.DrawBuffers, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
|
builder.addSubpassDepthStencilAttachmentRef(PassKey.DrawBuffers, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
|
||||||
builder.addExternalSubpassDependency(
|
builder.addExternalSubpassDependency(
|
||||||
VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
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_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||||
|
@ -253,8 +252,16 @@ void VkRenderPassSetup::CreateRenderPass(const VkRenderPassKey &key)
|
||||||
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||||
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT);
|
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT);
|
||||||
}
|
}
|
||||||
RenderPass = builder.create(GetVulkanFrameBuffer()->device);
|
auto renderpass = builder.create(GetVulkanFrameBuffer()->device);
|
||||||
RenderPass->SetDebugName("VkRenderPassSetup.RenderPass");
|
renderpass->SetDebugName("VkRenderPassSetup.RenderPass");
|
||||||
|
return renderpass;
|
||||||
|
}
|
||||||
|
|
||||||
|
VulkanRenderPass *VkRenderPassSetup::GetRenderPass(int clearTargets)
|
||||||
|
{
|
||||||
|
if (!RenderPasses[clearTargets])
|
||||||
|
RenderPasses[clearTargets] = CreateRenderPass(clearTargets);
|
||||||
|
return RenderPasses[clearTargets].get();
|
||||||
}
|
}
|
||||||
|
|
||||||
VulkanPipeline *VkRenderPassSetup::GetPipeline(const VkPipelineKey &key)
|
VulkanPipeline *VkRenderPassSetup::GetPipeline(const VkPipelineKey &key)
|
||||||
|
@ -273,11 +280,11 @@ std::unique_ptr<VulkanPipeline> VkRenderPassSetup::CreatePipeline(const VkPipeli
|
||||||
VkShaderProgram *program;
|
VkShaderProgram *program;
|
||||||
if (key.SpecialEffect != EFF_NONE)
|
if (key.SpecialEffect != EFF_NONE)
|
||||||
{
|
{
|
||||||
program = fb->GetShaderManager()->GetEffect(key.SpecialEffect, key.DrawBuffers > 1 ? GBUFFER_PASS : NORMAL_PASS);
|
program = fb->GetShaderManager()->GetEffect(key.SpecialEffect, PassKey.DrawBuffers > 1 ? GBUFFER_PASS : NORMAL_PASS);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
program = fb->GetShaderManager()->Get(key.EffectState, key.AlphaTest, key.DrawBuffers > 1 ? GBUFFER_PASS : NORMAL_PASS);
|
program = fb->GetShaderManager()->Get(key.EffectState, key.AlphaTest, PassKey.DrawBuffers > 1 ? GBUFFER_PASS : NORMAL_PASS);
|
||||||
}
|
}
|
||||||
builder.addVertexShader(program->vert.get());
|
builder.addVertexShader(program->vert.get());
|
||||||
builder.addFragmentShader(program->frag.get());
|
builder.addFragmentShader(program->frag.get());
|
||||||
|
@ -305,7 +312,7 @@ std::unique_ptr<VulkanPipeline> VkRenderPassSetup::CreatePipeline(const VkPipeli
|
||||||
inputLocations[attr.location] = true;
|
inputLocations[attr.location] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// To do: does vulkan absolutely needs a binding for each location or not? What happens if it isn't specified? Better be safe than sorry..
|
// Vulkan requires an attribute binding for each location specified in the shader
|
||||||
for (int i = 0; i < 6; i++)
|
for (int i = 0; i < 6; i++)
|
||||||
{
|
{
|
||||||
if (!inputLocations[i])
|
if (!inputLocations[i])
|
||||||
|
@ -350,11 +357,11 @@ std::unique_ptr<VulkanPipeline> VkRenderPassSetup::CreatePipeline(const VkPipeli
|
||||||
builder.setColorWriteMask((VkColorComponentFlags)key.ColorMask);
|
builder.setColorWriteMask((VkColorComponentFlags)key.ColorMask);
|
||||||
builder.setStencil(VK_STENCIL_OP_KEEP, op2vk[key.StencilPassOp], VK_STENCIL_OP_KEEP, VK_COMPARE_OP_EQUAL, 0xffffffff, 0xffffffff, 0);
|
builder.setStencil(VK_STENCIL_OP_KEEP, op2vk[key.StencilPassOp], VK_STENCIL_OP_KEEP, VK_COMPARE_OP_EQUAL, 0xffffffff, 0xffffffff, 0);
|
||||||
builder.setBlendMode(key.RenderStyle);
|
builder.setBlendMode(key.RenderStyle);
|
||||||
builder.setSubpassColorAttachmentCount(key.DrawBuffers);
|
builder.setSubpassColorAttachmentCount(PassKey.DrawBuffers);
|
||||||
builder.setRasterizationSamples((VkSampleCountFlagBits)key.Samples);
|
builder.setRasterizationSamples((VkSampleCountFlagBits)PassKey.Samples);
|
||||||
|
|
||||||
builder.setLayout(fb->GetRenderPassManager()->GetPipelineLayout(key.NumTextureLayers));
|
builder.setLayout(fb->GetRenderPassManager()->GetPipelineLayout(key.NumTextureLayers));
|
||||||
builder.setRenderPass(RenderPass.get());
|
builder.setRenderPass(GetRenderPass(0));
|
||||||
auto pipeline = builder.create(fb->device);
|
auto pipeline = builder.create(fb->device);
|
||||||
pipeline->SetDebugName("VkRenderPassSetup.Pipeline");
|
pipeline->SetDebugName("VkRenderPassSetup.Pipeline");
|
||||||
return pipeline;
|
return pipeline;
|
||||||
|
|
|
@ -28,13 +28,7 @@ public:
|
||||||
int CullMode;
|
int CullMode;
|
||||||
int VertexFormat;
|
int VertexFormat;
|
||||||
int DrawType;
|
int DrawType;
|
||||||
int Samples;
|
|
||||||
int ClearTargets;
|
|
||||||
int DrawBuffers;
|
|
||||||
int NumTextureLayers;
|
int NumTextureLayers;
|
||||||
VkFormat DrawBufferFormat;
|
|
||||||
|
|
||||||
bool UsesDepthStencil() const { return DepthTest || DepthWrite || StencilTest || (ClearTargets & (CT_Depth | CT_Stencil)); }
|
|
||||||
|
|
||||||
bool operator<(const VkPipelineKey &other) const { return memcmp(this, &other, sizeof(VkPipelineKey)) < 0; }
|
bool operator<(const VkPipelineKey &other) const { return memcmp(this, &other, sizeof(VkPipelineKey)) < 0; }
|
||||||
bool operator==(const VkPipelineKey &other) const { return memcmp(this, &other, sizeof(VkPipelineKey)) == 0; }
|
bool operator==(const VkPipelineKey &other) const { return memcmp(this, &other, sizeof(VkPipelineKey)) == 0; }
|
||||||
|
@ -44,28 +38,11 @@ public:
|
||||||
class VkRenderPassKey
|
class VkRenderPassKey
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
VkRenderPassKey() = default;
|
int DepthStencil;
|
||||||
VkRenderPassKey(const VkPipelineKey &key)
|
|
||||||
{
|
|
||||||
DepthWrite = key.DepthWrite;
|
|
||||||
DepthTest = key.DepthTest;
|
|
||||||
StencilTest = key.StencilTest;
|
|
||||||
Samples = key.Samples;
|
|
||||||
ClearTargets = key.ClearTargets;
|
|
||||||
DrawBuffers = key.DrawBuffers;
|
|
||||||
DrawBufferFormat = key.DrawBufferFormat;
|
|
||||||
}
|
|
||||||
|
|
||||||
int DepthWrite;
|
|
||||||
int DepthTest;
|
|
||||||
int StencilTest;
|
|
||||||
int Samples;
|
int Samples;
|
||||||
int ClearTargets;
|
|
||||||
int DrawBuffers;
|
int DrawBuffers;
|
||||||
VkFormat DrawBufferFormat;
|
VkFormat DrawBufferFormat;
|
||||||
|
|
||||||
bool UsesDepthStencil() const { return DepthTest || DepthWrite || StencilTest || (ClearTargets & (CT_Depth | CT_Stencil)); }
|
|
||||||
|
|
||||||
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; }
|
||||||
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; }
|
||||||
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; }
|
||||||
|
@ -76,14 +53,16 @@ class VkRenderPassSetup
|
||||||
public:
|
public:
|
||||||
VkRenderPassSetup(const VkRenderPassKey &key);
|
VkRenderPassSetup(const VkRenderPassKey &key);
|
||||||
|
|
||||||
|
VulkanRenderPass *GetRenderPass(int clearTargets);
|
||||||
VulkanPipeline *GetPipeline(const VkPipelineKey &key);
|
VulkanPipeline *GetPipeline(const VkPipelineKey &key);
|
||||||
|
|
||||||
std::unique_ptr<VulkanRenderPass> RenderPass;
|
VkRenderPassKey PassKey;
|
||||||
|
std::unique_ptr<VulkanRenderPass> RenderPasses[8];
|
||||||
std::map<VkPipelineKey, std::unique_ptr<VulkanPipeline>> Pipelines;
|
std::map<VkPipelineKey, std::unique_ptr<VulkanPipeline>> Pipelines;
|
||||||
std::map<VkImageView, std::unique_ptr<VulkanFramebuffer>> Framebuffer;
|
std::map<VkImageView, std::unique_ptr<VulkanFramebuffer>> Framebuffer;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void CreateRenderPass(const VkRenderPassKey &key);
|
std::unique_ptr<VulkanRenderPass> CreateRenderPass(int clearTargets);
|
||||||
std::unique_ptr<VulkanPipeline> CreatePipeline(const VkPipelineKey &key);
|
std::unique_ptr<VulkanPipeline> CreatePipeline(const VkPipelineKey &key);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -195,9 +195,8 @@ void VkRenderState::ApplyDepthBias()
|
||||||
|
|
||||||
void VkRenderState::ApplyRenderPass(int dt)
|
void VkRenderState::ApplyRenderPass(int dt)
|
||||||
{
|
{
|
||||||
// Find a render pass that matches our state
|
// Find a pipeline that matches our state
|
||||||
VkPipelineKey pipelineKey;
|
VkPipelineKey pipelineKey;
|
||||||
pipelineKey.ClearTargets = mPipelineKey.ClearTargets | mClearTargets;
|
|
||||||
pipelineKey.DrawType = dt;
|
pipelineKey.DrawType = dt;
|
||||||
pipelineKey.VertexFormat = static_cast<VKVertexBuffer*>(mVertexBuffer)->VertexFormat;
|
pipelineKey.VertexFormat = static_cast<VKVertexBuffer*>(mVertexBuffer)->VertexFormat;
|
||||||
pipelineKey.RenderStyle = mRenderStyle;
|
pipelineKey.RenderStyle = mRenderStyle;
|
||||||
|
@ -210,9 +209,6 @@ void VkRenderState::ApplyRenderPass(int dt)
|
||||||
pipelineKey.StencilPassOp = mStencilOp;
|
pipelineKey.StencilPassOp = mStencilOp;
|
||||||
pipelineKey.ColorMask = mColorMask;
|
pipelineKey.ColorMask = mColorMask;
|
||||||
pipelineKey.CullMode = mCullMode;
|
pipelineKey.CullMode = mCullMode;
|
||||||
pipelineKey.DrawBufferFormat = mRenderTarget.Format;
|
|
||||||
pipelineKey.Samples = mRenderTarget.Samples;
|
|
||||||
pipelineKey.DrawBuffers = mRenderTarget.DrawBuffers;
|
|
||||||
pipelineKey.NumTextureLayers = mMaterial.mMaterial ? mMaterial.mMaterial->GetLayers() : 0;
|
pipelineKey.NumTextureLayers = mMaterial.mMaterial ? mMaterial.mMaterial->GetLayers() : 0;
|
||||||
if (mSpecialEffect > EFF_NONE)
|
if (mSpecialEffect > EFF_NONE)
|
||||||
{
|
{
|
||||||
|
@ -228,44 +224,25 @@ void VkRenderState::ApplyRenderPass(int dt)
|
||||||
pipelineKey.AlphaTest = mAlphaThreshold >= 0.f;
|
pipelineKey.AlphaTest = mAlphaThreshold >= 0.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Is this the one we already have or do we need to change pipeline?
|
// Is this the one we already have?
|
||||||
bool changingPipeline = (pipelineKey != mPipelineKey);
|
|
||||||
bool inRenderPass = mCommandBuffer;
|
bool inRenderPass = mCommandBuffer;
|
||||||
|
bool changingPipeline = (!inRenderPass) || (pipelineKey != mPipelineKey);
|
||||||
|
|
||||||
if (!inRenderPass)
|
if (!inRenderPass)
|
||||||
{
|
{
|
||||||
mCommandBuffer = GetVulkanFrameBuffer()->GetDrawCommands();
|
mCommandBuffer = GetVulkanFrameBuffer()->GetDrawCommands();
|
||||||
changingPipeline = true;
|
|
||||||
mScissorChanged = true;
|
mScissorChanged = true;
|
||||||
mViewportChanged = true;
|
mViewportChanged = true;
|
||||||
mStencilRefChanged = true;
|
mStencilRefChanged = true;
|
||||||
mBias.mChanged = true;
|
mBias.mChanged = true;
|
||||||
|
|
||||||
|
BeginRenderPass(mCommandBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (changingPipeline)
|
if (changingPipeline)
|
||||||
{
|
{
|
||||||
pipelineKey.ClearTargets = mClearTargets;
|
mCommandBuffer->bindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, mPassSetup->GetPipeline(pipelineKey));
|
||||||
|
|
||||||
// Only clear depth+stencil if the render target actually has that
|
|
||||||
if (!mRenderTarget.DepthStencil)
|
|
||||||
pipelineKey.ClearTargets &= ~(CT_Depth | CT_Stencil);
|
|
||||||
|
|
||||||
// Begin new render pass if needed
|
|
||||||
VkRenderPassKey passKey = pipelineKey;
|
|
||||||
if (!inRenderPass || passKey != VkRenderPassKey(mPipelineKey))
|
|
||||||
{
|
|
||||||
if (inRenderPass)
|
|
||||||
mCommandBuffer->endRenderPass();
|
|
||||||
|
|
||||||
BeginRenderPass(passKey, mCommandBuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bind the pipeline
|
|
||||||
VkRenderPassSetup *passSetup = GetVulkanFrameBuffer()->GetRenderPassManager()->GetRenderPass(passKey);
|
|
||||||
mCommandBuffer->bindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, passSetup->GetPipeline(pipelineKey));
|
|
||||||
|
|
||||||
mPipelineKey = pipelineKey;
|
mPipelineKey = pipelineKey;
|
||||||
mClearTargets = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -563,32 +540,42 @@ void VkRenderState::SetRenderTarget(VulkanImageView *view, VulkanImageView *dept
|
||||||
mRenderTarget.Samples = samples;
|
mRenderTarget.Samples = samples;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VkRenderState::BeginRenderPass(const VkRenderPassKey &key, VulkanCommandBuffer *cmdbuffer)
|
void VkRenderState::BeginRenderPass(VulkanCommandBuffer *cmdbuffer)
|
||||||
{
|
{
|
||||||
auto fb = GetVulkanFrameBuffer();
|
auto fb = GetVulkanFrameBuffer();
|
||||||
|
|
||||||
VkRenderPassSetup *passSetup = fb->GetRenderPassManager()->GetRenderPass(key);
|
VkRenderPassKey key = {};
|
||||||
|
key.DrawBufferFormat = mRenderTarget.Format;
|
||||||
|
key.Samples = mRenderTarget.Samples;
|
||||||
|
key.DrawBuffers = mRenderTarget.DrawBuffers;
|
||||||
|
key.DepthStencil = !!mRenderTarget.DepthStencil;
|
||||||
|
|
||||||
auto &framebuffer = passSetup->Framebuffer[mRenderTarget.View->view];
|
mPassSetup = fb->GetRenderPassManager()->GetRenderPass(key);
|
||||||
|
|
||||||
|
auto &framebuffer = mPassSetup->Framebuffer[mRenderTarget.View->view];
|
||||||
if (!framebuffer)
|
if (!framebuffer)
|
||||||
{
|
{
|
||||||
auto buffers = fb->GetBuffers();
|
auto buffers = fb->GetBuffers();
|
||||||
FramebufferBuilder builder;
|
FramebufferBuilder builder;
|
||||||
builder.setRenderPass(passSetup->RenderPass.get());
|
builder.setRenderPass(mPassSetup->GetRenderPass(0));
|
||||||
builder.setSize(mRenderTarget.Width, mRenderTarget.Height);
|
builder.setSize(mRenderTarget.Width, mRenderTarget.Height);
|
||||||
builder.addAttachment(mRenderTarget.View);
|
builder.addAttachment(mRenderTarget.View);
|
||||||
if (key.DrawBuffers > 1)
|
if (key.DrawBuffers > 1)
|
||||||
builder.addAttachment(buffers->SceneFog.View.get());
|
builder.addAttachment(buffers->SceneFog.View.get());
|
||||||
if (key.DrawBuffers > 2)
|
if (key.DrawBuffers > 2)
|
||||||
builder.addAttachment(buffers->SceneNormal.View.get());
|
builder.addAttachment(buffers->SceneNormal.View.get());
|
||||||
if (key.UsesDepthStencil())
|
if (key.DepthStencil)
|
||||||
builder.addAttachment(mRenderTarget.DepthStencil);
|
builder.addAttachment(mRenderTarget.DepthStencil);
|
||||||
framebuffer = builder.create(GetVulkanFrameBuffer()->device);
|
framebuffer = builder.create(GetVulkanFrameBuffer()->device);
|
||||||
framebuffer->SetDebugName("VkRenderPassSetup.Framebuffer");
|
framebuffer->SetDebugName("VkRenderPassSetup.Framebuffer");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Only clear depth+stencil if the render target actually has that
|
||||||
|
if (!mRenderTarget.DepthStencil)
|
||||||
|
mClearTargets &= ~(CT_Depth | CT_Stencil);
|
||||||
|
|
||||||
RenderPassBegin beginInfo;
|
RenderPassBegin beginInfo;
|
||||||
beginInfo.setRenderPass(passSetup->RenderPass.get());
|
beginInfo.setRenderPass(mPassSetup->GetRenderPass(mClearTargets));
|
||||||
beginInfo.setRenderArea(0, 0, mRenderTarget.Width, mRenderTarget.Height);
|
beginInfo.setRenderArea(0, 0, mRenderTarget.Width, mRenderTarget.Height);
|
||||||
beginInfo.setFramebuffer(framebuffer.get());
|
beginInfo.setFramebuffer(framebuffer.get());
|
||||||
beginInfo.addClearColor(screen->mSceneClearColor[0], screen->mSceneClearColor[1], screen->mSceneClearColor[2], screen->mSceneClearColor[3]);
|
beginInfo.addClearColor(screen->mSceneClearColor[0], screen->mSceneClearColor[1], screen->mSceneClearColor[2], screen->mSceneClearColor[3]);
|
||||||
|
@ -600,6 +587,7 @@ void VkRenderState::BeginRenderPass(const VkRenderPassKey &key, VulkanCommandBuf
|
||||||
cmdbuffer->beginRenderPass(beginInfo);
|
cmdbuffer->beginRenderPass(beginInfo);
|
||||||
|
|
||||||
mMaterial.mChanged = true;
|
mMaterial.mChanged = true;
|
||||||
|
mClearTargets = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -62,11 +62,12 @@ protected:
|
||||||
void ApplyVertexBuffers();
|
void ApplyVertexBuffers();
|
||||||
void ApplyMaterial();
|
void ApplyMaterial();
|
||||||
|
|
||||||
void BeginRenderPass(const VkRenderPassKey &key, VulkanCommandBuffer *cmdbuffer);
|
void BeginRenderPass(VulkanCommandBuffer *cmdbuffer);
|
||||||
|
|
||||||
bool mDepthClamp = true;
|
bool mDepthClamp = true;
|
||||||
VulkanCommandBuffer *mCommandBuffer = nullptr;
|
VulkanCommandBuffer *mCommandBuffer = nullptr;
|
||||||
VkPipelineKey mPipelineKey = {};
|
VkPipelineKey mPipelineKey = {};
|
||||||
|
VkRenderPassSetup *mPassSetup = nullptr;
|
||||||
int mClearTargets = 0;
|
int mClearTargets = 0;
|
||||||
bool mNeedApply = true;
|
bool mNeedApply = true;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue