mirror of
https://github.com/RPCSX/rpcsx.git
synced 2025-12-06 07:12:14 +01:00
gpu: compute: implement IT_INDIRECT_BUFFER
This commit is contained in:
parent
4fe857485c
commit
7a7f317ce8
|
|
@ -95,6 +95,7 @@ ComputePipe::ComputePipe(int index)
|
|||
commandHandlers[gnm::IT_RELEASE_MEM] = &ComputePipe::releaseMem;
|
||||
commandHandlers[gnm::IT_WAIT_REG_MEM] = &ComputePipe::waitRegMem;
|
||||
commandHandlers[gnm::IT_WRITE_DATA] = &ComputePipe::writeData;
|
||||
commandHandlers[gnm::IT_INDIRECT_BUFFER] = &ComputePipe::indirectBuffer;
|
||||
}
|
||||
|
||||
bool ComputePipe::processAllRings() {
|
||||
|
|
@ -104,6 +105,7 @@ bool ComputePipe::processAllRings() {
|
|||
std::lock_guard lock(queueMtx[&queue - queues]);
|
||||
|
||||
for (auto &ring : queue) {
|
||||
currentQueueId = &ring - queue;
|
||||
if (!processRing(ring)) {
|
||||
allProcessed = false;
|
||||
}
|
||||
|
|
@ -172,6 +174,19 @@ bool ComputePipe::processRing(Ring &ring) {
|
|||
return true;
|
||||
}
|
||||
|
||||
void ComputePipe::setIndirectRing(int queueId, int indirectLevel, Ring ring) {
|
||||
if (indirectLevel != 1) {
|
||||
rx::die("unexpected compute indirect ring indirect level %d",
|
||||
ring.indirectLevel);
|
||||
}
|
||||
|
||||
ring.indirectLevel = indirectLevel;
|
||||
std::println("mapQueue: {}, {}, {}", (void *)ring.base, (void *)ring.wptr,
|
||||
ring.size);
|
||||
|
||||
queues[1 - ring.indirectLevel][queueId] = ring;
|
||||
}
|
||||
|
||||
void ComputePipe::mapQueue(int queueId, Ring ring,
|
||||
std::unique_lock<orbis::shared_mutex> &lock) {
|
||||
if (ring.indirectLevel < 0 || ring.indirectLevel > 1) {
|
||||
|
|
@ -390,6 +405,24 @@ bool ComputePipe::writeData(Ring &ring) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ComputePipe::indirectBuffer(Ring &ring) {
|
||||
rx::dieIf(ring.indirectLevel < 0, "unexpected indirect buffer from CP");
|
||||
|
||||
auto addressLo = ring.rptr[1] & ~3;
|
||||
auto addressHi = ring.rptr[2] & ((1 << 8) - 1);
|
||||
int vmId = ring.rptr[3] >> 24;
|
||||
auto ibSize = ring.rptr[3] & ((1 << 20) - 1);
|
||||
auto address = addressLo | (static_cast<std::uint64_t>(addressHi) << 32);
|
||||
|
||||
if (ring.indirectLevel != 0) {
|
||||
vmId = ring.vmId;
|
||||
}
|
||||
auto rptr = RemoteMemory{vmId}.getPointer<std::uint32_t>(address);
|
||||
setIndirectRing(currentQueueId, ring.indirectLevel + 1,
|
||||
Ring::createFromRange(vmId, rptr, ibSize));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ComputePipe::unknownPacket(Ring &ring) {
|
||||
auto op = rx::getBits(ring.rptr[0], 15, 8);
|
||||
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ struct ComputePipe {
|
|||
CommandHandler commandHandlers[255];
|
||||
orbis::shared_mutex queueMtx[8];
|
||||
int index;
|
||||
int currentQueueId;
|
||||
Ring queues[2][8];
|
||||
std::uint64_t drawIndexIndirPatchBase = 0;
|
||||
|
||||
|
|
@ -49,6 +50,7 @@ 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 waitForIdle(int queueId, std::unique_lock<orbis::shared_mutex> &lock);
|
||||
void submit(int queueId, std::uint32_t offset);
|
||||
|
|
@ -63,6 +65,7 @@ struct ComputePipe {
|
|||
bool releaseMem(Ring &ring);
|
||||
bool waitRegMem(Ring &ring);
|
||||
bool writeData(Ring &ring);
|
||||
bool indirectBuffer(Ring &ring);
|
||||
bool unknownPacket(Ring &ring);
|
||||
bool handleNop(Ring &ring);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue