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
VideoInterface::Preset(DiscIO::IsNTSC(config.m_region) ||
(config.bWii && Config::Get(Config::SYSCONF_PAL60)));
system.GetVideoInterface().Preset(DiscIO::IsNTSC(config.m_region) ||
(config.bWii && Config::Get(Config::SYSCONF_PAL60)));
struct BootTitle
{

View File

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

View File

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

View File

@ -51,7 +51,7 @@ void MemoryManager::InitMMIO(bool is_wii)
auto& system = Core::System::GetInstance();
system.GetCommandProcessor().RegisterMMIO(system, m_mmio_mapping.get(), 0x0C000000);
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.GetMemoryInterface().RegisterMMIO(m_mmio_mapping.get(), 0x0C004000);
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)
{
auto& core_timing = system.GetCoreTiming();
VideoInterface::Update(core_timing.GetTicks() - cyclesLate);
core_timing.ScheduleEvent(VideoInterface::GetTicksPerHalfLine() - cyclesLate, et_VI);
auto& vi = system.GetVideoInterface();
vi.Update(core_timing.GetTicks() - cyclesLate);
core_timing.ScheduleEvent(vi.GetTicksPerHalfLine() - cyclesLate, et_VI);
}
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 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 next_schedule = 0;
@ -282,6 +283,7 @@ void Init()
auto& system = Core::System::GetInstance();
auto& core_timing = system.GetCoreTiming();
auto& vi = system.GetVideoInterface();
core_timing.SetFakeTBStartValue(static_cast<u64>(s_cpu_core_clock / TIMER_RATIO) *
static_cast<u64>(ExpansionInterface::CEXIIPL::GetEmulatedTime(
@ -303,11 +305,11 @@ void Init()
core_timing.ScheduleEvent(0, et_perf_tracker);
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(GetAudioDMACallbackPeriod(), et_AudioDMA);
core_timing.ScheduleEvent(VideoInterface::GetTicksPerField(), et_PatchEngine);
core_timing.ScheduleEvent(vi.GetTicksPerField(), et_PatchEngine);
if (SConfig::GetInstance().bWii)
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
#include <array>
#include <memory>
#include "Common/CommonTypes.h"
enum class FieldType;
class PointerWrap;
namespace Core
{
class System;
}
namespace MMIO
{
class Mapping;
@ -15,23 +21,6 @@ class Mapping;
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
enum
{
@ -360,41 +349,104 @@ union UVIHorizontalStepping
};
};
// For BS2 HLE
void Preset(bool _bNTSC);
class VideoInterfaceManager
{
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();
void DoState(PointerWrap& p);
// For BS2 HLE
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
u32 GetXFBAddressTop();
u32 GetXFBAddressBottom();
void RegisterMMIO(MMIO::Mapping* mmio, u32 base);
// Update and draw framebuffer
void Update(u64 ticks);
// returns a pointer to the current visible xfb
u32 GetXFBAddressTop() const;
u32 GetXFBAddressBottom() const;
// UpdateInterrupts: check if we have to generate a new VI Interrupt
void UpdateInterrupts();
// Update and draw framebuffer
void Update(u64 ticks);
// Change values pertaining to video mode
void UpdateParameters();
// UpdateInterrupts: check if we have to generate a new VI Interrupt
void UpdateInterrupts();
double GetTargetRefreshRate();
u32 GetTargetRefreshRateNumerator();
u32 GetTargetRefreshRateDenominator();
// Change values pertaining to video mode
void UpdateParameters();
u32 GetTicksPerSample();
u32 GetTicksPerHalfLine();
u32 GetTicksPerField();
double GetTargetRefreshRate() const;
u32 GetTargetRefreshRateNumerator() const;
u32 GetTargetRefreshRateDenominator() const;
// Get the aspect ratio of VI's active area.
// This function only deals with standard aspect ratios. For widescreen aspect ratios, multiply the
// result by 1.33333..
float GetAspectRatio();
u32 GetTicksPerSample() const;
u32 GetTicksPerHalfLine() const;
u32 GetTicksPerField() const;
// Create a fake VI mode for a fifolog
void FakeVIUpdate(u32 xfb_address, u32 fb_width, u32 fb_stride, u32 fb_height);
// Get the aspect ratio of VI's active area.
// 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

View File

@ -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 = 158; // Last changed in PR 11522
constexpr u32 STATE_VERSION = 159; // Last changed in PR 11640
// Maps savestate versions to Dolphin versions.
// 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)
: 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_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;
Sram m_sram;
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)}
@ -224,8 +224,8 @@ VertexShaderManager& System::GetVertexShaderManager() const
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

View File

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

View File

@ -366,7 +366,8 @@ static void BPWritten(PixelShaderManager& pixel_shader_manager,
{
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/HW/SystemTimers.h"
#include "Core/HW/VideoInterface.h"
#include "Core/System.h"
#include "VideoCommon/FrameDumper.h"
#include "VideoCommon/OnScreenDisplay.h"
@ -65,10 +66,11 @@ namespace
{
AVRational GetTimeBaseForCurrentRefreshRate()
{
auto& vi = Core::System::GetInstance().GetVideoInterface();
int num;
int den;
av_reduce(&num, &den, int(VideoInterface::GetTargetRefreshRateDenominator()),
int(VideoInterface::GetTargetRefreshRateNumerator()), std::numeric_limits<int>::max());
av_reduce(&num, &den, int(vi.GetTargetRefreshRateDenominator()),
int(vi.GetTargetRefreshRateNumerator()), std::numeric_limits<int>::max());
return AVRational{num, den};
}

View File

@ -76,7 +76,8 @@ double PerformanceMetrics::GetMaxSpeed() 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)

View File

@ -6,6 +6,7 @@
#include "Common/ChunkFile.h"
#include "Core/HW/VideoInterface.h"
#include "Core/Host.h"
#include "Core/System.h"
#include "InputCommon/ControllerInterface/ControllerInterface.h"
@ -249,7 +250,8 @@ float Presenter::CalculateDrawAspectRatio() const
if (aspect_mode == AspectMode::Stretch)
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 ||
(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
if (g_ActiveConfig.bWidescreenHack)
{
float source_aspect = VideoInterface::GetAspectRatio();
auto& vi = Core::System::GetInstance().GetVideoInterface();
float source_aspect = vi.GetAspectRatio();
if (g_widescreen->IsGameWidescreen())
source_aspect = AspectToWidescreen(source_aspect);