diff options
| author | iwubcode <iwubcode@users.noreply.github.com> | 2017-05-29 17:02:09 -0500 |
|---|---|---|
| committer | iwubcode <iwubcode@users.noreply.github.com> | 2017-11-17 19:47:56 -0600 |
| commit | 79387dddb24ddf035b70cd9379a42368dcd49e93 (patch) | |
| tree | 7b783c46e1ffd052842f11112f58c61993f0af1b /Source/Core/VideoBackends/Vulkan | |
| parent | 84ca9a4aec0048e5ac01caea8f8be9210eb947f6 (diff) | |
Add support for hybrid XFB
Diffstat (limited to 'Source/Core/VideoBackends/Vulkan')
5 files changed, 21 insertions, 59 deletions
diff --git a/Source/Core/VideoBackends/Vulkan/FramebufferManager.cpp b/Source/Core/VideoBackends/Vulkan/FramebufferManager.cpp index 53351e0325..c23c19b544 100644 --- a/Source/Core/VideoBackends/Vulkan/FramebufferManager.cpp +++ b/Source/Core/VideoBackends/Vulkan/FramebufferManager.cpp @@ -89,11 +89,6 @@ MultisamplingState FramebufferManager::GetEFBMultisamplingState() const return ms; } -std::pair<u32, u32> FramebufferManager::GetTargetSize() const -{ - return std::make_pair(GetEFBWidth(), GetEFBHeight()); -} - bool FramebufferManager::Initialize() { if (!CreateEFBRenderPass()) @@ -1450,15 +1445,6 @@ VKTexture* XFBSource::GetTexture() const return static_cast<VKTexture*>(m_texture.get()); } -void XFBSource::DecodeToTexture(u32 xfb_addr, u32 fb_width, u32 fb_height) -{ - // Guest memory -> GPU EFB Textures - const u8* src_ptr = Memory::GetPointer(xfb_addr); - _assert_(src_ptr); - TextureCache::GetInstance()->GetTextureConverter()->DecodeYUYVTextureFromMemory( - static_cast<VKTexture*>(m_texture.get()), src_ptr, fb_width, fb_width * 2, fb_height); -} - void XFBSource::CopyEFB(float gamma) { // Pending/batched EFB pokes should be included in the copied image. diff --git a/Source/Core/VideoBackends/Vulkan/FramebufferManager.h b/Source/Core/VideoBackends/Vulkan/FramebufferManager.h index ca7065c3bb..3f2a251662 100644 --- a/Source/Core/VideoBackends/Vulkan/FramebufferManager.h +++ b/Source/Core/VideoBackends/Vulkan/FramebufferManager.h @@ -43,7 +43,6 @@ public: u32 GetEFBLayers() const; VkSampleCountFlagBits GetEFBSamples() const; MultisamplingState GetEFBMultisamplingState() const; - std::pair<u32, u32> GetTargetSize() const override; std::unique_ptr<XFBSourceBase> CreateXFBSource(unsigned int target_width, unsigned int target_height, @@ -178,8 +177,6 @@ public: ~XFBSource(); VKTexture* GetTexture() const; - // Guest -> GPU EFB Textures - void DecodeToTexture(u32 xfb_addr, u32 fb_width, u32 fb_height) override; // Used for virtual XFB void CopyEFB(float gamma) override; diff --git a/Source/Core/VideoBackends/Vulkan/Renderer.cpp b/Source/Core/VideoBackends/Vulkan/Renderer.cpp index 3a4907b88c..be442476ad 100644 --- a/Source/Core/VideoBackends/Vulkan/Renderer.cpp +++ b/Source/Core/VideoBackends/Vulkan/Renderer.cpp @@ -41,6 +41,7 @@ #include "VideoCommon/SamplerCommon.h" #include "VideoCommon/TextureCacheBase.h" #include "VideoCommon/VideoBackendBase.h" +#include "VideoCommon/VideoCommon.h" #include "VideoCommon/VideoConfig.h" #include "VideoCommon/XFMemory.h" @@ -485,27 +486,19 @@ void Renderer::ReinterpretPixelData(unsigned int convtype) BindEFBToStateTracker(); } -void Renderer::SwapImpl(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height, - const EFBRectangle& rc, u64 ticks, float gamma) +void Renderer::SwapImpl(AbstractTexture* texture, const EFBRectangle& rc, u64 ticks, float Gamma) { // Pending/batched EFB pokes should be included in the final image. FramebufferManager::GetInstance()->FlushEFBPokes(); // Check that we actually have an image to render in XFB-on modes. - if ((!m_xfb_written && !g_ActiveConfig.RealXFBEnabled()) || !fb_width || !fb_height) + if (!m_xfb_written) { Core::Callback_VideoCopiedToXFB(false); - return; - } - u32 xfb_count = 0; - const XFBSourceBase* const* xfb_sources = - FramebufferManager::GetXFBSource(xfb_addr, fb_stride, fb_height, &xfb_count); - if (g_ActiveConfig.VirtualXFBEnabled() && (!xfb_sources || xfb_count == 0)) - { - Core::Callback_VideoCopiedToXFB(false); - return; } + auto* xfb_texture = static_cast<VKTexture*>(texture); + // End the current render pass. StateTracker::GetInstance()->EndRenderPass(); StateTracker::GetInstance()->OnEndFrame(); @@ -514,14 +507,6 @@ void Renderer::SwapImpl(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height // are determined by guest state. Currently, the only way to catch these is to update every frame. UpdateDrawRectangle(); - // Scale the source rectangle to the internal resolution when XFB is disabled. - TargetRectangle scaled_efb_rect = Renderer::ConvertEFBRectangle(rc); - - // If MSAA is enabled, and we're not using XFB, we need to resolve the EFB framebuffer before - // rendering the final image to the screen, or dumping the frame. This is because we can't resolve - // an image within a render pass, which will have already started by the time it is used. - TransitionBuffersForSwap(scaled_efb_rect, xfb_sources, xfb_count); - // Render the frame dump image if enabled. if (IsFrameDumping()) { @@ -529,8 +514,8 @@ void Renderer::SwapImpl(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height if (!m_frame_dumping_active) StartFrameDumping(); - DrawFrameDump(scaled_efb_rect, xfb_addr, xfb_sources, xfb_count, fb_width, fb_stride, fb_height, - ticks); + /* DrawFrameDump(scaled_efb_rect, xfb_addr, xfb_sources, xfb_count, fb_width, fb_stride, fb_height, + ticks);*/ } else { @@ -547,7 +532,7 @@ void Renderer::SwapImpl(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height // Draw to the screen if we have a swap chain. if (m_swap_chain) { - DrawScreen(scaled_efb_rect, xfb_addr, xfb_sources, xfb_count, fb_width, fb_stride, fb_height); + DrawScreen(xfb_texture); // Submit the current command buffer, signaling rendering finished semaphore when it's done // Because this final command buffer is rendering to the swap chain, we need to wait for @@ -581,15 +566,12 @@ void Renderer::SwapImpl(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height // Handle host window resizes. CheckForSurfaceChange(); - // Handle output size changes from the guest. - // There is a downside to doing this here is that if the game changes its XFB source area, - // the changes will be delayed by one frame. For the moment it has to be done here because - // this can cause a target size change, which would result in a black frame if done earlier. - CheckForTargetResize(fb_width, fb_stride, fb_height); + if (CalculateTargetSize()) + ResizeEFBTextures(); // Update the window size based on the frame that was just rendered. // Due to depending on guest state, we need to call this every frame. - SetWindowSize(static_cast<int>(fb_stride), static_cast<int>(fb_height)); + SetWindowSize(xfb_texture->config.width, xfb_texture->config.height); // Clean up stale textures. TextureCache::GetInstance()->Cleanup(frameCount); @@ -714,9 +696,7 @@ void Renderer::DrawRealXFB(VkRenderPass render_pass, const TargetRectangle& targ } } -void Renderer::DrawScreen(const TargetRectangle& scaled_efb_rect, u32 xfb_addr, - const XFBSourceBase* const* xfb_sources, u32 xfb_count, u32 fb_width, - u32 fb_stride, u32 fb_height) +void Renderer::DrawScreen(VKTexture* xfb_texture) { VkResult res; if (!g_command_buffer_mgr->CheckLastPresentFail()) @@ -767,9 +747,9 @@ void Renderer::DrawScreen(const TargetRectangle& scaled_efb_rect, u32 xfb_addr, vkCmdBeginRenderPass(g_command_buffer_mgr->GetCurrentCommandBuffer(), &info, VK_SUBPASS_CONTENTS_INLINE); - // Draw guest buffers (EFB or XFB) - DrawFrame(m_swap_chain->GetRenderPass(), GetTargetRectangle(), scaled_efb_rect, xfb_addr, - xfb_sources, xfb_count, fb_width, fb_stride, fb_height); + // Draw + TargetRectangle source_rc = xfb_texture->config.Rect(); + BlitScreen(m_swap_chain->GetRenderPass(), GetTargetRectangle(), source_rc, xfb_texture->GetRawTexIdentifier()); // Draw OSD Util::SetViewportAndScissor(g_command_buffer_mgr->GetCurrentCommandBuffer(), 0, 0, @@ -1055,7 +1035,7 @@ void Renderer::DestroyFrameDumpResources() void Renderer::CheckForTargetResize(u32 fb_width, u32 fb_stride, u32 fb_height) { - if (FramebufferManagerBase::LastXfbWidth() == fb_stride && + /*if (FramebufferManagerBase::LastXfbWidth() == fb_stride && FramebufferManagerBase::LastXfbHeight() == fb_height) { return; @@ -1068,7 +1048,7 @@ void Renderer::CheckForTargetResize(u32 fb_width, u32 fb_stride, u32 fb_height) // Changing the XFB source area may alter the target size. if (CalculateTargetSize()) - ResizeEFBTextures(); + ResizeEFBTextures();*/ } void Renderer::CheckForSurfaceChange() diff --git a/Source/Core/VideoBackends/Vulkan/Renderer.h b/Source/Core/VideoBackends/Vulkan/Renderer.h index 5a367f2bcd..b9d746582c 100644 --- a/Source/Core/VideoBackends/Vulkan/Renderer.h +++ b/Source/Core/VideoBackends/Vulkan/Renderer.h @@ -23,6 +23,7 @@ class SwapChain; class StagingTexture2D; class Texture2D; class RasterFont; +class VKTexture; class Renderer : public ::Renderer { @@ -43,8 +44,7 @@ public: void BBoxWrite(int index, u16 value) override; TargetRectangle ConvertEFBRectangle(const EFBRectangle& rc) override; - void SwapImpl(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height, const EFBRectangle& rc, - u64 ticks, float gamma) override; + void SwapImpl(AbstractTexture* texture, const EFBRectangle& rc, u64 ticks, float Gamma) override; void ClearScreen(const EFBRectangle& rc, bool color_enable, bool alpha_enable, bool z_enable, u32 color, u32 z) override; @@ -106,9 +106,7 @@ private: u32 fb_stride, u32 fb_height); // Draw the frame, as well as the OSD to the swap chain. - void DrawScreen(const TargetRectangle& scaled_efb_rect, u32 xfb_addr, - const XFBSourceBase* const* xfb_sources, u32 xfb_count, u32 fb_width, - u32 fb_stride, u32 fb_height); + void DrawScreen(VKTexture* xfb_texture); // Draw the frame only to the screenshot buffer. bool DrawFrameDump(const TargetRectangle& scaled_efb_rect, u32 xfb_addr, diff --git a/Source/Core/VideoBackends/Vulkan/VulkanContext.cpp b/Source/Core/VideoBackends/Vulkan/VulkanContext.cpp index e2f44b73be..3edd507b23 100644 --- a/Source/Core/VideoBackends/Vulkan/VulkanContext.cpp +++ b/Source/Core/VideoBackends/Vulkan/VulkanContext.cpp @@ -246,6 +246,7 @@ void VulkanContext::PopulateBackendInfo(VideoConfig* config) config->backend_info.bSupportsST3CTextures = false; // Dependent on features. config->backend_info.bSupportsBPTCTextures = false; // Dependent on features. config->backend_info.bSupportsReversedDepthRange = false; // No support yet due to driver bugs. + config->backend_info.bSupportsCopyToVram = true; // Assumed support. } void VulkanContext::PopulateBackendInfoAdapters(VideoConfig* config, const GPUList& gpu_list) |
