mirror of
https://github.com/RPCSX/rpcsx.git
synced 2025-12-06 07:12:14 +01:00
dce: implement submit and write eop
This commit is contained in:
parent
bdd4b91a32
commit
208c245e95
|
|
@ -512,6 +512,7 @@ GraphicsPipe::GraphicsPipe(int index) : scheduler(createGfxScheduler(index)) {
|
|||
// IT_SURFACE_SYNC
|
||||
deHandlers[gnm::IT_COND_WRITE] = &GraphicsPipe::condWrite;
|
||||
deHandlers[gnm::IT_EVENT_WRITE] = &GraphicsPipe::eventWrite;
|
||||
mainHandlers[gnm::IT_EVENT_WRITE_EOP] = &GraphicsPipe::eventWriteEop;
|
||||
deHandlers[gnm::IT_EVENT_WRITE_EOP] = &GraphicsPipe::eventWriteEop;
|
||||
deHandlers[gnm::IT_EVENT_WRITE_EOS] = &GraphicsPipe::eventWriteEos;
|
||||
deHandlers[gnm::IT_RELEASE_MEM] = &GraphicsPipe::releaseMem;
|
||||
|
|
@ -1144,7 +1145,7 @@ bool GraphicsPipe::eventWrite(Ring &ring) {
|
|||
|
||||
bool GraphicsPipe::eventWriteEop(Ring &ring) {
|
||||
auto eventCntl = ring.rptr[1];
|
||||
auto addressLo = ring.rptr[2] & ~3;
|
||||
auto addressLo = ring.rptr[2];
|
||||
auto dataCntl = ring.rptr[3];
|
||||
auto dataLo = ring.rptr[4];
|
||||
auto dataHi = ring.rptr[5];
|
||||
|
|
@ -1161,44 +1162,63 @@ bool GraphicsPipe::eventWriteEop(Ring &ring) {
|
|||
|
||||
context.vgtEventInitiator = eventType;
|
||||
|
||||
switch (dataSel) {
|
||||
case 0: // none
|
||||
break;
|
||||
case 1: // 32 bit, low
|
||||
*reinterpret_cast<std::uint32_t *>(pointer) = dataLo;
|
||||
break;
|
||||
case 2: // 64 bit
|
||||
*pointer = dataLo | (static_cast<std::uint64_t>(dataHi) << 32);
|
||||
break;
|
||||
case 3: // 64 bit, global GPU clock
|
||||
*pointer = std::chrono::duration_cast<std::chrono::nanoseconds>(
|
||||
std::chrono::system_clock::now().time_since_epoch())
|
||||
.count();
|
||||
break;
|
||||
case 4: // 64 bit, perf counter
|
||||
*pointer = std::chrono::duration_cast<std::chrono::nanoseconds>(
|
||||
std::chrono::steady_clock::now().time_since_epoch())
|
||||
.count();
|
||||
break;
|
||||
if (pointer != nullptr) {
|
||||
switch (dataSel) {
|
||||
case 0: // none
|
||||
break;
|
||||
case 1: // 32 bit, low
|
||||
*reinterpret_cast<std::uint32_t *>(pointer) = dataLo;
|
||||
break;
|
||||
case 2: // 64 bit
|
||||
*pointer = dataLo | (static_cast<std::uint64_t>(dataHi) << 32);
|
||||
break;
|
||||
case 3: // 64 bit, global GPU clock
|
||||
*pointer = std::chrono::duration_cast<std::chrono::nanoseconds>(
|
||||
std::chrono::system_clock::now().time_since_epoch())
|
||||
.count();
|
||||
break;
|
||||
case 4: // 64 bit, perf counter
|
||||
*pointer = std::chrono::duration_cast<std::chrono::nanoseconds>(
|
||||
std::chrono::steady_clock::now().time_since_epoch())
|
||||
.count();
|
||||
break;
|
||||
|
||||
default:
|
||||
rx::die("unimplemented event write eop data %#x", dataSel);
|
||||
default:
|
||||
rx::die("unimplemented event write eop data %#x", dataSel);
|
||||
}
|
||||
}
|
||||
|
||||
if (intSel) {
|
||||
if (intSel != 0) {
|
||||
orbis::g_context.deviceEventEmitter->emit(orbis::kEvFiltGraphicsCore, 0,
|
||||
kGcEventGfxEop);
|
||||
}
|
||||
|
||||
if (intSel == 2) {
|
||||
std::println("event write eop {}, {}, {}, {:x}, {}, {}, {}:{}", eventIndex,
|
||||
dataSel, intSel, address, eventType, dataSel, dataHi, dataLo);
|
||||
|
||||
if (intSel != 0 && dataSel == 2) {
|
||||
std::optional<EopFlipRequest> request;
|
||||
int index;
|
||||
int index = -1;
|
||||
{
|
||||
std::lock_guard lock(eopFlipMtx);
|
||||
|
||||
if (eopFlipRequestCount > 0) {
|
||||
index = --eopFlipRequestCount;
|
||||
auto data = dataLo | (static_cast<std::uint64_t>(dataHi) << 32);
|
||||
for (auto &request : std::span(eopFlipRequests, eopFlipRequestCount)) {
|
||||
if (request.eopValue == data) {
|
||||
index = &request - eopFlipRequests;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (index >= 0) {
|
||||
request = eopFlipRequests[index];
|
||||
|
||||
if (index + 1 != eopFlipRequestCount) {
|
||||
std::swap(eopFlipRequests[index],
|
||||
eopFlipRequests[eopFlipRequestCount - 1]);
|
||||
}
|
||||
|
||||
--eopFlipRequestCount;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -78,6 +78,7 @@ struct EopFlipRequest {
|
|||
std::uint32_t pid;
|
||||
int bufferIndex;
|
||||
std::uint64_t arg;
|
||||
std::uint64_t eopValue;
|
||||
};
|
||||
|
||||
struct GraphicsPipe {
|
||||
|
|
|
|||
|
|
@ -396,10 +396,14 @@ static orbis::ErrorCode dce_ioctl(orbis::File *file, std::uint64_t request,
|
|||
gpu.submitFlip(thread->tproc->gfxRing, thread->tproc->pid,
|
||||
args->displayBufferIndex, args->flipArg);
|
||||
} else if (args->eop_nz == 1) {
|
||||
ORBIS_RET_ON_ERROR(
|
||||
gpu.submitFlipOnEop(thread->tproc->gfxRing, thread->tproc->pid,
|
||||
args->displayBufferIndex, args->flipArg));
|
||||
*args->eop_val = args->canary;
|
||||
std::uint64_t eopValue = args->canary;
|
||||
eopValue ^= 0xff00'0000;
|
||||
eopValue ^= static_cast<std::uint64_t>(device->eopCount++) << 32;
|
||||
|
||||
ORBIS_RET_ON_ERROR(gpu.submitFlipOnEop(
|
||||
thread->tproc->gfxRing, thread->tproc->pid, args->displayBufferIndex,
|
||||
args->flipArg, eopValue));
|
||||
*args->eop_val = eopValue;
|
||||
}
|
||||
|
||||
*args->rout = 0;
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ static constexpr auto kVmIdCount = 6;
|
|||
|
||||
struct DceDevice : IoDevice {
|
||||
orbis::shared_mutex mtx;
|
||||
std::uint32_t eopCount = 0;
|
||||
std::uint32_t freeVmIds = (1 << (kVmIdCount + 1)) - 1;
|
||||
orbis::uint64_t dmemOffset = ~static_cast<std::uint64_t>(0);
|
||||
|
||||
|
|
|
|||
|
|
@ -114,13 +114,13 @@ static orbis::ErrorCode gc_ioctl(orbis::File *file, std::uint64_t request,
|
|||
break;
|
||||
}
|
||||
|
||||
case 0xc020810c: { // submit and flip?
|
||||
case 0xc020810c: { // submit and write eop
|
||||
struct Args {
|
||||
std::uint32_t arg0;
|
||||
std::uint32_t count;
|
||||
std::uint32_t *cmds;
|
||||
std::uint64_t arg3; // flipArg?
|
||||
std::uint32_t arg4; // bufferIndex?
|
||||
orbis::uint32_t arg0;
|
||||
orbis::uint32_t count;
|
||||
orbis::ptr<orbis::uint32_t> cmds;
|
||||
orbis::uint64_t eopValue;
|
||||
orbis::uint32_t waitFlag;
|
||||
};
|
||||
|
||||
auto args = reinterpret_cast<Args *>(argp);
|
||||
|
|
@ -131,6 +131,9 @@ static orbis::ErrorCode gc_ioctl(orbis::File *file, std::uint64_t request,
|
|||
orbis::g_currentThread->tproc->vmId,
|
||||
{args->cmds + i * 4, 4});
|
||||
}
|
||||
|
||||
// ORBIS_LOG_ERROR("submit and write eop", args->eopValue, args->waitFlag);
|
||||
gpu.submitWriteEop(gcFile->gfxPipe, args->waitFlag, args->eopValue);
|
||||
} else {
|
||||
return orbis::ErrorCode::BUSY;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue