Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rsx: Fix gcm unmap events #6262

Merged
merged 3 commits into from Jul 26, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion rpcs3/Emu/Cell/Modules/cellCamera.cpp
Expand Up @@ -1308,7 +1308,7 @@ void camera_context::operator()()
if (time_passed >= frame_target_time)
break;

thread_ctrl::wait_for(frame_target_time - time_passed);
lv2_obj::wait_timeout(frame_target_time - time_passed);
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions rpcs3/Emu/Cell/lv2/sys_rsx.cpp
Expand Up @@ -222,6 +222,8 @@ error_code sys_rsx_context_iounmap(u32 context_id, u32 io, u32 size)
return CELL_EINVAL;
}

vm::reader_lock rlock;

std::scoped_lock lock(s_rsxmem_mtx);

const u32 end = (io >>= 20) + (size >>= 20);
Expand Down
6 changes: 3 additions & 3 deletions rpcs3/Emu/Cell/lv2/sys_rsx.h
Expand Up @@ -68,20 +68,20 @@ struct RsxDmaControl
be_t<u32> unk1;
};

struct RsxSemaphore
struct alignas(16) RsxSemaphore
{
be_t<u32> val;
be_t<u32> pad;
be_t<u64> timestamp;
};

struct RsxNotify
struct alignas(16) RsxNotify
{
be_t<u64> timestamp;
be_t<u64> zero;
};

struct RsxReport
struct alignas(16) RsxReport
{
be_t<u64> timestamp;
be_t<u32> val;
Expand Down
2 changes: 1 addition & 1 deletion rpcs3/Emu/RSX/GCM.h
Expand Up @@ -65,7 +65,7 @@ struct CellGcmSurface
be_t<u16> y;
};

struct CellGcmReportData
struct alignas(16) CellGcmReportData
{
be_t<u64> timer;
be_t<u32> value;
Expand Down
58 changes: 36 additions & 22 deletions rpcs3/Emu/RSX/RSXThread.cpp
Expand Up @@ -2340,10 +2340,7 @@ namespace rsx
}
}

vm::ptr<CellGcmReportData> result = sink;
result->value = value;
result->padding = 0;
result->timer = timestamp();
vm::_ref<atomic_t<CellGcmReportData>>(sink).store({ timestamp(), value, 0});
}

void thread::sync()
Expand Down Expand Up @@ -2398,25 +2395,45 @@ namespace rsx
{
if (!m_rsx_thread_exiting && address < rsx::constants::local_mem_base)
{
u32 ea = address >> 20, io = RSXIOMem.io[ea];

if (io < 512)
if (!isHLE)
{
if (!isHLE)
// Each bit represents io entry to be unmapped
u64 unmap_status[512 / 64]{};

for (u32 ea = address >> 20, end = ea + size >> 20; ea < end; ea++)
{
const u64 unmap_key = u64((1ull << (size >> 20)) - 1) << (io & 0x3f);
const u64 gcm_flag = 0x100000000ull << (io >> 6);
sys_event_port_send(fxm::get<SysRsxConfig>()->rsx_event_port, 0, gcm_flag, unmap_key);
u32 io = RSXIOMem.io[ea];

if (io < 512)
{
unmap_status[io / 64] |= 1ull << (io & 63);
RSXIOMem.ea[io].raw() = 0xFFFF;
RSXIOMem.io[ea].raw() = 0xFFFF;
}
}
else

for (u32 i = 0; i < std::size(unmap_status); i++)
{
for (const u32 end = ea + (size >> 20); ea < end;)
// TODO: Check order when sending multiple events
if (u64 to_unmap = unmap_status[i])
{
offsetTable.ioAddress[ea++] = 0xFFFF;
offsetTable.eaAddress[io++] = 0xFFFF;
// Each 64 entries are grouped by a bit
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting find

const u64 io_event = 0x100000000ull << i;
sys_event_port_send(fxm::get<SysRsxConfig>()->rsx_event_port, 0, io_event, to_unmap);
}
}
}
else
{
// TODO: Fix this
u32 ea = address >> 20, io = RSXIOMem.io[ea];

for (const u32 end = ea + (size >> 20); ea < end;)
{
offsetTable.ioAddress[ea++] = 0xFFFF;
offsetTable.eaAddress[io++] = 0xFFFF;
}
}

// Queue up memory invalidation
std::lock_guard lock(m_mtx_task);
Expand Down Expand Up @@ -2799,7 +2816,7 @@ namespace rsx
m_cycles_delay = max_zcull_delay_us;
}

void ZCULL_control::write(vm::addr_t sink, u32 timestamp, u32 type, u32 value)
void ZCULL_control::write(vm::addr_t sink, u64 timestamp, u32 type, u32 value)
Copy link
Contributor

@kd-11 kd-11 Jul 26, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice catch, this was a careless mistake on my part.
EDIT: Has anyone tested naughty dog engine with this fix? It used to trip up on timestamps and I fixed the one of the problems (lack of nanosecond precision) but I think this should clear up the remaining comparison failures.

{
verify(HERE), sink;

Expand All @@ -2820,10 +2837,7 @@ namespace rsx
break;
}

vm::ptr<CellGcmReportData> out = sink;
out->value = value;
out->timer = timestamp;
out->padding = 0;
vm::_ref<atomic_t<CellGcmReportData>>(sink).store({ timestamp, value, 0});
Copy link
Contributor

@kd-11 kd-11 Jul 26, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would argue making this atomic is overkill, but I guess it doesn't matter much. Afaik FlexIO bus width is 64-bit so I would have expected no such guarantees in hardware. InterlockedExchange shouldn't be too bad I guess.

}

void ZCULL_control::sync(::rsx::thread* ptimer)
Expand Down Expand Up @@ -2868,7 +2882,7 @@ namespace rsx

if (!writer.forwarder)
//No other queries in the chain, write result
write(writer.sink, (u32)ptimer->timestamp(), writer.type, result);
write(writer.sink, ptimer->timestamp(), writer.type, result);

processed++;
}
Expand Down Expand Up @@ -3029,7 +3043,7 @@ namespace rsx
//only zpass supported right now
if (!writer.forwarder)
//No other queries in the chain, write result
write(writer.sink, (u32)ptimer->timestamp(), writer.type, result);
write(writer.sink, ptimer->timestamp(), writer.type, result);

processed++;
}
Expand Down
2 changes: 1 addition & 1 deletion rpcs3/Emu/RSX/RSXThread.h
Expand Up @@ -371,7 +371,7 @@ namespace rsx
void set_enabled(class ::rsx::thread* ptimer, bool state);
void set_active(class ::rsx::thread* ptimer, bool state);

void write(vm::addr_t sink, u32 timestamp, u32 type, u32 value);
void write(vm::addr_t sink, u64 timestamp, u32 type, u32 value);

// Read current zcull statistics into the address provided
void read_report(class ::rsx::thread* ptimer, vm::addr_t sink, u32 type);
Expand Down
38 changes: 23 additions & 15 deletions rpcs3/Emu/RSX/rsx_methods.cpp
Expand Up @@ -180,9 +180,11 @@ namespace rsx
return;
}

auto& notify = vm::_ref<RsxNotify>(verify(HERE, RSXIOMem.RealAddr(0xf100000 + (index * 0x40))));
notify.zero = 0;
notify.timestamp = rsx->timestamp();
vm::_ref<atomic_t<RsxNotify>>(verify(HERE, RSXIOMem.RealAddr(0xf100000 + (index * 0x40)))).store(
{
rsx->timestamp(),
0
});
}

void texture_read_semaphore_release(thread* rsx, u32 _reg, u32 arg)
Expand All @@ -196,10 +198,12 @@ namespace rsx
//
}

auto& sema = vm::_ref<RsxSemaphore>(get_address(offset, method_registers.semaphore_context_dma_4097()));
sema.val = arg;
sema.pad = 0;
sema.timestamp = rsx->timestamp();
vm::_ref<atomic_t<RsxSemaphore>>(get_address(offset, method_registers.semaphore_context_dma_4097())).store(
{
arg,
0,
rsx->timestamp()
});
}

void back_end_write_semaphore_release(thread* rsx, u32 _reg, u32 arg)
Expand All @@ -213,10 +217,12 @@ namespace rsx

rsx->sync();
u32 val = (arg & 0xff00ff00) | ((arg & 0xff) << 16) | ((arg >> 16) & 0xff);
auto& sema = vm::_ref<RsxSemaphore>(get_address(offset, method_registers.semaphore_context_dma_4097()));
sema.val = val;
sema.pad = 0;
sema.timestamp = rsx->timestamp();
vm::_ref<atomic_t<RsxSemaphore>>(get_address(offset, method_registers.semaphore_context_dma_4097())).store(
{
val,
0,
rsx->timestamp()
});
}

/**
Expand Down Expand Up @@ -509,8 +515,6 @@ namespace rsx
return;
}

vm::ptr<CellGcmReportData> result = address_ptr;

switch (type)
{
case CELL_GCM_ZPASS_PIXEL_CNT:
Expand All @@ -522,8 +526,12 @@ namespace rsx
break;
default:
LOG_ERROR(RSX, "NV4097_GET_REPORT: Bad type %d", type);
result->timer = rsx->timestamp();
result->padding = 0;

vm::_ref<atomic_t<CellGcmReportData>>(address_ptr).atomic_op([&](CellGcmReportData& data)
{
data.timer = rsx->timestamp();
data.padding = 0;
});
break;
}
}
Expand Down