fix(libkernel): report AMPR completion events with the AMPR filter
AMPR events were registered and raised as EVFILT_USER. Titles that dispatch their AMPR queue by filter ignore those events, so reads that complete through WriteKernelEventQueue never finish. Add, delete and trigger them with EVFILT_AMPR (-25).
This commit is contained in:
parent
df16c4c256
commit
c95721f701
|
|
@ -590,7 +590,7 @@ void _execute(const Apr::CommandBufferObject& buffer) {
|
|||
}
|
||||
case Apr::Opcode::WriteKernelEventQueue: {
|
||||
const auto command = _read<Apr::WriteKernelEventQueueCommand>(buffer, cursor);
|
||||
EqueueTriggerEvent_nid_postfix(static_cast<KernelEqueue>(command.equeue), static_cast<uintptr_t>(command.ident), EVFILT_USER, reinterpret_cast<void*>(command.data));
|
||||
EqueueTriggerEvent_nid_postfix(static_cast<KernelEqueue>(command.equeue), static_cast<uintptr_t>(command.ident), EVFILT_AMPR, reinterpret_cast<void*>(command.data));
|
||||
break;
|
||||
}
|
||||
case Apr::Opcode::WriteAddressFromTimeCounter: {
|
||||
|
|
|
|||
|
|
@ -441,7 +441,7 @@ int APS5_VABI sceKernelAddAmprEvent(KernelEqueue eq, int id, void* udata) {
|
|||
}
|
||||
KernelEqueueEvent event{};
|
||||
event.event.ident = static_cast<uintptr_t>(id);
|
||||
event.event.filter = EVFILT_USER;
|
||||
event.event.filter = EVFILT_AMPR;
|
||||
event.event.flags = EV_ADD | EV_CLEAR;
|
||||
event.event.udata = udata;
|
||||
event.filter.triggerFunc = [](KernelEqueueEvent* e, void* data) {
|
||||
|
|
@ -473,7 +473,7 @@ int APS5_VABI sceKernelDeleteAmprEvent(KernelEqueue eq, int id) {
|
|||
if (eq == 0) {
|
||||
return EQUEUE_OK;
|
||||
}
|
||||
EqueueDeleteEvent_nid_postfix(eq, static_cast<uintptr_t>(id), EVFILT_USER);
|
||||
EqueueDeleteEvent_nid_postfix(eq, static_cast<uintptr_t>(id), EVFILT_AMPR);
|
||||
return EQUEUE_OK;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ static constexpr int16_t EVFILT_TIMER = -7;
|
|||
static constexpr int16_t EVFILT_USER = -11;
|
||||
static constexpr int16_t EVFILT_VIDEO_OUT = -13;
|
||||
static constexpr int16_t EVFILT_HRTIMER = -15;
|
||||
static constexpr int16_t EVFILT_AMPR = -25;
|
||||
|
||||
static constexpr uint16_t EV_ADD = 0x0001;
|
||||
static constexpr uint16_t EV_ONESHOT = 0x0010;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#include "SceTypes.hpp"
|
||||
#include "prx/libc/include/general/VabiMacros.hpp"
|
||||
#include "prx/libkernel/Apr/include/AprCommandBuffer.hpp"
|
||||
#include <array>
|
||||
|
|
@ -112,6 +113,15 @@ std::int64_t APS5_VABI sceAmprAmmMeasureAmmCommandSizeModifyProtect(std::uint64_
|
|||
std::int64_t APS5_VABI sceAmprAmmMeasureAmmCommandSizeModifyProtectWithGpuMaskId(std::uint64_t, std::uint64_t, std::int32_t, std::int32_t, std::uint8_t);
|
||||
std::int64_t APS5_VABI sceAmprAmmMeasureAmmCommandSizeModifyMtypeProtect(std::uint64_t, std::uint64_t, std::int32_t, std::int32_t, std::int32_t);
|
||||
std::int64_t APS5_VABI sceAmprAmmMeasureAmmCommandSizeModifyMtypeProtectWithGpuMaskId(std::uint64_t, std::uint64_t, std::int32_t, std::int32_t, std::int32_t, std::uint8_t);
|
||||
int APS5_VABI sceKernelCreateEqueue(KernelEqueue*, const char*);
|
||||
int APS5_VABI sceKernelDeleteEqueue(KernelEqueue);
|
||||
int APS5_VABI sceKernelWaitEqueue(KernelEqueue, KernelEvent*, int, int*, const KernelUseconds*);
|
||||
int APS5_VABI sceKernelAddAmprEvent(KernelEqueue, int, void*);
|
||||
int APS5_VABI sceKernelDeleteAmprEvent(KernelEqueue, int);
|
||||
int APS5_VABI sceKernelGetEventFilter(const KernelEvent*);
|
||||
std::uintptr_t APS5_VABI sceKernelGetEventId(const KernelEvent*);
|
||||
std::intptr_t APS5_VABI sceKernelGetEventData(const KernelEvent*);
|
||||
void* APS5_VABI sceKernelGetEventUserData(const KernelEvent*);
|
||||
}
|
||||
|
||||
static void RequireAt(bool value, int line) {
|
||||
|
|
@ -247,6 +257,24 @@ void TestSubmission() {
|
|||
Require(first == 0x1111 && second == 0x2222);
|
||||
}
|
||||
|
||||
void TestKernelEventQueue() {
|
||||
KernelEqueue eq = 0;
|
||||
int userData = 0;
|
||||
Require(sceKernelCreateEqueue(&eq, "ampr") == 0);
|
||||
Require(sceKernelAddAmprEvent(eq, 7, &userData) == 0);
|
||||
Recorder recorder;
|
||||
Require(sceAmprCommandBufferWriteKernelEventQueue_04_00(&recorder.buffer, static_cast<std::uint64_t>(eq), 7, 0x1234, 0) == 0);
|
||||
Require(sceKernelAprSubmitCommandBuffer(&recorder.buffer, 0) == 0);
|
||||
KernelEvent event{};
|
||||
int count = 0;
|
||||
const KernelUseconds poll = 0;
|
||||
Require(sceKernelWaitEqueue(eq, &event, 1, &count, &poll) == 0 && count == 1);
|
||||
Require(sceKernelGetEventFilter(&event) == -25);
|
||||
Require(sceKernelGetEventId(&event) == 7 && sceKernelGetEventData(&event) == 0x1234 && sceKernelGetEventUserData(&event) == &userData);
|
||||
Require(sceKernelDeleteAmprEvent(eq, 7) == 0);
|
||||
Require(sceKernelDeleteEqueue(eq) == 0);
|
||||
}
|
||||
|
||||
void TestWaits() {
|
||||
Recorder recorder;
|
||||
alignas(8) std::uint64_t value = 5;
|
||||
|
|
@ -902,6 +930,7 @@ int main() {
|
|||
TestRejectedArguments();
|
||||
TestFullBuffer();
|
||||
TestSubmission();
|
||||
TestKernelEventQueue();
|
||||
TestWaits();
|
||||
TestCounters();
|
||||
TestRejectedWaitsAndCounters();
|
||||
|
|
|
|||
Loading…
Reference in New Issue