diff --git a/src/core/libraries/error_codes.h b/src/core/libraries/error_codes.h index d4ae7edc..e4aac622 100644 --- a/src/core/libraries/error_codes.h +++ b/src/core/libraries/error_codes.h @@ -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; diff --git a/src/core/libraries/gnmdriver/gnmdriver.cpp b/src/core/libraries/gnmdriver/gnmdriver.cpp index 4df2709f..386446f7 100644 --- a/src/core/libraries/gnmdriver/gnmdriver.cpp +++ b/src/core/libraries/gnmdriver/gnmdriver.cpp @@ -5,6 +5,7 @@ #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" @@ -32,6 +33,13 @@ 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 asc_queues{}; + static void DumpCommandList(std::span cmd_list, const std::string& postfix) { using namespace Common::FS; const auto dump_dir = GetUserPath(PathType::PM4Dir); @@ -718,14 +726,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() { diff --git a/src/core/libraries/gnmdriver/gnmdriver.h b/src/core/libraries/gnmdriver/gnmdriver.h index 0f0e454e..4319d0dc 100644 --- a/src/core/libraries/gnmdriver/gnmdriver.h +++ b/src/core/libraries/gnmdriver/gnmdriver.h @@ -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();