Merge pull request #11640 from AdmiralCurtiss/vi-class

HW/VideoInterface: Refactor to class.
This commit is contained in:
Mai 2023-03-11 18:00:24 -05:00 committed by GitHub
commit ee28d332b0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 451 additions and 430 deletions

View File

@ -496,8 +496,8 @@ bool CBoot::BootUp(Core::System& system, const Core::CPUThreadGuard& guard,
} }
// PAL Wii uses NTSC framerate and linecount in 60Hz modes // PAL Wii uses NTSC framerate and linecount in 60Hz modes
VideoInterface::Preset(DiscIO::IsNTSC(config.m_region) || system.GetVideoInterface().Preset(DiscIO::IsNTSC(config.m_region) ||
(config.bWii && Config::Get(Config::SYSCONF_PAL60))); (config.bWii && Config::Get(Config::SYSCONF_PAL60)));
struct BootTitle struct BootTitle
{ {

View File

@ -414,9 +414,9 @@ FifoPlayer& FifoPlayer::GetInstance()
void FifoPlayer::WriteFrame(const FifoFrameInfo& frame, const AnalyzedFrameInfo& info) void FifoPlayer::WriteFrame(const FifoFrameInfo& frame, const AnalyzedFrameInfo& info)
{ {
// Core timing information // Core timing information
auto& vi = Core::System::GetInstance().GetVideoInterface();
m_CyclesPerFrame = static_cast<u64>(SystemTimers::GetTicksPerSecond()) * m_CyclesPerFrame = static_cast<u64>(SystemTimers::GetTicksPerSecond()) *
VideoInterface::GetTargetRefreshRateDenominator() / vi.GetTargetRefreshRateDenominator() / vi.GetTargetRefreshRateNumerator();
VideoInterface::GetTargetRefreshRateNumerator();
m_ElapsedCycles = 0; m_ElapsedCycles = 0;
m_FrameFifoSize = static_cast<u32>(frame.fifoData.size()); m_FrameFifoSize = static_cast<u32>(frame.fifoData.size());

View File

@ -41,7 +41,7 @@ void Init(const Sram* override_sram)
// Init the whole Hardware // Init the whole Hardware
system.GetAudioInterface().Init(); system.GetAudioInterface().Init();
VideoInterface::Init(); system.GetVideoInterface().Init();
SerialInterface::Init(); SerialInterface::Init();
system.GetProcessorInterface().Init(); system.GetProcessorInterface().Init();
system.GetExpansionInterface().Init(override_sram); // Needs to be initialized before Memory system.GetExpansionInterface().Init(override_sram); // Needs to be initialized before Memory
@ -93,7 +93,7 @@ void DoState(PointerWrap& p)
p.DoMarker("Memory"); p.DoMarker("Memory");
system.GetMemoryInterface().DoState(p); system.GetMemoryInterface().DoState(p);
p.DoMarker("MemoryInterface"); p.DoMarker("MemoryInterface");
VideoInterface::DoState(p); system.GetVideoInterface().DoState(p);
p.DoMarker("VideoInterface"); p.DoMarker("VideoInterface");
SerialInterface::DoState(p); SerialInterface::DoState(p);
p.DoMarker("SerialInterface"); p.DoMarker("SerialInterface");

View File

@ -51,7 +51,7 @@ void MemoryManager::InitMMIO(bool is_wii)
auto& system = Core::System::GetInstance(); auto& system = Core::System::GetInstance();
system.GetCommandProcessor().RegisterMMIO(system, m_mmio_mapping.get(), 0x0C000000); system.GetCommandProcessor().RegisterMMIO(system, m_mmio_mapping.get(), 0x0C000000);
system.GetPixelEngine().RegisterMMIO(m_mmio_mapping.get(), 0x0C001000); system.GetPixelEngine().RegisterMMIO(m_mmio_mapping.get(), 0x0C001000);
VideoInterface::RegisterMMIO(m_mmio_mapping.get(), 0x0C002000); system.GetVideoInterface().RegisterMMIO(m_mmio_mapping.get(), 0x0C002000);
system.GetProcessorInterface().RegisterMMIO(m_mmio_mapping.get(), 0x0C003000); system.GetProcessorInterface().RegisterMMIO(m_mmio_mapping.get(), 0x0C003000);
system.GetMemoryInterface().RegisterMMIO(m_mmio_mapping.get(), 0x0C004000); system.GetMemoryInterface().RegisterMMIO(m_mmio_mapping.get(), 0x0C004000);
system.GetDSP().RegisterMMIO(m_mmio_mapping.get(), 0x0C005000); system.GetDSP().RegisterMMIO(m_mmio_mapping.get(), 0x0C005000);

View File

@ -149,8 +149,9 @@ void PerfTrackerCallback(Core::System& system, u64 userdata, s64 cyclesLate)
void VICallback(Core::System& system, u64 userdata, s64 cyclesLate) void VICallback(Core::System& system, u64 userdata, s64 cyclesLate)
{ {
auto& core_timing = system.GetCoreTiming(); auto& core_timing = system.GetCoreTiming();
VideoInterface::Update(core_timing.GetTicks() - cyclesLate); auto& vi = system.GetVideoInterface();
core_timing.ScheduleEvent(VideoInterface::GetTicksPerHalfLine() - cyclesLate, et_VI); vi.Update(core_timing.GetTicks() - cyclesLate);
core_timing.ScheduleEvent(vi.GetTicksPerHalfLine() - cyclesLate, et_VI);
} }
void DecrementerCallback(Core::System& system, u64 userdata, s64 cyclesLate) void DecrementerCallback(Core::System& system, u64 userdata, s64 cyclesLate)
@ -164,7 +165,7 @@ void PatchEngineCallback(Core::System& system, u64 userdata, s64 cycles_late)
{ {
// We have 2 periods, a 1000 cycle error period and the VI period. // We have 2 periods, a 1000 cycle error period and the VI period.
// We have to carefully combine these together so that we stay on the VI period without drifting. // We have to carefully combine these together so that we stay on the VI period without drifting.
u32 vi_interval = VideoInterface::GetTicksPerField(); u32 vi_interval = system.GetVideoInterface().GetTicksPerField();
s64 cycles_pruned = (userdata + cycles_late) % vi_interval; s64 cycles_pruned = (userdata + cycles_late) % vi_interval;
s64 next_schedule = 0; s64 next_schedule = 0;
@ -282,6 +283,7 @@ void Init()
auto& system = Core::System::GetInstance(); auto& system = Core::System::GetInstance();
auto& core_timing = system.GetCoreTiming(); auto& core_timing = system.GetCoreTiming();
auto& vi = system.GetVideoInterface();
core_timing.SetFakeTBStartValue(static_cast<u64>(s_cpu_core_clock / TIMER_RATIO) * core_timing.SetFakeTBStartValue(static_cast<u64>(s_cpu_core_clock / TIMER_RATIO) *
static_cast<u64>(ExpansionInterface::CEXIIPL::GetEmulatedTime( static_cast<u64>(ExpansionInterface::CEXIIPL::GetEmulatedTime(
@ -303,11 +305,11 @@ void Init()
core_timing.ScheduleEvent(0, et_perf_tracker); core_timing.ScheduleEvent(0, et_perf_tracker);
core_timing.ScheduleEvent(0, et_GPU_sleeper); core_timing.ScheduleEvent(0, et_GPU_sleeper);
core_timing.ScheduleEvent(VideoInterface::GetTicksPerHalfLine(), et_VI); core_timing.ScheduleEvent(vi.GetTicksPerHalfLine(), et_VI);
core_timing.ScheduleEvent(0, et_DSP); core_timing.ScheduleEvent(0, et_DSP);
core_timing.ScheduleEvent(GetAudioDMACallbackPeriod(), et_AudioDMA); core_timing.ScheduleEvent(GetAudioDMACallbackPeriod(), et_AudioDMA);
core_timing.ScheduleEvent(VideoInterface::GetTicksPerField(), et_PatchEngine); core_timing.ScheduleEvent(vi.GetTicksPerField(), et_PatchEngine);
if (SConfig::GetInstance().bWii) if (SConfig::GetInstance().bWii)
core_timing.ScheduleEvent(s_ipc_hle_period, et_IPC_HLE); core_timing.ScheduleEvent(s_ipc_hle_period, et_IPC_HLE);

File diff suppressed because it is too large Load Diff

View File

@ -3,11 +3,17 @@
#pragma once #pragma once
#include <array>
#include <memory> #include <memory>
#include "Common/CommonTypes.h" #include "Common/CommonTypes.h"
enum class FieldType;
class PointerWrap; class PointerWrap;
namespace Core
{
class System;
}
namespace MMIO namespace MMIO
{ {
class Mapping; class Mapping;
@ -15,23 +21,6 @@ class Mapping;
namespace VideoInterface namespace VideoInterface
{ {
class VideoInterfaceState
{
public:
VideoInterfaceState();
VideoInterfaceState(const VideoInterfaceState&) = delete;
VideoInterfaceState(VideoInterfaceState&&) = delete;
VideoInterfaceState& operator=(const VideoInterfaceState&) = delete;
VideoInterfaceState& operator=(VideoInterfaceState&&) = delete;
~VideoInterfaceState();
struct Data;
Data& GetData() { return *m_data; }
private:
std::unique_ptr<Data> m_data;
};
// VI Internal Hardware Addresses // VI Internal Hardware Addresses
enum enum
{ {
@ -360,41 +349,104 @@ union UVIHorizontalStepping
}; };
}; };
// For BS2 HLE class VideoInterfaceManager
void Preset(bool _bNTSC); {
public:
explicit VideoInterfaceManager(Core::System& system);
VideoInterfaceManager(const VideoInterfaceManager&) = delete;
VideoInterfaceManager(VideoInterfaceManager&&) = delete;
VideoInterfaceManager& operator=(const VideoInterfaceManager&) = delete;
VideoInterfaceManager& operator=(VideoInterfaceManager&&) = delete;
~VideoInterfaceManager();
void Init(); // For BS2 HLE
void DoState(PointerWrap& p); void Preset(bool _bNTSC);
void RegisterMMIO(MMIO::Mapping* mmio, u32 base); void Init();
void DoState(PointerWrap& p);
// returns a pointer to the current visible xfb void RegisterMMIO(MMIO::Mapping* mmio, u32 base);
u32 GetXFBAddressTop();
u32 GetXFBAddressBottom();
// Update and draw framebuffer // returns a pointer to the current visible xfb
void Update(u64 ticks); u32 GetXFBAddressTop() const;
u32 GetXFBAddressBottom() const;
// UpdateInterrupts: check if we have to generate a new VI Interrupt // Update and draw framebuffer
void UpdateInterrupts(); void Update(u64 ticks);
// Change values pertaining to video mode // UpdateInterrupts: check if we have to generate a new VI Interrupt
void UpdateParameters(); void UpdateInterrupts();
double GetTargetRefreshRate(); // Change values pertaining to video mode
u32 GetTargetRefreshRateNumerator(); void UpdateParameters();
u32 GetTargetRefreshRateDenominator();
u32 GetTicksPerSample(); double GetTargetRefreshRate() const;
u32 GetTicksPerHalfLine(); u32 GetTargetRefreshRateNumerator() const;
u32 GetTicksPerField(); u32 GetTargetRefreshRateDenominator() const;
// Get the aspect ratio of VI's active area. u32 GetTicksPerSample() const;
// This function only deals with standard aspect ratios. For widescreen aspect ratios, multiply the u32 GetTicksPerHalfLine() const;
// result by 1.33333.. u32 GetTicksPerField() const;
float GetAspectRatio();
// Create a fake VI mode for a fifolog // Get the aspect ratio of VI's active area.
void FakeVIUpdate(u32 xfb_address, u32 fb_width, u32 fb_stride, u32 fb_height); // This function only deals with standard aspect ratios. For widescreen aspect ratios, multiply
// the result by 1.33333..
float GetAspectRatio() const;
// Create a fake VI mode for a fifolog
void FakeVIUpdate(u32 xfb_address, u32 fb_width, u32 fb_stride, u32 fb_height);
private:
u32 GetHalfLinesPerEvenField() const;
u32 GetHalfLinesPerOddField() const;
u32 GetTicksPerEvenField() const;
u32 GetTicksPerOddField() const;
void LogField(FieldType field, u32 xfb_address) const;
void OutputField(FieldType field, u64 ticks);
void BeginField(FieldType field, u64 ticks);
void EndField(FieldType field, u64 ticks);
// Registers listed in order:
UVIVerticalTimingRegister m_vertical_timing_register;
UVIDisplayControlRegister m_display_control_register;
UVIHorizontalTiming0 m_h_timing_0;
UVIHorizontalTiming1 m_h_timing_1;
UVIVBlankTimingRegister m_vblank_timing_odd;
UVIVBlankTimingRegister m_vblank_timing_even;
UVIBurstBlankingRegister m_burst_blanking_odd;
UVIBurstBlankingRegister m_burst_blanking_even;
UVIFBInfoRegister m_xfb_info_top;
UVIFBInfoRegister m_xfb_info_bottom;
UVIFBInfoRegister m_xfb_3d_info_top; // Start making your stereoscopic demos! :p
UVIFBInfoRegister m_xfb_3d_info_bottom;
std::array<UVIInterruptRegister, 4> m_interrupt_register{};
std::array<UVILatchRegister, 2> m_latch_register{};
PictureConfigurationRegister m_picture_configuration;
UVIHorizontalScaling m_horizontal_scaling;
SVIFilterCoefTables m_filter_coef_tables;
u32 m_unknown_aa_register = 0; // ??? 0x00FF0000
u16 m_clock = 0; // 0: 27MHz, 1: 54MHz
UVIDTVStatus m_dtv_status;
UVIHorizontalStepping m_fb_width; // Only correct when scaling is enabled?
UVIBorderBlankRegister m_border_hblank;
// 0xcc002076 - 0xcc00207f is full of 0x00FF: unknown
// 0xcc002080 - 0xcc002100 even more unknown
double m_target_refresh_rate = 0;
u32 m_target_refresh_rate_numerator = 0;
u32 m_target_refresh_rate_denominator = 1;
u64 m_ticks_last_line_start = 0; // number of ticks when the current full scanline started
u32 m_half_line_count = 0; // number of halflines that have occurred for this full frame
u32 m_half_line_of_next_si_poll = 0; // halfline when next SI poll results should be available
// below indexes are 0-based
u32 m_even_field_first_hl = 0; // index first halfline of the even field
u32 m_odd_field_first_hl = 0; // index first halfline of the odd field
u32 m_even_field_last_hl = 0; // index last halfline of the even field
u32 m_odd_field_last_hl = 0; // index last halfline of the odd field
Core::System& m_system;
};
} // namespace VideoInterface } // namespace VideoInterface

View File

@ -96,7 +96,7 @@ static size_t s_state_writes_in_queue;
static std::condition_variable s_state_write_queue_is_empty; static std::condition_variable s_state_write_queue_is_empty;
// Don't forget to increase this after doing changes on the savestate system // Don't forget to increase this after doing changes on the savestate system
constexpr u32 STATE_VERSION = 158; // Last changed in PR 11522 constexpr u32 STATE_VERSION = 159; // Last changed in PR 11640
// Maps savestate versions to Dolphin versions. // Maps savestate versions to Dolphin versions.
// Versions after 42 don't need to be added to this list, // Versions after 42 don't need to be added to this list,

View File

@ -38,7 +38,7 @@ struct System::Impl
explicit Impl(System& system) explicit Impl(System& system)
: m_audio_interface(system), m_core_timing(system), m_dsp(system), m_dvd_interface(system), : m_audio_interface(system), m_core_timing(system), m_dsp(system), m_dvd_interface(system),
m_dvd_thread(system), m_expansion_interface(system), m_gp_fifo(system), m_dvd_thread(system), m_expansion_interface(system), m_gp_fifo(system),
m_ppc_state(PowerPC::ppcState) m_ppc_state(PowerPC::ppcState), m_video_interface(system)
{ {
} }
@ -68,7 +68,7 @@ struct System::Impl
SerialInterface::SerialInterfaceState m_serial_interface_state; SerialInterface::SerialInterfaceState m_serial_interface_state;
Sram m_sram; Sram m_sram;
VertexShaderManager m_vertex_shader_manager; VertexShaderManager m_vertex_shader_manager;
VideoInterface::VideoInterfaceState m_video_interface_state; VideoInterface::VideoInterfaceManager m_video_interface;
}; };
System::System() : m_impl{std::make_unique<Impl>(*this)} System::System() : m_impl{std::make_unique<Impl>(*this)}
@ -224,8 +224,8 @@ VertexShaderManager& System::GetVertexShaderManager() const
return m_impl->m_vertex_shader_manager; return m_impl->m_vertex_shader_manager;
} }
VideoInterface::VideoInterfaceState& System::GetVideoInterfaceState() const VideoInterface::VideoInterfaceManager& System::GetVideoInterface() const
{ {
return m_impl->m_video_interface_state; return m_impl->m_video_interface;
} }
} // namespace Core } // namespace Core

View File

@ -82,7 +82,7 @@ class SerialInterfaceState;
}; };
namespace VideoInterface namespace VideoInterface
{ {
class VideoInterfaceState; class VideoInterfaceManager;
}; };
namespace Core namespace Core
@ -141,7 +141,7 @@ public:
SerialInterface::SerialInterfaceState& GetSerialInterfaceState() const; SerialInterface::SerialInterfaceState& GetSerialInterfaceState() const;
Sram& GetSRAM() const; Sram& GetSRAM() const;
VertexShaderManager& GetVertexShaderManager() const; VertexShaderManager& GetVertexShaderManager() const;
VideoInterface::VideoInterfaceState& GetVideoInterfaceState() const; VideoInterface::VideoInterfaceManager& GetVideoInterface() const;
private: private:
System(); System();

View File

@ -366,7 +366,8 @@ static void BPWritten(PixelShaderManager& pixel_shader_manager,
{ {
if (FifoPlayer::GetInstance().IsRunningWithFakeVideoInterfaceUpdates()) if (FifoPlayer::GetInstance().IsRunningWithFakeVideoInterfaceUpdates())
{ {
VideoInterface::FakeVIUpdate(destAddr, srcRect.GetWidth(), destStride, height); auto& vi = Core::System::GetInstance().GetVideoInterface();
vi.FakeVIUpdate(destAddr, srcRect.GetWidth(), destStride, height);
} }
} }
} }

View File

@ -36,6 +36,7 @@ extern "C" {
#include "Core/ConfigManager.h" #include "Core/ConfigManager.h"
#include "Core/HW/SystemTimers.h" #include "Core/HW/SystemTimers.h"
#include "Core/HW/VideoInterface.h" #include "Core/HW/VideoInterface.h"
#include "Core/System.h"
#include "VideoCommon/FrameDumper.h" #include "VideoCommon/FrameDumper.h"
#include "VideoCommon/OnScreenDisplay.h" #include "VideoCommon/OnScreenDisplay.h"
@ -65,10 +66,11 @@ namespace
{ {
AVRational GetTimeBaseForCurrentRefreshRate() AVRational GetTimeBaseForCurrentRefreshRate()
{ {
auto& vi = Core::System::GetInstance().GetVideoInterface();
int num; int num;
int den; int den;
av_reduce(&num, &den, int(VideoInterface::GetTargetRefreshRateDenominator()), av_reduce(&num, &den, int(vi.GetTargetRefreshRateDenominator()),
int(VideoInterface::GetTargetRefreshRateNumerator()), std::numeric_limits<int>::max()); int(vi.GetTargetRefreshRateNumerator()), std::numeric_limits<int>::max());
return AVRational{num, den}; return AVRational{num, den};
} }

View File

@ -76,7 +76,8 @@ double PerformanceMetrics::GetMaxSpeed() const
double PerformanceMetrics::GetLastSpeedDenominator() const double PerformanceMetrics::GetLastSpeedDenominator() const
{ {
return DT_s(m_speed_counter.GetLastRawDt()).count() * VideoInterface::GetTargetRefreshRate(); return DT_s(m_speed_counter.GetLastRawDt()).count() *
Core::System::GetInstance().GetVideoInterface().GetTargetRefreshRate();
} }
void PerformanceMetrics::DrawImGuiStats(const float backbuffer_scale) void PerformanceMetrics::DrawImGuiStats(const float backbuffer_scale)

View File

@ -6,6 +6,7 @@
#include "Common/ChunkFile.h" #include "Common/ChunkFile.h"
#include "Core/HW/VideoInterface.h" #include "Core/HW/VideoInterface.h"
#include "Core/Host.h" #include "Core/Host.h"
#include "Core/System.h"
#include "InputCommon/ControllerInterface/ControllerInterface.h" #include "InputCommon/ControllerInterface/ControllerInterface.h"
@ -249,7 +250,8 @@ float Presenter::CalculateDrawAspectRatio() const
if (aspect_mode == AspectMode::Stretch) if (aspect_mode == AspectMode::Stretch)
return (static_cast<float>(m_backbuffer_width) / static_cast<float>(m_backbuffer_height)); return (static_cast<float>(m_backbuffer_width) / static_cast<float>(m_backbuffer_height));
const float aspect_ratio = VideoInterface::GetAspectRatio(); auto& vi = Core::System::GetInstance().GetVideoInterface();
const float aspect_ratio = vi.GetAspectRatio();
if (aspect_mode == AspectMode::AnalogWide || if (aspect_mode == AspectMode::AnalogWide ||
(aspect_mode == AspectMode::Auto && g_widescreen->IsGameWidescreen())) (aspect_mode == AspectMode::Auto && g_widescreen->IsGameWidescreen()))
@ -378,7 +380,8 @@ void Presenter::UpdateDrawRectangle()
// Don't know if there is a better place for this code so there isn't a 1 frame delay // Don't know if there is a better place for this code so there isn't a 1 frame delay
if (g_ActiveConfig.bWidescreenHack) if (g_ActiveConfig.bWidescreenHack)
{ {
float source_aspect = VideoInterface::GetAspectRatio(); auto& vi = Core::System::GetInstance().GetVideoInterface();
float source_aspect = vi.GetAspectRatio();
if (g_widescreen->IsGameWidescreen()) if (g_widescreen->IsGameWidescreen())
source_aspect = AspectToWidescreen(source_aspect); source_aspect = AspectToWidescreen(source_aspect);