diff --git a/core/libs/prx/libSceAmpr/Export.cpp b/core/libs/prx/libSceAmpr/Export.cpp index 22af4667a..d169d2498 100644 --- a/core/libs/prx/libSceAmpr/Export.cpp +++ b/core/libs/prx/libSceAmpr/Export.cpp @@ -398,7 +398,7 @@ int APS5_VABI sceAmprCommandBufferConstructNop(Apr::CommandBufferObject* buffer, } int APS5_VABI sceAmprCommandBufferConstructor(Apr::CommandBufferObject* buffer) { - *buffer = {nullptr, 0, 0, 0, Apr::BufferType::Generic}; + *buffer = {Apr::BufferType::Generic, 0, 0, 0, 0, nullptr}; return 0; } diff --git a/core/libs/prx/libkernel/Apr/include/AprCommandBuffer.hpp b/core/libs/prx/libkernel/Apr/include/AprCommandBuffer.hpp index ebd001627..40cdef33b 100644 --- a/core/libs/prx/libkernel/Apr/include/AprCommandBuffer.hpp +++ b/core/libs/prx/libkernel/Apr/include/AprCommandBuffer.hpp @@ -5,7 +5,6 @@ #include // Shared between libSceAmpr (which records commands) and libkernel (which executes them). -// The guest treats both the command buffer object and its memory as opaque, so the encoding is ours. namespace Apr { enum class BufferType : std::uint16_t { @@ -14,15 +13,19 @@ enum class BufferType : std::uint16_t { }; struct CommandBufferObject { - std::uint8_t* base; - std::uint32_t size; - std::uint32_t offset; - std::uint32_t numCommands; BufferType type; std::uint16_t recording; + std::uint32_t offset; + std::uint32_t numCommands; + std::uint32_t size; + std::uint8_t* base; }; static_assert(sizeof(CommandBufferObject) == 0x18, "guest reserves 0x18 bytes for sce::Ampr::CommandBuffer"); +static_assert(offsetof(CommandBufferObject, offset) == 0x04); +static_assert(offsetof(CommandBufferObject, size) == 0x0c); +static_assert(offsetof(CommandBufferObject, base) == 0x10); + inline constexpr std::uint16_t ScatterGatherValid = 1; inline constexpr std::uint16_t MapActive = 2; diff --git a/core/libs/prx/libkernel/Apr/src/Apr.cpp b/core/libs/prx/libkernel/Apr/src/Apr.cpp index 82dafbcb5..58d604628 100644 --- a/core/libs/prx/libkernel/Apr/src/Apr.cpp +++ b/core/libs/prx/libkernel/Apr/src/Apr.cpp @@ -645,7 +645,7 @@ void AmmVirtualAddressRanges_nid_no_patch(std::uint64_t* start, std::uint64_t* e } std::uint32_t AmmSubmit_nid_no_patch(void* base, std::uint32_t bytes) { - _execute(Apr::CommandBufferObject{static_cast(base), bytes, bytes, 0, Apr::BufferType::Generic, 0}); + _execute(Apr::CommandBufferObject{Apr::BufferType::Generic, 0, bytes, 0, bytes, static_cast(base)}); auto& last = _amm().lastSubmit; std::uint32_t id = last.fetch_add(1) + 1; while (id == 0) id = last.fetch_add(1) + 1; diff --git a/core/libs/tests/GuestAmpr.cpp b/core/libs/tests/GuestAmpr.cpp index 7accd9917..0b8f2ec47 100644 --- a/core/libs/tests/GuestAmpr.cpp +++ b/core/libs/tests/GuestAmpr.cpp @@ -980,7 +980,7 @@ void TestAmmPrt() { Require(sceAmprAmmCommandBufferRemapIntoPrt(&unbound, prt, source, page, cpuReadWrite, 0) == permissionDenied); Require(sceAmprAmmCommandBufferUnmapToPrt(&unbound, prt, page) == permissionDenied); std::array loose{}; - Apr::CommandBufferObject sized{nullptr, static_cast(loose.size()), 0, 0, Apr::BufferType::Generic, 0}; + Apr::CommandBufferObject sized{Apr::BufferType::Generic, 0, 0, 0, static_cast(loose.size()), nullptr}; Require(sceAmprAmmCommandBufferMapAsPrt(&sized, prt, page) == permissionDenied); Require(sceAmprAmmMeasureAmmCommandSizeMapAsPrt(prt, 0) == ammRejected); Require(sceAmprAmmMeasureAmmCommandSizeAllocatePaForPrt(prt, page, 0, 0x08) == ammRejected);