Merge pull request #175 from shadps4-emu/missing_gnm_calls

Additional GnmDriver functions
This commit is contained in:
georgemoralis 2024-06-09 00:58:45 +03:00 committed by GitHub
commit ac192134e8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 126 additions and 30 deletions

View file

@ -246,6 +246,13 @@ constexpr int SCE_VIDEO_OUT_ERROR_SLOT_OCCUPIED = 0x80290010; // slot alr
constexpr int SCE_VIDEO_OUT_ERROR_FLIP_QUEUE_FULL = 0x80290012; // flip queue is full
constexpr int SCE_VIDEO_OUT_ERROR_INVALID_OPTION = 0x8029001A; // Invalid buffer attribute option
// GnmDriver
constexpr int ORBIS_GNM_ERROR_COMPUTEQUEUE_INVALID_PIPE_ID = 0x80D17000;
constexpr int ORBIS_GNM_ERROR_COMPUTEQUEUE_INVALID_QUEUE_ID = 0x80D17001;
constexpr int ORBIS_GNM_ERROR_COMPUTEQUEUE_INVALID_RING_BASE_ADDR = 0x80D17003;
constexpr int ORBIS_GNM_ERROR_COMPUTEQUEUE_INVALID_RING_SIZE = 0x80D17002;
constexpr int ORBIS_GNM_ERROR_COMPUTEQUEUE_INVALID_READ_PTR_ADDR = 0x80D17004;
// Generic
constexpr int ORBIS_OK = 0x00000000;
constexpr int ORBIS_FAIL = 0xFFFFFFFF;

View file

@ -5,10 +5,12 @@
#include "common/config.h"
#include "common/logging/log.h"
#include "common/path_util.h"
#include "common/slot_vector.h"
#include "core/libraries/error_codes.h"
#include "core/libraries/gnmdriver/gnmdriver.h"
#include "core/libraries/libs.h"
#include "core/libraries/videoout/video_out.h"
#include "core/memory.h"
#include "core/platform.h"
#include "video_core/amdgpu/liverpool.h"
#include "video_core/amdgpu/pm4_cmds.h"
@ -32,6 +34,17 @@ static constexpr bool g_fair_hw_init = false;
static u32 submission_lock{};
static u64 frames_submitted{}; // frame counter
struct AscQueueInfo {
VAddr map_addr;
u32* read_addr;
u32 ring_size_dw;
};
static VideoCore::SlotVector<AscQueueInfo> asc_queues{};
static constexpr u32 TessellationFactorRingSize = 128_KB;
static constexpr u32 TessellationFactorRingAlignment = 64_KB; // toolkit is using this alignment
VAddr tessellation_factors_ring_addr{0};
static void DumpCommandList(std::span<const u32> cmd_list, const std::string& postfix) {
using namespace Common::FS;
const auto dump_dir = GetUserPath(PathType::PM4Dir);
@ -367,9 +380,18 @@ int PS4_SYSV_ABI sceGnmDrawInitDefaultHardwareState() {
return ORBIS_OK;
}
int PS4_SYSV_ABI sceGnmDrawInitDefaultHardwareState175() {
LOG_ERROR(Lib_GnmDriver, "(STUBBED) called");
return ORBIS_OK;
u32 PS4_SYSV_ABI sceGnmDrawInitDefaultHardwareState175(u32* cmdbuf, u32 size) {
LOG_TRACE(Lib_GnmDriver, "called");
if (size > 0xff) {
if constexpr (g_fair_hw_init) {
ASSERT_MSG(0, "Not implemented");
} else {
cmdbuf = WriteHeader<PM4ItOpcode::Nop>(cmdbuf, 0xff);
}
return 0x100; // it is a size, not a retcode
}
return 0;
}
u32 PS4_SYSV_ABI sceGnmDrawInitDefaultHardwareState200(u32* cmdbuf, u32 size) {
@ -379,7 +401,7 @@ u32 PS4_SYSV_ABI sceGnmDrawInitDefaultHardwareState200(u32* cmdbuf, u32 size) {
if constexpr (g_fair_hw_init) {
ASSERT_MSG(0, "Not implemented");
} else {
cmdbuf = cmdbuf = WriteHeader<PM4ItOpcode::Nop>(cmdbuf, 0xff);
cmdbuf = WriteHeader<PM4ItOpcode::Nop>(cmdbuf, 0xff);
}
return 0x100; // it is a size, not a retcode
}
@ -393,7 +415,7 @@ u32 PS4_SYSV_ABI sceGnmDrawInitDefaultHardwareState350(u32* cmdbuf, u32 size) {
if constexpr (g_fair_hw_init) {
ASSERT_MSG(0, "Not implemented");
} else {
cmdbuf = cmdbuf = WriteHeader<PM4ItOpcode::Nop>(cmdbuf, 0xff);
cmdbuf = WriteHeader<PM4ItOpcode::Nop>(cmdbuf, 0xff);
}
return 0x100; // it is a size, not a retcode
}
@ -599,9 +621,15 @@ int PS4_SYSV_ABI sceGnmGetShaderStatus() {
return ORBIS_OK;
}
int PS4_SYSV_ABI sceGnmGetTheTessellationFactorRingBufferBaseAddress() {
LOG_ERROR(Lib_GnmDriver, "(STUBBED) called");
return ORBIS_OK;
VAddr PS4_SYSV_ABI sceGnmGetTheTessellationFactorRingBufferBaseAddress() {
LOG_TRACE(Lib_GnmDriver, "called");
// Actual virtual buffer address is hardcoded in the driver to 0xff00'000
if (tessellation_factors_ring_addr == 0) {
auto* memory = Core::Memory::Instance();
tessellation_factors_ring_addr =
memory->Reserve(TessellationFactorRingSize, TessellationFactorRingAlignment);
}
return tessellation_factors_ring_addr;
}
int PS4_SYSV_ABI sceGnmGpuPaDebugEnter() {
@ -718,14 +746,44 @@ int PS4_SYSV_ABI sceGnmLogicalTcaUnitToPhysical() {
return ORBIS_OK;
}
int PS4_SYSV_ABI sceGnmMapComputeQueue() {
LOG_ERROR(Lib_GnmDriver, "(STUBBED) called");
return ORBIS_OK;
int PS4_SYSV_ABI sceGnmMapComputeQueue(u32 pipe_id, u32 queue_id, VAddr ring_base_addr,
u32 ring_size_dw, u32* read_ptr_addr) {
LOG_TRACE(Lib_GnmDriver, "called");
if (pipe_id >= Liverpool::NumComputePipes) {
return ORBIS_GNM_ERROR_COMPUTEQUEUE_INVALID_PIPE_ID;
}
if (queue_id >= Liverpool::NumQueuesPerPipe) {
return ORBIS_GNM_ERROR_COMPUTEQUEUE_INVALID_QUEUE_ID;
}
if (VAddr(ring_base_addr) % 256 != 0) { // alignment check
return ORBIS_GNM_ERROR_COMPUTEQUEUE_INVALID_RING_BASE_ADDR;
}
if (!std::has_single_bit(ring_size_dw)) {
return ORBIS_GNM_ERROR_COMPUTEQUEUE_INVALID_RING_SIZE;
}
if (VAddr(read_ptr_addr) % 4 != 0) { // alignment check
return ORBIS_GNM_ERROR_COMPUTEQUEUE_INVALID_READ_PTR_ADDR;
}
auto vqid = asc_queues.insert(VAddr(ring_base_addr), read_ptr_addr, ring_size_dw);
LOG_INFO(Lib_GnmDriver, "ASC pipe {} queue {} mapped to vqueue {}", pipe_id, queue_id,
vqid.index);
return vqid.index;
}
int PS4_SYSV_ABI sceGnmMapComputeQueueWithPriority() {
LOG_ERROR(Lib_GnmDriver, "(STUBBED) called");
return ORBIS_OK;
int PS4_SYSV_ABI sceGnmMapComputeQueueWithPriority(u32 pipe_id, u32 queue_id, VAddr ring_base_addr,
u32 ring_size_dw, u32* read_ptr_addr,
u32 pipePriority) {
LOG_TRACE(Lib_GnmDriver, "called");
(void)pipePriority;
return sceGnmMapComputeQueue(pipe_id, queue_id, ring_base_addr, ring_size_dw, read_ptr_addr);
}
int PS4_SYSV_ABI sceGnmPaDisableFlipCallbacks() {

View file

@ -54,7 +54,7 @@ int PS4_SYSV_ABI sceGnmDrawIndirect();
int PS4_SYSV_ABI sceGnmDrawIndirectCountMulti();
int PS4_SYSV_ABI sceGnmDrawIndirectMulti();
int PS4_SYSV_ABI sceGnmDrawInitDefaultHardwareState();
int PS4_SYSV_ABI sceGnmDrawInitDefaultHardwareState175();
u32 PS4_SYSV_ABI sceGnmDrawInitDefaultHardwareState175(u32* cmdbuf, u32 size);
u32 PS4_SYSV_ABI sceGnmDrawInitDefaultHardwareState200(u32* cmdbuf, u32 size);
u32 PS4_SYSV_ABI sceGnmDrawInitDefaultHardwareState350(u32* cmdbuf, u32 size);
int PS4_SYSV_ABI sceGnmDrawInitToDefaultContextState();
@ -97,7 +97,7 @@ int PS4_SYSV_ABI sceGnmGetResourceType();
int PS4_SYSV_ABI sceGnmGetResourceUserData();
int PS4_SYSV_ABI sceGnmGetShaderProgramBaseAddress();
int PS4_SYSV_ABI sceGnmGetShaderStatus();
int PS4_SYSV_ABI sceGnmGetTheTessellationFactorRingBufferBaseAddress();
VAddr PS4_SYSV_ABI sceGnmGetTheTessellationFactorRingBufferBaseAddress();
int PS4_SYSV_ABI sceGnmGpuPaDebugEnter();
int PS4_SYSV_ABI sceGnmGpuPaDebugLeave();
int PS4_SYSV_ABI sceGnmInsertDingDongMarker();
@ -113,8 +113,11 @@ int PS4_SYSV_ABI sceGnmIsUserPaEnabled();
int PS4_SYSV_ABI sceGnmLogicalCuIndexToPhysicalCuIndex();
int PS4_SYSV_ABI sceGnmLogicalCuMaskToPhysicalCuMask();
int PS4_SYSV_ABI sceGnmLogicalTcaUnitToPhysical();
int PS4_SYSV_ABI sceGnmMapComputeQueue();
int PS4_SYSV_ABI sceGnmMapComputeQueueWithPriority();
int PS4_SYSV_ABI sceGnmMapComputeQueue(u32 pipe_id, u32 queue_id, VAddr ring_base_addr,
u32 ring_size_dw, u32* read_ptr_addr);
int PS4_SYSV_ABI sceGnmMapComputeQueueWithPriority(u32 pipe_id, u32 queue_id, VAddr ring_base_addr,
u32 ring_size_dw, u32* read_ptr_addr,
u32 pipePriority);
int PS4_SYSV_ABI sceGnmPaDisableFlipCallbacks();
int PS4_SYSV_ABI sceGnmPaEnableFlipCallbacks();
int PS4_SYSV_ABI sceGnmPaHeartbeat();