mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-20 19:07:01 +02:00
remove readback hacks, allows to read/write guest memory directly
This commit is contained in:
@@ -1,14 +1,11 @@
|
||||
#include "graphics/host_gpu/objects/label.h"
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "kernel/memory.h"
|
||||
#include "common/threads.h"
|
||||
#include "graphics/host_gpu/graphicContext.h"
|
||||
#include "graphics/host_gpu/renderer/render.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <atomic>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
@@ -22,10 +19,6 @@ enum LabelStatus {
|
||||
};
|
||||
|
||||
struct LabelCallbacks {
|
||||
uint64_t* dst_gpu_addr64 = nullptr;
|
||||
uint64_t value64 = 0;
|
||||
uint32_t* dst_gpu_addr32 = nullptr;
|
||||
uint32_t value32 = 0;
|
||||
LabelCallback callback_1 = nullptr;
|
||||
LabelCallback callback_2 = nullptr;
|
||||
uint64_t args[LABEL_ARGS_MAX] = {};
|
||||
@@ -64,10 +57,8 @@ public:
|
||||
~LabelManager() { KYTY_NOT_IMPLEMENTED; }
|
||||
KYTY_CLASS_NO_COPY(LabelManager);
|
||||
|
||||
Label* Create64(GraphicContext* ctx, uint64_t* dst_gpu_addr, uint64_t value,
|
||||
LabelCallback callback_1, LabelCallback callback_2, const uint64_t* args);
|
||||
Label* Create32(GraphicContext* ctx, uint32_t* dst_gpu_addr, uint32_t value,
|
||||
LabelCallback callback_1, LabelCallback callback_2, const uint64_t* args);
|
||||
Label* Create(GraphicContext* ctx, LabelCallback callback_1, LabelCallback callback_2,
|
||||
const uint64_t* args);
|
||||
void Delete(Label* label);
|
||||
void Set(CommandBuffer* buffer, Label* label);
|
||||
void Drain();
|
||||
@@ -75,9 +66,6 @@ public:
|
||||
private:
|
||||
static void ThreadRun(void* data);
|
||||
|
||||
template <typename T>
|
||||
Label* Create(GraphicContext* ctx, T* dst_gpu_addr, T value, LabelCallback callback_1,
|
||||
LabelCallback callback_2, const uint64_t* args);
|
||||
bool Remove(Label* label);
|
||||
static void Destroy(Label* label);
|
||||
|
||||
@@ -90,11 +78,6 @@ private:
|
||||
static LabelManager* g_label_manager = nullptr;
|
||||
static thread_local bool g_in_label_callback = false;
|
||||
|
||||
template <typename T>
|
||||
void WriteGuestLabel(T* address, T value) {
|
||||
LabelWriteGuestMemory(address, &value, sizeof(value));
|
||||
}
|
||||
|
||||
class LabelCallbackScope final {
|
||||
public:
|
||||
LabelCallbackScope() {
|
||||
@@ -132,8 +115,7 @@ void LabelManager::ThreadRun(void* data) {
|
||||
it->completion->event == nullptr) {
|
||||
EXIT("GPU label submission has no completion event\n");
|
||||
}
|
||||
const auto status =
|
||||
vkGetEventStatus(it->completion->device, it->completion->event);
|
||||
const auto status = vkGetEventStatus(it->completion->device, it->completion->event);
|
||||
switch (status) {
|
||||
case VK_EVENT_SET:
|
||||
fired_labels.push_back(it->callbacks);
|
||||
@@ -180,35 +162,9 @@ void LabelManager::ThreadRun(void* data) {
|
||||
|
||||
for (auto& label: fired_labels) {
|
||||
LabelCallbackScope callback_scope;
|
||||
bool write = true;
|
||||
|
||||
if (label.callback_1 != nullptr) {
|
||||
write = label.callback_1(label.args);
|
||||
}
|
||||
|
||||
if (write && label.dst_gpu_addr64 != nullptr) {
|
||||
// Publishing EOP fences through physical backing keeps a fence word coherent even
|
||||
// when unrelated bytes on its host page are
|
||||
// protected for BufferCache GPU ownership.
|
||||
WriteGuestLabel(label.dst_gpu_addr64, label.value64);
|
||||
|
||||
static std::atomic<uint32_t> log_count {0};
|
||||
if (log_count.fetch_add(1) < 256) {
|
||||
LOGF_COLOR(Log::Color::BrightGreen,
|
||||
"EndOfPipe Signal!!! [0x%016" PRIx64 "] <- 0x%016" PRIx64 "\n",
|
||||
reinterpret_cast<uint64_t>(label.dst_gpu_addr64), label.value64);
|
||||
}
|
||||
}
|
||||
|
||||
if (write && label.dst_gpu_addr32 != nullptr) {
|
||||
WriteGuestLabel(label.dst_gpu_addr32, label.value32);
|
||||
|
||||
static std::atomic<uint32_t> log_count {0};
|
||||
if (log_count.fetch_add(1) < 256) {
|
||||
LOGF_COLOR(Log::Color::BrightGreen,
|
||||
"EndOfPipe Signal!!! [0x%016" PRIx64 "] <- 0x%08" PRIx32 "\n",
|
||||
reinterpret_cast<uint64_t>(label.dst_gpu_addr32), label.value32);
|
||||
}
|
||||
(void)label.callback_1(label.args);
|
||||
}
|
||||
|
||||
if (label.callback_2 != nullptr) {
|
||||
@@ -229,29 +185,15 @@ void LabelManager::ThreadRun(void* data) {
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Label* LabelManager::Create(GraphicContext* ctx, T* dst_gpu_addr, T value, LabelCallback callback_1,
|
||||
LabelCallback callback_2, const uint64_t* args) {
|
||||
static_assert(sizeof(T) == sizeof(uint32_t) || sizeof(T) == sizeof(uint64_t));
|
||||
|
||||
Label* LabelManager::Create(GraphicContext* ctx, LabelCallback callback_1, LabelCallback callback_2,
|
||||
const uint64_t* args) {
|
||||
EXIT_IF(ctx == nullptr);
|
||||
|
||||
Common::LockGuard lock(m_mutex);
|
||||
|
||||
auto* label = new Label;
|
||||
|
||||
label->status = LabelStatus::New;
|
||||
if constexpr (sizeof(T) == sizeof(uint64_t)) {
|
||||
label->callbacks.dst_gpu_addr64 = dst_gpu_addr;
|
||||
label->callbacks.value64 = value;
|
||||
label->callbacks.dst_gpu_addr32 = nullptr;
|
||||
label->callbacks.value32 = 0;
|
||||
} else {
|
||||
label->callbacks.dst_gpu_addr32 = dst_gpu_addr;
|
||||
label->callbacks.value32 = value;
|
||||
label->callbacks.dst_gpu_addr64 = nullptr;
|
||||
label->callbacks.value64 = 0;
|
||||
}
|
||||
label->status = LabelStatus::New;
|
||||
label->device = ctx->device;
|
||||
label->callbacks.callback_1 = callback_1;
|
||||
label->callbacks.callback_2 = callback_2;
|
||||
@@ -267,18 +209,6 @@ Label* LabelManager::Create(GraphicContext* ctx, T* dst_gpu_addr, T value, Label
|
||||
return label;
|
||||
}
|
||||
|
||||
Label* LabelManager::Create64(GraphicContext* ctx, uint64_t* dst_gpu_addr, uint64_t value,
|
||||
LabelCallback callback_1, LabelCallback callback_2,
|
||||
const uint64_t* args) {
|
||||
return Create(ctx, dst_gpu_addr, value, callback_1, callback_2, args);
|
||||
}
|
||||
|
||||
Label* LabelManager::Create32(GraphicContext* ctx, uint32_t* dst_gpu_addr, uint32_t value,
|
||||
LabelCallback callback_1, LabelCallback callback_2,
|
||||
const uint64_t* args) {
|
||||
return Create(ctx, dst_gpu_addr, value, callback_1, callback_2, args);
|
||||
}
|
||||
|
||||
bool LabelManager::Remove(Label* label) {
|
||||
EXIT_IF(label == nullptr);
|
||||
EXIT_IF(label->device == nullptr);
|
||||
@@ -336,8 +266,8 @@ void LabelManager::Set(CommandBuffer* buffer, Label* label) {
|
||||
label->status = LabelStatus::Active;
|
||||
|
||||
LabelSubmission submission {};
|
||||
submission.callbacks = label->callbacks;
|
||||
submission.completion = std::make_shared<LabelEvent>();
|
||||
submission.callbacks = label->callbacks;
|
||||
submission.completion = std::make_shared<LabelEvent>();
|
||||
submission.completion->device = label->device;
|
||||
|
||||
auto* vk_buffer = buffer->GetPool()->buffers[buffer->GetIndex()];
|
||||
@@ -385,18 +315,11 @@ void LabelInit() {
|
||||
g_label_manager = new LabelManager;
|
||||
}
|
||||
|
||||
Label* LabelCreate64(GraphicContext* ctx, uint64_t* dst_gpu_addr, uint64_t value,
|
||||
LabelCallback callback_1, LabelCallback callback_2, const uint64_t* args) {
|
||||
Label* LabelCreate(GraphicContext* ctx, LabelCallback callback_1, LabelCallback callback_2,
|
||||
const uint64_t* args) {
|
||||
EXIT_IF(g_label_manager == nullptr);
|
||||
|
||||
return g_label_manager->Create64(ctx, dst_gpu_addr, value, callback_1, callback_2, args);
|
||||
}
|
||||
|
||||
Label* LabelCreate32(GraphicContext* ctx, uint32_t* dst_gpu_addr, uint32_t value,
|
||||
LabelCallback callback_1, LabelCallback callback_2, const uint64_t* args) {
|
||||
EXIT_IF(g_label_manager == nullptr);
|
||||
|
||||
return g_label_manager->Create32(ctx, dst_gpu_addr, value, callback_1, callback_2, args);
|
||||
return g_label_manager->Create(ctx, callback_1, callback_2, args);
|
||||
}
|
||||
|
||||
void LabelDelete(Label* label) {
|
||||
@@ -416,15 +339,6 @@ void LabelDrain() {
|
||||
g_label_manager->Drain();
|
||||
}
|
||||
|
||||
void LabelWriteGuestMemory(void* address, const void* data, uint64_t size) {
|
||||
if (address == nullptr || data == nullptr || size == 0) {
|
||||
EXIT("invalid guest label write\n");
|
||||
}
|
||||
if (!Libs::LibKernel::Memory::TryWriteBacking(reinterpret_cast<uint64_t>(address), data, size)) {
|
||||
std::memcpy(address, data, static_cast<size_t>(size));
|
||||
}
|
||||
}
|
||||
|
||||
bool LabelInCallback() noexcept {
|
||||
return g_in_label_callback;
|
||||
}
|
||||
|
||||
@@ -15,14 +15,11 @@ void LabelInit();
|
||||
constexpr int LABEL_ARGS_MAX = 5;
|
||||
using LabelCallback = bool (*)(const uint64_t* args);
|
||||
|
||||
Label* LabelCreate64(GraphicContext* ctx, uint64_t* dst_gpu_addr, uint64_t value,
|
||||
LabelCallback callback_1, LabelCallback callback_2, const uint64_t* args);
|
||||
Label* LabelCreate32(GraphicContext* ctx, uint32_t* dst_gpu_addr, uint32_t value,
|
||||
LabelCallback callback_1, LabelCallback callback_2, const uint64_t* args);
|
||||
Label* LabelCreate(GraphicContext* ctx, LabelCallback callback_1, LabelCallback callback_2,
|
||||
const uint64_t* args);
|
||||
void LabelDelete(Label* label);
|
||||
void LabelSet(CommandBuffer* buffer, Label* label);
|
||||
void LabelDrain();
|
||||
void LabelWriteGuestMemory(void* address, const void* data, uint64_t size);
|
||||
[[nodiscard]] bool LabelInCallback() noexcept;
|
||||
|
||||
} // namespace Libs::Graphics
|
||||
|
||||
Reference in New Issue
Block a user