mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-02-19 12:40:29 +00:00
rsx: Cleanup changes for the flip patch
This commit is contained in:
parent
699eadc84f
commit
a3d44b5e1f
@ -1,4 +1,4 @@
|
|||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "Emu/Memory/vm.h"
|
#include "Emu/Memory/vm.h"
|
||||||
#include "Emu/System.h"
|
#include "Emu/System.h"
|
||||||
#include "Emu/Cell/PPUModule.h"
|
#include "Emu/Cell/PPUModule.h"
|
||||||
@ -13,7 +13,8 @@ LOG_CHANNEL(sys_rsx);
|
|||||||
|
|
||||||
extern u64 get_timebased_time();
|
extern u64 get_timebased_time();
|
||||||
|
|
||||||
u64 rsxTimeStamp() {
|
u64 rsxTimeStamp()
|
||||||
|
{
|
||||||
return get_timebased_time();
|
return get_timebased_time();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -178,8 +179,8 @@ s32 sys_rsx_context_iomap(u32 context_id, u32 io, u32 ea, u32 size, u64 flags)
|
|||||||
{
|
{
|
||||||
sys_rsx.warning("sys_rsx_context_iomap(context_id=0x%x, io=0x%x, ea=0x%x, size=0x%x, flags=0x%llx)", context_id, io, ea, size, flags);
|
sys_rsx.warning("sys_rsx_context_iomap(context_id=0x%x, io=0x%x, ea=0x%x, size=0x%x, flags=0x%llx)", context_id, io, ea, size, flags);
|
||||||
|
|
||||||
if (!size || io & 0xFFFFF || ea & 0xFFFFF || size & 0xFFFFF
|
if (!size || io & 0xFFFFF || ea & 0xFFFFF || size & 0xFFFFF ||
|
||||||
|| rsx::get_current_renderer()->main_mem_size < io + size)
|
rsx::get_current_renderer()->main_mem_size < io + size)
|
||||||
{
|
{
|
||||||
return CELL_EINVAL;
|
return CELL_EINVAL;
|
||||||
}
|
}
|
||||||
@ -323,6 +324,7 @@ s32 sys_rsx_context_attribute(s32 context_id, u32 package_id, u64 a3, u64 a4, u6
|
|||||||
if (a3 == 1)
|
if (a3 == 1)
|
||||||
sys_event_port_send(m_sysrsx->rsx_event_port, 0, (1 << 6), 0);
|
sys_event_port_send(m_sysrsx->rsx_event_port, 0, (1 << 6), 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x104: // Display buffer
|
case 0x104: // Display buffer
|
||||||
{
|
{
|
||||||
u8 id = a3 & 0xFF;
|
u8 id = a3 & 0xFF;
|
||||||
@ -340,11 +342,13 @@ s32 sys_rsx_context_attribute(s32 context_id, u32 package_id, u64 a3, u64 a4, u6
|
|||||||
render->display_buffers_count = std::max((u32)id + 1, render->display_buffers_count);
|
render->display_buffers_count = std::max((u32)id + 1, render->display_buffers_count);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x105: // destroy buffer?
|
case 0x105: // destroy buffer?
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x106: // ? (Used by cellGcmInitPerfMon)
|
case 0x106: // ? (Used by cellGcmInitPerfMon)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x108: // cellGcmSetSecondVFrequency
|
case 0x108: // cellGcmSetSecondVFrequency
|
||||||
// a4 == 3, CELL_GCM_DISPLAY_FREQUENCY_59_94HZ
|
// a4 == 3, CELL_GCM_DISPLAY_FREQUENCY_59_94HZ
|
||||||
// a4 == 2, CELL_GCM_DISPLAY_FREQUENCY_SCANOUT
|
// a4 == 2, CELL_GCM_DISPLAY_FREQUENCY_SCANOUT
|
||||||
@ -352,10 +356,12 @@ s32 sys_rsx_context_attribute(s32 context_id, u32 package_id, u64 a3, u64 a4, u6
|
|||||||
// Note: Scanout/59_94 is ignored currently as we report refresh rate of 59_94hz as it is, so the difference doesnt matter
|
// Note: Scanout/59_94 is ignored currently as we report refresh rate of 59_94hz as it is, so the difference doesnt matter
|
||||||
render->enable_second_vhandler.store(a4 != 4);
|
render->enable_second_vhandler.store(a4 != 4);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x10a: // ? Involved in managing flip status through cellGcmResetFlipStatus
|
case 0x10a: // ? Involved in managing flip status through cellGcmResetFlipStatus
|
||||||
{
|
{
|
||||||
if (a3 > 7)
|
if (a3 > 7)
|
||||||
return -17;
|
return -17;
|
||||||
|
|
||||||
u32 flipStatus = driverInfo.head[a3].flipFlags;
|
u32 flipStatus = driverInfo.head[a3].flipFlags;
|
||||||
flipStatus = (flipStatus & a4) | a5;
|
flipStatus = (flipStatus & a4) | a5;
|
||||||
driverInfo.head[a3].flipFlags = flipStatus;
|
driverInfo.head[a3].flipFlags = flipStatus;
|
||||||
@ -417,6 +423,7 @@ s32 sys_rsx_context_attribute(s32 context_id, u32 package_id, u64 a3, u64 a4, u6
|
|||||||
|
|
||||||
case 0x302: // something with zcull
|
case 0x302: // something with zcull
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x600: // Framebuffer setup
|
case 0x600: // Framebuffer setup
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -429,14 +436,32 @@ s32 sys_rsx_context_attribute(s32 context_id, u32 package_id, u64 a3, u64 a4, u6
|
|||||||
case 0x603: // Framebuffer close
|
case 0x603: // Framebuffer close
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 0xFEC: // hack: flip event notification
|
||||||
|
// we only ever use head 1 for now
|
||||||
|
driverInfo.head[1].flipFlags |= 0x80000000;
|
||||||
|
driverInfo.head[1].lastFlipTime = rsxTimeStamp(); // should rsxthread set this?
|
||||||
|
driverInfo.head[1].flipBufferId = (u32)a3;
|
||||||
|
|
||||||
|
// seems gcmSysWaitLabel uses this offset, so lets set it to 0 every flip
|
||||||
|
vm::_ref<u32>(render->label_addr + 0x10) = 0;
|
||||||
|
|
||||||
|
//if (a3 == 0)
|
||||||
|
// sys_event_port_send(m_sysrsx->rsx_event_port, 0, (1 << 3), 0);
|
||||||
|
//if (a3 == 1)
|
||||||
|
sys_event_port_send(m_sysrsx->rsx_event_port, 0, (1 << 4), 0);
|
||||||
|
break;
|
||||||
|
|
||||||
case 0xFED: // hack: vblank command
|
case 0xFED: // hack: vblank command
|
||||||
// todo: this is wrong and should be 'second' vblank handler and freq, but since currently everything is reported as being 59.94, this should be fine
|
// todo: this is wrong and should be 'second' vblank handler and freq, but since currently everything is reported as being 59.94, this should be fine
|
||||||
driverInfo.head[a3].vBlankCount++;
|
driverInfo.head[a3].vBlankCount++;
|
||||||
driverInfo.head[a3].lastSecondVTime = rsxTimeStamp();
|
driverInfo.head[a3].lastSecondVTime = rsxTimeStamp();
|
||||||
sys_event_port_send(m_sysrsx->rsx_event_port, 0, (1 << 1), 0);
|
sys_event_port_send(m_sysrsx->rsx_event_port, 0, (1 << 1), 0);
|
||||||
|
|
||||||
if (render->enable_second_vhandler)
|
if (render->enable_second_vhandler)
|
||||||
sys_event_port_send(m_sysrsx->rsx_event_port, 0, (1 << 11), 0); // second vhandler
|
sys_event_port_send(m_sysrsx->rsx_event_port, 0, (1 << 11), 0); // second vhandler
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xFEF: // hack: user command
|
case 0xFEF: // hack: user command
|
||||||
// 'custom' invalid package id for now
|
// 'custom' invalid package id for now
|
||||||
// as i think we need custom lv1 interrupts to handle this accurately
|
// as i think we need custom lv1 interrupts to handle this accurately
|
||||||
@ -444,6 +469,7 @@ s32 sys_rsx_context_attribute(s32 context_id, u32 package_id, u64 a3, u64 a4, u6
|
|||||||
driverInfo.userCmdParam = a4;
|
driverInfo.userCmdParam = a4;
|
||||||
sys_event_port_send(m_sysrsx->rsx_event_port, 0, (1 << 7), 0);
|
sys_event_port_send(m_sysrsx->rsx_event_port, 0, (1 << 7), 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return CELL_EINVAL;
|
return CELL_EINVAL;
|
||||||
}
|
}
|
||||||
@ -506,27 +532,3 @@ s32 sys_rsx_attribute(u32 packageId, u32 a2, u32 a3, u32 a4, u32 a5)
|
|||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sys_rsx_flip_event(u32 buffer)
|
|
||||||
{
|
|
||||||
auto m_sysrsx = fxm::get<SysRsxConfig>();
|
|
||||||
if (!m_sysrsx)
|
|
||||||
return;
|
|
||||||
|
|
||||||
auto &driverInfo = vm::_ref<RsxDriverInfo>(m_sysrsx->driverInfo);
|
|
||||||
const auto render = rsx::get_current_renderer();
|
|
||||||
|
|
||||||
// we only ever use head 1 for now
|
|
||||||
|
|
||||||
driverInfo.head[1].flipFlags |= 0x80000000;
|
|
||||||
driverInfo.head[1].lastFlipTime = rsxTimeStamp(); // should rsxthread set this?
|
|
||||||
driverInfo.head[1].flipBufferId = buffer;
|
|
||||||
|
|
||||||
// seems gcmSysWaitLabel uses this offset, so lets set it to 0 every flip
|
|
||||||
vm::_ref<u32>(render->label_addr + 0x10) = 0;
|
|
||||||
|
|
||||||
//if (a3 == 0)
|
|
||||||
// sys_event_port_send(m_sysrsx->rsx_event_port, 0, (1 << 3), 0);
|
|
||||||
//if (a3 == 1)
|
|
||||||
sys_event_port_send(m_sysrsx->rsx_event_port, 0, (1 << 4), 0);
|
|
||||||
}
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
struct RsxDriverInfo
|
struct RsxDriverInfo
|
||||||
{
|
{
|
||||||
@ -119,6 +119,3 @@ s32 sys_rsx_context_attribute(s32 context_id, u32 package_id, u64 a3, u64 a4, u6
|
|||||||
s32 sys_rsx_device_map(vm::ptr<u64> dev_addr, vm::ptr<u64> a2, u32 dev_id);
|
s32 sys_rsx_device_map(vm::ptr<u64> dev_addr, vm::ptr<u64> a2, u32 dev_id);
|
||||||
s32 sys_rsx_device_unmap(u32 dev_id);
|
s32 sys_rsx_device_unmap(u32 dev_id);
|
||||||
s32 sys_rsx_attribute(u32 a1, u32 a2, u32 a3, u32 a4, u32 a5);
|
s32 sys_rsx_attribute(u32 a1, u32 a2, u32 a3, u32 a4, u32 a5);
|
||||||
|
|
||||||
// Custom 'RSX Events', not lv2 syscalls
|
|
||||||
void sys_rsx_flip_event(u32 buffer);
|
|
||||||
|
@ -1722,9 +1722,10 @@ void GLGSRender::do_local_task(rsx::FIFO_state state)
|
|||||||
|
|
||||||
if (m_overlay_manager)
|
if (m_overlay_manager)
|
||||||
{
|
{
|
||||||
if (!in_begin_end && async_flip_requested.test_and_reset(flip_request::native_ui))
|
if (!in_begin_end && async_flip_requested & flip_request::native_ui)
|
||||||
{
|
{
|
||||||
flip((s32)current_display_buffer);
|
s32 buffer_id = (async_flip_requested & flip_request::emu_requested) ? async_flip_buffer : (s32)current_display_buffer;
|
||||||
|
flip(buffer_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "overlays.h"
|
#include "overlays.h"
|
||||||
#include "../GSRender.h"
|
#include "../GSRender.h"
|
||||||
|
|
||||||
@ -35,7 +35,7 @@ namespace rsx
|
|||||||
const auto now = get_system_time() - 1000000;
|
const auto now = get_system_time() - 1000000;
|
||||||
if ((now - rsxthr->last_flip_time) > min_refresh_duration_us)
|
if ((now - rsxthr->last_flip_time) > min_refresh_duration_us)
|
||||||
{
|
{
|
||||||
rsxthr->async_flip_requested.test_and_set(rsx::thread::flip_request::native_ui);
|
rsxthr->async_flip_requested |= rsx::thread::flip_request::native_ui;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1356,10 +1356,9 @@ namespace rsx
|
|||||||
|
|
||||||
void thread::do_local_task(FIFO_state state)
|
void thread::do_local_task(FIFO_state state)
|
||||||
{
|
{
|
||||||
if (test(async_flip_requested, flip_request::emu_requested))
|
if (async_flip_requested & flip_request::any)
|
||||||
{
|
{
|
||||||
handle_emu_flip(async_flip_buffer);
|
handle_emu_flip(async_flip_buffer);
|
||||||
async_flip_requested.test_and_reset(flip_request::emu_requested);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!in_begin_end && state != FIFO_state::lock_wait)
|
if (!in_begin_end && state != FIFO_state::lock_wait)
|
||||||
@ -2554,6 +2553,8 @@ namespace rsx
|
|||||||
|
|
||||||
void thread::flip(int buffer)
|
void thread::flip(int buffer)
|
||||||
{
|
{
|
||||||
|
async_flip_requested.clear();
|
||||||
|
|
||||||
if (g_cfg.video.frame_skip_enabled)
|
if (g_cfg.video.frame_skip_enabled)
|
||||||
{
|
{
|
||||||
m_skip_frame_ctr++;
|
m_skip_frame_ctr++;
|
||||||
@ -2811,22 +2812,19 @@ namespace rsx
|
|||||||
// requested through command buffer
|
// requested through command buffer
|
||||||
if (is_rsxthr)
|
if (is_rsxthr)
|
||||||
{
|
{
|
||||||
// async flip hasnt been handled before next requested...?
|
// NOTE: The flip will clear any queued flip requests
|
||||||
if (test(async_flip_requested, flip_request::emu_requested))
|
|
||||||
{
|
|
||||||
handle_emu_flip(async_flip_buffer);
|
|
||||||
async_flip_requested.test_and_reset(flip_request::emu_requested);
|
|
||||||
}
|
|
||||||
handle_emu_flip(buffer);
|
handle_emu_flip(buffer);
|
||||||
}
|
}
|
||||||
else // requested 'manually' through ppu syscall
|
else // requested 'manually' through ppu syscall
|
||||||
|
{
|
||||||
|
if (async_flip_requested & flip_request::emu_requested)
|
||||||
{
|
{
|
||||||
// ignore multiple requests until previous happens
|
// ignore multiple requests until previous happens
|
||||||
if (test(async_flip_requested, flip_request::emu_requested))
|
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
async_flip_buffer = buffer;
|
async_flip_buffer = buffer;
|
||||||
async_flip_requested.test_and_set(flip_request::emu_requested);
|
async_flip_requested |= flip_request::emu_requested;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2914,10 +2912,6 @@ namespace rsx
|
|||||||
int_flip_index++;
|
int_flip_index++;
|
||||||
current_display_buffer = buffer;
|
current_display_buffer = buffer;
|
||||||
flip(buffer);
|
flip(buffer);
|
||||||
// After each flip PS3 system is executing a routine that changes registers value to some default.
|
|
||||||
// Some game use this default state (SH3).
|
|
||||||
if (isHLE)
|
|
||||||
reset();
|
|
||||||
|
|
||||||
last_flip_time = get_system_time() - 1000000;
|
last_flip_time = get_system_time() - 1000000;
|
||||||
flip_status = CELL_GCM_DISPLAY_FLIP_STATUS_DONE;
|
flip_status = CELL_GCM_DISPLAY_FLIP_STATUS_DONE;
|
||||||
@ -2933,7 +2927,8 @@ namespace rsx
|
|||||||
|
|
||||||
intr_thread->notify();
|
intr_thread->notify();
|
||||||
}
|
}
|
||||||
sys_rsx_flip_event(buffer);
|
|
||||||
|
sys_rsx_context_attribute(0x55555555, 0xFEC, buffer, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -323,6 +323,7 @@ namespace rsx
|
|||||||
u64 timestamp_subvalue = 0;
|
u64 timestamp_subvalue = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
std::thread::id m_rsx_thread;
|
||||||
atomic_t<bool> m_rsx_thread_exiting{true};
|
atomic_t<bool> m_rsx_thread_exiting{true};
|
||||||
s32 m_return_addr{-1}, restore_ret_addr{-1};
|
s32 m_return_addr{-1}, restore_ret_addr{-1};
|
||||||
std::array<push_buffer_vertex_info, 16> vertex_push_buffers;
|
std::array<push_buffer_vertex_info, 16> vertex_push_buffers;
|
||||||
@ -370,13 +371,13 @@ namespace rsx
|
|||||||
|
|
||||||
enum class flip_request : u32
|
enum class flip_request : u32
|
||||||
{
|
{
|
||||||
emu_requested,
|
emu_requested = 1,
|
||||||
native_ui,
|
native_ui = 2,
|
||||||
|
|
||||||
__bitset_enum_max
|
any = emu_requested | native_ui
|
||||||
};
|
};
|
||||||
|
|
||||||
atomic_t<bs_t<flip_request>> async_flip_requested{};
|
atomic_bitmask_t<flip_request> async_flip_requested{};
|
||||||
u8 async_flip_buffer{ 0 };
|
u8 async_flip_buffer{ 0 };
|
||||||
|
|
||||||
GcmTileInfo tiles[limits::tiles_count];
|
GcmTileInfo tiles[limits::tiles_count];
|
||||||
|
@ -2192,10 +2192,12 @@ void VKGSRender::do_local_task(rsx::FIFO_state state)
|
|||||||
|
|
||||||
if (m_overlay_manager)
|
if (m_overlay_manager)
|
||||||
{
|
{
|
||||||
if (!in_begin_end && async_flip_requested.test_and_reset(flip_request::native_ui))
|
if (!in_begin_end && async_flip_requested & flip_request::native_ui)
|
||||||
{
|
{
|
||||||
|
s32 buffer_id = (async_flip_requested & flip_request::emu_requested) ? async_flip_buffer : (s32)current_display_buffer;
|
||||||
|
|
||||||
flush_command_queue(true);
|
flush_command_queue(true);
|
||||||
flip((s32)current_display_buffer);
|
flip((s32)buffer_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1116,6 +1116,8 @@ namespace rsx
|
|||||||
|
|
||||||
void flip_command(thread* rsx, u32, u32 arg)
|
void flip_command(thread* rsx, u32, u32 arg)
|
||||||
{
|
{
|
||||||
|
verify(HERE), rsx->isHLE;
|
||||||
|
rsx->reset();
|
||||||
rsx->request_emu_flip(arg);
|
rsx->request_emu_flip(arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -784,4 +784,56 @@ namespace rsx
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T, typename bitmask_type = u32>
|
||||||
|
class atomic_bitmask_t
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
atomic_t<bitmask_type> m_data;
|
||||||
|
|
||||||
|
public:
|
||||||
|
atomic_bitmask_t() { m_data.store(0); };
|
||||||
|
~atomic_bitmask_t() {}
|
||||||
|
|
||||||
|
T load() const
|
||||||
|
{
|
||||||
|
return static_cast<T>(m_data.load());
|
||||||
|
}
|
||||||
|
|
||||||
|
void store(T value)
|
||||||
|
{
|
||||||
|
m_data.store(static_cast<bitmask_type>(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator & (T mask) const
|
||||||
|
{
|
||||||
|
return ((m_data.load() & static_cast<bitmask_type>(mask)) != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
T operator | (T mask) const
|
||||||
|
{
|
||||||
|
return static_cast<T>(m_data.load() | static_cast<bitmask_type>(mask));
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator &= (T mask)
|
||||||
|
{
|
||||||
|
m_data.fetch_and(static_cast<bitmask_type>(mask));
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator |= (T mask)
|
||||||
|
{
|
||||||
|
m_data.fetch_or(static_cast<bitmask_type>(mask));
|
||||||
|
}
|
||||||
|
|
||||||
|
auto clear(T mask)
|
||||||
|
{
|
||||||
|
bitmask_type clear_mask = ~(static_cast<bitmask_type>(mask));
|
||||||
|
return m_data.and_fetch(clear_mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear()
|
||||||
|
{
|
||||||
|
m_data.store(0);
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user