mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-23 06:09:50 -06:00
Merge pull request #4999 from stenzek/renderer-statics
VideoCommon: Eliminate static state in Renderer
This commit is contained in:
@ -136,8 +136,8 @@ void AsyncRequests::HandleEvent(const AsyncRequests::Event& e)
|
||||
break;
|
||||
|
||||
case Event::SWAP_EVENT:
|
||||
Renderer::Swap(e.swap_event.xfbAddr, e.swap_event.fbWidth, e.swap_event.fbStride,
|
||||
e.swap_event.fbHeight, rc, e.time);
|
||||
g_renderer->Swap(e.swap_event.xfbAddr, e.swap_event.fbWidth, e.swap_event.fbStride,
|
||||
e.swap_event.fbHeight, rc, e.time);
|
||||
break;
|
||||
|
||||
case Event::BBOX_READ:
|
||||
|
@ -156,7 +156,7 @@ void OnPixelFormatChange()
|
||||
if (!g_ActiveConfig.bEFBEmulateFormatChanges)
|
||||
return;
|
||||
|
||||
auto old_format = Renderer::GetPrevPixelFormat();
|
||||
auto old_format = g_renderer->GetPrevPixelFormat();
|
||||
auto new_format = bpmem.zcontrol.pixel_format;
|
||||
|
||||
// no need to reinterpret pixel data in these cases
|
||||
@ -209,7 +209,7 @@ skip:
|
||||
DEBUG_LOG(VIDEO, "pixelfmt: pixel=%d, zc=%d", static_cast<int>(new_format),
|
||||
static_cast<int>(bpmem.zcontrol.zformat));
|
||||
|
||||
Renderer::StorePixelFormat(new_format);
|
||||
g_renderer->StorePixelFormat(new_format);
|
||||
}
|
||||
|
||||
void SetInterlacingMode(const BPCmd& bp)
|
||||
|
@ -261,7 +261,7 @@ static void BPWritten(const BPCmd& bp)
|
||||
"fbStride: %u | fbHeight: %u",
|
||||
destAddr, srcRect.left, srcRect.top, srcRect.right, srcRect.bottom,
|
||||
bpmem.copyTexSrcWH.x + 1, destStride, height);
|
||||
Renderer::RenderToXFB(destAddr, srcRect, destStride, height, s_gammaLUT[PE_copy.gamma]);
|
||||
g_renderer->RenderToXFB(destAddr, srcRect, destStride, height, s_gammaLUT[PE_copy.gamma]);
|
||||
}
|
||||
|
||||
// Clear the rectangular region after copying it.
|
||||
|
@ -253,8 +253,8 @@ int FramebufferManagerBase::ScaleToVirtualXfbWidth(int x)
|
||||
if (g_ActiveConfig.RealXFBEnabled())
|
||||
return x;
|
||||
|
||||
return x * (int)Renderer::GetTargetRectangle().GetWidth() /
|
||||
(int)FramebufferManagerBase::LastXfbWidth();
|
||||
return x * static_cast<int>(g_renderer->GetTargetRectangle().GetWidth()) /
|
||||
static_cast<int>(FramebufferManagerBase::LastXfbWidth());
|
||||
}
|
||||
|
||||
int FramebufferManagerBase::ScaleToVirtualXfbHeight(int y)
|
||||
@ -262,6 +262,6 @@ int FramebufferManagerBase::ScaleToVirtualXfbHeight(int y)
|
||||
if (g_ActiveConfig.RealXFBEnabled())
|
||||
return y;
|
||||
|
||||
return y * (int)Renderer::GetTargetRectangle().GetHeight() /
|
||||
(int)FramebufferManagerBase::LastXfbHeight();
|
||||
return y * static_cast<int>(g_renderer->GetTargetRectangle().GetHeight()) /
|
||||
static_cast<int>(FramebufferManagerBase::LastXfbHeight());
|
||||
}
|
||||
|
@ -27,7 +27,6 @@ void PixelShaderManager::Init()
|
||||
s_bFogRangeAdjustChanged = true;
|
||||
s_bViewPortChanged = false;
|
||||
|
||||
SetEfbScaleChanged();
|
||||
SetIndMatrixChanged(0);
|
||||
SetIndMatrixChanged(1);
|
||||
SetIndMatrixChanged(2);
|
||||
@ -50,7 +49,7 @@ void PixelShaderManager::Dirty()
|
||||
// Any constants that can changed based on settings should be re-calculated
|
||||
s_bFogRangeAdjustChanged = true;
|
||||
|
||||
SetEfbScaleChanged();
|
||||
SetEfbScaleChanged(g_renderer->EFBToScaledXf(1), g_renderer->EFBToScaledYf(1));
|
||||
SetFogParamChanged();
|
||||
|
||||
dirty = true;
|
||||
@ -78,7 +77,8 @@ void PixelShaderManager::SetConstants()
|
||||
// so to simplify I use the hi coefficient as K in the shader taking 256 as the scale
|
||||
// TODO: Shouldn't this be EFBToScaledXf?
|
||||
constants.fogf[0][0] = ScreenSpaceCenter;
|
||||
constants.fogf[0][1] = (float)Renderer::EFBToScaledX((int)(2.0f * xfmem.viewport.wd));
|
||||
constants.fogf[0][1] =
|
||||
static_cast<float>(g_renderer->EFBToScaledX(static_cast<int>(2.0f * xfmem.viewport.wd)));
|
||||
constants.fogf[0][2] = bpmem.fogRange.K[4].HI / 256.0f;
|
||||
}
|
||||
else
|
||||
@ -159,10 +159,10 @@ void PixelShaderManager::SetViewportChanged()
|
||||
true; // TODO: Shouldn't be necessary with an accurate fog range adjust implementation
|
||||
}
|
||||
|
||||
void PixelShaderManager::SetEfbScaleChanged()
|
||||
void PixelShaderManager::SetEfbScaleChanged(float scalex, float scaley)
|
||||
{
|
||||
constants.efbscale[0] = 1.0f / Renderer::EFBToScaledXf(1);
|
||||
constants.efbscale[1] = 1.0f / Renderer::EFBToScaledYf(1);
|
||||
constants.efbscale[0] = 1.0f / scalex;
|
||||
constants.efbscale[1] = 1.0f / scaley;
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,7 @@ public:
|
||||
static void SetTexDims(int texmapid, u32 width, u32 height);
|
||||
static void SetZTextureBias();
|
||||
static void SetViewportChanged();
|
||||
static void SetEfbScaleChanged();
|
||||
static void SetEfbScaleChanged(float scalex, float scaley);
|
||||
static void SetZSlope(float dfdx, float dfdy, float f0);
|
||||
static void SetIndMatrixChanged(int matrixidx);
|
||||
static void SetZTextureTypeChanged();
|
||||
|
@ -50,6 +50,7 @@
|
||||
#include "VideoCommon/FramebufferManagerBase.h"
|
||||
#include "VideoCommon/ImageWrite.h"
|
||||
#include "VideoCommon/OnScreenDisplay.h"
|
||||
#include "VideoCommon/PixelShaderManager.h"
|
||||
#include "VideoCommon/PostProcessing.h"
|
||||
#include "VideoCommon/Statistics.h"
|
||||
#include "VideoCommon/TextureCacheBase.h"
|
||||
@ -64,39 +65,6 @@ static int OSDTime;
|
||||
|
||||
std::unique_ptr<Renderer> g_renderer;
|
||||
|
||||
std::mutex Renderer::s_criticalScreenshot;
|
||||
std::string Renderer::s_sScreenshotName;
|
||||
|
||||
Common::Event Renderer::s_screenshotCompleted;
|
||||
Common::Flag Renderer::s_screenshot;
|
||||
|
||||
// The framebuffer size
|
||||
int Renderer::s_target_width;
|
||||
int Renderer::s_target_height;
|
||||
|
||||
// TODO: Add functionality to reinit all the render targets when the window is resized.
|
||||
int Renderer::s_backbuffer_width;
|
||||
int Renderer::s_backbuffer_height;
|
||||
|
||||
std::unique_ptr<PostProcessingShaderImplementation> Renderer::m_post_processor;
|
||||
|
||||
// Final surface changing
|
||||
Common::Flag Renderer::s_surface_needs_change;
|
||||
Common::Event Renderer::s_surface_changed;
|
||||
void* Renderer::s_new_surface_handle;
|
||||
|
||||
TargetRectangle Renderer::target_rc;
|
||||
|
||||
int Renderer::s_last_efb_scale;
|
||||
|
||||
bool Renderer::XFBWrited;
|
||||
|
||||
PEControl::PixelFormat Renderer::prev_efb_format = PEControl::INVALID_FMT;
|
||||
unsigned int Renderer::efb_scale_numeratorX = 1;
|
||||
unsigned int Renderer::efb_scale_numeratorY = 1;
|
||||
unsigned int Renderer::efb_scale_denominatorX = 1;
|
||||
unsigned int Renderer::efb_scale_denominatorY = 1;
|
||||
|
||||
// The maximum depth that is written to the depth buffer should never exceed this value.
|
||||
// This is necessary because we use a 2^24 divisor for all our depth values to prevent
|
||||
// floating-point round-trip errors. However the console GPU doesn't ever write a value
|
||||
@ -108,9 +76,16 @@ static float AspectToWidescreen(float aspect)
|
||||
return aspect * ((16.0f / 9.0f) / (4.0f / 3.0f));
|
||||
}
|
||||
|
||||
Renderer::Renderer()
|
||||
Renderer::Renderer(int backbuffer_width, int backbuffer_height)
|
||||
: m_backbuffer_width(backbuffer_width), m_backbuffer_height(backbuffer_height),
|
||||
m_last_efb_scale(g_ActiveConfig.iEFBScale)
|
||||
{
|
||||
FramebufferManagerBase::SetLastXfbWidth(MAX_XFB_WIDTH);
|
||||
FramebufferManagerBase::SetLastXfbHeight(MAX_XFB_HEIGHT);
|
||||
|
||||
UpdateActiveConfig();
|
||||
CalculateTargetSize();
|
||||
UpdateDrawRectangle();
|
||||
|
||||
OSDChoice = 0;
|
||||
OSDTime = 0;
|
||||
@ -118,11 +93,6 @@ Renderer::Renderer()
|
||||
|
||||
Renderer::~Renderer()
|
||||
{
|
||||
// invalidate previous efb format
|
||||
prev_efb_format = PEControl::INVALID_FMT;
|
||||
|
||||
efb_scale_numeratorX = efb_scale_numeratorY = efb_scale_denominatorX = efb_scale_denominatorY = 1;
|
||||
|
||||
ShutdownFrameDumping();
|
||||
if (m_frame_dump_thread.joinable())
|
||||
m_frame_dump_thread.join();
|
||||
@ -136,7 +106,7 @@ void Renderer::RenderToXFB(u32 xfbAddr, const EFBRectangle& sourceRc, u32 fbStri
|
||||
if (!fbStride || !fbHeight)
|
||||
return;
|
||||
|
||||
XFBWrited = true;
|
||||
m_xfb_written = true;
|
||||
|
||||
if (g_ActiveConfig.bUseXFB)
|
||||
{
|
||||
@ -160,7 +130,7 @@ int Renderer::EFBToScaledX(int x)
|
||||
return FramebufferManagerBase::ScaleToVirtualXfbWidth(x);
|
||||
|
||||
default:
|
||||
return x * (int)efb_scale_numeratorX / (int)efb_scale_denominatorX;
|
||||
return x * (int)m_efb_scale_numeratorX / (int)m_efb_scale_denominatorX;
|
||||
};
|
||||
}
|
||||
|
||||
@ -172,7 +142,7 @@ int Renderer::EFBToScaledY(int y)
|
||||
return FramebufferManagerBase::ScaleToVirtualXfbHeight(y);
|
||||
|
||||
default:
|
||||
return y * (int)efb_scale_numeratorY / (int)efb_scale_denominatorY;
|
||||
return y * (int)m_efb_scale_numeratorY / (int)m_efb_scale_denominatorY;
|
||||
};
|
||||
}
|
||||
|
||||
@ -185,8 +155,8 @@ void Renderer::CalculateTargetScale(int x, int y, int* scaledX, int* scaledY)
|
||||
}
|
||||
else
|
||||
{
|
||||
*scaledX = x * (int)efb_scale_numeratorX / (int)efb_scale_denominatorX;
|
||||
*scaledY = y * (int)efb_scale_numeratorY / (int)efb_scale_denominatorY;
|
||||
*scaledX = x * (int)m_efb_scale_numeratorX / (int)m_efb_scale_denominatorX;
|
||||
*scaledY = y * (int)m_efb_scale_numeratorY / (int)m_efb_scale_denominatorY;
|
||||
}
|
||||
}
|
||||
|
||||
@ -196,71 +166,74 @@ bool Renderer::CalculateTargetSize()
|
||||
int newEFBWidth, newEFBHeight;
|
||||
newEFBWidth = newEFBHeight = 0;
|
||||
|
||||
m_last_efb_scale = g_ActiveConfig.iEFBScale;
|
||||
|
||||
// TODO: Ugly. Clean up
|
||||
switch (s_last_efb_scale)
|
||||
switch (m_last_efb_scale)
|
||||
{
|
||||
case SCALE_AUTO:
|
||||
case SCALE_AUTO_INTEGRAL:
|
||||
newEFBWidth = FramebufferManagerBase::ScaleToVirtualXfbWidth(EFB_WIDTH);
|
||||
newEFBHeight = FramebufferManagerBase::ScaleToVirtualXfbHeight(EFB_HEIGHT);
|
||||
|
||||
if (s_last_efb_scale == SCALE_AUTO_INTEGRAL)
|
||||
if (m_last_efb_scale == SCALE_AUTO_INTEGRAL)
|
||||
{
|
||||
efb_scale_numeratorX = efb_scale_numeratorY =
|
||||
m_efb_scale_numeratorX = m_efb_scale_numeratorY =
|
||||
std::max((newEFBWidth - 1) / EFB_WIDTH + 1, (newEFBHeight - 1) / EFB_HEIGHT + 1);
|
||||
efb_scale_denominatorX = efb_scale_denominatorY = 1;
|
||||
m_efb_scale_denominatorX = m_efb_scale_denominatorY = 1;
|
||||
newEFBWidth = EFBToScaledX(EFB_WIDTH);
|
||||
newEFBHeight = EFBToScaledY(EFB_HEIGHT);
|
||||
}
|
||||
else
|
||||
{
|
||||
efb_scale_numeratorX = newEFBWidth;
|
||||
efb_scale_denominatorX = EFB_WIDTH;
|
||||
efb_scale_numeratorY = newEFBHeight;
|
||||
efb_scale_denominatorY = EFB_HEIGHT;
|
||||
m_efb_scale_numeratorX = newEFBWidth;
|
||||
m_efb_scale_denominatorX = EFB_WIDTH;
|
||||
m_efb_scale_numeratorY = newEFBHeight;
|
||||
m_efb_scale_denominatorY = EFB_HEIGHT;
|
||||
}
|
||||
break;
|
||||
|
||||
case SCALE_1X:
|
||||
efb_scale_numeratorX = efb_scale_numeratorY = 1;
|
||||
efb_scale_denominatorX = efb_scale_denominatorY = 1;
|
||||
m_efb_scale_numeratorX = m_efb_scale_numeratorY = 1;
|
||||
m_efb_scale_denominatorX = m_efb_scale_denominatorY = 1;
|
||||
break;
|
||||
|
||||
case SCALE_1_5X:
|
||||
efb_scale_numeratorX = efb_scale_numeratorY = 3;
|
||||
efb_scale_denominatorX = efb_scale_denominatorY = 2;
|
||||
m_efb_scale_numeratorX = m_efb_scale_numeratorY = 3;
|
||||
m_efb_scale_denominatorX = m_efb_scale_denominatorY = 2;
|
||||
break;
|
||||
|
||||
case SCALE_2X:
|
||||
efb_scale_numeratorX = efb_scale_numeratorY = 2;
|
||||
efb_scale_denominatorX = efb_scale_denominatorY = 1;
|
||||
m_efb_scale_numeratorX = m_efb_scale_numeratorY = 2;
|
||||
m_efb_scale_denominatorX = m_efb_scale_denominatorY = 1;
|
||||
break;
|
||||
|
||||
case SCALE_2_5X:
|
||||
efb_scale_numeratorX = efb_scale_numeratorY = 5;
|
||||
efb_scale_denominatorX = efb_scale_denominatorY = 2;
|
||||
m_efb_scale_numeratorX = m_efb_scale_numeratorY = 5;
|
||||
m_efb_scale_denominatorX = m_efb_scale_denominatorY = 2;
|
||||
break;
|
||||
|
||||
default:
|
||||
efb_scale_numeratorX = efb_scale_numeratorY = s_last_efb_scale - 3;
|
||||
efb_scale_denominatorX = efb_scale_denominatorY = 1;
|
||||
m_efb_scale_numeratorX = m_efb_scale_numeratorY = m_last_efb_scale - 3;
|
||||
m_efb_scale_denominatorX = m_efb_scale_denominatorY = 1;
|
||||
|
||||
const u32 max_size = GetMaxTextureSize();
|
||||
if (max_size < EFB_WIDTH * efb_scale_numeratorX / efb_scale_denominatorX)
|
||||
if (max_size < EFB_WIDTH * m_efb_scale_numeratorX / m_efb_scale_denominatorX)
|
||||
{
|
||||
efb_scale_numeratorX = efb_scale_numeratorY = (max_size / EFB_WIDTH);
|
||||
efb_scale_denominatorX = efb_scale_denominatorY = 1;
|
||||
m_efb_scale_numeratorX = m_efb_scale_numeratorY = (max_size / EFB_WIDTH);
|
||||
m_efb_scale_denominatorX = m_efb_scale_denominatorY = 1;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
if (s_last_efb_scale > SCALE_AUTO_INTEGRAL)
|
||||
if (m_last_efb_scale > SCALE_AUTO_INTEGRAL)
|
||||
CalculateTargetScale(EFB_WIDTH, EFB_HEIGHT, &newEFBWidth, &newEFBHeight);
|
||||
|
||||
if (newEFBWidth != s_target_width || newEFBHeight != s_target_height)
|
||||
if (newEFBWidth != m_target_width || newEFBHeight != m_target_height)
|
||||
{
|
||||
s_target_width = newEFBWidth;
|
||||
s_target_height = newEFBHeight;
|
||||
m_target_width = newEFBWidth;
|
||||
m_target_height = newEFBHeight;
|
||||
PixelShaderManager::SetEfbScaleChanged(EFBToScaledXf(1), EFBToScaledYf(1));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -289,25 +262,34 @@ void Renderer::ConvertStereoRectangle(const TargetRectangle& rc, TargetRectangle
|
||||
leftRc = drawRc, rightRc = drawRc;
|
||||
if (g_ActiveConfig.iStereoMode == STEREO_TAB)
|
||||
{
|
||||
leftRc.top -= s_backbuffer_height / 4;
|
||||
leftRc.bottom -= s_backbuffer_height / 4;
|
||||
rightRc.top += s_backbuffer_height / 4;
|
||||
rightRc.bottom += s_backbuffer_height / 4;
|
||||
leftRc.top -= m_backbuffer_height / 4;
|
||||
leftRc.bottom -= m_backbuffer_height / 4;
|
||||
rightRc.top += m_backbuffer_height / 4;
|
||||
rightRc.bottom += m_backbuffer_height / 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
leftRc.left -= s_backbuffer_width / 4;
|
||||
leftRc.right -= s_backbuffer_width / 4;
|
||||
rightRc.left += s_backbuffer_width / 4;
|
||||
rightRc.right += s_backbuffer_width / 4;
|
||||
leftRc.left -= m_backbuffer_width / 4;
|
||||
leftRc.right -= m_backbuffer_width / 4;
|
||||
rightRc.left += m_backbuffer_width / 4;
|
||||
rightRc.right += m_backbuffer_width / 4;
|
||||
}
|
||||
}
|
||||
|
||||
void Renderer::SetScreenshot(const std::string& filename)
|
||||
void Renderer::SaveScreenshot(const std::string& filename, bool wait_for_completion)
|
||||
{
|
||||
std::lock_guard<std::mutex> lk(s_criticalScreenshot);
|
||||
s_sScreenshotName = filename;
|
||||
s_screenshot.Set();
|
||||
// We must not hold the lock while waiting for the screenshot to complete.
|
||||
{
|
||||
std::lock_guard<std::mutex> lk(m_screenshot_lock);
|
||||
m_screenshot_name = filename;
|
||||
m_screenshot_request.Set();
|
||||
}
|
||||
|
||||
if (wait_for_completion)
|
||||
{
|
||||
// This is currently only used by Android, and it was using a wait time of 2 seconds.
|
||||
m_screenshot_completed.WaitFor(std::chrono::seconds(2));
|
||||
}
|
||||
}
|
||||
|
||||
// Create On-Screen-Messages
|
||||
@ -460,7 +442,7 @@ float Renderer::CalculateDrawAspectRatio(int target_width, int target_height)
|
||||
{
|
||||
// If stretch is enabled, we prefer the aspect ratio of the window.
|
||||
return (static_cast<float>(target_width) / static_cast<float>(target_height)) /
|
||||
(static_cast<float>(s_backbuffer_width) / static_cast<float>(s_backbuffer_height));
|
||||
(static_cast<float>(m_backbuffer_width) / static_cast<float>(m_backbuffer_height));
|
||||
}
|
||||
|
||||
// The rendering window aspect ratio as a proportion of the 4:3 or 16:9 ratio
|
||||
@ -505,8 +487,8 @@ TargetRectangle Renderer::CalculateFrameDumpDrawRectangle()
|
||||
if (!g_ActiveConfig.bInternalResolutionFrameDumps || g_ActiveConfig.RealXFBEnabled())
|
||||
{
|
||||
// But still remove the borders, since the caller expects this.
|
||||
rc.right = target_rc.GetWidth();
|
||||
rc.bottom = target_rc.GetHeight();
|
||||
rc.right = m_target_rectangle.GetWidth();
|
||||
rc.bottom = m_target_rectangle.GetHeight();
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -524,8 +506,8 @@ TargetRectangle Renderer::CalculateFrameDumpDrawRectangle()
|
||||
|
||||
void Renderer::UpdateDrawRectangle()
|
||||
{
|
||||
float FloatGLWidth = static_cast<float>(s_backbuffer_width);
|
||||
float FloatGLHeight = static_cast<float>(s_backbuffer_height);
|
||||
float FloatGLWidth = static_cast<float>(m_backbuffer_width);
|
||||
float FloatGLHeight = static_cast<float>(m_backbuffer_height);
|
||||
float FloatXOffset = 0;
|
||||
float FloatYOffset = 0;
|
||||
|
||||
@ -584,7 +566,7 @@ void Renderer::UpdateDrawRectangle()
|
||||
// Check for force-settings and override.
|
||||
|
||||
// The rendering window aspect ratio as a proportion of the 4:3 or 16:9 ratio
|
||||
float Ratio = CalculateDrawAspectRatio(s_backbuffer_width, s_backbuffer_height);
|
||||
float Ratio = CalculateDrawAspectRatio(m_backbuffer_width, m_backbuffer_height);
|
||||
if (g_ActiveConfig.iAspectRatio != ASPECT_STRETCH)
|
||||
{
|
||||
if (Ratio >= 0.995f && Ratio <= 1.005f)
|
||||
@ -638,18 +620,16 @@ void Renderer::UpdateDrawRectangle()
|
||||
iWhidth % 4; // ensure divisibility by 4 to make it compatible with all the video encoders
|
||||
iHeight -= iHeight % 4;
|
||||
|
||||
target_rc.left = XOffset;
|
||||
target_rc.top = YOffset;
|
||||
target_rc.right = XOffset + iWhidth;
|
||||
target_rc.bottom = YOffset + iHeight;
|
||||
m_target_rectangle.left = XOffset;
|
||||
m_target_rectangle.top = YOffset;
|
||||
m_target_rectangle.right = XOffset + iWhidth;
|
||||
m_target_rectangle.bottom = YOffset + iHeight;
|
||||
}
|
||||
|
||||
void Renderer::SetWindowSize(int width, int height)
|
||||
{
|
||||
if (width < 1)
|
||||
width = 1;
|
||||
if (height < 1)
|
||||
height = 1;
|
||||
width = std::max(width, 1);
|
||||
height = std::max(height, 1);
|
||||
|
||||
// Scale the window size by the EFB scale.
|
||||
CalculateTargetScale(width, height, &width, &height);
|
||||
@ -686,7 +666,13 @@ void Renderer::SetWindowSize(int width, int height)
|
||||
width -= width % 4;
|
||||
height -= height % 4;
|
||||
|
||||
Host_RequestRenderWindowSize(width, height);
|
||||
// Track the last values of width/height to avoid sending a window resize event every frame.
|
||||
if (width != m_last_window_request_width || height != m_last_window_request_height)
|
||||
{
|
||||
m_last_window_request_width = width;
|
||||
m_last_window_request_height = height;
|
||||
Host_RequestRenderWindowSize(width, height);
|
||||
}
|
||||
}
|
||||
|
||||
void Renderer::CheckFifoRecording()
|
||||
@ -728,7 +714,7 @@ void Renderer::Swap(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, const
|
||||
// TODO: merge more generic parts into VideoCommon
|
||||
g_renderer->SwapImpl(xfbAddr, fbWidth, fbStride, fbHeight, rc, ticks, Gamma);
|
||||
|
||||
if (XFBWrited)
|
||||
if (m_xfb_written)
|
||||
g_renderer->m_fps_counter.Update();
|
||||
|
||||
frameCount++;
|
||||
@ -739,14 +725,14 @@ void Renderer::Swap(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, const
|
||||
// New frame
|
||||
stats.ResetFrame();
|
||||
|
||||
Core::Callback_VideoCopiedToXFB(XFBWrited ||
|
||||
Core::Callback_VideoCopiedToXFB(m_xfb_written ||
|
||||
(g_ActiveConfig.bUseXFB && g_ActiveConfig.bUseRealXFB));
|
||||
XFBWrited = false;
|
||||
m_xfb_written = false;
|
||||
}
|
||||
|
||||
bool Renderer::IsFrameDumping()
|
||||
{
|
||||
if (s_screenshot.IsSet())
|
||||
if (m_screenshot_request.IsSet())
|
||||
return true;
|
||||
|
||||
#if defined(HAVE_LIBAV) || defined(_WIN32)
|
||||
@ -827,17 +813,17 @@ void Renderer::RunFrameDumps()
|
||||
}
|
||||
|
||||
// Save screenshot
|
||||
if (s_screenshot.TestAndClear())
|
||||
if (m_screenshot_request.TestAndClear())
|
||||
{
|
||||
std::lock_guard<std::mutex> lk(s_criticalScreenshot);
|
||||
std::lock_guard<std::mutex> lk(m_screenshot_lock);
|
||||
|
||||
if (TextureToPng(config.data, config.stride, s_sScreenshotName, config.width, config.height,
|
||||
if (TextureToPng(config.data, config.stride, m_screenshot_name, config.width, config.height,
|
||||
false))
|
||||
OSD::AddMessage("Screenshot saved to " + s_sScreenshotName);
|
||||
OSD::AddMessage("Screenshot saved to " + m_screenshot_name);
|
||||
|
||||
// Reset settings
|
||||
s_sScreenshotName.clear();
|
||||
s_screenshotCompleted.Set();
|
||||
m_screenshot_name.clear();
|
||||
m_screenshot_completed.Set();
|
||||
}
|
||||
|
||||
if (SConfig::GetInstance().m_DumpFrames)
|
||||
|
@ -50,7 +50,7 @@ extern int OSDChoice;
|
||||
class Renderer
|
||||
{
|
||||
public:
|
||||
Renderer();
|
||||
Renderer(int backbuffer_width, int backbuffer_height);
|
||||
virtual ~Renderer();
|
||||
|
||||
enum PixelPerfQuery
|
||||
@ -81,46 +81,46 @@ public:
|
||||
virtual void RestoreAPIState() {}
|
||||
// Ideal internal resolution - determined by display resolution (automatic scaling) and/or a
|
||||
// multiple of the native EFB resolution
|
||||
static int GetTargetWidth() { return s_target_width; }
|
||||
static int GetTargetHeight() { return s_target_height; }
|
||||
int GetTargetWidth() { return m_target_width; }
|
||||
int GetTargetHeight() { return m_target_height; }
|
||||
// Display resolution
|
||||
static int GetBackbufferWidth() { return s_backbuffer_width; }
|
||||
static int GetBackbufferHeight() { return s_backbuffer_height; }
|
||||
static void SetWindowSize(int width, int height);
|
||||
int GetBackbufferWidth() { return m_backbuffer_width; }
|
||||
int GetBackbufferHeight() { return m_backbuffer_height; }
|
||||
void SetWindowSize(int width, int height);
|
||||
|
||||
// EFB coordinate conversion functions
|
||||
|
||||
// Use this to convert a whole native EFB rect to backbuffer coordinates
|
||||
virtual TargetRectangle ConvertEFBRectangle(const EFBRectangle& rc) = 0;
|
||||
|
||||
static const TargetRectangle& GetTargetRectangle() { return target_rc; }
|
||||
static float CalculateDrawAspectRatio(int target_width, int target_height);
|
||||
static std::tuple<float, float> ScaleToDisplayAspectRatio(int width, int height);
|
||||
static TargetRectangle CalculateFrameDumpDrawRectangle();
|
||||
static void UpdateDrawRectangle();
|
||||
const TargetRectangle& GetTargetRectangle() { return m_target_rectangle; }
|
||||
float CalculateDrawAspectRatio(int target_width, int target_height);
|
||||
std::tuple<float, float> ScaleToDisplayAspectRatio(int width, int height);
|
||||
TargetRectangle CalculateFrameDumpDrawRectangle();
|
||||
void UpdateDrawRectangle();
|
||||
|
||||
// Use this to convert a single target rectangle to two stereo rectangles
|
||||
static void ConvertStereoRectangle(const TargetRectangle& rc, TargetRectangle& leftRc,
|
||||
TargetRectangle& rightRc);
|
||||
void ConvertStereoRectangle(const TargetRectangle& rc, TargetRectangle& leftRc,
|
||||
TargetRectangle& rightRc);
|
||||
|
||||
// Use this to upscale native EFB coordinates to IDEAL internal resolution
|
||||
static int EFBToScaledX(int x);
|
||||
static int EFBToScaledY(int y);
|
||||
int EFBToScaledX(int x);
|
||||
int EFBToScaledY(int y);
|
||||
|
||||
// Floating point versions of the above - only use them if really necessary
|
||||
static float EFBToScaledXf(float x) { return x * ((float)GetTargetWidth() / (float)EFB_WIDTH); }
|
||||
static float EFBToScaledYf(float y) { return y * ((float)GetTargetHeight() / (float)EFB_HEIGHT); }
|
||||
float EFBToScaledXf(float x) { return x * ((float)GetTargetWidth() / (float)EFB_WIDTH); }
|
||||
float EFBToScaledYf(float y) { return y * ((float)GetTargetHeight() / (float)EFB_HEIGHT); }
|
||||
// Random utilities
|
||||
static void SetScreenshot(const std::string& filename);
|
||||
static void DrawDebugText();
|
||||
void SaveScreenshot(const std::string& filename, bool wait_for_completion);
|
||||
void DrawDebugText();
|
||||
|
||||
virtual void RenderText(const std::string& text, int left, int top, u32 color) = 0;
|
||||
|
||||
virtual void ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable,
|
||||
u32 color, u32 z) = 0;
|
||||
virtual void ReinterpretPixelData(unsigned int convtype) = 0;
|
||||
static void RenderToXFB(u32 xfbAddr, const EFBRectangle& sourceRc, u32 fbStride, u32 fbHeight,
|
||||
float Gamma = 1.0f);
|
||||
void RenderToXFB(u32 xfbAddr, const EFBRectangle& sourceRc, u32 fbStride, u32 fbHeight,
|
||||
float Gamma = 1.0f);
|
||||
|
||||
virtual u32 AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) = 0;
|
||||
virtual void PokeEFB(EFBAccessType type, const EfbPokeData* points, size_t num_points) = 0;
|
||||
@ -129,72 +129,71 @@ public:
|
||||
virtual void BBoxWrite(int index, u16 value) = 0;
|
||||
|
||||
// Finish up the current frame, print some stats
|
||||
static void Swap(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, const EFBRectangle& rc,
|
||||
u64 ticks, float Gamma = 1.0f);
|
||||
void Swap(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, const EFBRectangle& rc, u64 ticks,
|
||||
float Gamma = 1.0f);
|
||||
virtual void SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight,
|
||||
const EFBRectangle& rc, u64 ticks, float Gamma = 1.0f) = 0;
|
||||
|
||||
static PEControl::PixelFormat GetPrevPixelFormat() { return prev_efb_format; }
|
||||
static void StorePixelFormat(PEControl::PixelFormat new_format) { prev_efb_format = new_format; }
|
||||
PEControl::PixelFormat GetPrevPixelFormat() { return m_prev_efb_format; }
|
||||
void StorePixelFormat(PEControl::PixelFormat new_format) { m_prev_efb_format = new_format; }
|
||||
PostProcessingShaderImplementation* GetPostProcessor() { return m_post_processor.get(); }
|
||||
// Max height/width
|
||||
virtual u32 GetMaxTextureSize() = 0;
|
||||
|
||||
static Common::Event s_screenshotCompleted;
|
||||
|
||||
// Final surface changing
|
||||
// This is called when the surface is resized (WX) or the window changes (Android).
|
||||
virtual void ChangeSurface(void* new_surface_handle) {}
|
||||
protected:
|
||||
static void CalculateTargetScale(int x, int y, int* scaledX, int* scaledY);
|
||||
void CalculateTargetScale(int x, int y, int* scaledX, int* scaledY);
|
||||
bool CalculateTargetSize();
|
||||
|
||||
static void CheckFifoRecording();
|
||||
static void RecordVideoMemory();
|
||||
void CheckFifoRecording();
|
||||
void RecordVideoMemory();
|
||||
|
||||
bool IsFrameDumping();
|
||||
void DumpFrameData(const u8* data, int w, int h, int stride, const AVIDump::Frame& state,
|
||||
bool swap_upside_down = false);
|
||||
void FinishFrameData();
|
||||
|
||||
static Common::Flag s_screenshot;
|
||||
static std::mutex s_criticalScreenshot;
|
||||
static std::string s_sScreenshotName;
|
||||
Common::Flag m_screenshot_request;
|
||||
Common::Event m_screenshot_completed;
|
||||
std::mutex m_screenshot_lock;
|
||||
std::string m_screenshot_name;
|
||||
|
||||
// The framebuffer size
|
||||
static int s_target_width;
|
||||
static int s_target_height;
|
||||
int m_target_width = 0;
|
||||
int m_target_height = 0;
|
||||
|
||||
// TODO: Add functionality to reinit all the render targets when the window is resized.
|
||||
static int s_backbuffer_width;
|
||||
static int s_backbuffer_height;
|
||||
|
||||
static TargetRectangle target_rc;
|
||||
|
||||
// TODO: Can probably eliminate this static var.
|
||||
static int s_last_efb_scale;
|
||||
|
||||
static bool XFBWrited;
|
||||
int m_backbuffer_width = 0;
|
||||
int m_backbuffer_height = 0;
|
||||
int m_last_efb_scale = 0;
|
||||
TargetRectangle m_target_rectangle;
|
||||
bool m_xfb_written = false;
|
||||
|
||||
FPSCounter m_fps_counter;
|
||||
|
||||
static std::unique_ptr<PostProcessingShaderImplementation> m_post_processor;
|
||||
std::unique_ptr<PostProcessingShaderImplementation> m_post_processor;
|
||||
|
||||
static const float GX_MAX_DEPTH;
|
||||
|
||||
static Common::Flag s_surface_needs_change;
|
||||
static Common::Event s_surface_changed;
|
||||
static void* s_new_surface_handle;
|
||||
Common::Flag m_surface_needs_change;
|
||||
Common::Event m_surface_changed;
|
||||
void* m_new_surface_handle = nullptr;
|
||||
|
||||
private:
|
||||
void RunFrameDumps();
|
||||
void ShutdownFrameDumping();
|
||||
|
||||
static PEControl::PixelFormat prev_efb_format;
|
||||
static unsigned int efb_scale_numeratorX;
|
||||
static unsigned int efb_scale_numeratorY;
|
||||
static unsigned int efb_scale_denominatorX;
|
||||
static unsigned int efb_scale_denominatorY;
|
||||
PEControl::PixelFormat m_prev_efb_format = PEControl::INVALID_FMT;
|
||||
unsigned int m_efb_scale_numeratorX = 1;
|
||||
unsigned int m_efb_scale_numeratorY = 1;
|
||||
unsigned int m_efb_scale_denominatorX = 1;
|
||||
unsigned int m_efb_scale_denominatorY = 1;
|
||||
|
||||
// These will be set on the first call to SetWindowSize.
|
||||
int m_last_window_request_width = 0;
|
||||
int m_last_window_request_height = 0;
|
||||
|
||||
// frame dumping
|
||||
std::thread m_frame_dump_thread;
|
||||
|
@ -385,17 +385,17 @@ TextureCacheBase::DoPartialTextureUpdates(TCacheEntryBase* entry_to_update, u8*
|
||||
entry->native_height != entry->config.height)
|
||||
{
|
||||
ScaleTextureCacheEntryTo(&entry_to_update,
|
||||
Renderer::EFBToScaledX(entry_to_update->native_width),
|
||||
Renderer::EFBToScaledY(entry_to_update->native_height));
|
||||
ScaleTextureCacheEntryTo(&entry, Renderer::EFBToScaledX(entry->native_width),
|
||||
Renderer::EFBToScaledY(entry->native_height));
|
||||
g_renderer->EFBToScaledX(entry_to_update->native_width),
|
||||
g_renderer->EFBToScaledY(entry_to_update->native_height));
|
||||
ScaleTextureCacheEntryTo(&entry, g_renderer->EFBToScaledX(entry->native_width),
|
||||
g_renderer->EFBToScaledY(entry->native_height));
|
||||
|
||||
src_x = Renderer::EFBToScaledX(src_x);
|
||||
src_y = Renderer::EFBToScaledY(src_y);
|
||||
dst_x = Renderer::EFBToScaledX(dst_x);
|
||||
dst_y = Renderer::EFBToScaledY(dst_y);
|
||||
copy_width = Renderer::EFBToScaledX(copy_width);
|
||||
copy_height = Renderer::EFBToScaledY(copy_height);
|
||||
src_x = g_renderer->EFBToScaledX(src_x);
|
||||
src_y = g_renderer->EFBToScaledY(src_y);
|
||||
dst_x = g_renderer->EFBToScaledX(dst_x);
|
||||
dst_y = g_renderer->EFBToScaledY(dst_y);
|
||||
copy_width = g_renderer->EFBToScaledX(copy_width);
|
||||
copy_height = g_renderer->EFBToScaledY(copy_height);
|
||||
}
|
||||
|
||||
MathUtil::Rectangle<int> srcrect, dstrect;
|
||||
@ -1197,8 +1197,10 @@ void TextureCacheBase::CopyRenderTargetToTexture(u32 dstAddr, unsigned int dstFo
|
||||
const unsigned int tex_w = scaleByHalf ? srcRect.GetWidth() / 2 : srcRect.GetWidth();
|
||||
const unsigned int tex_h = scaleByHalf ? srcRect.GetHeight() / 2 : srcRect.GetHeight();
|
||||
|
||||
unsigned int scaled_tex_w = g_ActiveConfig.bCopyEFBScaled ? Renderer::EFBToScaledX(tex_w) : tex_w;
|
||||
unsigned int scaled_tex_h = g_ActiveConfig.bCopyEFBScaled ? Renderer::EFBToScaledY(tex_h) : tex_h;
|
||||
unsigned int scaled_tex_w =
|
||||
g_ActiveConfig.bCopyEFBScaled ? g_renderer->EFBToScaledX(tex_w) : tex_w;
|
||||
unsigned int scaled_tex_h =
|
||||
g_ActiveConfig.bCopyEFBScaled ? g_renderer->EFBToScaledY(tex_h) : tex_h;
|
||||
|
||||
// Remove all texture cache entries at dstAddr
|
||||
// It's not possible to have two EFB copies at the same address, this makes sure any old efb
|
||||
|
@ -382,8 +382,8 @@ void VertexShaderManager::SetConstants()
|
||||
// NOTE: If we ever emulate antialiasing, the sample locations set by
|
||||
// BP registers 0x01-0x04 need to be considered here.
|
||||
const float pixel_center_correction = 7.0f / 12.0f - 0.5f;
|
||||
const float pixel_size_x = 2.f / Renderer::EFBToScaledXf(2.f * xfmem.viewport.wd);
|
||||
const float pixel_size_y = 2.f / Renderer::EFBToScaledXf(2.f * xfmem.viewport.ht);
|
||||
const float pixel_size_x = 2.f / g_renderer->EFBToScaledXf(2.f * xfmem.viewport.wd);
|
||||
const float pixel_size_y = 2.f / g_renderer->EFBToScaledXf(2.f * xfmem.viewport.ht);
|
||||
constants.pixelcentercorrection[0] = pixel_center_correction * pixel_size_x;
|
||||
constants.pixelcentercorrection[1] = pixel_center_correction * pixel_size_y;
|
||||
|
||||
|
Reference in New Issue
Block a user