mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-02-17 12:47:46 +00:00
Merge pull request #3850 from unknownbrackets/ge-minor
Improve accuracy of sceGeEdram* and sceGeSave/LoadContext
This commit is contained in:
commit
faa8d9434b
@ -476,7 +476,7 @@ u32 sceGeSaveContext(u32 ctxAddr)
|
||||
// Let's just dump gstate.
|
||||
if (Memory::IsValidAddress(ctxAddr))
|
||||
{
|
||||
Memory::WriteStruct(ctxAddr, &gstate);
|
||||
gstate.Save((u32_le *)Memory::GetPointer(ctxAddr));
|
||||
}
|
||||
|
||||
// This action should probably be pushed to the end of the queue of the display thread -
|
||||
@ -497,7 +497,7 @@ u32 sceGeRestoreContext(u32 ctxAddr)
|
||||
|
||||
if (Memory::IsValidAddress(ctxAddr))
|
||||
{
|
||||
Memory::ReadStruct(ctxAddr, &gstate);
|
||||
gstate.Restore((u32_le *)Memory::GetPointer(ctxAddr));
|
||||
}
|
||||
ReapplyGfxState();
|
||||
|
||||
@ -550,8 +550,16 @@ u32 sceGeGetCmd(int cmd)
|
||||
|
||||
u32 sceGeEdramSetAddrTranslation(int new_size)
|
||||
{
|
||||
INFO_LOG(SCEGE, "sceGeEdramSetAddrTranslation(%i)", new_size);
|
||||
static int EDRamWidth;
|
||||
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;
|
||||
}
|
||||
|
||||
DEBUG_LOG(SCEGE, "sceGeEdramSetAddrTranslation(%i)", new_size);
|
||||
static int EDRamWidth = 0x400;
|
||||
int last = EDRamWidth;
|
||||
EDRamWidth = new_size;
|
||||
return last;
|
||||
|
@ -530,17 +530,6 @@ void GPUCommon::ReapplyGfxStateInternal() {
|
||||
// ShaderManager_DirtyShader();
|
||||
// The commands are embedded in the command memory so we can just reexecute the words. Convenient.
|
||||
// To be safe we pass 0xFFFFFFFF as the diff.
|
||||
/*
|
||||
ExecuteOp(gstate.cmdmem[GE_CMD_ALPHABLENDENABLE], 0xFFFFFFFF);
|
||||
ExecuteOp(gstate.cmdmem[GE_CMD_ALPHATESTENABLE], 0xFFFFFFFF);
|
||||
ExecuteOp(gstate.cmdmem[GE_CMD_BLENDMODE], 0xFFFFFFFF);
|
||||
ExecuteOp(gstate.cmdmem[GE_CMD_ZTEST], 0xFFFFFFFF);
|
||||
ExecuteOp(gstate.cmdmem[GE_CMD_ZTESTENABLE], 0xFFFFFFFF);
|
||||
ExecuteOp(gstate.cmdmem[GE_CMD_CULL], 0xFFFFFFFF);
|
||||
ExecuteOp(gstate.cmdmem[GE_CMD_CULLFACEENABLE], 0xFFFFFFFF);
|
||||
ExecuteOp(gstate.cmdmem[GE_CMD_SCISSOR1], 0xFFFFFFFF);
|
||||
ExecuteOp(gstate.cmdmem[GE_CMD_SCISSOR2], 0xFFFFFFFF);
|
||||
*/
|
||||
|
||||
for (int i = GE_CMD_VERTEXTYPE; i < GE_CMD_BONEMATRIXNUMBER; i++) {
|
||||
if (i != GE_CMD_ORIGIN) {
|
||||
@ -550,7 +539,7 @@ void GPUCommon::ReapplyGfxStateInternal() {
|
||||
|
||||
// Can't write to bonematrixnumber here
|
||||
|
||||
for (int i = GE_CMD_MORPHWEIGHT0; i < GE_CMD_PATCHFACING; i++) {
|
||||
for (int i = GE_CMD_MORPHWEIGHT0; i <= GE_CMD_PATCHFACING; i++) {
|
||||
ExecuteOp(gstate.cmdmem[i], 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
@ -560,7 +549,7 @@ void GPUCommon::ReapplyGfxStateInternal() {
|
||||
ExecuteOp(gstate.cmdmem[i], 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
// TODO: there's more...
|
||||
// Let's just skip the transfer size stuff, it's just values.
|
||||
}
|
||||
|
||||
inline void GPUCommon::UpdateState(GPUState state) {
|
||||
|
137
GPU/GPUState.cpp
137
GPU/GPUState.cpp
@ -67,45 +67,130 @@ void GPU_Shutdown() {
|
||||
gpu = 0;
|
||||
}
|
||||
|
||||
void InitGfxState()
|
||||
{
|
||||
void InitGfxState() {
|
||||
memset(&gstate, 0, sizeof(gstate));
|
||||
memset(&gstate_c, 0, sizeof(gstate_c));
|
||||
for (int i = 0; i < 256; i++) {
|
||||
gstate.cmdmem[i] = i << 24;
|
||||
}
|
||||
|
||||
gstate.lightingEnable = 0x17000001;
|
||||
|
||||
static const float identity4x3[12] =
|
||||
{1,0,0,
|
||||
0,1,0,
|
||||
0,0,1,
|
||||
0,0,0,};
|
||||
static const float identity4x4[16] =
|
||||
{1,0,0,0,
|
||||
0,1,0,0,
|
||||
0,0,1,0,
|
||||
0,0,0,1};
|
||||
|
||||
memcpy(gstate.worldMatrix, identity4x3, 12 * sizeof(float));
|
||||
memcpy(gstate.viewMatrix, identity4x3, 12 * sizeof(float));
|
||||
memcpy(gstate.projMatrix, identity4x4, 16 * sizeof(float));
|
||||
memcpy(gstate.tgenMatrix, identity4x3, 12 * sizeof(float));
|
||||
for (int i = 0; i < 8; i++) {
|
||||
memcpy(gstate.boneMatrix + i * 12, identity4x3, 12 * sizeof(float));
|
||||
}
|
||||
// Lighting is not enabled by default, matrices are zero initialized.
|
||||
memset(gstate.worldMatrix, 0, sizeof(gstate.worldMatrix));
|
||||
memset(gstate.viewMatrix, 0, sizeof(gstate.viewMatrix));
|
||||
memset(gstate.projMatrix, 0, sizeof(gstate.projMatrix));
|
||||
memset(gstate.tgenMatrix, 0, sizeof(gstate.tgenMatrix));
|
||||
memset(gstate.boneMatrix, 0, sizeof(gstate.boneMatrix));
|
||||
}
|
||||
|
||||
void ShutdownGfxState()
|
||||
{
|
||||
void ShutdownGfxState() {
|
||||
}
|
||||
|
||||
// When you have changed state outside the psp gfx core,
|
||||
// or saved the context and has reloaded it, call this function.
|
||||
void ReapplyGfxState()
|
||||
{
|
||||
void ReapplyGfxState() {
|
||||
if (!gpu)
|
||||
return;
|
||||
gpu->ReapplyGfxState();
|
||||
}
|
||||
|
||||
struct CmdRange {
|
||||
u8 start;
|
||||
u8 end;
|
||||
};
|
||||
|
||||
static const CmdRange contextCmdRanges[] = {
|
||||
{0x00, 0x02},
|
||||
// Skip: {0x03, 0x0F},
|
||||
{0x10, 0x10},
|
||||
// Skip: {0x11, 0x11},
|
||||
{0x12, 0x28},
|
||||
// Skip: {0x29, 0x2B},
|
||||
{0x2c, 0x33},
|
||||
// Skip: {0x34, 0x35},
|
||||
{0x36, 0x38},
|
||||
// Skip: {0x39, 0x41},
|
||||
{0x42, 0x4D},
|
||||
// Skip: {0x4E, 0x4F},
|
||||
{0x50, 0x51},
|
||||
// Skip: {0x52, 0x52},
|
||||
{0x53, 0x58},
|
||||
// Skip: {0x59, 0x5A},
|
||||
{0x5B, 0xB5},
|
||||
// Skip: {0xB6, 0xB7},
|
||||
{0xB8, 0xC3},
|
||||
// Skip: {0xC4, 0xC4},
|
||||
{0xC5, 0xD0},
|
||||
// Skip: {0xD1, 0xD1}
|
||||
{0xD2, 0xE9},
|
||||
// Skip: {0xEA, 0xEA},
|
||||
{0xEB, 0xEC},
|
||||
// Skip: {0xED, 0xED},
|
||||
{0xEE, 0xEE},
|
||||
// Skip: {0xEF, 0xEF},
|
||||
{0xF0, 0xF6},
|
||||
// Skip: {0xF7, 0xF7},
|
||||
{0xF8, 0xF9},
|
||||
// Skip: {0xFA, 0xFF},
|
||||
};
|
||||
|
||||
void GPUgstate::Save(u32_le *ptr) {
|
||||
// Not sure what the first 10 values are, exactly, but these seem right.
|
||||
ptr[5] = gstate_c.vertexAddr;
|
||||
ptr[6] = gstate_c.indexAddr;
|
||||
ptr[7] = gstate_c.offsetAddr;
|
||||
|
||||
// Command values start 17 bytes in.
|
||||
u32_le *cmds = ptr + 17;
|
||||
for (size_t i = 0; i < ARRAY_SIZE(contextCmdRanges); ++i) {
|
||||
for (int n = contextCmdRanges[i].start; n <= contextCmdRanges[i].end; ++n) {
|
||||
*cmds++ = cmdmem[n];
|
||||
}
|
||||
}
|
||||
|
||||
if (Memory::IsValidAddress(getClutAddress()))
|
||||
*cmds++ = loadclut;
|
||||
|
||||
// Seems like it actually writes commands to load the matrices and then reset the counts.
|
||||
*cmds++ = boneMatrixNumber;
|
||||
*cmds++ = worldmtxnum;
|
||||
*cmds++ = viewmtxnum;
|
||||
*cmds++ = projmtxnum;
|
||||
*cmds++ = texmtxnum;
|
||||
|
||||
u8 *matrices = (u8 *)cmds;
|
||||
memcpy(matrices, boneMatrix, sizeof(boneMatrix)); matrices += sizeof(boneMatrix);
|
||||
memcpy(matrices, worldMatrix, sizeof(worldMatrix)); matrices += sizeof(worldMatrix);
|
||||
memcpy(matrices, viewMatrix, sizeof(viewMatrix)); matrices += sizeof(viewMatrix);
|
||||
memcpy(matrices, projMatrix, sizeof(projMatrix)); matrices += sizeof(projMatrix);
|
||||
memcpy(matrices, tgenMatrix, sizeof(tgenMatrix)); matrices += sizeof(tgenMatrix);
|
||||
}
|
||||
|
||||
void GPUgstate::Restore(u32_le *ptr) {
|
||||
// Not sure what the first 10 values are, exactly, but these seem right.
|
||||
gstate_c.vertexAddr = ptr[5];
|
||||
gstate_c.indexAddr = ptr[6];
|
||||
gstate_c.offsetAddr = ptr[7];
|
||||
|
||||
// Command values start 17 bytes in.
|
||||
u32_le *cmds = ptr + 17;
|
||||
for (size_t i = 0; i < ARRAY_SIZE(contextCmdRanges); ++i) {
|
||||
for (int n = contextCmdRanges[i].start; n <= contextCmdRanges[i].end; ++n) {
|
||||
cmdmem[n] = *cmds++;
|
||||
}
|
||||
}
|
||||
|
||||
if (Memory::IsValidAddress(getClutAddress()))
|
||||
loadclut = *cmds++;
|
||||
boneMatrixNumber = *cmds++;
|
||||
worldmtxnum = *cmds++;
|
||||
viewmtxnum = *cmds++;
|
||||
projmtxnum = *cmds++;
|
||||
texmtxnum = *cmds++;
|
||||
|
||||
u8 *matrices = (u8 *)cmds;
|
||||
memcpy(boneMatrix, matrices, sizeof(boneMatrix)); matrices += sizeof(boneMatrix);
|
||||
memcpy(worldMatrix, matrices, sizeof(worldMatrix)); matrices += sizeof(worldMatrix);
|
||||
memcpy(viewMatrix, matrices, sizeof(viewMatrix)); matrices += sizeof(viewMatrix);
|
||||
memcpy(projMatrix, matrices, sizeof(projMatrix)); matrices += sizeof(projMatrix);
|
||||
memcpy(tgenMatrix, matrices, sizeof(tgenMatrix)); matrices += sizeof(tgenMatrix);
|
||||
}
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include <cmath>
|
||||
#include "../Globals.h"
|
||||
#include "ge_constants.h"
|
||||
#include "Common/Swap.h"
|
||||
|
||||
// PSP uses a curious 24-bit float - it's basically the top 24 bits of a regular IEEE754 32-bit float.
|
||||
// This is used for light positions, transform matrices, you name it.
|
||||
@ -389,6 +390,9 @@ struct GPUgstate
|
||||
int getTransferBpp() const { return (transferstart & 1) ? 4 : 2; }
|
||||
|
||||
// Real data in the context ends here
|
||||
|
||||
void Save(u32_le *ptr);
|
||||
void Restore(u32_le *ptr);
|
||||
};
|
||||
|
||||
enum SkipDrawReasonFlags {
|
||||
|
Loading…
x
Reference in New Issue
Block a user