Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pangya Fantasy Golf: Often crashes when changing equipment in "My Room". #6398

Closed
thedax opened this issue Jun 22, 2014 · 27 comments
Closed

Comments

@thedax
Copy link
Collaborator

thedax commented Jun 22, 2014

This crash goes as far back as 0.9.6.2 at least, so I think it's safe to assume it's always existed since the game has run in the emulator.

Steps to reproduce:

  1. Load your save.
  2. Go to Pangya Collection -> My Room.
  3. Change any equipment, and one of two things will happen:
  • The game will either outright crash with a useless stack trace (more on this in a moment)
  • The game will continue as normal, with no crash, refreshing the character model preview with the desired item.

Now, about the stack trace: It doesn't matter if JIT is on or off, nor if fast memory is on or off, the emulator will crash with no usable stack trace. See below.

>   0000000004df090c()  Unknown

Here's the kicker: If I use softGPU, it does not crash at all. It only crashes with OpenGL.

@thedax
Copy link
Collaborator Author

thedax commented Jun 22, 2014

Okay, I messed around some more, and it seems as if software skinning is the problem. If it's off, the game doesn't crash.

@unknownbrackets
Copy link
Collaborator

It probably won't, but does #6402 help? It fixes some cases where vertex arrays are left enabled which has caused crashes in the GPU driver in some games for me.

Note that weights are sent as attribs, so that means it could be related to that.

-[Unknown]

@thedax
Copy link
Collaborator Author

thedax commented Jun 23, 2014

Unfortunately, no. It still crashes.

@sum2012
Copy link
Collaborator

sum2012 commented Jun 23, 2014

@unknownbrackets
in GPU\GLES\TransformPipeline.cpp
void TransformDrawEngine::SubmitPrim(void *verts, void *inds, GEPrimitiveType prim, int vertexCount, u32 vertType, int *bytesRead) {
...
if (g_Config.bSoftwareSkinning && (vertType & GE_VTYPE_WEIGHT_MASK)) {
DecodeVertsStep();
decodeCounter_++;
}
}

change to if (false) will fix crash.
Hope you have idea to fix

@unknownbrackets
Copy link
Collaborator

What if you disable vertex jit? VertexDecoder.cpp:

if (jitCache && g_Config.bVertexDecoderJit) {

Replace with if (false) {.

-[Unknown]

@sum2012
Copy link
Collaborator

sum2012 commented Jun 23, 2014

Change equipment ~ 8 times crash
edit: ( I press very fast on the same equipment )
2

PPSSPPDebug64.exe!VertexDecoder::Step_TcFloat() Line 183 C++
PPSSPPDebug64.exe!VertexDecoder::DecodeVerts(unsigned char * decodedptr, const void * verts, int indexLowerBound, int indexUpperBound) Line 860 C++
PPSSPPDebug64.exe!TransformDrawEngine::DecodeVertsStep() Line 420 C++
PPSSPPDebug64.exe!TransformDrawEngine::SubmitPrim(void * verts, void * inds, GEPrimitiveType prim, int vertexCount, unsigned int vertType, int * bytesRead) Line 331 C++
PPSSPPDebug64.exe!GLES_GPU::Execute_Prim(unsigned int op, unsigned int diff) Line 786 C++
PPSSPPDebug64.exe!GLES_GPU::FastRunLoop(DisplayList & list) Line 658 C++
PPSSPPDebug64.exe!GPUCommon::InterpretList(DisplayList & list) Line 516 C++
PPSSPPDebug64.exe!GPUCommon::ProcessDLQueueInternal() Line 686 C++
PPSSPPDebug64.exe!GPUCommon::ProcessEvent(GPUEvent ev) Line 643 C++
PPSSPPDebug64.exe!GLES_GPU::ProcessEvent(GPUEvent ev) Line 695 C++
PPSSPPDebug64.exe!ThreadEventQueue<GPUInterface,GPUEvent,enum GPUEventType,0,8,7>::RunEventsUntil(unsigned __int64 globalticks) Line 96 C++
PPSSPPDebug64.exe!ThreadEventQueue<GPUInterface,GPUEvent,enum GPUEventType,0,8,7>::ScheduleEvent(GPUEvent ev) Line 48 C++
PPSSPPDebug64.exe!GPUCommon::ProcessDLQueue() Line 666 C++
PPSSPPDebug64.exe!GPUCommon::EnqueueList(unsigned int listpc, unsigned int stall, int subIntrBase, PSPPointer args, bool head) Line 301 C++
PPSSPPDebug64.exe!sceGeListEnQueue(unsigned int listAddress, unsigned int stallAddress, int callbackId, unsigned int optParamAddr) Line 432 C++
PPSSPPDebug64.exe!WrapU_UUIU<&sceGeListEnQueue>() Line 671 C++
PPSSPPDebug64.exe!CallSyscallWithoutFlags(const HLEFunction * info) Line 469 C++
[External Code]

@thedax
Copy link
Collaborator Author

thedax commented Jun 23, 2014

How did you manage to get a useful stack trace? :/

@unknownbrackets
Copy link
Collaborator

How did you manage to get a useful stack trace? :/

By disabling vertexjit, it's crashing inside there. My guess is that it's running out of decode buffer space. What are indexLowerBound and indexUpperBound?

Although, hmm, shouldn't software skinning run out of space less? It'd be good to know the vertexCount and vertType too (all these variables should be accessible in a debug build by double clicking the appropriate stack lines.)

-[Unknown]

@thedax
Copy link
Collaborator Author

thedax commented Jun 23, 2014

I meant more like how did he know it was in the vertexJIT (aside from the stack trace)? Trial and error with settings I guess..

Anyway, indexUpperBound is 65535 (0xFFFF), lower is 0. vertexCount is 65536 (0x10000), vertType is 302110691 (0x1201d7e3).

@hrydgard
Copy link
Owner

That vertexcount is off the charts, I haven't seen any PSP game draw that much in one call (only the "Sprite" homebrew demo). Seems likely to be bogus, maybe a game bug, especially in the context of a simple club changing screen... Any chance you can trace it back to the previous PRIM call? Maybe add a little check for one with many verts. Would be interesting to see if it's an indexed draw, and which prim it is.

BTW, if you get crap stack traces, odds are that it's in one of the JITs. We don't have that many, so trying to disable the vertex jit is a pretty logical thing to do :)

@unknownbrackets
Copy link
Collaborator

Yeah, that's why I guessed it was in vertexjit (and that particular usage of g_Config.bSoftwareSkinning is a main entry for the vertexjit iirc.)

Wait, that vertexCount shouldn't be valid:

u32 count = data & 0xFFFF;

It can't be > 0xFFFF... can it? It's also == the max:

VERTEX_BUFFER_MAX = 65536,

It doesn't fix it if you change this to >= does it?

if (!indexGen.PrimCompatible(prevPrim_, prim) || numDrawCalls >= MAX_DEFERRED_DRAW_CALLS || vertexCountInDrawCalls + vertexCount > VERTEX_BUFFER_MAX)
(vertexCountInDrawCalls + vertexCount > VERTEX_BUFFER_MAX)

Does it fix it to increase 48/20 here:

DECODED_VERTEX_BUFFER_SIZE = VERTEX_BUFFER_MAX * 48,

Maybe to 52/24?

-[Unknown]

@hrydgard
Copy link
Owner

That vertexcount is possible if we are combining multiple drawcalls into one big one. Still rather weird.

@unknownbrackets
Copy link
Collaborator

Oh, I thought it was the one at SubmitPrim().

-[Unknown]

@sum2012
Copy link
Collaborator

sum2012 commented Jun 23, 2014

Both 2 change still fail

@sum2012
Copy link
Collaborator

sum2012 commented Jun 23, 2014

I feel user_main W[KERNEL]: HLE\sceKernelMemory.cpp:1715 800201b6=sceKernelFreeVpl(288, 09967598): Unable to free is wrong
Unfortunately,JPCSPTrace log fail in the middle (psp auto off in the loading)
but match same error code

v0.9.8-1380-gb4a9780-windows-amd64
info log:
https://gist.github.com/sum2012/17a5eb4ba83e8f529001
debug log:
https://drive.google.com/file/d/0B3OaSdeV0L8kbEh3Q01zVjJCUkU/edit?usp=sharing

JPCSPTrace log with sceKernelFreeVpl (psp auto off in the loading)
https://gist.github.com/sum2012/a56f449a295ca2c1d4d2

@unknownbrackets
Copy link
Collaborator

What happens if you change this:

    if (g_Config.bSoftwareSkinning && (vertType & GE_VTYPE_WEIGHT_MASK)) {
        DecodeVertsStep();
        decodeCounter_++;
    }

To:

    if (g_Config.bSoftwareSkinning && (vertType & GE_VTYPE_WEIGHT_MASK)) {
        DecodeVertsStep();
        decodeCounter_++;
        Flush();
    }

Does it still crash, or not anymore?

-[Unknown]

@thedax
Copy link
Collaborator Author

thedax commented Jan 20, 2015

@unknownbrackets: Adding a flush there seems to prevent the crash, at the "cost" of the game freezing for a few seconds while it frees (or tries to, anyhow) a bunch of memory.

@unknownbrackets
Copy link
Collaborator

Hmm, if you pause it while it's frozen, are any threads showing a useful stack trace? What is it trying to free?

-[Unknown]

@unknownbrackets
Copy link
Collaborator

Does this still happen? If yes (I'm assuming yes), what if you increase the buffer sizes in GPU/Common/DrawEngineCommon.cpp? I just want to make sure it is overflowing the buffers.

These:

enum {
    VERTEX_BUFFER_MAX = 65536,
    DECODED_VERTEX_BUFFER_SIZE = VERTEX_BUFFER_MAX * 48,
    DECODED_INDEX_BUFFER_SIZE = VERTEX_BUFFER_MAX * 20,
    SPLINE_BUFFER_SIZE = VERTEX_BUFFER_MAX * 20,
};

Change to e.g.:

enum {
    VERTEX_BUFFER_MAX = 65536,
    DECODED_VERTEX_BUFFER_SIZE = VERTEX_BUFFER_MAX * 64,
    DECODED_INDEX_BUFFER_SIZE = VERTEX_BUFFER_MAX * 32,
    SPLINE_BUFFER_SIZE = VERTEX_BUFFER_MAX * 32,
};

-[Unknown]

@thedax
Copy link
Collaborator Author

thedax commented Mar 1, 2015

Last time I checked (like 2 months ago, maybe?) it did. I'll try your change in a little while.

@sum2012
Copy link
Collaborator

sum2012 commented Mar 1, 2015

Still crash in v1.0.1-52-g3773d25

@sum2012
Copy link
Collaborator

sum2012 commented Mar 1, 2015

@unknownbrackets
it is not in DrawEngineCommon.cpp
it is in DrawEngineCommon.h
Anyway it still crash.

edit1:Forget 1 change,need re-do
edit2:confirm crash

@hrydgard
Copy link
Owner

hrydgard commented Mar 1, 2015

The game appears to make a draw with bogus index buffer data, causing the vertex decoder to run on way too many vertices.

As the game has some rather severe memory management issues:

09:56:380 user_main    W[KERNEL]: HLE\sceKernelMemory.cpp:1727 800201b6=sceKernelFreeVpl(288, 097e78b8): Unable to free
09:56:380 user_main    W[KERNEL]: HLE\sceKernelMemory.cpp:1727 800201b6=sceKernelFreeVpl(278, 097e9c88): Unable to free
09:56:380 user_main    W[KERNEL]: HLE\sceKernelMemory.cpp:1727 800201b6=sceKernelFreeVpl(288, 097e9c88): Unable to free
09:56:380 user_main    W[KERNEL]: HLE\sceKernelMemory.cpp:1727 800201b6=sceKernelFreeVpl(278, 09914858): Unable to free
09:56:380 user_main    W[KERNEL]: HLE\sceKernelMemory.cpp:1727 800201b6=sceKernelFreeVpl(288, 09914858): Unable to free
09:56:380 user_main    W[KERNEL]: HLE\sceKernelMemory.cpp:1727 800201b6=sceKernelFreeVpl(278, 097e5448): Unable to free

this is probably not too surprising.

We might be able to get around the crash with some sanity checks in the drawing code, but I can't quite figure out where to put them..

@sum2012
Copy link
Collaborator

sum2012 commented Mar 1, 2015

Use @unknownbrackets this change #6398 (comment)
freeze 1-2 second,I try to pause in visual studio
1

[External Code] 
PPSSPPDebug64.exe!condition_variable::wait(recursive_mutex & mtx) Line 291  C++
PPSSPPDebug64.exe!PrioritizedWorkQueue::Pop() Line 45   C++
PPSSPPDebug64.exe!threadfunc(PrioritizedWorkQueue * wq) Line 76 C++
[External Code] 
PPSSPPDebug64.exe!std::thread::Func<std::_Bind<1,void,void (__cdecl*const)(PrioritizedWorkQueue * __ptr64),PrioritizedWorkQueue * __ptr64 & __ptr64> >::Run() Line 245  C++
PPSSPPDebug64.exe!std::thread::RunAndDelete<std::thread::Func<std::_Bind<1,void,void (__cdecl*const)(PrioritizedWorkQueue * __ptr64),PrioritizedWorkQueue * __ptr64 & __ptr64> > >(void * param) Line 286   C++
[External Code] 

hrydgard added a commit that referenced this issue Mar 1, 2015
(Simple sanity check when decoding software skinned vertices)
@hrydgard
Copy link
Owner

hrydgard commented Mar 1, 2015

That should take care of it, can you test if it works for you @sum2012 ?

@sum2012
Copy link
Collaborator

sum2012 commented Mar 1, 2015

OK,wait 30 minute

@sum2012
Copy link
Collaborator

sum2012 commented Mar 1, 2015

I test v1.0.1-56-gbfa52e6 fixed

@hrydgard hrydgard closed this as completed Mar 1, 2015
hrydgard added a commit that referenced this issue Mar 1, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants