mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-21 19:36:55 +02:00
agc: initialize function table in tracked driver memory
This commit is contained in:
@@ -20,6 +20,7 @@
|
||||
#include "graphics/presentation/videoOut.h"
|
||||
#include "graphics/presentation/window.h"
|
||||
#include "graphics/shader/shader.h"
|
||||
#include "kernel/memory.h"
|
||||
#include "kernel/pthread.h"
|
||||
#include "libs/errno.h"
|
||||
#include "libs/libs.h"
|
||||
@@ -44,6 +45,23 @@ namespace Libs::Graphics {
|
||||
|
||||
static RenderContext* g_renderer = nullptr;
|
||||
|
||||
namespace Gen5Driver {
|
||||
|
||||
static constexpr uint64_t DriverDmemBase = 0x0fe0000000ull;
|
||||
static constexpr uint32_t DriverDmemSize = 0x200000;
|
||||
static constexpr uint32_t AgcDmemOffset = 0x40000;
|
||||
|
||||
struct DriverDmem {
|
||||
std::mutex mutex;
|
||||
int64_t physical_offset = -1;
|
||||
};
|
||||
|
||||
static DriverDmem g_driver_dmem;
|
||||
static int InitializeDmem();
|
||||
static void ReleaseDmem();
|
||||
|
||||
} // namespace Gen5Driver
|
||||
|
||||
template <typename... Args>
|
||||
static void AgcTrace(const char* format, const Args&... args) {
|
||||
if (Config::GraphicsDebugDumpEnabled()) {
|
||||
@@ -70,6 +88,7 @@ void Initialize() {
|
||||
void Shutdown() {
|
||||
EXIT_IF(g_renderer == nullptr);
|
||||
g_renderer->ShutdownGpu();
|
||||
Gen5Driver::ReleaseDmem();
|
||||
VideoOut::VideoOutShutdown();
|
||||
WindowShutdown();
|
||||
g_renderer = nullptr;
|
||||
@@ -337,6 +356,38 @@ int KYTY_SYSV_ABI AgcInit(uint32_t* state, uint32_t ver) {
|
||||
}
|
||||
|
||||
printf("version = %u\n", ver);
|
||||
std::scoped_lock lock {Gen5Driver::g_driver_dmem.mutex};
|
||||
if (Gen5Driver::g_driver_dmem.physical_offset >= 0) {
|
||||
return OK;
|
||||
}
|
||||
if (const auto result = Gen5Driver::InitializeDmem(); result != OK) {
|
||||
return result;
|
||||
}
|
||||
struct FunctionShaderBindings {
|
||||
uint64_t code;
|
||||
uint32_t user_data[2];
|
||||
};
|
||||
static_assert(sizeof(FunctionShaderBindings) == 16);
|
||||
// Ordered-count queue validator, including its return to the caller.
|
||||
static constexpr std::array<uint32_t, 16> validator {
|
||||
0xbeeb03ff, 0x00000021, 0xb96a1818, 0xbf06106a,
|
||||
0xbf800000, 0x8590807e, 0xb96a0a18, 0xbf066a80,
|
||||
0xbf800000, 0x85ea807e, 0x88ea106a, 0xbf870003,
|
||||
0xbefc03ff, 0x8a6ca000, 0xbf920009, 0xbefd210e,
|
||||
};
|
||||
const auto base = Gen5Driver::DriverDmemBase + Gen5Driver::AgcDmemOffset;
|
||||
const auto function_table = base + 0x60;
|
||||
const auto code_address = base + 0x100; // Shader code requires 256-byte alignment.
|
||||
std::array<FunctionShaderBindings, 8> functions {};
|
||||
functions[2].code = code_address;
|
||||
const std::array<uint32_t, 4> descriptor {
|
||||
static_cast<uint32_t>(function_table),
|
||||
static_cast<uint32_t>(function_table >> 32u) | 0x00100000u,
|
||||
static_cast<uint32_t>(functions.size()), 0x5204u,
|
||||
};
|
||||
std::memcpy(reinterpret_cast<void*>(function_table), functions.data(), sizeof(functions));
|
||||
std::memcpy(reinterpret_cast<void*>(code_address), validator.data(), sizeof(validator));
|
||||
std::memcpy(reinterpret_cast<void*>(base), descriptor.data(), sizeof(descriptor));
|
||||
|
||||
return OK;
|
||||
}
|
||||
@@ -4224,6 +4275,36 @@ namespace Gen5Driver {
|
||||
|
||||
LIB_NAME("Graphics5Driver", "Graphics5Driver");
|
||||
|
||||
static int InitializeDmem() {
|
||||
int64_t physical_offset = -1;
|
||||
auto result = LibKernel::Memory::KernelAllocateDirectMemory(
|
||||
0, LibKernel::Memory::KernelGetDirectMemorySize(), DriverDmemSize, DriverDmemSize,
|
||||
12, &physical_offset);
|
||||
if (result != OK) {
|
||||
return result;
|
||||
}
|
||||
void* address = reinterpret_cast<void*>(DriverDmemBase);
|
||||
result = LibKernel::Memory::KernelMapNamedDirectMemory(
|
||||
&address, DriverDmemSize, 0x33, 0, physical_offset, DriverDmemSize, "SceAgcDriver");
|
||||
if (result != OK) {
|
||||
EXIT_IF(LibKernel::Memory::KernelCheckedReleaseDirectMemory(physical_offset, DriverDmemSize) != OK);
|
||||
return result;
|
||||
}
|
||||
EXIT_IF(reinterpret_cast<uint64_t>(address) != DriverDmemBase);
|
||||
std::memset(address, 0, DriverDmemSize);
|
||||
g_driver_dmem.physical_offset = physical_offset;
|
||||
return OK;
|
||||
}
|
||||
|
||||
static void ReleaseDmem() {
|
||||
std::scoped_lock lock {g_driver_dmem.mutex};
|
||||
if (g_driver_dmem.physical_offset >= 0) {
|
||||
EXIT_IF(LibKernel::Memory::KernelCheckedReleaseDirectMemory(
|
||||
g_driver_dmem.physical_offset, DriverDmemSize) != OK);
|
||||
g_driver_dmem.physical_offset = -1;
|
||||
}
|
||||
}
|
||||
|
||||
struct TessellationDriverState {
|
||||
uint64_t tf_ring_base = 0;
|
||||
uint32_t tf_ring_size = 0;
|
||||
|
||||
Reference in New Issue
Block a user