update gpu memory function

This commit is contained in:
georgemoralis 2023-09-27 08:34:02 +03:00
parent 21120ac0ae
commit 98ccbe7f30
3 changed files with 98 additions and 35 deletions

View File

@ -58,6 +58,11 @@ bool GPU::vulkanAllocateMemory(HLE::Libs::Graphics::GraphicCtx* ctx, HLE::Libs::
return false; return false;
} }
void GPU::flushGarlic(HLE::Libs::Graphics::GraphicCtx* ctx) {
auto* gpumemory = Singleton<GPUMemory>::Instance();
gpumemory->flushAllHeaps(ctx);
}
int GPU::GPUMemory::getHeapId(u64 virtual_addr, u64 size) { int GPU::GPUMemory::getHeapId(u64 virtual_addr, u64 size) {
int index = 0; int index = 0;
for (const auto& heap : m_heaps) { for (const auto& heap : m_heaps) {
@ -106,6 +111,7 @@ void* GPU::GPUMemory::memoryCreateObj(u64 submit_id, HLE::Libs::Graphics::Graphi
objInfo.gpu_object.obj = info.getCreateFunc()(ctx, objInfo.obj_params, virtual_addr, size, virtual_addr_num, &objInfo.mem); objInfo.gpu_object.obj = info.getCreateFunc()(ctx, objInfo.obj_params, virtual_addr, size, virtual_addr_num, &objInfo.mem);
objInfo.update_func = info.getUpdateFunc();
int index = static_cast<int>(heap.objects.size()); int index = static_cast<int>(heap.objects.size());
HeapObject hobj{}; HeapObject hobj{};
@ -128,3 +134,55 @@ GPU::HeapBlock GPU::GPUMemory::createHeapBlock(const u64* virtual_addr, const u6
} }
return heapBlock; return heapBlock;
} }
void GPU::GPUMemory::update(u64 submit_id, HLE::Libs::Graphics::GraphicCtx* ctx, int heap_id, int obj_id) {
auto& heap = m_heaps[heap_id];
auto& heapObj = heap.objects[obj_id];
auto& objInfo = heapObj.info;
bool need_update = false;
if (submit_id > objInfo.submit_id) {
uint64_t hash[3] = {};
for (int i = 0; i < heapObj.block.virtual_addr_num; i++) {
if (objInfo.check_hash) {
hash[i] = GPU::calculate_hash(reinterpret_cast<const uint8_t*>(heapObj.block.virtual_addr[i]), heapObj.block.size[i]);
} else {
hash[i] = 0;
}
}
for (int i = 0; i < heapObj.block.virtual_addr_num; i++) {
if (objInfo.hash[i] != hash[i]) {
need_update = true;
objInfo.hash[i] = hash[i];
}
}
if (submit_id != UINT64_MAX) {
objInfo.submit_id = submit_id;
}
}
if (need_update) {
objInfo.update_func(ctx, objInfo.obj_params, objInfo.gpu_object.obj, heapObj.block.virtual_addr, heapObj.block.size,
heapObj.block.virtual_addr_num);
}
}
void GPU::GPUMemory::flushAllHeaps(HLE::Libs::Graphics::GraphicCtx* ctx) {
Lib::LockMutexGuard lock(m_mutex);
int heap_id = 0;
for (auto& heap : m_heaps) {
int index = 0;
for (auto& heapObj : heap.objects) {
if (!heapObj.free) {
update(UINT64_MAX, ctx, heap_id, index);
}
index++;
}
heap_id++;
}
}

View File

@ -11,51 +11,17 @@ class GPUObject;
enum class MemoryMode : u32 { NoAccess = 0, Read = 1, Write = 2, ReadWrite = 3 }; enum class MemoryMode : u32 { NoAccess = 0, Read = 1, Write = 2, ReadWrite = 3 };
enum class MemoryObjectType : u64 { InvalidObj, VideoOutBufferObj }; enum class MemoryObjectType : u64 { InvalidObj, VideoOutBufferObj };
struct GpuMemoryObject { struct GpuMemoryObject {
MemoryObjectType objectType = MemoryObjectType::InvalidObj; MemoryObjectType objectType = MemoryObjectType::InvalidObj;
void* obj = nullptr; void* obj = nullptr;
}; };
struct ObjInfo {
u64 obj_params[8] = {};
GpuMemoryObject gpu_object;
u64 hash[3] = {};
u64 submit_id = 0;
bool check_hash = false;
HLE::Libs::Graphics::VulkanMemory mem;
};
struct HeapBlock { struct HeapBlock {
u64 virtual_addr[3] = {}; u64 virtual_addr[3] = {};
u64 size[3] = {}; u64 size[3] = {};
int virtual_addr_num = 0; int virtual_addr_num = 0;
}; };
struct HeapObject {
HeapBlock block;
ObjInfo info;
bool free = true;
};
struct MemoryHeap {
u64 allocated_virtual_addr = 0;
u64 allocated_size = 0;
std::vector<HeapObject> objects;
};
class GPUMemory {
public:
GPUMemory() {}
virtual ~GPUMemory() {}
int getHeapId(u64 vaddr, u64 size);
Lib::Mutex m_mutex;
std::vector<MemoryHeap> m_heaps;
void* memoryCreateObj(u64 submit_id, HLE::Libs::Graphics::GraphicCtx* ctx, /*CommandBuffer* buffer*/ void* todo, const u64* virtual_addr,
const u64* size, int virtual_addr_num, const GPUObject& info);
HeapBlock createHeapBlock(const u64* virtual_addr, const u64* size, int virtual_addr_num, int heap_id, int obj_id);
};
class GPUObject { class GPUObject {
public: public:
GPUObject() = default; GPUObject() = default;
@ -74,9 +40,45 @@ class GPUObject {
virtual update_func_t getUpdateFunc() const = 0; virtual update_func_t getUpdateFunc() const = 0;
}; };
struct ObjInfo {
u64 obj_params[8] = {};
GpuMemoryObject gpu_object;
u64 hash[3] = {};
u64 submit_id = 0;
bool check_hash = false;
HLE::Libs::Graphics::VulkanMemory mem;
GPU::GPUObject::update_func_t update_func = nullptr;
};
struct HeapObject {
HeapBlock block;
ObjInfo info;
bool free = true;
};
struct MemoryHeap {
u64 allocated_virtual_addr = 0;
u64 allocated_size = 0;
std::vector<HeapObject> objects;
};
class GPUMemory {
public:
GPUMemory() {}
virtual ~GPUMemory() {}
int getHeapId(u64 vaddr, u64 size);
Lib::Mutex m_mutex;
std::vector<MemoryHeap> m_heaps;
void* memoryCreateObj(u64 submit_id, HLE::Libs::Graphics::GraphicCtx* ctx, /*CommandBuffer* buffer*/ void* todo, const u64* virtual_addr,
const u64* size, int virtual_addr_num, const GPUObject& info);
HeapBlock createHeapBlock(const u64* virtual_addr, const u64* size, int virtual_addr_num, int heap_id, int obj_id);
void update(u64 submit_id, HLE::Libs::Graphics::GraphicCtx* ctx, int heap_id, int obj_id);
void flushAllHeaps(HLE::Libs::Graphics::GraphicCtx* ctx);
};
void memorySetAllocArea(u64 virtual_addr, u64 size); void memorySetAllocArea(u64 virtual_addr, u64 size);
void* memoryCreateObj(u64 submit_id, HLE::Libs::Graphics::GraphicCtx* ctx, /*CommandBuffer* buffer*/ void* todo, u64 virtual_addr, u64 size, void* memoryCreateObj(u64 submit_id, HLE::Libs::Graphics::GraphicCtx* ctx, /*CommandBuffer* buffer*/ void* todo, u64 virtual_addr, u64 size,
const GPUObject& info); const GPUObject& info);
u64 calculate_hash(const u08* buf, u64 size); u64 calculate_hash(const u08* buf, u64 size);
bool vulkanAllocateMemory(HLE::Libs::Graphics::GraphicCtx* ctx, HLE::Libs::Graphics::VulkanMemory* mem); bool vulkanAllocateMemory(HLE::Libs::Graphics::GraphicCtx* ctx, HLE::Libs::Graphics::VulkanMemory* mem);
void flushGarlic(HLE::Libs::Graphics::GraphicCtx* ctx);
} // namespace GPU } // namespace GPU

View File

@ -3,6 +3,8 @@
#include "../Loader/Elf.h" #include "../Loader/Elf.h"
#include <Util/log.h> #include <Util/log.h>
#include <debug.h> #include <debug.h>
#include <Core/PS4/GPU/gpu_memory.h>
#include <emulator.h>
namespace HLE::Libs::LibSceGnmDriver { namespace HLE::Libs::LibSceGnmDriver {
@ -88,7 +90,8 @@ namespace HLE::Libs::LibSceGnmDriver {
void sceGnmDriverTraceInProgress(){} void sceGnmDriverTraceInProgress(){}
void sceGnmDriverTriggerCapture(){} void sceGnmDriverTriggerCapture(){}
void sceGnmEndWorkload(){} void sceGnmEndWorkload(){}
void sceGnmFlushGarlic() { PRINT_DUMMY_FUNCTION_NAME(); void sceGnmFlushGarlic() { PRINT_FUNCTION_NAME();
GPU::flushGarlic(Emulator::getGraphicCtx());
} }
void sceGnmGetEqEventType(){} void sceGnmGetEqEventType(){}
void sceGnmGetEqTimeStamp(){} void sceGnmGetEqTimeStamp(){}