mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2026-06-01 12:15:43 -06:00
Refactor memory size handling to better handle vdec titles (#4373)
* Refactor memory size constants and calculations Updated memory size handling in video decoder functions. * Refactor video decoder frame size calculations Updated frame size computation to use worst-case dimensions and adjusted alignment values. * Refactor alignment logic to use Common::AlignUp
This commit is contained in:
parent
d85a5013ec
commit
7132795b7a
@ -1,6 +1,7 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include "common/alignment.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "core/libraries/libs.h"
|
#include "core/libraries/libs.h"
|
||||||
#include "core/libraries/videodec/videodec.h"
|
#include "core/libraries/videodec/videodec.h"
|
||||||
@ -9,7 +10,44 @@
|
|||||||
|
|
||||||
namespace Libraries::Videodec {
|
namespace Libraries::Videodec {
|
||||||
|
|
||||||
static constexpr u64 kMinimumMemorySize = 16_MB; ///> Fake minimum memory size for querying
|
static constexpr u64 kFallbackMemorySize = 16_MB;
|
||||||
|
|
||||||
|
static u64 ComputeFrameSizeBytes(s32 width, s32 height) {
|
||||||
|
if (width <= 0 || height <= 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const u32 aligned_width = Common::AlignUp<u32>((u32)width, 256);
|
||||||
|
const u32 aligned_height = Common::AlignUp<u32>((u32)height, 16);
|
||||||
|
|
||||||
|
const u64 pixels = (u64)aligned_width * (u64)aligned_height;
|
||||||
|
return (pixels * 3) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
static s32 ComputeDpbCount(const OrbisVideodecConfigInfo& cfg) {
|
||||||
|
if (cfg.maxDpbFrameCount > 0) {
|
||||||
|
return cfg.maxDpbFrameCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ComputeWorstCaseDimensions(const OrbisVideodecConfigInfo& cfg, s32& out_width,
|
||||||
|
s32& out_height) {
|
||||||
|
if (cfg.maxFrameWidth > 0 && cfg.maxFrameHeight > 0) {
|
||||||
|
out_width = cfg.maxFrameWidth;
|
||||||
|
out_height = cfg.maxFrameHeight;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
out_width = 1920;
|
||||||
|
out_height = 1080;
|
||||||
|
|
||||||
|
if (cfg.maxLevel >= 150) {
|
||||||
|
out_width = 3840;
|
||||||
|
out_height = 2160;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceVideodecCreateDecoder(const OrbisVideodecConfigInfo* pCfgInfoIn,
|
int PS4_SYSV_ABI sceVideodecCreateDecoder(const OrbisVideodecConfigInfo* pCfgInfoIn,
|
||||||
const OrbisVideodecResourceInfo* pRsrcInfoIn,
|
const OrbisVideodecResourceInfo* pRsrcInfoIn,
|
||||||
@ -29,7 +67,7 @@ int PS4_SYSV_ABI sceVideodecCreateDecoder(const OrbisVideodecConfigInfo* pCfgInf
|
|||||||
VdecDecoder* decoder = new VdecDecoder(*pCfgInfoIn, *pRsrcInfoIn);
|
VdecDecoder* decoder = new VdecDecoder(*pCfgInfoIn, *pRsrcInfoIn);
|
||||||
pCtrlOut->thisSize = sizeof(OrbisVideodecCtrl);
|
pCtrlOut->thisSize = sizeof(OrbisVideodecCtrl);
|
||||||
pCtrlOut->handle = decoder;
|
pCtrlOut->handle = decoder;
|
||||||
pCtrlOut->version = 1; //???
|
pCtrlOut->version = 1;
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,14 +148,39 @@ int PS4_SYSV_ABI sceVideodecQueryResourceInfo(const OrbisVideodecConfigInfo* pCf
|
|||||||
return ORBIS_VIDEODEC_ERROR_STRUCT_SIZE;
|
return ORBIS_VIDEODEC_ERROR_STRUCT_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s32 width = 0;
|
||||||
|
s32 height = 0;
|
||||||
|
ComputeWorstCaseDimensions(*pCfgInfoIn, width, height);
|
||||||
|
|
||||||
|
const u64 frame_size = ComputeFrameSizeBytes(width, height);
|
||||||
|
const s32 dpb_count = ComputeDpbCount(*pCfgInfoIn);
|
||||||
|
|
||||||
|
u64 cpu_gpu_size = 0;
|
||||||
|
u64 cpu_size = 0;
|
||||||
|
u64 max_frame_buffer = 0;
|
||||||
|
|
||||||
|
if (frame_size == 0) {
|
||||||
|
cpu_gpu_size = kFallbackMemorySize;
|
||||||
|
cpu_size = kFallbackMemorySize;
|
||||||
|
max_frame_buffer = kFallbackMemorySize;
|
||||||
|
} else {
|
||||||
|
const u64 padded_frame = Common::AlignUp<u64>(frame_size, 256) + 0x4000;
|
||||||
|
const u64 surfaces = (u64)dpb_count + 2;
|
||||||
|
|
||||||
|
max_frame_buffer = padded_frame;
|
||||||
|
|
||||||
|
cpu_gpu_size = (padded_frame * surfaces) + 8_MB;
|
||||||
|
cpu_size = 16_MB;
|
||||||
|
}
|
||||||
|
|
||||||
pRsrcInfoOut->thisSize = sizeof(OrbisVideodecResourceInfo);
|
pRsrcInfoOut->thisSize = sizeof(OrbisVideodecResourceInfo);
|
||||||
pRsrcInfoOut->pCpuMemory = nullptr;
|
pRsrcInfoOut->pCpuMemory = nullptr;
|
||||||
pRsrcInfoOut->pCpuGpuMemory = nullptr;
|
pRsrcInfoOut->pCpuGpuMemory = nullptr;
|
||||||
|
|
||||||
pRsrcInfoOut->cpuGpuMemorySize = kMinimumMemorySize;
|
pRsrcInfoOut->cpuGpuMemorySize = cpu_gpu_size;
|
||||||
pRsrcInfoOut->cpuMemorySize = kMinimumMemorySize;
|
pRsrcInfoOut->cpuMemorySize = cpu_size;
|
||||||
|
|
||||||
pRsrcInfoOut->maxFrameBufferSize = kMinimumMemorySize;
|
pRsrcInfoOut->maxFrameBufferSize = max_frame_buffer;
|
||||||
pRsrcInfoOut->frameBufferAlignment = 0x100;
|
pRsrcInfoOut->frameBufferAlignment = 0x100;
|
||||||
|
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user