diff --git a/rpcsx/gpu/DeviceCtl.cpp b/rpcsx/gpu/DeviceCtl.cpp index ecedbb1d4..b299e40ac 100644 --- a/rpcsx/gpu/DeviceCtl.cpp +++ b/rpcsx/gpu/DeviceCtl.cpp @@ -36,17 +36,21 @@ void DeviceCtl::submitGfxCommand(int gfxPipe, int vmId, auto type = rx::getBits(command[0], 31, 30); auto len = rx::getBits(command[0], 29, 16) + 2; - if ((op != gnm::IT_INDIRECT_BUFFER && op != gnm::IT_INDIRECT_BUFFER_CNST) || - type != 3 || len != 4 || command.size() != len) { - std::println(stderr, "unexpected gfx command for main ring: {}, {}, {}", op, - type, len); + if ((op != gnm::IT_INDIRECT_BUFFER && op != gnm::IT_INDIRECT_BUFFER_CNST && + op != gnm::IT_CONTEXT_CONTROL) || + type != 3 || command.size() != len) { + std::println(stderr, "unexpected gfx command for main ring: {}, {}, {}", + gnm::Pm4Opcode(op), type, len); rx::die(""); } std::vector patchedCommand{command.data(), command.data() + command.size()}; - patchedCommand[3] &= ~(~0 << 24); - patchedCommand[3] |= vmId << 24; + + if (op == gnm::IT_INDIRECT_BUFFER || op == gnm::IT_INDIRECT_BUFFER_CNST) { + patchedCommand[3] &= ~(~0 << 24); + patchedCommand[3] |= vmId << 24; + } mDevice->submitGfxCommand(gfxPipe, patchedCommand); } diff --git a/rpcsx/gpu/Pipe.cpp b/rpcsx/gpu/Pipe.cpp index 57036b532..8b6f5eae0 100644 --- a/rpcsx/gpu/Pipe.cpp +++ b/rpcsx/gpu/Pipe.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include using namespace amdgpu; @@ -28,6 +29,11 @@ enum GraphicsCoreEvent { kGcEventClockSet = 0x84, }; +struct RegSpan { + std::uint32_t offset; + std::uint32_t count; +}; + static Scheduler createGfxScheduler(int index) { auto queue = vk::context->presentQueue; auto family = vk::context->presentQueueFamily; @@ -621,6 +627,7 @@ GraphicsPipe::GraphicsPipe(int index) : scheduler(createGfxScheduler(index)) { deHandlers[gnm::IT_INDEX_BASE] = &GraphicsPipe::indexBase; deHandlers[gnm::IT_DRAW_INDEX_2] = &GraphicsPipe::drawIndex2; + mainHandlers[gnm::IT_CONTEXT_CONTROL] = &GraphicsPipe::contextControl; deHandlers[gnm::IT_CONTEXT_CONTROL] = &GraphicsPipe::contextControl; deHandlers[gnm::IT_INDEX_TYPE] = &GraphicsPipe::indexType; @@ -651,7 +658,7 @@ GraphicsPipe::GraphicsPipe(int index) : scheduler(createGfxScheduler(index)) { deHandlers[gnm::IT_EVENT_WRITE_EOP] = &GraphicsPipe::eventWriteEop; deHandlers[gnm::IT_EVENT_WRITE_EOS] = &GraphicsPipe::eventWriteEos; deHandlers[gnm::IT_RELEASE_MEM] = &GraphicsPipe::releaseMem; - // IT_PREAMBLE_CNTL + deHandlers[gnm::IT_PREAMBLE_CNTL] = &GraphicsPipe::releaseMem; deHandlers[gnm::IT_DMA_DATA] = &GraphicsPipe::dmaData; deHandlers[gnm::IT_ACQUIRE_MEM] = &GraphicsPipe::acquireMem; // IT_REWIND @@ -659,7 +666,10 @@ GraphicsPipe::GraphicsPipe(int index) : scheduler(createGfxScheduler(index)) { // IT_LOAD_UCONFIG_REG // IT_LOAD_SH_REG // IT_LOAD_CONFIG_REG - // IT_LOAD_CONTEXT_REG + deHandlers[gnm::IT_LOAD_UCONFIG_REG] = &GraphicsPipe::loadUConfigReg; + deHandlers[gnm::IT_LOAD_SH_REG] = &GraphicsPipe::loadShReg; + deHandlers[gnm::IT_LOAD_CONFIG_REG] = &GraphicsPipe::loadConfigReg; + deHandlers[gnm::IT_LOAD_CONTEXT_REG] = &GraphicsPipe::loadContextReg; deHandlers[gnm::IT_SET_CONFIG_REG] = &GraphicsPipe::setConfigReg; deHandlers[gnm::IT_SET_CONTEXT_REG] = &GraphicsPipe::setContextReg; // IT_SET_CONTEXT_REG_INDIRECT @@ -688,6 +698,14 @@ GraphicsPipe::GraphicsPipe(int index) : scheduler(createGfxScheduler(index)) { ceHandlers[gnm::IT_LOAD_CONST_RAM] = &GraphicsPipe::loadConstRam; ceHandlers[gnm::IT_WRITE_CONST_RAM] = &GraphicsPipe::writeConstRam; ceHandlers[gnm::IT_DUMP_CONST_RAM] = &GraphicsPipe::dumpConstRam; + + deHandlers[gnm::IT_WAIT_REG_MEM64] = &GraphicsPipe::waitRegMem64; + deHandlers[gnm::IT_LOAD_CONTEXT_REG_INDEX] = + &GraphicsPipe::loadContextRegIndex; + deHandlers[gnm::IT_LOAD_SH_REG_INDEX] = &GraphicsPipe::loadShRegIndex; + deHandlers[gnm::IT_LOAD_UCONFIG_REG_INDEX] = + &GraphicsPipe::loadUConfigRegIndex; + deHandlers[gnm::IT_SET_UCONFIG_REG_INDEX] = &GraphicsPipe::setUConfigRegIndex; } void GraphicsPipe::setCeQueue(Ring ring) { @@ -814,12 +832,12 @@ void GraphicsPipe::processRing(Ring &ring) { // } if (op == gnm::IT_COND_EXEC) { - rx::die("unimplemented COND_EXEC"); - } - - auto handler = commandHandlers[cp][op]; - if (!(this->*handler)(ring)) { - return; + std::println("unimplemented COND_EXEC"); + } else { + auto handler = commandHandlers[cp][op]; + if (!(this->*handler)(ring)) { + return; + } } ring.rptr += @@ -953,7 +971,10 @@ bool GraphicsPipe::releaseMem(Ring &ring) { break; default: - rx::die("unimplemented event release mem data %#x", dataSel); + std::println(stderr, + "unimplemented event release mem data {:#x}, address {}, " + "dataLo {:x}, dataHi {:x}", + dataSel, address, dataLo, dataHi); } return true; @@ -1556,6 +1577,130 @@ bool GraphicsPipe::dmaData(Ring &ring) { return true; } +bool GraphicsPipe::loadUConfigReg(Ring &ring) { + auto len = rx::getBits(ring.rptr[0], 29, 16) - 1; + uint32_t addressLo = ring.rptr[1] & ~3; + uint32_t addressHiOffset = ring.rptr[2]; + auto ranges = (RegSpan *)(ring.rptr + 3); + + constexpr auto mmioOffset = Registers::UConfig::kMmioOffset; + std::uint64_t address = + addressLo | (static_cast(addressHiOffset) << 32); + auto data = + amdgpu::RemoteMemory{ring.vmId}.getPointer(address); + + for (auto range : std::span{ranges, len / 2}) { + // std::println(stderr, "loadUConfigReg: address={} regOffset={} + // numWords={}", + // data, range.offset, range.count); + // for (auto offset = range.offset; + // auto value : std::span{data, range.count}) { + // std::fprintf(stderr, "writing %x to %s\n", value, + // gnm::mmio::registerName(mmioOffset + offset)); + // ++offset; + // } + + std::memcpy(getMmRegister(mmioOffset + range.offset), data, + sizeof(std::uint32_t) * range.count); + data += range.count; + } + + return true; +} + +bool GraphicsPipe::loadShReg(Ring &ring) { + auto len = rx::getBits(ring.rptr[0], 29, 16) - 1; + uint32_t addressLo = ring.rptr[1] & ~3; + uint32_t addressHiOffset = ring.rptr[2]; + auto ranges = (RegSpan *)(ring.rptr + 3); + + constexpr auto mmioOffset = Registers::ShaderConfig::kMmioOffset; + std::uint64_t address = + addressLo | (static_cast(addressHiOffset) << 32); + auto data = + amdgpu::RemoteMemory{ring.vmId}.getPointer(address); + + for (auto range : std::span{ranges, len / 2}) { + // std::println(stderr, "loadShReg: address={} regOffset={} numWords={}", + // data, + // range.offset, range.count); + // for (auto offset = range.offset; + // auto value : std::span{data, range.count}) { + // std::fprintf(stderr, "writing %x to %s\n", value, + // gnm::mmio::registerName(mmioOffset + offset)); + // ++offset; + // } + + std::memcpy(getMmRegister(mmioOffset + range.offset), data, + sizeof(std::uint32_t) * range.count); + data += range.count; + } + + return true; +} + +bool GraphicsPipe::loadConfigReg(Ring &ring) { + auto len = rx::getBits(ring.rptr[0], 29, 16) - 1; + uint32_t addressLo = ring.rptr[1] & ~3; + uint32_t addressHiOffset = ring.rptr[2]; + auto ranges = (RegSpan *)(ring.rptr + 3); + + constexpr auto mmioOffset = Registers::Config::kMmioOffset; + std::uint64_t address = + addressLo | (static_cast(addressHiOffset) << 32); + auto data = + amdgpu::RemoteMemory{ring.vmId}.getPointer(address); + + for (auto range : std::span{ranges, len / 2}) { + // std::println(stderr, "loadConfigReg: address={} regOffset={} + // numWords={}", + // data, range.offset, range.count); + // for (auto offset = range.offset; + // auto value : std::span{data, range.count}) { + // std::fprintf(stderr, "writing %x to %s\n", value, + // gnm::mmio::registerName(mmioOffset + offset)); + // ++offset; + // } + + std::memcpy(getMmRegister(mmioOffset + range.offset), data, + sizeof(std::uint32_t) * range.count); + data += range.count; + } + + return true; +} + +bool GraphicsPipe::loadContextReg(Ring &ring) { + auto len = rx::getBits(ring.rptr[0], 29, 16) - 1; + uint32_t addressLo = ring.rptr[1] & ~3; + uint32_t addressHiOffset = ring.rptr[2]; + auto ranges = (RegSpan *)(ring.rptr + 3); + + constexpr auto mmioOffset = Registers::Context::kMmioOffset; + std::uint64_t address = + addressLo | (static_cast(addressHiOffset) << 32); + auto data = + amdgpu::RemoteMemory{ring.vmId}.getPointer(address); + + for (auto range : std::span{ranges, len / 2}) { + // std::println(stderr, "loadContextReg: address={} regOffset={} + // numWords={}", + // data, range.offset, range.count); + // for (auto offset = range.offset; + // auto value : std::span{data, range.count}) { + // std::fprintf(stderr, "writing %x to %s\n", value, + // gnm::mmio::registerName(mmioOffset + offset)); + // ++offset; + // } + + std::memcpy(getMmRegister(mmioOffset + range.offset), data, + sizeof(std::uint32_t) * range.count); + data += range.count; + } + + return true; +} + bool GraphicsPipe::setConfigReg(Ring &ring) { auto len = rx::getBits(ring.rptr[0], 29, 16); auto offset = ring.rptr[1] & 0xffff; @@ -1613,25 +1758,27 @@ bool GraphicsPipe::setUConfigReg(Ring &ring) { auto index = ring.rptr[1] >> 26; auto data = ring.rptr + 2; - if (index != 0) { - { - auto name = - gnm::mmio::registerName(decltype(uConfig)::kMmioOffset + offset); - std::println( - stderr, - "set UConfig regs with index, offset: {:x}, count {}, index {}, {}", - offset, len, index, name ? name : ""); - } + // if (index != 0) { + // { + // auto name = + // gnm::mmio::registerName(decltype(uConfig)::kMmioOffset + offset); + // std::println( + // stderr, + // "set UConfig regs with index, offset: {:x}, count {}, index {}, + // {}", offset, len, index, name ? name : ""); + // } - for (std::size_t i = 0; i < len; ++i) { - auto id = decltype(uConfig)::kMmioOffset + offset + i; - if (auto regName = gnm::mmio::registerName(id)) { - std::println(stderr, "writing to {} value {:x}", regName, uint32_t(data[i])); - } else { - std::println(stderr, "writing to {:x} value {:x}", id, uint32_t(data[i])); - } - } - } + // for (std::size_t i = 0; i < len; ++i) { + // auto id = decltype(uConfig)::kMmioOffset + offset + i; + // if (auto regName = gnm::mmio::registerName(id)) { + // std::println(stderr, "writing to {} value {:x}", regName, + // uint32_t(data[i])); + // } else { + // std::println(stderr, "writing to {:x} value {:x}", id, + // uint32_t(data[i])); + // } + // } + // } rx::dieIf((offset + len) * sizeof(std::uint32_t) > sizeof(context), "out of UConfig regs, offset: %u, count %u, %s\n", offset, len, @@ -1654,25 +1801,27 @@ bool GraphicsPipe::setContextReg(Ring &ring) { auto index = ring.rptr[1] >> 26; auto data = ring.rptr + 2; - if (index != 0) { - { - auto name = - gnm::mmio::registerName(decltype(context)::kMmioOffset + offset); - std::println( - stderr, - "set Context regs with index, offset: {:x}, count {}, index {}, {}", - offset, len, index, name ? name : ""); - } + // if (index != 0) { + // { + // auto name = + // gnm::mmio::registerName(decltype(context)::kMmioOffset + offset); + // std::println( + // stderr, + // "set Context regs with index, offset: {:x}, count {}, index {}, + // {}", offset, len, index, name ? name : ""); + // } - for (std::size_t i = 0; i < len; ++i) { - auto id = decltype(context)::kMmioOffset + offset + i; - if (auto regName = gnm::mmio::registerName(id)) { - std::println(stderr, "writing to {} value {:x}", regName, uint32_t(data[i])); - } else { - std::println(stderr, "writing to {:x} value {:x}", id, uint32_t(data[i])); - } - } - } + // for (std::size_t i = 0; i < len; ++i) { + // auto id = decltype(context)::kMmioOffset + offset + i; + // if (auto regName = gnm::mmio::registerName(id)) { + // std::println(stderr, "writing to {} value {:x}", regName, + // uint32_t(data[i])); + // } else { + // std::println(stderr, "writing to {:x} value {:x}", id, + // uint32_t(data[i])); + // } + // } + // } rx::dieIf((offset + len) * sizeof(std::uint32_t) > sizeof(context), "out of Context regs, offset: %u, count %u, %s\n", offset, len, @@ -1779,6 +1928,216 @@ bool GraphicsPipe::unmapQueues(Ring &ring) { return true; } +bool GraphicsPipe::waitRegMem64(Ring &ring) { + // FIXME: implement + return true; +} + +bool GraphicsPipe::loadContextRegIndex(Ring &ring) { + uint32_t index = ring.rptr[1] & 1; + uint32_t addressLo = ring.rptr[1] & ~3; + uint32_t addressHiOffset = ring.rptr[2]; + uint32_t regOffset = ring.rptr[3] & ((1 << 16) - 1); + uint32_t dataFormat = ring.rptr[3] >> 31; + uint32_t numWords = (ring.rptr[4] & ((1 << 14) - 1)); + + if (index == 0) { + // direct address + } else { + // offset + rx::die("%s: unimplemented index 1", __FUNCTION__); + } + + // std::println( + // stderr, + // "loadContextRegIndex: index={} addressLo={:x} addressHiOffset={:x} " + // "regOffset={} dataFormat={} numWords={}", + // index, addressLo, addressHiOffset, regOffset, dataFormat, numWords); + std::uint64_t address = + addressLo | (static_cast(addressHiOffset) << 32); + auto data = + amdgpu::RemoteMemory{ring.vmId}.getPointer(address); + + constexpr auto mmioOffset = Registers::Context::kMmioOffset; + + if (dataFormat == 0) { + // offset and size + // for (auto offset = regOffset; auto value : std::span{data, numWords}) { + // if (auto name = gnm::mmio::registerName(mmioOffset + offset)) { + // std::println(stderr, "writing {:x} to {}", value, name); + // } else { + // std::println(stderr, "writing {:x} to {:x}", value, + // mmioOffset + offset); + // } + // ++offset; + // } + + std::memcpy(getMmRegister(mmioOffset + regOffset), data, + sizeof(std::uint32_t) * numWords); + } else { + // offset and data + + for (auto value : + std::span{(std::pair *)data, numWords}) { + // if (auto name = gnm::mmio::registerName(mmioOffset + value.first)) { + // std::println(stderr, "writing {:x} to {}", value.second, name); + // } else { + // std::println(stderr, "writing {:x} to {:x}", value.second, + // mmioOffset + value.first); + // } + + auto regPtr = getMmRegister(mmioOffset + value.first); + + *regPtr = value.second; + } + } + + return true; +} + +bool GraphicsPipe::loadShRegIndex(Ring &ring) { + uint32_t index = ring.rptr[1] & 1; + uint32_t addressLo = ring.rptr[1] & ~3; + uint32_t addressHiOffset = ring.rptr[2]; + uint32_t regOffset = ring.rptr[3] & ((1 << 16) - 1); + uint32_t dataFormat = ring.rptr[3] >> 31; + uint32_t numWords = (ring.rptr[4] & ((1 << 14) - 1)); + + if (index == 0) { + // direct address + } else { + // offset + rx::die("%s: unimplemented index 1", __FUNCTION__); + } + + if (dataFormat == 0) { + // offset and size + } else { + // offset and data + } + // std::println(stderr, + // "loadShRegIndex: index={} addressLo={:x} addressHiOffset={:x} + // " "regOffset={} dataFormat={} numWords={}", index, addressLo, + // addressHiOffset, regOffset, dataFormat, numWords); + std::uint64_t address = + addressLo | (static_cast(addressHiOffset) << 32); + auto data = + amdgpu::RemoteMemory{ring.vmId}.getPointer(address); + + constexpr auto mmioOffset = Registers::ShaderConfig::kMmioOffset; + + if (dataFormat == 0) { + // offset and size + // for (auto offset = regOffset; auto value : std::span{data, numWords}) { + // std::fprintf(stderr, "writing %x to %s\n", value, + // gnm::mmio::registerName(mmioOffset + offset)); + // ++offset; + // } + + std::memcpy(getMmRegister(mmioOffset + regOffset), data, + sizeof(std::uint32_t) * numWords); + } else { + // offset and data + + for (auto value : + std::span{(std::pair *)data, numWords}) { + // std::fprintf(stderr, "writing %x to %s\n", value.second, + // gnm::mmio::registerName(mmioOffset + value.first)); + + auto regPtr = getMmRegister(mmioOffset + value.first); + + *regPtr = value.second; + } + } + + return true; +} + +bool GraphicsPipe::loadUConfigRegIndex(Ring &ring) { + uint32_t index = ring.rptr[1] & 1; + uint32_t addressLo = ring.rptr[1] & ~3; + uint32_t addressHiOffset = ring.rptr[2]; + uint32_t regOffset = ring.rptr[3] & ((1 << 16) - 1); + uint32_t dataFormat = ring.rptr[3] >> 31; + uint32_t numWords = (ring.rptr[4] & ((1 << 14) - 1)); + + if (index == 0) { + // direct address + } else { + // offset + rx::die("%s: unimplemented index 1", __FUNCTION__); + } + + if (dataFormat == 0) { + // offset and size + } else { + // offset and data + } + + // std::println( + // stderr, + // "loadUConfigRegIndex: index={} addressLo={:x} addressHiOffset={:x} " + // "regOffset={} dataFormat={} numWords={}", + // index, addressLo, addressHiOffset, regOffset, dataFormat, numWords); + // FIXME: implement + std::uint64_t address = + addressLo | (static_cast(addressHiOffset) << 32); + auto data = + amdgpu::RemoteMemory{ring.vmId}.getPointer(address); + + constexpr auto mmioOffset = Registers::UConfig::kMmioOffset; + + if (dataFormat == 0) { + // offset and size + // for (auto offset = regOffset; auto value : std::span{data, numWords}) { + // std::fprintf(stderr, "writing %x to %s\n", value, + // gnm::mmio::registerName(mmioOffset + offset)); + // ++offset; + // } + + std::memcpy(getMmRegister(mmioOffset + regOffset), data, + sizeof(std::uint32_t) * numWords); + } else { + // offset and data + + for (auto value : + std::span{(std::pair *)data, numWords}) { + // std::fprintf(stderr, "writing %x to %s\n", value.second, + // gnm::mmio::registerName(mmioOffset + value.first)); + + auto regPtr = getMmRegister(mmioOffset + value.first); + + *regPtr = value.second; + } + } + + return true; +} + +bool GraphicsPipe::setUConfigRegIndex(Ring &ring) { + auto len = rx::getBits(ring.rptr[0], 29, 16); + auto offset = ring.rptr[1] & 0xffff; + auto data = ring.rptr + 2; + + rx::dieIf((offset + len) * sizeof(std::uint32_t) > sizeof(context), + "out of UConfig regs, offset: %u, count %u, %s\n", offset, len, + gnm::mmio::registerName(decltype(uConfig)::kMmioOffset + offset)); + + // for (std::size_t i = 0; i < len; ++i) { + // auto id = decltype(uConfig)::kMmioOffset + offset + i; + // if (auto regName = gnm::mmio::registerName(id)) { + // std::println(stderr, "writing to {} value {:x}", regName, + // uint32_t(data[i])); + // } else { + // std::println(stderr, "writing to {:x} value {:x}", id, uint32_t(data[i])); + // } + // } + + std::memcpy(reinterpret_cast(&uConfig) + offset, + const_cast(data), sizeof(std::uint32_t) * len); + return true; +} + CommandPipe::CommandPipe() { for (auto &handler : commandHandlers) { handler = &CommandPipe::unknownPacket; diff --git a/rpcsx/gpu/Pipe.hpp b/rpcsx/gpu/Pipe.hpp index e512b2ffa..77d9edeeb 100644 --- a/rpcsx/gpu/Pipe.hpp +++ b/rpcsx/gpu/Pipe.hpp @@ -130,6 +130,7 @@ struct GraphicsPipe { bool contextControl(Ring &ring); bool acquireMem(Ring &ring); bool releaseMem(Ring &ring); + bool preambleCtl(Ring &ring); bool dispatchDirect(Ring &ring); bool dispatchIndirect(Ring &ring); bool writeData(Ring &ring); @@ -163,6 +164,10 @@ struct GraphicsPipe { bool loadConstRam(Ring &ring); bool writeConstRam(Ring &ring); bool dumpConstRam(Ring &ring); + bool loadUConfigReg(Ring &ring); + bool loadShReg(Ring &ring); + bool loadConfigReg(Ring &ring); + bool loadContextReg(Ring &ring); bool setConfigReg(Ring &ring); bool setShReg(Ring &ring); bool setUConfigReg(Ring &ring); @@ -170,6 +175,12 @@ struct GraphicsPipe { bool mapQueues(Ring &ring); bool unmapQueues(Ring &ring); + bool waitRegMem64(Ring &ring); + bool loadContextRegIndex(Ring &ring); + bool loadShRegIndex(Ring &ring); + bool loadUConfigRegIndex(Ring &ring); + bool setUConfigRegIndex(Ring &ring); + bool unknownPacket(Ring &ring); bool switchBuffer(Ring &ring); diff --git a/rpcsx/gpu/Registers.hpp b/rpcsx/gpu/Registers.hpp index 33461d49d..1e4b68753 100644 --- a/rpcsx/gpu/Registers.hpp +++ b/rpcsx/gpu/Registers.hpp @@ -660,6 +660,7 @@ struct Registers { Register<0x107, SpiShaderPgm> spiShaderPgmHs; Register<0x147, SpiShaderPgm> spiShaderPgmLs; Register<0x200, ComputeConfig> compute; + Register<0x277, SpiShaderPgm> unk; }; }; @@ -818,6 +819,7 @@ struct Registers { Register<0x316> unk_316; Register<0x317> vgtOutDeallocCntl; Register<0x318, std::array> cbColor; + Register<0x500> unk; }; }; diff --git a/rpcsx/gpu/lib/gnm/include/gnm/pm4.hpp b/rpcsx/gpu/lib/gnm/include/gnm/pm4.hpp index 77d156362..8bc1bfe52 100644 --- a/rpcsx/gpu/lib/gnm/include/gnm/pm4.hpp +++ b/rpcsx/gpu/lib/gnm/include/gnm/pm4.hpp @@ -51,6 +51,8 @@ enum Pm4Opcode { IT_LOAD_SH_REG = 0x5f, IT_LOAD_CONFIG_REG = 0x60, IT_LOAD_CONTEXT_REG = 0x61, + IT_LOAD_SH_REG_INDEX = 0x63, + IT_LOAD_UCONFIG_REG_INDEX = 0x64, IT_SET_CONFIG_REG = 0x68, IT_SET_CONTEXT_REG = 0x69, IT_SET_CONTEXT_REG_INDIRECT = 0x73, @@ -58,6 +60,7 @@ enum Pm4Opcode { IT_SET_SH_REG_OFFSET = 0x77, IT_SET_QUEUE_REG = 0x78, IT_SET_UCONFIG_REG = 0x79, + IT_SET_UCONFIG_REG_INDEX = 0x7a, IT_SCRATCH_RAM_WRITE = 0x7d, IT_SCRATCH_RAM_READ = 0x7e, IT_LOAD_CONST_RAM = 0x80, @@ -70,14 +73,18 @@ enum Pm4Opcode { IT_SET_CE_DE_COUNTERS = 0x89, IT_WAIT_ON_AVAIL_BUFFER = 0x8a, IT_SWITCH_BUFFER = 0x8b, + IT_DISPATCH_DRAW_PREAMBLE = 0x8c, + IT_DISPATCH_DRAW = 0x8d, + IT_WAIT_REG_MEM64 = 0x93, + IT_LOAD_CONTEXT_REG_INDEX = 0x9f, IT_SET_RESOURCES = 0xa0, IT_MAP_PROCESS = 0xa1, IT_MAP_QUEUES = 0xa2, IT_UNMAP_QUEUES = 0xa3, IT_QUERY_STATUS = 0xa4, IT_RUN_LIST = 0xa5, - IT_DISPATCH_DRAW_PREAMBLE = 0x8c, - IT_DISPATCH_DRAW = 0x8d, + + _count }; const char *pm4OpcodeToString(int opcode); diff --git a/rpcsx/iodev/dce.cpp b/rpcsx/iodev/dce.cpp index c5b415d88..6573d5ab1 100644 --- a/rpcsx/iodev/dce.cpp +++ b/rpcsx/iodev/dce.cpp @@ -294,6 +294,7 @@ static orbis::ErrorCode dce_ioctl(orbis::File *file, std::uint64_t request, ORBIS_LOG_FATAL("dce: unimplemented 0x80308217 request", args->id, args->padding, args->arg2, args->ptr, args->size, args->arg5, args->arg6); + return {}; } }