Move xfb tracking and IR scaling out of RenderBase
This commit is contained in:
parent
e009002411
commit
11de923dcb
|
@ -96,7 +96,7 @@ static size_t s_state_writes_in_queue;
|
|||
static std::condition_variable s_state_write_queue_is_empty;
|
||||
|
||||
// Don't forget to increase this after doing changes on the savestate system
|
||||
constexpr u32 STATE_VERSION = 157; // Last changed in PR 11183
|
||||
constexpr u32 STATE_VERSION = 158; // Last changed in PR ???
|
||||
|
||||
// Maps savestate versions to Dolphin versions.
|
||||
// Versions after 42 don't need to be added to this list,
|
||||
|
|
|
@ -114,8 +114,8 @@ void PerfQuery::FlushOne()
|
|||
// NOTE: Reported pixel metrics should be referenced to native resolution
|
||||
// TODO: Dropping the lower 2 bits from this count should be closer to actual
|
||||
// hardware behavior when drawing triangles.
|
||||
const u64 native_res_result = result * EFB_WIDTH / g_renderer->GetTargetWidth() * EFB_HEIGHT /
|
||||
g_renderer->GetTargetHeight();
|
||||
const u64 native_res_result = result * EFB_WIDTH / g_framebuffer_manager->GetEFBWidth() * EFB_HEIGHT /
|
||||
g_framebuffer_manager->GetEFBHeight();
|
||||
m_results[entry.query_group].fetch_add(static_cast<u32>(native_res_result),
|
||||
std::memory_order_relaxed);
|
||||
|
||||
|
@ -143,8 +143,8 @@ void PerfQuery::WeakFlush()
|
|||
if (hr == S_OK)
|
||||
{
|
||||
// NOTE: Reported pixel metrics should be referenced to native resolution
|
||||
const u64 native_res_result = result * EFB_WIDTH / g_renderer->GetTargetWidth() * EFB_HEIGHT /
|
||||
g_renderer->GetTargetHeight();
|
||||
const u64 native_res_result = result * EFB_WIDTH / g_framebuffer_manager->GetEFBWidth() * EFB_HEIGHT /
|
||||
g_framebuffer_manager->GetEFBHeight();
|
||||
m_results[entry.query_group].store(static_cast<u32>(native_res_result),
|
||||
std::memory_order_relaxed);
|
||||
|
||||
|
|
|
@ -245,8 +245,8 @@ void PerfQuery::AccumulateQueriesFromBuffer(u32 query_count)
|
|||
|
||||
// NOTE: Reported pixel metrics should be referenced to native resolution
|
||||
const u64 native_res_result = static_cast<u64>(result) * EFB_WIDTH /
|
||||
g_renderer->GetTargetWidth() * EFB_HEIGHT /
|
||||
g_renderer->GetTargetHeight();
|
||||
g_framebuffer_manager->GetEFBWidth() * EFB_HEIGHT /
|
||||
g_framebuffer_manager->GetEFBHeight();
|
||||
m_results[entry.query_group].fetch_add(static_cast<u32>(native_res_result),
|
||||
std::memory_order_relaxed);
|
||||
}
|
||||
|
|
|
@ -78,7 +78,7 @@ void Metal::PerfQuery::ReturnResults(const u64* data, const PerfQueryGroup* grou
|
|||
for (size_t i = 0; i < count; ++i)
|
||||
{
|
||||
u64 native_res_result = data[i] * (EFB_WIDTH * EFB_HEIGHT) /
|
||||
(g_renderer->GetTargetWidth() * g_renderer->GetTargetHeight());
|
||||
(g_framebuffer_manager->GetEFBWidth() * g_framebuffer_manager->GetEFBHeight());
|
||||
|
||||
native_res_result /= g_ActiveConfig.iMultisamples;
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#include "Common/GL/GLExtensions/GLExtensions.h"
|
||||
|
||||
#include "VideoBackends/OGL/OGLGfx.h"
|
||||
#include "VideoCommon/RenderBase.h"
|
||||
#include "VideoCommon/FramebufferManager.h"
|
||||
#include "VideoCommon/VideoCommon.h"
|
||||
#include "VideoCommon/VideoConfig.h"
|
||||
|
||||
|
@ -165,7 +165,7 @@ void PerfQueryGL::FlushOne()
|
|||
// TODO: Dropping the lower 2 bits from this count should be closer to actual
|
||||
// hardware behavior when drawing triangles.
|
||||
result = static_cast<u64>(result) * EFB_WIDTH * EFB_HEIGHT /
|
||||
(g_renderer->GetTargetWidth() * g_renderer->GetTargetHeight());
|
||||
(g_framebuffer_manager->GetEFBWidth() * g_framebuffer_manager->GetEFBHeight());
|
||||
|
||||
// Adjust for multisampling
|
||||
if (g_ActiveConfig.iMultisamples > 1)
|
||||
|
@ -265,7 +265,7 @@ void PerfQueryGLESNV::FlushOne()
|
|||
// TODO: Dropping the lower 2 bits from this count should be closer to actual
|
||||
// hardware behavior when drawing triangles.
|
||||
const u64 native_res_result = static_cast<u64>(result) * EFB_WIDTH * EFB_HEIGHT /
|
||||
(g_renderer->GetTargetWidth() * g_renderer->GetTargetHeight());
|
||||
(g_framebuffer_manager->GetEFBWidth() * g_framebuffer_manager->GetEFBHeight());
|
||||
m_results[entry.query_group].fetch_add(static_cast<u32>(native_res_result),
|
||||
std::memory_order_relaxed);
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
#include "VideoBackends/Vulkan/StateTracker.h"
|
||||
#include "VideoBackends/Vulkan/VKGfx.h"
|
||||
#include "VideoBackends/Vulkan/VulkanContext.h"
|
||||
#include "VideoCommon/RenderBase.h"
|
||||
#include "VideoCommon/FramebufferManager.h"
|
||||
#include "VideoCommon/VideoCommon.h"
|
||||
|
||||
namespace Vulkan
|
||||
|
@ -219,8 +219,8 @@ void PerfQuery::ReadbackQueries(u32 query_count)
|
|||
|
||||
// NOTE: Reported pixel metrics should be referenced to native resolution
|
||||
const u64 native_res_result = static_cast<u64>(m_query_result_buffer[i]) * EFB_WIDTH /
|
||||
g_renderer->GetTargetWidth() * EFB_HEIGHT /
|
||||
g_renderer->GetTargetHeight();
|
||||
g_framebuffer_manager->GetEFBWidth() * EFB_HEIGHT /
|
||||
g_framebuffer_manager->GetEFBHeight();
|
||||
m_results[entry.query_group].fetch_add(static_cast<u32>(native_res_result),
|
||||
std::memory_order_relaxed);
|
||||
}
|
||||
|
|
|
@ -158,8 +158,6 @@ void AsyncRequests::HandleEvent(const AsyncRequests::Event& e)
|
|||
case Event::SWAP_EVENT:
|
||||
g_presenter->ViSwap(e.swap_event.xfbAddr, e.swap_event.fbWidth, e.swap_event.fbStride,
|
||||
e.swap_event.fbHeight, e.time);
|
||||
g_renderer->TrackSwaps(e.swap_event.xfbAddr, e.swap_event.fbWidth, e.swap_event.fbStride,
|
||||
e.swap_event.fbHeight, e.time);
|
||||
break;
|
||||
|
||||
case Event::BBOX_READ:
|
||||
|
|
|
@ -198,7 +198,7 @@ void SetScissorAndViewport()
|
|||
{
|
||||
auto native_rc = ComputeScissorRects().Best();
|
||||
|
||||
auto target_rc = g_renderer->ConvertEFBRectangle(native_rc.rect);
|
||||
auto target_rc = g_framebuffer_manager->ConvertEFBRectangle(native_rc.rect);
|
||||
auto converted_rc = g_gfx->ConvertFramebufferRectangle(target_rc, g_gfx->GetCurrentFramebuffer());
|
||||
g_gfx->SetScissorRect(converted_rc);
|
||||
|
||||
|
@ -216,10 +216,10 @@ void SetScissorAndViewport()
|
|||
raw_height = std::round(raw_height);
|
||||
}
|
||||
|
||||
float x = g_renderer->EFBToScaledXf(raw_x);
|
||||
float y = g_renderer->EFBToScaledYf(raw_y);
|
||||
float width = g_renderer->EFBToScaledXf(raw_width);
|
||||
float height = g_renderer->EFBToScaledYf(raw_height);
|
||||
float x = g_framebuffer_manager->EFBToScaledXf(raw_x);
|
||||
float y = g_framebuffer_manager->EFBToScaledYf(raw_y);
|
||||
float width = g_framebuffer_manager->EFBToScaledXf(raw_width);
|
||||
float height = g_framebuffer_manager->EFBToScaledYf(raw_height);
|
||||
float min_depth = (xfmem.viewport.farZ - xfmem.viewport.zRange) / 16777216.0f;
|
||||
float max_depth = xfmem.viewport.farZ / 16777216.0f;
|
||||
if (width < 0.f)
|
||||
|
|
|
@ -352,7 +352,6 @@ static void BPWritten(PixelShaderManager& pixel_shader_manager,
|
|||
// below div two to convert from bytes to pixels - it expects width, not stride
|
||||
u64 ticks = Core::System::GetInstance().GetCoreTiming().GetTicks();
|
||||
g_presenter->ImmediateSwap(destAddr, destStride / 2, destStride, height, ticks);
|
||||
g_renderer->TrackSwaps(destAddr, destStride / 2, destStride, height, ticks);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "Common/Logging/Log.h"
|
||||
#include "Common/MsgHandler.h"
|
||||
#include "Core/Config/GraphicsSettings.h"
|
||||
#include "Core/System.h"
|
||||
#include "VideoCommon/AbstractFramebuffer.h"
|
||||
#include "VideoCommon/AbstractGfx.h"
|
||||
#include "VideoCommon/AbstractPipeline.h"
|
||||
|
@ -19,7 +20,8 @@
|
|||
#include "VideoCommon/BPFunctions.h"
|
||||
#include "VideoCommon/DriverDetails.h"
|
||||
#include "VideoCommon/FramebufferShaderGen.h"
|
||||
#include "VideoCommon/RenderBase.h"
|
||||
#include "VideoCommon/PixelShaderManager.h"
|
||||
#include "VideoCommon/Present.h"
|
||||
#include "VideoCommon/VertexManagerBase.h"
|
||||
#include "VideoCommon/VideoCommon.h"
|
||||
#include "VideoCommon/VideoConfig.h"
|
||||
|
@ -145,16 +147,16 @@ static u32 CalculateEFBLayers()
|
|||
return (g_ActiveConfig.stereo_mode != StereoMode::Off) ? 2 : 1;
|
||||
}
|
||||
|
||||
TextureConfig FramebufferManager::GetEFBColorTextureConfig()
|
||||
TextureConfig FramebufferManager::GetEFBColorTextureConfig(u32 width, u32 height)
|
||||
{
|
||||
return TextureConfig(g_renderer->GetTargetWidth(), g_renderer->GetTargetHeight(), 1,
|
||||
return TextureConfig(width, height, 1,
|
||||
CalculateEFBLayers(), g_ActiveConfig.iMultisamples, GetEFBColorFormat(),
|
||||
AbstractTextureFlag_RenderTarget);
|
||||
}
|
||||
|
||||
TextureConfig FramebufferManager::GetEFBDepthTextureConfig()
|
||||
TextureConfig FramebufferManager::GetEFBDepthTextureConfig(u32 width, u32 height)
|
||||
{
|
||||
return TextureConfig(g_renderer->GetTargetWidth(), g_renderer->GetTargetHeight(), 1,
|
||||
return TextureConfig(width, height, 1,
|
||||
CalculateEFBLayers(), g_ActiveConfig.iMultisamples, GetEFBDepthFormat(),
|
||||
AbstractTextureFlag_RenderTarget);
|
||||
}
|
||||
|
@ -169,10 +171,65 @@ FramebufferState FramebufferManager::GetEFBFramebufferState() const
|
|||
return ret;
|
||||
}
|
||||
|
||||
MathUtil::Rectangle<int>
|
||||
FramebufferManager::ConvertEFBRectangle(const MathUtil::Rectangle<int>& rc) const
|
||||
{
|
||||
MathUtil::Rectangle<int> result;
|
||||
result.left = EFBToScaledX(rc.left);
|
||||
result.top = EFBToScaledY(rc.top);
|
||||
result.right = EFBToScaledX(rc.right);
|
||||
result.bottom = EFBToScaledY(rc.bottom);
|
||||
return result;
|
||||
}
|
||||
|
||||
unsigned int FramebufferManager::GetEFBScale() const
|
||||
{
|
||||
return m_efb_scale;
|
||||
}
|
||||
|
||||
int FramebufferManager::EFBToScaledX(int x) const
|
||||
{
|
||||
return x * static_cast<int>(m_efb_scale);
|
||||
}
|
||||
|
||||
int FramebufferManager::EFBToScaledY(int y) const
|
||||
{
|
||||
return y * static_cast<int>(m_efb_scale);
|
||||
}
|
||||
|
||||
float FramebufferManager::EFBToScaledXf(float x) const
|
||||
{
|
||||
return x * ((float)GetEFBWidth() / (float)EFB_WIDTH);
|
||||
}
|
||||
|
||||
float FramebufferManager::EFBToScaledYf(float y) const
|
||||
{
|
||||
return y * ((float)GetEFBHeight() / (float)EFB_HEIGHT);
|
||||
}
|
||||
|
||||
std::tuple<u32, u32> FramebufferManager::CalculateTargetSize()
|
||||
{
|
||||
if (g_ActiveConfig.iEFBScale == EFB_SCALE_AUTO_INTEGRAL)
|
||||
m_efb_scale = g_presenter->AutoIntegralScale();
|
||||
else
|
||||
m_efb_scale = g_ActiveConfig.iEFBScale;
|
||||
|
||||
const u32 max_size = g_ActiveConfig.backend_info.MaxTextureSize;
|
||||
if (max_size < EFB_WIDTH * m_efb_scale)
|
||||
m_efb_scale = max_size / EFB_WIDTH;
|
||||
|
||||
u32 new_efb_width = std::max(EFB_WIDTH * static_cast<int>(m_efb_scale), 1u);
|
||||
u32 new_efb_height = std::max(EFB_HEIGHT * static_cast<int>(m_efb_scale), 1u);
|
||||
|
||||
return std::make_tuple(new_efb_width, new_efb_height);
|
||||
}
|
||||
|
||||
bool FramebufferManager::CreateEFBFramebuffer()
|
||||
{
|
||||
const TextureConfig efb_color_texture_config = GetEFBColorTextureConfig();
|
||||
const TextureConfig efb_depth_texture_config = GetEFBDepthTextureConfig();
|
||||
auto [width, height] = CalculateTargetSize();
|
||||
|
||||
const TextureConfig efb_color_texture_config = GetEFBColorTextureConfig(width, height);
|
||||
const TextureConfig efb_depth_texture_config = GetEFBDepthTextureConfig(width, height);
|
||||
|
||||
// We need a second texture to swap with for changing pixel formats
|
||||
m_efb_color_texture = g_gfx->CreateTexture(efb_color_texture_config, "EFB color texture");
|
||||
|
@ -634,7 +691,7 @@ void FramebufferManager::DestroyReadbackPipelines()
|
|||
|
||||
bool FramebufferManager::CreateReadbackFramebuffer()
|
||||
{
|
||||
if (g_renderer->GetEFBScale() != 1)
|
||||
if (GetEFBScale() != 1)
|
||||
{
|
||||
const TextureConfig color_config(IsUsingTiledEFBCache() ? m_efb_cache_tile_size : EFB_WIDTH,
|
||||
IsUsingTiledEFBCache() ? m_efb_cache_tile_size : EFB_HEIGHT, 1,
|
||||
|
@ -655,7 +712,7 @@ bool FramebufferManager::CreateReadbackFramebuffer()
|
|||
(IsUsingTiledEFBCache() && !g_ActiveConfig.backend_info.bSupportsPartialDepthCopies) ||
|
||||
!AbstractTexture::IsCompatibleDepthAndColorFormats(m_efb_depth_texture->GetFormat(),
|
||||
GetEFBDepthCopyFormat()) ||
|
||||
g_renderer->GetEFBScale() != 1)
|
||||
GetEFBScale() != 1)
|
||||
{
|
||||
const TextureConfig depth_config(IsUsingTiledEFBCache() ? m_efb_cache_tile_size : EFB_WIDTH,
|
||||
IsUsingTiledEFBCache() ? m_efb_cache_tile_size : EFB_HEIGHT, 1,
|
||||
|
@ -732,10 +789,10 @@ void FramebufferManager::PopulateEFBCache(bool depth, u32 tile_index, bool async
|
|||
// Issue a copy from framebuffer -> copy texture if we have >1xIR or MSAA on.
|
||||
EFBCacheData& data = depth ? m_efb_depth_cache : m_efb_color_cache;
|
||||
const MathUtil::Rectangle<int> rect = GetEFBCacheTileRect(tile_index);
|
||||
const MathUtil::Rectangle<int> native_rect = g_renderer->ConvertEFBRectangle(rect);
|
||||
const MathUtil::Rectangle<int> native_rect = ConvertEFBRectangle(rect);
|
||||
AbstractTexture* src_texture =
|
||||
depth ? ResolveEFBDepthTexture(native_rect) : ResolveEFBColorTexture(native_rect);
|
||||
if (g_renderer->GetEFBScale() != 1 || force_intermediate_copy)
|
||||
if (GetEFBScale() != 1 || force_intermediate_copy)
|
||||
{
|
||||
// Downsample from internal resolution to 1x.
|
||||
// TODO: This won't produce correct results at IRs above 2x. More samples are required.
|
||||
|
@ -795,9 +852,9 @@ void FramebufferManager::ClearEFB(const MathUtil::Rectangle<int>& rc, bool color
|
|||
FlagPeekCacheAsOutOfDate();
|
||||
|
||||
// Native -> EFB coordinates
|
||||
MathUtil::Rectangle<int> target_rc = g_renderer->ConvertEFBRectangle(rc);
|
||||
MathUtil::Rectangle<int> target_rc = ConvertEFBRectangle(rc);
|
||||
target_rc = g_gfx->ConvertFramebufferRectangle(target_rc, m_efb_framebuffer.get());
|
||||
target_rc.ClampUL(0, 0, g_renderer->GetTargetWidth(), g_renderer->GetTargetHeight());
|
||||
target_rc.ClampUL(0, 0, m_efb_framebuffer->GetWidth(), m_efb_framebuffer->GetWidth());
|
||||
|
||||
// Determine whether the EFB has an alpha channel. If it doesn't, we can clear the alpha
|
||||
// channel to 0xFF.
|
||||
|
@ -925,7 +982,7 @@ void FramebufferManager::CreatePokeVertices(std::vector<EFBPokeVertex>* destinat
|
|||
// GPU will expand the point to a quad.
|
||||
const float cs_x = (static_cast<float>(x) + 0.5f) * cs_pixel_width - 1.0f;
|
||||
const float cs_y = 1.0f - (static_cast<float>(y) + 0.5f) * cs_pixel_height;
|
||||
const float point_size = static_cast<float>(g_renderer->GetEFBScale());
|
||||
const float point_size = static_cast<float>(GetEFBScale());
|
||||
destination_list->push_back({{cs_x, cs_y, z, point_size}, color});
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <array>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <tuple>
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/EnumFormatter.h"
|
||||
|
@ -54,8 +55,8 @@ public:
|
|||
static AbstractTextureFormat GetEFBColorFormat();
|
||||
static AbstractTextureFormat GetEFBDepthFormat();
|
||||
static AbstractTextureFormat GetEFBDepthCopyFormat();
|
||||
static TextureConfig GetEFBColorTextureConfig();
|
||||
static TextureConfig GetEFBDepthTextureConfig();
|
||||
static TextureConfig GetEFBColorTextureConfig(u32 width, u32 height);
|
||||
static TextureConfig GetEFBDepthTextureConfig(u32 width, u32 height);
|
||||
|
||||
// Accessors.
|
||||
AbstractTexture* GetEFBColorTexture() const { return m_efb_color_texture.get(); }
|
||||
|
@ -69,6 +70,20 @@ public:
|
|||
bool IsEFBStereo() const { return m_efb_color_texture->GetLayers() > 1; }
|
||||
FramebufferState GetEFBFramebufferState() const;
|
||||
|
||||
// EFB coordinate conversion functions
|
||||
// Use this to convert a whole native EFB rect to backbuffer coordinates
|
||||
MathUtil::Rectangle<int> ConvertEFBRectangle(const MathUtil::Rectangle<int>& rc) const;
|
||||
|
||||
unsigned int GetEFBScale() const;
|
||||
|
||||
// Use this to upscale native EFB coordinates to IDEAL internal resolution
|
||||
int EFBToScaledX(int x) const;
|
||||
int EFBToScaledY(int y) const;
|
||||
|
||||
// Floating point versions of the above - only use them if really necessary
|
||||
float EFBToScaledXf(float x) const;
|
||||
float EFBToScaledYf(float y) const;
|
||||
|
||||
// First-time setup.
|
||||
bool Initialize();
|
||||
|
||||
|
@ -172,9 +187,13 @@ protected:
|
|||
void DrawPokeVertices(const EFBPokeVertex* vertices, u32 vertex_count,
|
||||
const AbstractPipeline* pipeline);
|
||||
|
||||
std::tuple<u32, u32> CalculateTargetSize();
|
||||
|
||||
void DoLoadState(PointerWrap& p);
|
||||
void DoSaveState(PointerWrap& p);
|
||||
|
||||
float m_efb_scale = 0.0f;
|
||||
|
||||
std::unique_ptr<AbstractTexture> m_efb_color_texture;
|
||||
std::unique_ptr<AbstractTexture> m_efb_convert_color_texture;
|
||||
std::unique_ptr<AbstractTexture> m_efb_depth_texture;
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
#include "Common/ChunkFile.h"
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "VideoCommon/RenderBase.h"
|
||||
#include "VideoCommon/FramebufferManager.h"
|
||||
#include "VideoCommon/VideoCommon.h"
|
||||
#include "VideoCommon/VideoConfig.h"
|
||||
#include "VideoCommon/XFMemory.h"
|
||||
|
@ -74,7 +74,7 @@ void PixelShaderManager::Dirty()
|
|||
// Any constants that can changed based on settings should be re-calculated
|
||||
m_fog_range_adjusted_changed = true;
|
||||
|
||||
SetEfbScaleChanged(g_renderer->EFBToScaledXf(1), g_renderer->EFBToScaledYf(1));
|
||||
SetEfbScaleChanged(g_framebuffer_manager->EFBToScaledXf(1), g_framebuffer_manager->EFBToScaledYf(1));
|
||||
SetFogParamChanged();
|
||||
|
||||
dirty = true;
|
||||
|
@ -103,7 +103,7 @@ void PixelShaderManager::SetConstants()
|
|||
// TODO: Shouldn't this be EFBToScaledXf?
|
||||
constants.fogf[2] = ScreenSpaceCenter;
|
||||
constants.fogf[3] =
|
||||
static_cast<float>(g_renderer->EFBToScaledX(static_cast<int>(2.0f * xfmem.viewport.wd)));
|
||||
static_cast<float>(g_framebuffer_manager->EFBToScaledX(static_cast<int>(2.0f * xfmem.viewport.wd)));
|
||||
|
||||
for (size_t i = 0, vec_index = 0; i < std::size(bpmem.fogRange.K); i++)
|
||||
{
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include "VideoCommon/Present.h"
|
||||
|
||||
#include "Common/ChunkFile.h"
|
||||
#include "Core/HW/VideoInterface.h"
|
||||
#include "Core/Host.h"
|
||||
|
||||
|
@ -17,6 +18,7 @@
|
|||
#include "VideoCommon/VertexManagerBase.h"
|
||||
#include "VideoCommon/VideoConfig.h"
|
||||
#include "VideoCommon/VideoEvents.h"
|
||||
#include "Present.h"
|
||||
|
||||
std::unique_ptr<VideoCommon::Presenter> g_presenter;
|
||||
|
||||
|
@ -61,35 +63,39 @@ bool Presenter::Initialize()
|
|||
return true;
|
||||
}
|
||||
|
||||
bool Presenter::FetchXFB(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height)
|
||||
bool Presenter::FetchXFB(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height, u64 ticks)
|
||||
{
|
||||
ReleaseXFBContentLock();
|
||||
|
||||
m_xfb_entry = g_texture_cache->GetXFBTexture(xfb_addr, fb_width, fb_height, fb_stride, &m_xfb_rect);
|
||||
bool is_duplicate = m_xfb_entry->id == m_last_xfb_id;
|
||||
|
||||
m_xfb_entry->AcquireContentLock();
|
||||
if (m_last_xfb_id == m_xfb_entry->id)
|
||||
return false;
|
||||
|
||||
m_last_xfb_addr = xfb_addr;
|
||||
m_last_xfb_ticks = ticks;
|
||||
m_last_xfb_width = fb_width;
|
||||
m_last_xfb_stride = fb_stride;
|
||||
m_last_xfb_height = fb_height;
|
||||
m_last_xfb_id = m_xfb_entry->id;
|
||||
|
||||
return true;
|
||||
return is_duplicate;
|
||||
}
|
||||
|
||||
void Presenter::ViSwap(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height, u64 ticks)
|
||||
{
|
||||
bool unique = FetchXFB(xfb_addr, fb_width, fb_stride, fb_height);
|
||||
bool unique = FetchXFB(xfb_addr, fb_width, fb_stride, fb_height, ticks);
|
||||
|
||||
PresentInfo present_info;
|
||||
present_info.emulated_timestamp = ticks;
|
||||
if (unique)
|
||||
{
|
||||
present_info.frame_count = g_renderer->FrameCountIncrement();
|
||||
present_info.frame_count = m_frame_count++;
|
||||
present_info.reason = PresentInfo::PresentReason::VideoInterface;
|
||||
}
|
||||
else
|
||||
{
|
||||
present_info.frame_count = g_renderer->FrameCount() - 1; // Previous frame
|
||||
present_info.frame_count = m_frame_count - 1; // Previous frame
|
||||
present_info.reason = PresentInfo::PresentReason::VideoInterfaceDuplicate;
|
||||
}
|
||||
present_info.present_count = m_present_count;
|
||||
|
@ -111,11 +117,11 @@ void Presenter::ViSwap(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height,
|
|||
|
||||
void Presenter::ImmediateSwap(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height, u64 ticks)
|
||||
{
|
||||
FetchXFB(xfb_addr, fb_width, fb_stride, fb_height);
|
||||
FetchXFB(xfb_addr, fb_width, fb_stride, fb_height, ticks);
|
||||
|
||||
PresentInfo present_info;
|
||||
present_info.emulated_timestamp = ticks;
|
||||
present_info.frame_count = g_renderer->FrameCountIncrement();
|
||||
present_info.frame_count = m_frame_count++;
|
||||
present_info.reason = PresentInfo::PresentReason::Immediate;
|
||||
present_info.present_count = m_present_count++;
|
||||
|
||||
|
@ -145,7 +151,7 @@ void Presenter::ProcessFrameDumping(u64 ticks) const
|
|||
}
|
||||
|
||||
g_frame_dumper->DumpCurrentFrame(m_xfb_entry->texture.get(), m_xfb_rect, target_rect, ticks,
|
||||
g_renderer->FrameCount());
|
||||
m_frame_count);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -307,6 +313,13 @@ void* Presenter::GetNewSurfaceHandle()
|
|||
return handle;
|
||||
}
|
||||
|
||||
u32 Presenter::AutoIntegralScale() const
|
||||
{
|
||||
// Calculate a scale based on the window size
|
||||
u32 width = EFB_WIDTH * m_target_rectangle.GetWidth() / m_last_xfb_width;
|
||||
u32 height = EFB_HEIGHT * m_target_rectangle.GetHeight() / m_last_xfb_height;
|
||||
return std::max((width - 1) / EFB_WIDTH + 1, (height - 1) / EFB_HEIGHT + 1);
|
||||
}
|
||||
void Presenter::SetWindowSize(int width, int height)
|
||||
{
|
||||
const auto [out_width, out_height] = g_presenter->CalculateOutputDimensions(width, height);
|
||||
|
@ -577,4 +590,26 @@ void Presenter::SetMousePress(u32 button_mask)
|
|||
m_onscreen_ui->SetMousePress(button_mask);
|
||||
}
|
||||
|
||||
void Presenter::DoState(PointerWrap& p)
|
||||
{
|
||||
p.Do(m_frame_count);
|
||||
p.Do(m_last_xfb_ticks);
|
||||
p.Do(m_last_xfb_addr);
|
||||
p.Do(m_last_xfb_width);
|
||||
p.Do(m_last_xfb_stride);
|
||||
p.Do(m_last_xfb_height);
|
||||
|
||||
if (p.IsReadMode())
|
||||
{
|
||||
// This technically counts as the end of the frame
|
||||
AfterFrameEvent::Trigger();
|
||||
|
||||
// re-display the most recent XFB
|
||||
ImmediateSwap(m_last_xfb_addr, m_last_xfb_width, m_last_xfb_stride,
|
||||
m_last_xfb_height, m_last_xfb_ticks);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
} // namespace VideoCommon
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include "VideoCommon/TextureCacheBase.h"
|
||||
#include "VideoCommon/TextureConfig.h"
|
||||
#include "VideoCommon/VideoCommon.h"
|
||||
|
||||
#include <array>
|
||||
#include <memory>
|
||||
|
@ -47,6 +48,7 @@ public:
|
|||
int GetBackbufferWidth() const { return m_backbuffer_width; }
|
||||
int GetBackbufferHeight() const { return m_backbuffer_height; }
|
||||
float GetBackbufferScale() const { return m_backbuffer_scale; }
|
||||
u32 AutoIntegralScale() const;
|
||||
AbstractTextureFormat GetBackbufferFormat() const { return m_backbuffer_format; }
|
||||
void SetWindowSize(int width, int height);
|
||||
void SetBackbuffer(int backbuffer_width, int backbuffer_height);
|
||||
|
@ -86,12 +88,16 @@ public:
|
|||
void SetMousePos(float x, float y);
|
||||
void SetMousePress(u32 button_mask);
|
||||
|
||||
int FrameCount() const { return m_frame_count; }
|
||||
|
||||
void DoState(PointerWrap& p);
|
||||
|
||||
const MathUtil::Rectangle<int>& GetTargetRectangle() const { return m_target_rectangle; }
|
||||
|
||||
private:
|
||||
// Fetches the XFB texture from the texture cache.
|
||||
// Returns true the contents have changed since last time
|
||||
bool FetchXFB(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height);
|
||||
bool FetchXFB(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height, u64 ticks);
|
||||
|
||||
void ProcessFrameDumping(u64 ticks) const;
|
||||
|
||||
|
@ -130,7 +136,15 @@ private:
|
|||
std::unique_ptr<VideoCommon::PostProcessing> m_post_processor;
|
||||
std::unique_ptr<VideoCommon::OnScreenUI> m_onscreen_ui;
|
||||
|
||||
u64 m_frame_count = 0;
|
||||
u64 m_present_count = 0;
|
||||
|
||||
// XFB tracking
|
||||
u64 m_last_xfb_ticks = 0;
|
||||
u32 m_last_xfb_addr = 0;
|
||||
u32 m_last_xfb_width = MAX_XFB_WIDTH;
|
||||
u32 m_last_xfb_stride = 0;
|
||||
u32 m_last_xfb_height = MAX_XFB_HEIGHT;
|
||||
};
|
||||
|
||||
} // namespace VideoCommon
|
||||
|
|
|
@ -37,7 +37,6 @@
|
|||
#include "VideoCommon/FrameDumper.h"
|
||||
#include "VideoCommon/FramebufferManager.h"
|
||||
#include "VideoCommon/PixelEngine.h"
|
||||
#include "VideoCommon/PixelShaderManager.h"
|
||||
#include "VideoCommon/Present.h"
|
||||
#include "VideoCommon/VertexManagerBase.h"
|
||||
#include "VideoCommon/VideoBackendBase.h"
|
||||
|
@ -48,10 +47,8 @@
|
|||
std::unique_ptr<Renderer> g_renderer;
|
||||
|
||||
Renderer::Renderer()
|
||||
: m_prev_efb_format{PixelFormat::INVALID_FMT},
|
||||
m_last_xfb_width{MAX_XFB_WIDTH}, m_last_xfb_height{MAX_XFB_HEIGHT}
|
||||
: m_prev_efb_format{PixelFormat::INVALID_FMT}
|
||||
{
|
||||
CalculateTargetSize();
|
||||
UpdateWidescreen();
|
||||
|
||||
m_config_changed_handle = ConfigChangedEvent::Register([this](u32 bits) { OnConfigChanged(bits); }, "Renderer");
|
||||
|
@ -168,83 +165,6 @@ void Renderer::PokeEFB(EFBAccessType type, const EfbPokeData* points, size_t num
|
|||
}
|
||||
}
|
||||
|
||||
unsigned int Renderer::GetEFBScale() const
|
||||
{
|
||||
return m_efb_scale;
|
||||
}
|
||||
|
||||
int Renderer::EFBToScaledX(int x) const
|
||||
{
|
||||
return x * static_cast<int>(m_efb_scale);
|
||||
}
|
||||
|
||||
int Renderer::EFBToScaledY(int y) const
|
||||
{
|
||||
return y * static_cast<int>(m_efb_scale);
|
||||
}
|
||||
|
||||
float Renderer::EFBToScaledXf(float x) const
|
||||
{
|
||||
return x * ((float)GetTargetWidth() / (float)EFB_WIDTH);
|
||||
}
|
||||
|
||||
float Renderer::EFBToScaledYf(float y) const
|
||||
{
|
||||
return y * ((float)GetTargetHeight() / (float)EFB_HEIGHT);
|
||||
}
|
||||
|
||||
std::tuple<int, int> Renderer::CalculateTargetScale(int x, int y) const
|
||||
{
|
||||
return std::make_tuple(x * static_cast<int>(m_efb_scale), y * static_cast<int>(m_efb_scale));
|
||||
}
|
||||
|
||||
// return true if target size changed
|
||||
bool Renderer::CalculateTargetSize()
|
||||
{
|
||||
if (g_ActiveConfig.iEFBScale == EFB_SCALE_AUTO_INTEGRAL)
|
||||
{
|
||||
auto target_rectangle = g_presenter->GetTargetRectangle();
|
||||
// Set a scale based on the window size
|
||||
int width = EFB_WIDTH * target_rectangle.GetWidth() / m_last_xfb_width;
|
||||
int height = EFB_HEIGHT * target_rectangle.GetHeight() / m_last_xfb_height;
|
||||
m_efb_scale = std::max((width - 1) / EFB_WIDTH + 1, (height - 1) / EFB_HEIGHT + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_efb_scale = g_ActiveConfig.iEFBScale;
|
||||
}
|
||||
|
||||
const u32 max_size = g_ActiveConfig.backend_info.MaxTextureSize;
|
||||
if (max_size < EFB_WIDTH * m_efb_scale)
|
||||
m_efb_scale = max_size / EFB_WIDTH;
|
||||
|
||||
auto [new_efb_width, new_efb_height] = CalculateTargetScale(EFB_WIDTH, EFB_HEIGHT);
|
||||
new_efb_width = std::max(new_efb_width, 1);
|
||||
new_efb_height = std::max(new_efb_height, 1);
|
||||
|
||||
if (new_efb_width != m_target_width || new_efb_height != m_target_height)
|
||||
{
|
||||
m_target_width = new_efb_width;
|
||||
m_target_height = new_efb_height;
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& pixel_shader_manager = system.GetPixelShaderManager();
|
||||
pixel_shader_manager.SetEfbScaleChanged(EFBToScaledXf(1), EFBToScaledYf(1));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
MathUtil::Rectangle<int> Renderer::ConvertEFBRectangle(const MathUtil::Rectangle<int>& rc) const
|
||||
{
|
||||
MathUtil::Rectangle<int> result;
|
||||
result.left = EFBToScaledX(rc.left);
|
||||
result.top = EFBToScaledY(rc.top);
|
||||
result.right = EFBToScaledX(rc.right);
|
||||
result.bottom = EFBToScaledY(rc.bottom);
|
||||
return result;
|
||||
}
|
||||
|
||||
void Renderer::UpdateWidescreen()
|
||||
{
|
||||
if (SConfig::GetInstance().bWii)
|
||||
|
@ -324,20 +244,7 @@ void Renderer::OnConfigChanged(u32 bits)
|
|||
UpdateWidescreen();
|
||||
}
|
||||
|
||||
void Renderer::TrackSwaps(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height, u64 ticks)
|
||||
{
|
||||
if (xfb_addr && fb_width && fb_stride && fb_height)
|
||||
{
|
||||
// Update our last xfb values
|
||||
m_last_xfb_addr = xfb_addr;
|
||||
m_last_xfb_ticks = ticks;
|
||||
m_last_xfb_width = fb_width;
|
||||
m_last_xfb_stride = fb_stride;
|
||||
m_last_xfb_height = fb_height;
|
||||
}
|
||||
}
|
||||
|
||||
bool Renderer::UseVertexDepthRange() const
|
||||
bool Renderer::UseVertexDepthRange()
|
||||
{
|
||||
// We can't compute the depth range in the vertex shader if we don't support depth clamp.
|
||||
if (!g_ActiveConfig.backend_info.bSupportsDepthClamp)
|
||||
|
@ -359,29 +266,9 @@ bool Renderer::UseVertexDepthRange() const
|
|||
void Renderer::DoState(PointerWrap& p)
|
||||
{
|
||||
p.Do(m_is_game_widescreen);
|
||||
p.Do(m_frame_count);
|
||||
p.Do(m_prev_efb_format);
|
||||
p.Do(m_last_xfb_ticks);
|
||||
p.Do(m_last_xfb_addr);
|
||||
p.Do(m_last_xfb_width);
|
||||
p.Do(m_last_xfb_stride);
|
||||
p.Do(m_last_xfb_height);
|
||||
|
||||
g_bounding_box->DoState(p);
|
||||
|
||||
if (p.IsReadMode())
|
||||
{
|
||||
m_was_orthographically_anamorphic = false;
|
||||
|
||||
// This technically counts as the end of the frame
|
||||
AfterFrameEvent::Trigger();
|
||||
|
||||
// re-display the most recent XFB
|
||||
g_presenter->ImmediateSwap(m_last_xfb_addr, m_last_xfb_width, m_last_xfb_stride,
|
||||
m_last_xfb_height, m_last_xfb_ticks);
|
||||
}
|
||||
|
||||
#if defined(HAVE_FFMPEG)
|
||||
g_frame_dumper->DoState(p);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -25,80 +25,38 @@ struct EfbPokeData
|
|||
// Renderer really isn't a very good name for this class - it's more like "Misc".
|
||||
// It used to be a massive mess, but almost everything has been refactored out.
|
||||
//
|
||||
// Most of the remaining functionality is related to EFB and Internal Resolution scaling
|
||||
//
|
||||
// It also handles the Widescreen heuristic, frame counting and tracking xfb across save states.
|
||||
// All that's left is Widescreen tracking, pixel format and a thin abstraction layer
|
||||
// for VideoSoftware to intercept EFB accesses.
|
||||
class Renderer
|
||||
{
|
||||
public:
|
||||
Renderer();
|
||||
virtual ~Renderer();
|
||||
|
||||
// Ideal internal resolution - multiple of the native EFB resolution
|
||||
int GetTargetWidth() const { return m_target_width; }
|
||||
int GetTargetHeight() const { return m_target_height; }
|
||||
|
||||
// EFB coordinate conversion functions
|
||||
// Use this to convert a whole native EFB rect to backbuffer coordinates
|
||||
MathUtil::Rectangle<int> ConvertEFBRectangle(const MathUtil::Rectangle<int>& rc) const;
|
||||
|
||||
unsigned int GetEFBScale() const;
|
||||
|
||||
// Use this to upscale native EFB coordinates to IDEAL internal resolution
|
||||
int EFBToScaledX(int x) const;
|
||||
int EFBToScaledY(int y) const;
|
||||
|
||||
// Floating point versions of the above - only use them if really necessary
|
||||
float EFBToScaledXf(float x) const;
|
||||
float EFBToScaledYf(float y) const;
|
||||
|
||||
virtual void ReinterpretPixelData(EFBReinterpretType convtype);
|
||||
|
||||
virtual u32 AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data);
|
||||
virtual void PokeEFB(EFBAccessType type, const EfbPokeData* points, size_t num_points);
|
||||
|
||||
// Track swaps for save-states
|
||||
void TrackSwaps(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height, u64 ticks);
|
||||
|
||||
bool IsGameWidescreen() const { return m_is_game_widescreen; }
|
||||
|
||||
PixelFormat GetPrevPixelFormat() const { return m_prev_efb_format; }
|
||||
void StorePixelFormat(PixelFormat new_format) { m_prev_efb_format = new_format; }
|
||||
|
||||
bool UseVertexDepthRange() const;
|
||||
static bool UseVertexDepthRange();
|
||||
void DoState(PointerWrap& p);
|
||||
|
||||
bool CalculateTargetSize();
|
||||
|
||||
int FrameCount() const { return m_frame_count; }
|
||||
int FrameCountIncrement() { return m_frame_count++; }
|
||||
|
||||
void OnConfigChanged(u32 bits);
|
||||
|
||||
protected:
|
||||
void UpdateWidescreen();
|
||||
void UpdateWidescreenHeuristic();
|
||||
|
||||
std::tuple<int, int> CalculateTargetScale(int x, int y) const;
|
||||
|
||||
bool m_is_game_widescreen = false;
|
||||
bool m_was_orthographically_anamorphic = false;
|
||||
|
||||
// The framebuffer size
|
||||
int m_target_width = 1;
|
||||
int m_target_height = 1;
|
||||
|
||||
private:
|
||||
PixelFormat m_prev_efb_format;
|
||||
unsigned int m_efb_scale = 1;
|
||||
|
||||
u64 m_last_xfb_ticks = 0;
|
||||
u32 m_last_xfb_addr = 0;
|
||||
u32 m_last_xfb_width = 0;
|
||||
u32 m_last_xfb_stride = 0;
|
||||
u32 m_last_xfb_height = 0;
|
||||
|
||||
int m_frame_count = 0;
|
||||
|
||||
EventHook m_update_widescreen_handle;
|
||||
EventHook m_config_changed_handle;
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
#include "VideoCommon/HiresTextures.h"
|
||||
#include "VideoCommon/OpcodeDecoding.h"
|
||||
#include "VideoCommon/PixelShaderManager.h"
|
||||
#include "VideoCommon/RenderBase.h"
|
||||
#include "VideoCommon/Present.h"
|
||||
#include "VideoCommon/ShaderCache.h"
|
||||
#include "VideoCommon/Statistics.h"
|
||||
#include "VideoCommon/TMEM.h"
|
||||
|
@ -783,7 +783,7 @@ void TextureCacheBase::OnFrameEnd()
|
|||
g_texture_cache->FlushEFBCopies();
|
||||
}
|
||||
|
||||
g_texture_cache->Cleanup(g_renderer->FrameCount());
|
||||
g_texture_cache->Cleanup(g_presenter->FrameCount());
|
||||
}
|
||||
|
||||
void TCacheEntry::DoState(PointerWrap& p)
|
||||
|
@ -921,17 +921,17 @@ RcTcacheEntry TextureCacheBase::DoPartialTextureUpdates(RcTcacheEntry& entry_to_
|
|||
entry->native_width != entry->GetWidth() || entry->native_height != entry->GetHeight())
|
||||
{
|
||||
ScaleTextureCacheEntryTo(entry_to_update,
|
||||
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));
|
||||
g_framebuffer_manager->EFBToScaledX(entry_to_update->native_width),
|
||||
g_framebuffer_manager->EFBToScaledY(entry_to_update->native_height));
|
||||
ScaleTextureCacheEntryTo(entry, g_framebuffer_manager->EFBToScaledX(entry->native_width),
|
||||
g_framebuffer_manager->EFBToScaledY(entry->native_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);
|
||||
src_x = g_framebuffer_manager->EFBToScaledX(src_x);
|
||||
src_y = g_framebuffer_manager->EFBToScaledY(src_y);
|
||||
dst_x = g_framebuffer_manager->EFBToScaledX(dst_x);
|
||||
dst_y = g_framebuffer_manager->EFBToScaledY(dst_y);
|
||||
copy_width = g_framebuffer_manager->EFBToScaledX(copy_width);
|
||||
copy_height = g_framebuffer_manager->EFBToScaledY(copy_height);
|
||||
}
|
||||
|
||||
// If the source rectangle is outside of what we actually have in VRAM, skip the copy.
|
||||
|
@ -1091,7 +1091,7 @@ static void SetSamplerState(u32 index, float custom_tex_scale, bool custom_tex,
|
|||
// that have arbitrary contents, eg. are used for fog effects where the
|
||||
// distance they kick in at is important to preserve at any resolution.
|
||||
// Correct this with the upscaling factor of custom textures.
|
||||
s32 lod_offset = std::log2(g_renderer->GetEFBScale() / custom_tex_scale) * 256.f;
|
||||
s32 lod_offset = std::log2(g_framebuffer_manager->GetEFBScale() / custom_tex_scale) * 256.f;
|
||||
state.tm0.lod_bias = std::clamp<s32>(state.tm0.lod_bias + lod_offset, -32768, 32767);
|
||||
|
||||
// Anisotropic also pushes mips farther away so it cannot be used either
|
||||
|
@ -1957,8 +1957,8 @@ void TextureCacheBase::StitchXFBCopy(RcTcacheEntry& stitched_entry)
|
|||
// copies to be stitched together.
|
||||
if (create_upscaled_copy)
|
||||
{
|
||||
ScaleTextureCacheEntryTo(stitched_entry, g_renderer->EFBToScaledX(stitched_entry->native_width),
|
||||
g_renderer->EFBToScaledY(stitched_entry->native_height));
|
||||
ScaleTextureCacheEntryTo(stitched_entry, g_framebuffer_manager->EFBToScaledX(stitched_entry->native_width),
|
||||
g_framebuffer_manager->EFBToScaledY(stitched_entry->native_height));
|
||||
}
|
||||
|
||||
for (TCacheEntry* entry : candidates)
|
||||
|
@ -1993,17 +1993,17 @@ void TextureCacheBase::StitchXFBCopy(RcTcacheEntry& stitched_entry)
|
|||
// Scale to internal resolution.
|
||||
if (entry->native_width != entry->GetWidth())
|
||||
{
|
||||
src_x = g_renderer->EFBToScaledX(src_x);
|
||||
src_y = g_renderer->EFBToScaledY(src_y);
|
||||
src_width = g_renderer->EFBToScaledX(src_width);
|
||||
src_height = g_renderer->EFBToScaledY(src_height);
|
||||
src_x = g_framebuffer_manager->EFBToScaledX(src_x);
|
||||
src_y = g_framebuffer_manager->EFBToScaledY(src_y);
|
||||
src_width = g_framebuffer_manager->EFBToScaledX(src_width);
|
||||
src_height = g_framebuffer_manager->EFBToScaledY(src_height);
|
||||
}
|
||||
if (create_upscaled_copy)
|
||||
{
|
||||
dst_x = g_renderer->EFBToScaledX(dst_x);
|
||||
dst_y = g_renderer->EFBToScaledY(dst_y);
|
||||
dst_width = g_renderer->EFBToScaledX(dst_width);
|
||||
dst_height = g_renderer->EFBToScaledY(dst_height);
|
||||
dst_x = g_framebuffer_manager->EFBToScaledX(dst_x);
|
||||
dst_y = g_framebuffer_manager->EFBToScaledY(dst_y);
|
||||
dst_width = g_framebuffer_manager->EFBToScaledX(dst_width);
|
||||
dst_height = g_framebuffer_manager->EFBToScaledY(dst_height);
|
||||
}
|
||||
|
||||
// If the source rectangle is outside of what we actually have in VRAM, skip the copy.
|
||||
|
@ -2183,8 +2183,8 @@ void TextureCacheBase::CopyRenderTargetToTexture(
|
|||
// For the latter, we keep the EFB resolution for the virtual XFB blit.
|
||||
u32 tex_w = width;
|
||||
u32 tex_h = height;
|
||||
u32 scaled_tex_w = g_renderer->EFBToScaledX(width);
|
||||
u32 scaled_tex_h = g_renderer->EFBToScaledY(height);
|
||||
u32 scaled_tex_w = g_framebuffer_manager->EFBToScaledX(width);
|
||||
u32 scaled_tex_h = g_framebuffer_manager->EFBToScaledY(height);
|
||||
|
||||
if (scaleByHalf)
|
||||
{
|
||||
|
@ -2269,7 +2269,7 @@ void TextureCacheBase::CopyRenderTargetToTexture(
|
|||
// TODO: This only produces perfect downsampling for 2x IR, other resolutions will need more
|
||||
// complex down filtering to average all pixels and produce the correct result.
|
||||
const bool linear_filter =
|
||||
!is_depth_copy && (scaleByHalf || g_renderer->GetEFBScale() != 1 || y_scale > 1.0f);
|
||||
!is_depth_copy && (scaleByHalf || g_framebuffer_manager->GetEFBScale() != 1 || y_scale > 1.0f);
|
||||
|
||||
RcTcacheEntry entry;
|
||||
if (copy_to_vram)
|
||||
|
@ -2803,7 +2803,7 @@ void TextureCacheBase::CopyEFBToCacheEntry(RcTcacheEntry& entry, bool is_depth_c
|
|||
return;
|
||||
}
|
||||
|
||||
const auto scaled_src_rect = g_renderer->ConvertEFBRectangle(src_rect);
|
||||
const auto scaled_src_rect = g_framebuffer_manager->ConvertEFBRectangle(src_rect);
|
||||
const auto framebuffer_rect = g_gfx->ConvertFramebufferRectangle(
|
||||
scaled_src_rect, g_framebuffer_manager->GetEFBFramebuffer());
|
||||
AbstractTexture* src_texture =
|
||||
|
@ -2877,7 +2877,7 @@ void TextureCacheBase::CopyEFB(AbstractStagingTexture* dst, const EFBCopyParams&
|
|||
return;
|
||||
}
|
||||
|
||||
const auto scaled_src_rect = g_renderer->ConvertEFBRectangle(src_rect);
|
||||
const auto scaled_src_rect = g_framebuffer_manager->ConvertEFBRectangle(src_rect);
|
||||
const auto framebuffer_rect = g_gfx->ConvertFramebufferRectangle(
|
||||
scaled_src_rect, g_framebuffer_manager->GetEFBFramebuffer());
|
||||
AbstractTexture* src_texture =
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "VideoCommon/BPFunctions.h"
|
||||
#include "VideoCommon/BPMemory.h"
|
||||
#include "VideoCommon/CPMemory.h"
|
||||
#include "VideoCommon/FramebufferManager.h"
|
||||
#include "VideoCommon/FreeLookCamera.h"
|
||||
#include "VideoCommon/GraphicsModSystem/Runtime/GraphicsModActionData.h"
|
||||
#include "VideoCommon/GraphicsModSystem/Runtime/GraphicsModManager.h"
|
||||
|
@ -339,10 +340,10 @@ void VertexShaderManager::SetConstants(const std::vector<std::string>& textures)
|
|||
const bool bUseVertexRounding = g_ActiveConfig.UseVertexRounding();
|
||||
const float viewport_width = bUseVertexRounding ?
|
||||
(2.f * xfmem.viewport.wd) :
|
||||
g_renderer->EFBToScaledXf(2.f * xfmem.viewport.wd);
|
||||
g_framebuffer_manager->EFBToScaledXf(2.f * xfmem.viewport.wd);
|
||||
const float viewport_height = bUseVertexRounding ?
|
||||
(2.f * xfmem.viewport.ht) :
|
||||
g_renderer->EFBToScaledXf(2.f * xfmem.viewport.ht);
|
||||
g_framebuffer_manager->EFBToScaledXf(2.f * xfmem.viewport.ht);
|
||||
const float pixel_size_x = 2.f / viewport_width;
|
||||
const float pixel_size_y = 2.f / viewport_height;
|
||||
constants.pixelcentercorrection[0] = pixel_center_correction * pixel_size_x;
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "Core/ConfigManager.h"
|
||||
#include "Core/Core.h"
|
||||
#include "Core/Movie.h"
|
||||
#include "Core/System.h"
|
||||
|
||||
#include "VideoCommon/AbstractGfx.h"
|
||||
#include "VideoCommon/BPFunctions.h"
|
||||
|
@ -24,7 +25,7 @@
|
|||
#include "VideoCommon/GraphicsModSystem/Runtime/GraphicsModManager.h"
|
||||
#include "VideoCommon/OnScreenDisplay.h"
|
||||
#include "VideoCommon/Present.h"
|
||||
#include "VideoCommon/RenderBase.h"
|
||||
#include "VideoCommon/PixelShaderManager.h"
|
||||
#include "VideoCommon/ShaderGenCommon.h"
|
||||
#include "VideoCommon/TextureCacheBase.h"
|
||||
#include "VideoCommon/VertexManagerBase.h"
|
||||
|
@ -253,6 +254,7 @@ void CheckForConfigChanges()
|
|||
const auto old_texture_filtering_mode = g_ActiveConfig.texture_filtering_mode;
|
||||
const bool old_vsync = g_ActiveConfig.bVSyncActive;
|
||||
const bool old_bbox = g_ActiveConfig.bBBoxEnable;
|
||||
const int old_efb_scale = g_ActiveConfig.iEFBScale;
|
||||
const u32 old_game_mod_changes =
|
||||
g_ActiveConfig.graphics_mod_config ? g_ActiveConfig.graphics_mod_config->GetChangeCount() : 0;
|
||||
const bool old_graphics_mods_enabled = g_ActiveConfig.bGraphicMods;
|
||||
|
@ -302,7 +304,7 @@ void CheckForConfigChanges()
|
|||
changed_bits |= CONFIG_CHANGE_BIT_VSYNC;
|
||||
if (old_bbox != g_ActiveConfig.bBBoxEnable)
|
||||
changed_bits |= CONFIG_CHANGE_BIT_BBOX;
|
||||
if (g_renderer->CalculateTargetSize())
|
||||
if (old_efb_scale != g_ActiveConfig.iEFBScale)
|
||||
changed_bits |= CONFIG_CHANGE_BIT_TARGET_SIZE;
|
||||
if (old_suggested_aspect_mode != g_ActiveConfig.suggested_aspect_mode)
|
||||
changed_bits |= CONFIG_CHANGE_BIT_ASPECT_RATIO;
|
||||
|
@ -315,10 +317,7 @@ void CheckForConfigChanges()
|
|||
if (changed_bits == 0)
|
||||
return;
|
||||
|
||||
// Notify all listeners
|
||||
ConfigChangedEvent::Trigger(changed_bits);
|
||||
|
||||
// TODO: Move everything else to the ConfigChanged event
|
||||
float old_scale = g_framebuffer_manager->GetEFBScale();
|
||||
|
||||
// Framebuffer changed?
|
||||
if (changed_bits & (CONFIG_CHANGE_BIT_MULTISAMPLES | CONFIG_CHANGE_BIT_STEREO_MODE |
|
||||
|
@ -327,6 +326,13 @@ void CheckForConfigChanges()
|
|||
g_framebuffer_manager->RecreateEFBFramebuffer();
|
||||
}
|
||||
|
||||
if (old_scale != g_framebuffer_manager->GetEFBScale())
|
||||
{
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& pixel_shader_manager = system.GetPixelShaderManager();
|
||||
pixel_shader_manager.Dirty();
|
||||
}
|
||||
|
||||
// Reload shaders if host config has changed.
|
||||
if (changed_bits & (CONFIG_CHANGE_BIT_HOST_CONFIG | CONFIG_CHANGE_BIT_MULTISAMPLES))
|
||||
{
|
||||
|
@ -342,6 +348,11 @@ void CheckForConfigChanges()
|
|||
{
|
||||
BPFunctions::SetScissorAndViewport();
|
||||
}
|
||||
|
||||
// Notify all listeners
|
||||
ConfigChangedEvent::Trigger(changed_bits);
|
||||
|
||||
// TODO: Move everything else to the ConfigChanged event
|
||||
}
|
||||
|
||||
static EventHook s_check_config_event = AfterFrameEvent::Register([] {
|
||||
|
|
|
@ -7,15 +7,18 @@
|
|||
|
||||
#include "Common/ChunkFile.h"
|
||||
#include "Core/System.h"
|
||||
#include "VideoCommon/BoundingBox.h"
|
||||
#include "VideoCommon/BPMemory.h"
|
||||
#include "VideoCommon/BPStructs.h"
|
||||
#include "VideoCommon/CPMemory.h"
|
||||
#include "VideoCommon/CommandProcessor.h"
|
||||
#include "VideoCommon/Fifo.h"
|
||||
#include "VideoCommon/FramebufferManager.h"
|
||||
#include "VideoCommon/FrameDumper.h"
|
||||
#include "VideoCommon/GeometryShaderManager.h"
|
||||
#include "VideoCommon/PixelEngine.h"
|
||||
#include "VideoCommon/PixelShaderManager.h"
|
||||
#include "VideoCommon/Present.h"
|
||||
#include "VideoCommon/RenderBase.h"
|
||||
#include "VideoCommon/TMEM.h"
|
||||
#include "VideoCommon/TextureCacheBase.h"
|
||||
|
@ -95,6 +98,14 @@ void VideoCommon_DoState(PointerWrap& p)
|
|||
g_renderer->DoState(p);
|
||||
p.DoMarker("Renderer");
|
||||
|
||||
g_presenter->DoState(p);
|
||||
g_frame_dumper->DoState(p);
|
||||
p.DoMarker("Presenter");
|
||||
|
||||
g_bounding_box->DoState(p);
|
||||
p.DoMarker("Bounding Box");
|
||||
|
||||
|
||||
// Refresh state.
|
||||
if (p.IsReadMode())
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue