summaryrefslogtreecommitdiff
path: root/Source/Core/VideoBackends/Vulkan/Renderer.cpp
diff options
context:
space:
mode:
authorStenzek <stenzek@users.noreply.github.com>2018-03-08 00:52:49 +1000
committerGitHub <noreply@github.com>2018-03-08 00:52:49 +1000
commit24a46dc6af007ba5085a0425de7a7937623eb333 (patch)
tree05f61d35ff03d15e07455c458ae2069af455264f /Source/Core/VideoBackends/Vulkan/Renderer.cpp
parentaee977e32a0054e6a32a750c90c941d979db9d5a (diff)
parent4c24a697106471b33973da619a43167c947276aa (diff)
Merge pull request #6315 from stenzek/abstract-framebuffers
Abstract Framebuffers
Diffstat (limited to 'Source/Core/VideoBackends/Vulkan/Renderer.cpp')
-rw-r--r--Source/Core/VideoBackends/Vulkan/Renderer.cpp89
1 files changed, 87 insertions, 2 deletions
diff --git a/Source/Core/VideoBackends/Vulkan/Renderer.cpp b/Source/Core/VideoBackends/Vulkan/Renderer.cpp
index e4a7401c54..588e4b0919 100644
--- a/Source/Core/VideoBackends/Vulkan/Renderer.cpp
+++ b/Source/Core/VideoBackends/Vulkan/Renderer.cpp
@@ -192,6 +192,14 @@ std::unique_ptr<AbstractPipeline> Renderer::CreatePipeline(const AbstractPipelin
return VKPipeline::Create(config);
}
+std::unique_ptr<AbstractFramebuffer>
+Renderer::CreateFramebuffer(const AbstractTexture* color_attachment,
+ const AbstractTexture* depth_attachment)
+{
+ return VKFramebuffer::Create(static_cast<const VKTexture*>(color_attachment),
+ static_cast<const VKTexture*>(depth_attachment));
+}
+
std::tuple<VkBuffer, u32> Renderer::UpdateUtilityUniformBuffer(const void* uniforms,
u32 uniforms_size)
{
@@ -593,8 +601,9 @@ void Renderer::ClearScreen(const EFBRectangle& rc, bool color_enable, bool alpha
// Fastest path: Use a render pass to clear the buffers.
if (use_clear_render_pass)
{
- VkClearValue clear_values[2] = {clear_color_value, clear_depth_value};
- StateTracker::GetInstance()->BeginClearRenderPass(target_vk_rc, clear_values);
+ const std::array<VkClearValue, 2> clear_values = {{clear_color_value, clear_depth_value}};
+ StateTracker::GetInstance()->BeginClearRenderPass(target_vk_rc, clear_values.data(),
+ static_cast<u32>(clear_values.size()));
return;
}
@@ -743,6 +752,7 @@ void Renderer::SwapImpl(AbstractTexture* texture, const EFBRectangle& xfb_region
// Restore the EFB color texture to color attachment ready for rendering the next frame.
FramebufferManager::GetInstance()->GetEFBColorTexture()->TransitionToLayout(
g_command_buffer_mgr->GetCurrentCommandBuffer(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
+ RestoreAPIState();
// Determine what (if anything) has changed in the config.
CheckForConfigChanges();
@@ -792,6 +802,9 @@ void Renderer::DrawScreen(VKTexture* xfb_texture, const EFBRectangle& xfb_region
backbuffer->OverrideImageLayout(VK_IMAGE_LAYOUT_UNDEFINED);
backbuffer->TransitionToLayout(g_command_buffer_mgr->GetCurrentCommandBuffer(),
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
+ m_current_framebuffer = nullptr;
+ m_current_framebuffer_width = backbuffer->GetWidth();
+ m_current_framebuffer_height = backbuffer->GetHeight();
// Begin render pass for rendering to the swap chain.
VkClearValue clear_value = {{{0.0f, 0.0f, 0.0f, 1.0f}}};
@@ -1010,6 +1023,9 @@ void Renderer::BindEFBToStateTracker()
FramebufferManager::GetInstance()->GetEFBFramebuffer(), framebuffer_size);
StateTracker::GetInstance()->SetMultisamplingstate(
FramebufferManager::GetInstance()->GetEFBMultisamplingState());
+ m_current_framebuffer = nullptr;
+ m_current_framebuffer_width = FramebufferManager::GetInstance()->GetEFBWidth();
+ m_current_framebuffer_height = FramebufferManager::GetInstance()->GetEFBHeight();
}
void Renderer::RecreateEFBFramebuffer()
@@ -1036,10 +1052,79 @@ void Renderer::ResetAPIState()
void Renderer::RestoreAPIState()
{
+ StateTracker::GetInstance()->EndRenderPass();
+ if (m_current_framebuffer)
+ static_cast<const VKFramebuffer*>(m_current_framebuffer)->TransitionForSample();
+
+ BindEFBToStateTracker();
+
// Instruct the state tracker to re-bind everything before the next draw
StateTracker::GetInstance()->SetPendingRebind();
}
+void Renderer::BindFramebuffer(const VKFramebuffer* fb)
+{
+ const VkRect2D render_area = {static_cast<int>(fb->GetWidth()),
+ static_cast<int>(fb->GetHeight())};
+
+ StateTracker::GetInstance()->EndRenderPass();
+ if (m_current_framebuffer)
+ static_cast<const VKFramebuffer*>(m_current_framebuffer)->TransitionForSample();
+
+ fb->TransitionForRender();
+ StateTracker::GetInstance()->SetFramebuffer(fb->GetFB(), render_area);
+ StateTracker::GetInstance()->SetRenderPass(fb->GetLoadRenderPass(), fb->GetClearRenderPass());
+ m_current_framebuffer = fb;
+ m_current_framebuffer_width = fb->GetWidth();
+ m_current_framebuffer_height = fb->GetHeight();
+}
+
+void Renderer::SetFramebuffer(const AbstractFramebuffer* framebuffer)
+{
+ const VKFramebuffer* vkfb = static_cast<const VKFramebuffer*>(framebuffer);
+ BindFramebuffer(vkfb);
+ StateTracker::GetInstance()->BeginRenderPass();
+}
+
+void Renderer::SetAndDiscardFramebuffer(const AbstractFramebuffer* framebuffer)
+{
+ const VKFramebuffer* vkfb = static_cast<const VKFramebuffer*>(framebuffer);
+ BindFramebuffer(vkfb);
+
+ // If we're discarding, begin the discard pass, then switch to a load pass.
+ // This way if the command buffer is flushed, we don't start another discard pass.
+ StateTracker::GetInstance()->SetRenderPass(vkfb->GetDiscardRenderPass(),
+ vkfb->GetClearRenderPass());
+ StateTracker::GetInstance()->BeginRenderPass();
+ StateTracker::GetInstance()->SetRenderPass(vkfb->GetLoadRenderPass(), vkfb->GetClearRenderPass());
+}
+
+void Renderer::SetAndClearFramebuffer(const AbstractFramebuffer* framebuffer,
+ const ClearColor& color_value, float depth_value)
+{
+ const VKFramebuffer* vkfb = static_cast<const VKFramebuffer*>(framebuffer);
+ BindFramebuffer(vkfb);
+
+ const VkRect2D render_area = {static_cast<int>(vkfb->GetWidth()),
+ static_cast<int>(vkfb->GetHeight())};
+ std::array<VkClearValue, 2> clear_values;
+ u32 num_clear_values = 0;
+ if (vkfb->GetColorFormat() != AbstractTextureFormat::Undefined)
+ {
+ std::memcpy(clear_values[num_clear_values].color.float32, color_value.data(),
+ sizeof(clear_values[num_clear_values].color.float32));
+ num_clear_values++;
+ }
+ if (vkfb->GetDepthFormat() != AbstractTextureFormat::Undefined)
+ {
+ clear_values[num_clear_values].depthStencil.depth = depth_value;
+ clear_values[num_clear_values].depthStencil.stencil = 0;
+ num_clear_values++;
+ }
+ StateTracker::GetInstance()->BeginClearRenderPass(render_area, clear_values.data(),
+ num_clear_values);
+}
+
void Renderer::SetRasterizationState(const RasterizationState& state)
{
StateTracker::GetInstance()->SetRasterizationState(state);