mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-23 14:19:46 -06:00
Decouple XFB scanout from presentation
This commit is contained in:
@ -66,19 +66,10 @@ Renderer::Renderer(int backbuffer_width, int backbuffer_height, float backbuffer
|
||||
: ::Renderer(backbuffer_width, backbuffer_height, backbuffer_scale,
|
||||
AbstractTextureFormat::RGBA8)
|
||||
{
|
||||
m_last_multisamples = g_ActiveConfig.iMultisamples;
|
||||
m_last_stereo_mode = g_ActiveConfig.stereo_mode != StereoMode::Off;
|
||||
m_last_fullscreen_state = D3D::GetFullscreenState();
|
||||
g_framebuffer_manager = std::make_unique<FramebufferManager>(m_target_width, m_target_height);
|
||||
SetupDeviceObjects();
|
||||
|
||||
// Clear EFB textures
|
||||
constexpr std::array<float, 4> clear_color{{0.f, 0.f, 0.f, 1.f}};
|
||||
D3D::context->ClearRenderTargetView(FramebufferManager::GetEFBColorTexture()->GetRTV(),
|
||||
clear_color.data());
|
||||
D3D::context->ClearDepthStencilView(FramebufferManager::GetEFBDepthTexture()->GetDSV(),
|
||||
D3D11_CLEAR_DEPTH, 0.f, 0);
|
||||
|
||||
D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, (float)m_target_width, (float)m_target_height);
|
||||
D3D::context->RSSetViewports(1, &vp);
|
||||
FramebufferManager::BindEFBRenderTarget();
|
||||
@ -560,68 +551,33 @@ void Renderer::ReinterpretPixelData(unsigned int convtype)
|
||||
RestoreAPIState();
|
||||
}
|
||||
|
||||
// This function has the final picture. We adjust the aspect ratio here.
|
||||
void Renderer::SwapImpl(AbstractTexture* texture, const EFBRectangle& xfb_region, u64 ticks)
|
||||
void Renderer::BindBackbuffer(const ClearColor& clear_color)
|
||||
{
|
||||
ResetAPIState();
|
||||
|
||||
// Prepare to copy the XFBs to our backbuffer
|
||||
CheckForSurfaceChange();
|
||||
CheckForSurfaceResize();
|
||||
UpdateDrawRectangle();
|
||||
|
||||
TargetRectangle targetRc = GetTargetRectangle();
|
||||
static constexpr std::array<float, 4> clear_color{{0.f, 0.f, 0.f, 1.f}};
|
||||
D3D::context->OMSetRenderTargets(1, &D3D::GetBackBuffer()->GetRTV(), nullptr);
|
||||
D3D::context->ClearRenderTargetView(D3D::GetBackBuffer()->GetRTV(), clear_color.data());
|
||||
m_current_framebuffer = nullptr;
|
||||
m_current_framebuffer_width = m_backbuffer_width;
|
||||
m_current_framebuffer_height = m_backbuffer_height;
|
||||
}
|
||||
|
||||
// activate linear filtering for the buffer copies
|
||||
D3D::SetLinearCopySampler();
|
||||
auto* xfb_texture = static_cast<DXTexture*>(texture);
|
||||
|
||||
BlitScreen(xfb_region, targetRc, xfb_texture->GetRawTexIdentifier(),
|
||||
xfb_texture->GetConfig().width, xfb_texture->GetConfig().height);
|
||||
|
||||
// Reset viewport for drawing text
|
||||
D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.0f, 0.0f, static_cast<float>(m_backbuffer_width),
|
||||
static_cast<float>(m_backbuffer_height));
|
||||
D3D::context->RSSetViewports(1, &vp);
|
||||
DrawImGui();
|
||||
|
||||
g_texture_cache->Cleanup(frameCount);
|
||||
|
||||
// Enable configuration changes
|
||||
UpdateActiveConfig();
|
||||
g_texture_cache->OnConfigChanged(g_ActiveConfig);
|
||||
|
||||
// Flip/present backbuffer to frontbuffer here
|
||||
if (D3D::swapchain)
|
||||
D3D::Present();
|
||||
void Renderer::PresentBackbuffer()
|
||||
{
|
||||
D3D::Present();
|
||||
}
|
||||
|
||||
void Renderer::OnConfigChanged(u32 bits)
|
||||
{
|
||||
// Resize the back buffers NOW to avoid flickering
|
||||
if (CalculateTargetSize() || m_last_multisamples != g_ActiveConfig.iMultisamples ||
|
||||
m_last_stereo_mode != (g_ActiveConfig.stereo_mode != StereoMode::Off))
|
||||
if (bits & (CONFIG_CHANGE_BIT_TARGET_SIZE | CONFIG_CHANGE_BIT_MULTISAMPLES |
|
||||
CONFIG_CHANGE_BIT_STEREO_MODE))
|
||||
{
|
||||
m_last_multisamples = g_ActiveConfig.iMultisamples;
|
||||
m_last_stereo_mode = g_ActiveConfig.stereo_mode != StereoMode::Off;
|
||||
PixelShaderCache::InvalidateMSAAShaders();
|
||||
UpdateDrawRectangle();
|
||||
|
||||
g_framebuffer_manager.reset();
|
||||
g_framebuffer_manager = std::make_unique<FramebufferManager>(m_target_width, m_target_height);
|
||||
D3D::context->ClearRenderTargetView(FramebufferManager::GetEFBColorTexture()->GetRTV(),
|
||||
clear_color.data());
|
||||
D3D::context->ClearDepthStencilView(FramebufferManager::GetEFBDepthTexture()->GetDSV(),
|
||||
D3D11_CLEAR_DEPTH, 0.f, 0);
|
||||
}
|
||||
|
||||
CheckForHostConfigChanges();
|
||||
|
||||
// begin next frame
|
||||
RestoreAPIState();
|
||||
}
|
||||
|
||||
void Renderer::CheckForSurfaceChange()
|
||||
@ -780,28 +736,34 @@ void Renderer::BBoxWrite(int index, u16 _value)
|
||||
BBox::Set(index, value);
|
||||
}
|
||||
|
||||
void Renderer::BlitScreen(TargetRectangle src, TargetRectangle dst, D3DTexture2D* src_texture,
|
||||
u32 src_width, u32 src_height)
|
||||
void Renderer::RenderXFBToScreen(const AbstractTexture* texture, const EFBRectangle& rc)
|
||||
{
|
||||
const CD3D11_RECT source_rc(rc.left, rc.top, rc.right, rc.bottom);
|
||||
const TargetRectangle target_rc = GetTargetRectangle();
|
||||
|
||||
// activate linear filtering for the buffer copies
|
||||
D3D::SetLinearCopySampler();
|
||||
|
||||
if (g_ActiveConfig.stereo_mode == StereoMode::SBS ||
|
||||
g_ActiveConfig.stereo_mode == StereoMode::TAB)
|
||||
{
|
||||
TargetRectangle leftRc, rightRc;
|
||||
std::tie(leftRc, rightRc) = ConvertStereoRectangle(dst);
|
||||
TargetRectangle left_rc, right_rc;
|
||||
std::tie(left_rc, right_rc) = ConvertStereoRectangle(target_rc);
|
||||
|
||||
D3D11_VIEWPORT leftVp = CD3D11_VIEWPORT((float)leftRc.left, (float)leftRc.top,
|
||||
(float)leftRc.GetWidth(), (float)leftRc.GetHeight());
|
||||
D3D11_VIEWPORT rightVp = CD3D11_VIEWPORT((float)rightRc.left, (float)rightRc.top,
|
||||
(float)rightRc.GetWidth(), (float)rightRc.GetHeight());
|
||||
|
||||
D3D::context->RSSetViewports(1, &leftVp);
|
||||
D3D::drawShadedTexQuad(src_texture->GetSRV(), src.AsRECT(), src_width, src_height,
|
||||
SetViewport(static_cast<float>(left_rc.left), static_cast<float>(left_rc.top),
|
||||
static_cast<float>(left_rc.GetWidth()), static_cast<float>(right_rc.GetHeight()),
|
||||
0.0f, 1.0f);
|
||||
D3D::drawShadedTexQuad(static_cast<const DXTexture*>(texture)->GetRawTexIdentifier()->GetSRV(),
|
||||
&source_rc, texture->GetWidth(), texture->GetHeight(),
|
||||
PixelShaderCache::GetColorCopyProgram(false),
|
||||
VertexShaderCache::GetSimpleVertexShader(),
|
||||
VertexShaderCache::GetSimpleInputLayout(), nullptr, 0);
|
||||
|
||||
D3D::context->RSSetViewports(1, &rightVp);
|
||||
D3D::drawShadedTexQuad(src_texture->GetSRV(), src.AsRECT(), src_width, src_height,
|
||||
SetViewport(static_cast<float>(right_rc.left), static_cast<float>(right_rc.top),
|
||||
static_cast<float>(right_rc.GetWidth()), static_cast<float>(right_rc.GetHeight()),
|
||||
0.0f, 1.0f);
|
||||
D3D::drawShadedTexQuad(static_cast<const DXTexture*>(texture)->GetRawTexIdentifier()->GetSRV(),
|
||||
&source_rc, texture->GetWidth(), texture->GetHeight(),
|
||||
PixelShaderCache::GetColorCopyProgram(false),
|
||||
VertexShaderCache::GetSimpleVertexShader(),
|
||||
VertexShaderCache::GetSimpleInputLayout(), nullptr, 1);
|
||||
@ -811,29 +773,33 @@ void Renderer::BlitScreen(TargetRectangle src, TargetRectangle dst, D3DTexture2D
|
||||
if (!m_3d_vision_texture)
|
||||
Create3DVisionTexture(m_backbuffer_width, m_backbuffer_height);
|
||||
|
||||
D3D11_VIEWPORT leftVp = CD3D11_VIEWPORT((float)dst.left, (float)dst.top, (float)dst.GetWidth(),
|
||||
(float)dst.GetHeight());
|
||||
D3D11_VIEWPORT rightVp = CD3D11_VIEWPORT((float)(dst.left + m_backbuffer_width), (float)dst.top,
|
||||
(float)dst.GetWidth(), (float)dst.GetHeight());
|
||||
const CD3D11_VIEWPORT left_vp(
|
||||
static_cast<float>(target_rc.left), static_cast<float>(target_rc.top),
|
||||
static_cast<float>(target_rc.GetWidth()), static_cast<float>(target_rc.GetHeight()));
|
||||
const CD3D11_VIEWPORT right_vp(
|
||||
static_cast<float>(target_rc.left + m_backbuffer_width), static_cast<float>(target_rc.top),
|
||||
static_cast<float>(target_rc.GetWidth()), static_cast<float>(target_rc.GetHeight()));
|
||||
|
||||
// Render to staging texture which is double the width of the backbuffer
|
||||
D3D::context->OMSetRenderTargets(1, &m_3d_vision_texture->GetRTV(), nullptr);
|
||||
|
||||
D3D::context->RSSetViewports(1, &leftVp);
|
||||
D3D::drawShadedTexQuad(src_texture->GetSRV(), src.AsRECT(), src_width, src_height,
|
||||
D3D::context->RSSetViewports(1, &left_vp);
|
||||
D3D::drawShadedTexQuad(static_cast<const DXTexture*>(texture)->GetRawTexIdentifier()->GetSRV(),
|
||||
&source_rc, texture->GetWidth(), texture->GetHeight(),
|
||||
PixelShaderCache::GetColorCopyProgram(false),
|
||||
VertexShaderCache::GetSimpleVertexShader(),
|
||||
VertexShaderCache::GetSimpleInputLayout(), nullptr, 0);
|
||||
|
||||
D3D::context->RSSetViewports(1, &rightVp);
|
||||
D3D::drawShadedTexQuad(src_texture->GetSRV(), src.AsRECT(), src_width, src_height,
|
||||
D3D::context->RSSetViewports(1, &right_vp);
|
||||
D3D::drawShadedTexQuad(static_cast<const DXTexture*>(texture)->GetRawTexIdentifier()->GetSRV(),
|
||||
&source_rc, texture->GetWidth(), texture->GetHeight(),
|
||||
PixelShaderCache::GetColorCopyProgram(false),
|
||||
VertexShaderCache::GetSimpleVertexShader(),
|
||||
VertexShaderCache::GetSimpleInputLayout(), nullptr, 1);
|
||||
|
||||
// Copy the left eye to the backbuffer, if Nvidia 3D Vision is enabled it should
|
||||
// recognize the signature and automatically include the right eye frame.
|
||||
D3D11_BOX box = CD3D11_BOX(0, 0, 0, m_backbuffer_width, m_backbuffer_height, 1);
|
||||
const CD3D11_BOX box(0, 0, 0, m_backbuffer_width, m_backbuffer_height, 1);
|
||||
D3D::context->CopySubresourceRegion(D3D::GetBackBuffer()->GetTex(), 0, 0, 0, 0,
|
||||
m_3d_vision_texture->GetTex(), 0, &box);
|
||||
|
||||
@ -842,9 +808,9 @@ void Renderer::BlitScreen(TargetRectangle src, TargetRectangle dst, D3DTexture2D
|
||||
}
|
||||
else
|
||||
{
|
||||
D3D11_VIEWPORT vp = CD3D11_VIEWPORT((float)dst.left, (float)dst.top, (float)dst.GetWidth(),
|
||||
(float)dst.GetHeight());
|
||||
D3D::context->RSSetViewports(1, &vp);
|
||||
SetViewport(static_cast<float>(target_rc.left), static_cast<float>(target_rc.top),
|
||||
static_cast<float>(target_rc.GetWidth()), static_cast<float>(target_rc.GetHeight()),
|
||||
0.0f, 1.0f);
|
||||
|
||||
ID3D11PixelShader* pixelShader = (g_Config.stereo_mode == StereoMode::Anaglyph) ?
|
||||
PixelShaderCache::GetAnaglyphProgram() :
|
||||
@ -852,7 +818,8 @@ void Renderer::BlitScreen(TargetRectangle src, TargetRectangle dst, D3DTexture2D
|
||||
ID3D11GeometryShader* geomShader = (g_ActiveConfig.stereo_mode == StereoMode::QuadBuffer) ?
|
||||
GeometryShaderCache::GetCopyGeometryShader() :
|
||||
nullptr;
|
||||
D3D::drawShadedTexQuad(src_texture->GetSRV(), src.AsRECT(), src_width, src_height, pixelShader,
|
||||
D3D::drawShadedTexQuad(static_cast<const DXTexture*>(texture)->GetRawTexIdentifier()->GetSRV(),
|
||||
&source_rc, texture->GetWidth(), texture->GetHeight(), pixelShader,
|
||||
VertexShaderCache::GetSimpleVertexShader(),
|
||||
VertexShaderCache::GetSimpleInputLayout(), geomShader);
|
||||
}
|
||||
|
Reference in New Issue
Block a user