mirror of
https://github.com/RPCSX/rpcsx.git
synced 2025-12-06 07:12:14 +01:00
gpu: implement flip on eop
This commit is contained in:
parent
175ea2d623
commit
bdd4b91a32
|
|
@ -60,6 +60,29 @@ void DeviceCtl::submitFlip(int gfxPipe, std::uint32_t pid, int bufferIndex,
|
|||
flipArg >> 32, pid));
|
||||
}
|
||||
|
||||
orbis::ErrorCode DeviceCtl::submitFlipOnEop(int gfxPipe, std::uint32_t pid,
|
||||
int bufferIndex,
|
||||
std::uint64_t flipArg) {
|
||||
int index;
|
||||
auto &pipe = mDevice->graphicsPipes[gfxPipe];
|
||||
{
|
||||
std::lock_guard lock(pipe.eopFlipMtx);
|
||||
if (pipe.eopFlipRequestCount >= GraphicsPipe::kEopFlipRequestMax) {
|
||||
return orbis::ErrorCode::AGAIN;
|
||||
}
|
||||
|
||||
index = pipe.eopFlipRequestCount++;
|
||||
|
||||
pipe.eopFlipRequests[index] = {
|
||||
.pid = pid,
|
||||
.bufferIndex = bufferIndex,
|
||||
.arg = flipArg,
|
||||
};
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
void DeviceCtl::submitMapMemory(int gfxPipe, std::uint32_t pid,
|
||||
std::uint64_t address, std::uint64_t size,
|
||||
int memoryType, int dmemIndex, int prot,
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@ public:
|
|||
void submitSwitchBuffer(int gfxPipe);
|
||||
void submitFlip(int gfxPipe, std::uint32_t pid, int bufferIndex,
|
||||
std::uint64_t flipArg);
|
||||
orbis::ErrorCode submitFlipOnEop(int gfxPipe, std::uint32_t pid,
|
||||
int bufferIndex, std::uint64_t flipArg);
|
||||
void submitMapMemory(int gfxPipe, std::uint32_t pid, std::uint64_t address,
|
||||
std::uint64_t size, int memoryType, int dmemIndex,
|
||||
int prot, std::int64_t offset);
|
||||
|
|
@ -48,7 +50,7 @@ public:
|
|||
orbis::uint64_t readPtrAddress, orbis::uint64_t doorbell,
|
||||
orbis::uint64_t ringSize);
|
||||
void submitComputeQueue(std::uint32_t meId, std::uint32_t pipeId,
|
||||
std::uint32_t queueId, std::uint64_t offset);
|
||||
std::uint32_t queueId, std::uint64_t offset);
|
||||
void start();
|
||||
void waitForIdle();
|
||||
|
||||
|
|
|
|||
|
|
@ -1190,6 +1190,23 @@ bool GraphicsPipe::eventWriteEop(Ring &ring) {
|
|||
kGcEventGfxEop);
|
||||
}
|
||||
|
||||
if (intSel == 2) {
|
||||
std::optional<EopFlipRequest> request;
|
||||
int index;
|
||||
{
|
||||
std::lock_guard lock(eopFlipMtx);
|
||||
|
||||
if (eopFlipRequestCount > 0) {
|
||||
index = --eopFlipRequestCount;
|
||||
request = eopFlipRequests[index];
|
||||
}
|
||||
}
|
||||
|
||||
if (request) {
|
||||
device->flip(request->pid, request->bufferIndex, request->arg);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -51,7 +51,8 @@ struct ComputePipe {
|
|||
bool processAllRings();
|
||||
bool processRing(Ring &ring);
|
||||
void setIndirectRing(int queueId, int level, Ring ring);
|
||||
void mapQueue(int queueId, Ring ring, std::unique_lock<orbis::shared_mutex> &lock);
|
||||
void mapQueue(int queueId, Ring ring,
|
||||
std::unique_lock<orbis::shared_mutex> &lock);
|
||||
void waitForIdle(int queueId, std::unique_lock<orbis::shared_mutex> &lock);
|
||||
void submit(int queueId, std::uint32_t offset);
|
||||
|
||||
|
|
@ -73,7 +74,14 @@ struct ComputePipe {
|
|||
std::uint32_t *getMmRegister(Ring &ring, std::uint32_t dwAddress);
|
||||
};
|
||||
|
||||
struct EopFlipRequest {
|
||||
std::uint32_t pid;
|
||||
int bufferIndex;
|
||||
std::uint64_t arg;
|
||||
};
|
||||
|
||||
struct GraphicsPipe {
|
||||
static constexpr auto kEopFlipRequestMax = 0x10;
|
||||
Device *device;
|
||||
Scheduler scheduler;
|
||||
|
||||
|
|
@ -95,6 +103,10 @@ struct GraphicsPipe {
|
|||
Ring deQueues[3];
|
||||
Ring ceQueue;
|
||||
|
||||
orbis::shared_mutex eopFlipMtx;
|
||||
std::uint32_t eopFlipRequestCount{0};
|
||||
EopFlipRequest eopFlipRequests[kEopFlipRequestMax];
|
||||
|
||||
using CommandHandler = bool (GraphicsPipe::*)(Ring &);
|
||||
CommandHandler commandHandlers[4][255];
|
||||
|
||||
|
|
|
|||
|
|
@ -392,15 +392,17 @@ static orbis::ErrorCode dce_ioctl(orbis::File *file, std::uint64_t request,
|
|||
// flip request
|
||||
auto args = reinterpret_cast<FlipRequestArgs *>(argp);
|
||||
|
||||
// ORBIS_LOG_ERROR("dce: FlipRequestArgs", args->canary,
|
||||
// args->displayBufferIndex, args->flipMode, args->unk1,
|
||||
// args->flipArg, args->flipArg2, args->eop_nz, args->unk2,
|
||||
// args->eop_val, args->unk3, args->unk4, args->rout);
|
||||
gpu.submitFlip(thread->tproc->gfxRing, thread->tproc->pid,
|
||||
args->displayBufferIndex,
|
||||
/*args->flipMode,*/ args->flipArg);
|
||||
if (args->eop_nz == 0) {
|
||||
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;
|
||||
}
|
||||
|
||||
// *args->rout = 0;
|
||||
*args->rout = 0;
|
||||
return {};
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue