Ge: Report and save Edram translation value.

See #16126 for some details on its usage and effects.
This commit is contained in:
Unknown W. Brackets 2022-10-01 23:18:42 -07:00
parent f12a5101e6
commit 24999e792a
5 changed files with 28 additions and 12 deletions

View File

@ -570,21 +570,17 @@ static int sceGeGetStack(int index, u32 stackPtr) {
return gpu->GetStack(index, stackPtr);
}
static u32 sceGeEdramSetAddrTranslation(int new_size) {
static u32 sceGeEdramSetAddrTranslation(u32 new_size) {
bool outsideRange = new_size != 0 && (new_size < 0x200 || new_size > 0x1000);
bool notPowerOfTwo = (new_size & (new_size - 1)) != 0;
if (outsideRange || notPowerOfTwo) {
WARN_LOG(SCEGE, "sceGeEdramSetAddrTranslation(%i): invalid value", new_size);
return SCE_KERNEL_ERROR_INVALID_VALUE;
return hleLogWarning(SCEGE, SCE_KERNEL_ERROR_INVALID_VALUE, "invalid value");
}
if (!gpu) {
return hleLogError(SCEGE, -1, "GPUInterface not available");
}
DEBUG_LOG(SCEGE, "sceGeEdramSetAddrTranslation(%i)", new_size);
// TODO: This isn't safe. EDRamWidth should be global and saved.
static int EDRamWidth = 0x400;
int last = EDRamWidth;
EDRamWidth = new_size;
return last;
return hleReportDebug(SCEGE, gpu->SetAddrTranslation(new_size));
}
const HLEFunction sceGe_user[] = {
@ -599,7 +595,7 @@ const HLEFunction sceGe_user[] = {
{0XA4FC06A4, &WrapU_U<sceGeSetCallback>, "sceGeSetCallback", 'i', "p" },
{0X05DB22CE, &WrapI_U<sceGeUnsetCallback>, "sceGeUnsetCallback", 'i', "x" },
{0X1F6752AD, &WrapU_V<sceGeEdramGetSize>, "sceGeEdramGetSize", 'x', "" },
{0XB77905EA, &WrapU_I<sceGeEdramSetAddrTranslation>, "sceGeEdramSetAddrTranslation", 'x', "i" },
{0XB77905EA, &WrapU_U<sceGeEdramSetAddrTranslation>, "sceGeEdramSetAddrTranslation", 'x', "x" },
{0XDC93CFEF, &WrapU_I<sceGeGetCmd>, "sceGeGetCmd", 'x', "i" },
{0X57C8945B, &WrapI_IU<sceGeGetMtx>, "sceGeGetMtx", 'i', "ip" },
{0X438A385A, &WrapU_U<sceGeSaveContext>, "sceGeSaveContext", 'x', "x" },

View File

@ -213,6 +213,9 @@ public:
virtual void SetCmdValue(u32 op) = 0;
virtual void DispatchFlush() = 0;
virtual uint32_t SetAddrTranslation(uint32_t value) = 0;
virtual uint32_t GetAddrTranslation() = 0;
virtual bool GetCurrentSimpleVertices(int count, std::vector<GPUDebugVertex> &vertices, std::vector<u16> &indices) {
return false;
}

View File

@ -1280,6 +1280,15 @@ void GPUCommon::ReapplyGfxState() {
// Let's just skip the transfer size stuff, it's just values.
}
uint32_t GPUCommon::SetAddrTranslation(uint32_t value) {
std::swap(edramTranslation_, value);
return value;
}
uint32_t GPUCommon::GetAddrTranslation() {
return edramTranslation_;
}
inline void GPUCommon::UpdateState(GPURunState state) {
gpuState = state;
if (state != GPUSTATE_RUNNING)
@ -2706,7 +2715,7 @@ struct DisplayList_v2 {
};
void GPUCommon::DoState(PointerWrap &p) {
auto s = p.Section("GPUCommon", 1, 5);
auto s = p.Section("GPUCommon", 1, 6);
if (!s)
return;
@ -2782,6 +2791,9 @@ void GPUCommon::DoState(PointerWrap &p) {
if (s >= 5) {
Do(p, matrixVisible.all);
}
if (s >= 6) {
Do(p, edramTranslation_);
}
}
void GPUCommon::InterruptStart(int listid) {

View File

@ -118,6 +118,8 @@ public:
u32 Continue() override;
u32 Break(int mode) override;
void ReapplyGfxState() override;
uint32_t SetAddrTranslation(uint32_t value) override;
uint32_t GetAddrTranslation() override;
void SetDisplayFramebuffer(u32 framebuf, u32 stride, GEBufferFormat format) override;
void CopyDisplayToOutput(bool reallyDirty) override = 0;
@ -367,6 +369,8 @@ protected:
uint32_t immFlags_ = 0;
bool immFirstSent_ = false;
uint32_t edramTranslation_ = 0x400;
// Whe matrix data overflows, the CPU visible values wrap and bleed between matrices.
// But this doesn't actually change the values used by rendering.
// The CPU visible values affect the GPU when list contexts are restored.

View File

@ -200,6 +200,7 @@ public:
virtual int GetStack(int index, u32 stackPtr) = 0;
virtual bool GetMatrix24(GEMatrixType type, u32_le *result, u32 cmdbits) = 0;
virtual void ResetMatrices() = 0;
virtual uint32_t SetAddrTranslation(uint32_t value) = 0;
virtual void InterruptStart(int listid) = 0;
virtual void InterruptEnd(int listid) = 0;