mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-10-18 23:07:07 -05:00
feat(libSceAgc): implement DCB atomic GDS operations and correct size accessor
This commit is contained in:
1 parent
ccbd40240f
commit
cf994f1f60
5 files changed
+60
-11
No files matched your search
@@ -1,4 +1,12 @@
|
||||
#ifndef CORE_LIBS_PRX_LIBSCEAGC_DCBFLOW_INCLUDE_CONTROL_HPP
|
||||
#define CORE_LIBS_PRX_LIBSCEAGC_DCBFLOW_INCLUDE_CONTROL_HPP
|
||||
|
||||
#include "SceTypes.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
extern "C" {
|
||||
std::uint32_t* APS5_VABI sceAgcDcbAtomicGds(CommandBuffer* buf, std::uint32_t control, std::uint32_t mode, std::uint32_t gdsOp, std::uint32_t src, std::uint16_t offset, std::uint16_t index, std::uint32_t mask, std::uint32_t data, std::uint64_t compareData, std::uint64_t extraData);
|
||||
std::uint32_t* APS5_VABI sceAgcDcbAtomicGds_0900(CommandBuffer* buf, std::uint32_t control, std::uint32_t mode, std::uint32_t gdsOp, std::uint32_t src, std::uint16_t offset, std::uint16_t index, std::uint32_t mask, std::uint32_t data, std::uint64_t compareData, std::uint64_t extraData);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -2,7 +2,11 @@
|
||||
#define CORE_LIBS_PRX_LIBSCEAGC_DCBFLOW_INCLUDE_MEMORY_HPP
|
||||
|
||||
#include "SceTypes.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
extern "C" std::uint32_t* APS5_VABI sceAgcDcbAcquireMem(CommandBuffer* buf, std::uint8_t engine, std::uint32_t cbDbOp, std::uint32_t gcrControl, const volatile void* base, std::uint64_t sizeBytes, std::uint32_t pollCycles);
|
||||
extern "C" {
|
||||
std::uint32_t* APS5_VABI sceAgcDcbAcquireMem(CommandBuffer* buf, std::uint8_t engine, std::uint32_t cbDbOp, std::uint32_t gcrControl, const volatile void* base, std::uint64_t sizeBytes, std::uint32_t pollCycles);
|
||||
std::uint32_t APS5_VABI sceAgcDcbAtomicGdsGetSize();
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -12,10 +12,19 @@
|
||||
|
||||
extern "C" {
|
||||
|
||||
// unknown signature
|
||||
void* APS5_VABI sceAgcDcbAtomicGds_0900(void) {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
return nullptr;
|
||||
std::uint32_t* APS5_VABI sceAgcDcbAtomicGds_0900(CommandBuffer* buf, std::uint32_t control, std::uint32_t mode, std::uint32_t gdsOp, std::uint32_t src, std::uint16_t offset, std::uint16_t index, std::uint32_t mask, std::uint32_t data, std::uint64_t compareData, std::uint64_t extraData) {
|
||||
const auto operation = (control & 0xffu) | ((control & 0x200u) << 7u) |
|
||||
((control & 0x20u) << 13u) | ((control & 0x40u) << 14u) |
|
||||
((control & 0x20u) == 0 && mode == 1 ? 0x20000u : 0u);
|
||||
return Agc::Command::Emit(buf, 0x1du, {
|
||||
operation, ((gdsOp & 1u) << 8u) | (src & 0x3fu), offset, index,
|
||||
mask & 0x00ff00ffu, data, static_cast<std::uint32_t>(compareData),
|
||||
static_cast<std::uint32_t>(compareData >> 32u), static_cast<std::uint32_t>(extraData),
|
||||
static_cast<std::uint32_t>(extraData >> 32u)}, __func__);
|
||||
}
|
||||
|
||||
std::uint32_t* APS5_VABI sceAgcDcbAtomicGds(CommandBuffer* buf, std::uint32_t control, std::uint32_t mode, std::uint32_t gdsOp, std::uint32_t src, std::uint16_t offset, std::uint16_t index, std::uint32_t mask, std::uint32_t data, std::uint64_t compareData, std::uint64_t extraData) {
|
||||
return sceAgcDcbAtomicGds_0900(buf, control, mode, gdsOp, src, offset, index, mask, data, compareData, extraData);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ std::uint32_t APS5_VABI sceAgcDcbAtomicMemGetSize() {
|
||||
}
|
||||
|
||||
std::uint32_t APS5_VABI sceAgcDcbAtomicGdsGetSize() {
|
||||
return 36;
|
||||
return 44;
|
||||
}
|
||||
|
||||
std::uint32_t* APS5_VABI sceAgcDcbWriteData(CommandBuffer* buf, std::uint8_t dst, std::uint8_t cachePolicy, std::uint64_t address, const void* data, std::uint32_t numDwords, std::uint8_t increment, std::uint8_t writeConfirm) {
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "prx/libc/include/general/VabiMacros.hpp"
|
||||
#include "prx/libc/include/Shutdown.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
@@ -11,6 +12,9 @@ extern "C" {
|
||||
std::uint32_t APS5_VABI sceAgcDcbQueueEndOfShaderActionGetSize();
|
||||
std::uint32_t APS5_VABI sceAgcAcbQueueEndOfShaderActionGetSize();
|
||||
std::uint32_t* APS5_VABI sceAgcCbReleaseMem(CommandBuffer*, std::uint8_t, std::uint16_t, std::uint8_t, std::uint8_t, const volatile Label*, std::uint8_t, std::uint64_t, std::uint16_t, std::uint16_t, std::uint8_t, std::uint32_t);
|
||||
std::uint32_t APS5_VABI sceAgcDcbAtomicGdsGetSize();
|
||||
std::uint32_t* APS5_VABI sceAgcDcbAtomicGds_0900(CommandBuffer*, std::uint32_t, std::uint32_t, std::uint32_t, std::uint32_t, std::uint16_t, std::uint16_t, std::uint32_t, std::uint32_t, std::uint64_t, std::uint64_t);
|
||||
std::uint32_t* APS5_VABI sceAgcDcbAtomicGds(CommandBuffer*, std::uint32_t, std::uint32_t, std::uint32_t, std::uint32_t, std::uint16_t, std::uint16_t, std::uint32_t, std::uint32_t, std::uint64_t, std::uint64_t);
|
||||
}
|
||||
|
||||
namespace {
|
||||
@@ -19,10 +23,7 @@ void check(bool condition, const char* message) {
|
||||
if (!condition) throw std::runtime_error(message);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int main() {
|
||||
try {
|
||||
void testEndOfShaderActionSize() {
|
||||
std::array<std::uint32_t, 16> words{};
|
||||
CommandBuffer buffer{words.data(), words.data() + words.size(), words.data(), words.data() + words.size(), nullptr, nullptr, 0};
|
||||
const auto* packet = sceAgcCbReleaseMem(&buffer, 0x2f, 0, 0, 0, nullptr, 0, 0, 0, 0, 0, 0);
|
||||
@@ -30,8 +31,35 @@ int main() {
|
||||
check(((packet[0] >> 8u) & 0xffu) == 0x49u && releaseBytes == 32, "end-of-shader RELEASE_MEM size mismatch");
|
||||
check(sceAgcDcbQueueEndOfShaderActionGetSize() == releaseBytes, "DCB end-of-shader action size differs from its RELEASE_MEM");
|
||||
check(sceAgcDcbQueueEndOfShaderActionGetSize() == sceAgcAcbQueueEndOfShaderActionGetSize(), "DCB and ACB end-of-shader action sizes differ");
|
||||
}
|
||||
|
||||
void testAtomicGds() {
|
||||
constexpr std::uint32_t expectedBytes = 11u * sizeof(std::uint32_t);
|
||||
check(sceAgcDcbAtomicGdsGetSize() == expectedBytes, "DCB atomic GDS size does not match 11-dword packet");
|
||||
|
||||
std::array<std::uint32_t, 32> words{};
|
||||
CommandBuffer buffer{words.data(), words.data() + words.size(), words.data(), words.data() + words.size(), nullptr, nullptr, 0};
|
||||
const auto* packet = sceAgcDcbAtomicGds_0900(&buffer, 0x261u, 1, 3, 7, 0x100, 0x200, 0x00ff00ffu, 0x12345678u, 0x1122334455667788ull, 0x99aabbccddeeff00ull);
|
||||
check(packet != nullptr && packet == words.data(), "DCB atomic GDS returned unexpected packet pointer");
|
||||
check(buffer.cursor_up == words.data() + 11, "DCB atomic GDS cursor advance does not match 11 dwords");
|
||||
check(packet[0] == 0xc0091d00u, "DCB atomic GDS header opcode mismatch");
|
||||
|
||||
std::array<std::uint32_t, 32> unversionedWords{};
|
||||
CommandBuffer unversionedBuffer{unversionedWords.data(), unversionedWords.data() + unversionedWords.size(), unversionedWords.data(), unversionedWords.data() + unversionedWords.size(), nullptr, nullptr, 0};
|
||||
const auto* unversionedPacket = sceAgcDcbAtomicGds(&unversionedBuffer, 0x261u, 1, 3, 7, 0x100, 0x200, 0x00ff00ffu, 0x12345678u, 0x1122334455667788ull, 0x99aabbccddeeff00ull);
|
||||
check(unversionedPacket != nullptr && unversionedPacket == unversionedWords.data(), "unversioned DCB atomic GDS returned unexpected packet pointer");
|
||||
check(unversionedBuffer.cursor_up == unversionedWords.data() + 11, "unversioned DCB atomic GDS cursor advance does not match 11 dwords");
|
||||
check(std::equal(words.begin(), words.begin() + 11, unversionedWords.begin()), "versioned and unversioned DCB atomic GDS emitted different packets");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int main() {
|
||||
try {
|
||||
testEndOfShaderActionSize();
|
||||
testAtomicGds();
|
||||
LibcRunShutdown_nid_postfix();
|
||||
std::puts("AGC end-of-shader action size tests passed");
|
||||
std::puts("AGC end-of-shader action and atomic GDS size tests passed");
|
||||
return 0;
|
||||
} catch (const std::exception& error) {
|
||||
std::fprintf(stderr, "%s\n", error.what());
|
||||
|
||||
Reference in new issue
Block a user