hrydgard / ppsspp

A PSP emulator for Android, Windows, Mac and Linux, written in C++. Want to contribute? Join us on Discord at https://discord.gg/5NJB6dD or just send pull requests / issues. For discussion use the forums at forums.ppsspp.org.
https://www.ppsspp.org
Other
11.04k stars 2.15k forks source link

Silent Hill: Origins [flickering screen,mising some graphics] #1541

Closed brujo5 closed 10 years ago

brujo5 commented 11 years ago

Silent Hill Origins (ULUS10285)

Notes : The game seems to be working completely full screen now but is unplayable due to heavy flickering of the screen . Fps is currently too low and the are some heavy on screen Sps.

more info here.

http://forums.ppsspp.org/showthread.php?tid=1127&highlight=silent+hill

djalireza2mixer commented 10 years ago

any update?

ratfield commented 10 years ago

Nope... Latest win32 build: awful

mtmarco commented 10 years ago

I've tested Silent Hill origins on PPSSPP 0.9.8 stable for Android, and on latest github x86 build (0.9.8-697-gc4d8b31) compiled with Visual Studio 2013 under Win 8.1 x64.

The result of my test is as for everyone else that 1) Screen is Always flickering, above all in the boot Konami logo, till the intro menu, but however also ingame; 2) there are many glitches here and there; 3) black screen but sounds with non-buffered rendering, playable but flickering/glitches with buffered rendering, slow/glitches with cpu/gpu memory framebuffer; correct rendering in soft mode (but obviously slow);

Starting the game with buffered rendering (with flickerings), executing the GE Debugger, and stepping by prims i've seen in a first try an alternation of black frames, the frame of the KONAMI logo in White background, and then the KONAMI Logo wrapped into an Alpha red background; and in correspondence of the black frames i was steadly in Texture:0x0404c000 and in display list i've got Always the vaddress =08e507c0.

Stepping further i've still got the Texture:0x0404c000 and in display list i've got Always the vaddress =08e507c0 but in correspondence of the correct konami logo with White background.

I've seen also that in the alternance between Konami logo and red background konami logo we got a different resolution image: we get a 960x544(texture 512x512) correct konami logo, then a red wrapped 960x544(texture 512x512) konami logo, and in the end a 512x512(texture 256x16) konami logo reduced in size with black background around it.

What does this alternance mean? Why the correspondence of the vaddres 08e507c0 and texture 0x0404c000 in each black frame and konami logo? I want to understand what these Address stands for, can someone of the @dev, as @unknownbrackets or Others help me understanding the corresponding instruction/gpu-opengl-dx call in the source code, or perhaps the point in which the HLE interpretates the game instruction ending in this behaviour? I don't know the entire architecture of the emulator, but what does these address/instruction opcodes stand for? Perhaps the problem is around there.

Thank you. I'm posting some screenshots.

2try 3try 4try 5try 6try 7try 8try 1try 10try

unknownbrackets commented 10 years ago

The red here highlights where it's about to draw something: https://cloud.githubusercontent.com/assets/524458/3033657/4dfa3ca8-e067-11e3-9055-5042cf93687f.png

The game is not actually drawing red. We just highlight the vertices in red.

Anyway, the first thing it does (per that screenshot) is clearing the screen. It highlights the KONAMI logo in red and draws black/white on it (Vertices tab would show which color it is using.)

The next red rectangle, I dunno what it's doing. What shows up right after that if you hit "step draw"?

Here: https://cloud.githubusercontent.com/assets/524458/3033691/824aa038-e067-11e3-97c4-2b89a52d013b.png

It appears to be rendering the texture at 0404c000 to 040d4000. That part seems roughly normal.

This screenshot seems somewhat concerning: https://cloud.githubusercontent.com/assets/524458/3033704/abd4578c-e067-11e3-8982-4e485bec89c8.png

Deleting an FBO and turning around and creating it again right away is not a great thing. It must be rendering somewhere, though...

Anyway, the question is, where is it texturing from when it draws a black screen? Does it always texture from the KONAMI logo? Maybe it's drawing to a lower part of the framebuffer and setting the framebuffer address specially, or it's staggering access...

-[Unknown]

mtmarco commented 10 years ago

Hi @unknownbrackets thank you for the answer:)

Here are the screenshot you wanted after: https://cloud.githubusercontent.com/assets/524458/3033691/824aa038-e067-11e3-97c4-2b89a52d013b.png

--> This is after a Step Draw: stepdraw I'm still not in the low level logic of the framebuffers/low level graphic instructions, but from what this screen is showing a Step Draw after that red highlight on the black frame, we have two cut on the sides of the black frame.

--> this is a Step Prim after: 9try

We have a cycle, i've put all the screenshots of Step Prim from the very beginning of the flickering konami logo, till this last red highlight, after this we have again the konami logo if i don't remember bad.

With your informations, i've reviewed all the cycle, and i've seen that when we have the first red highlight of the konami logo, in vectors we have various color hex values, then the Prim after we have all 000000 hex values (black right?), and so we are drawing black to clear the previous frame ok; the strange thing in all this is that in this "cycle" we pass from a 512x512 konami logo to an intermediate resized logo smaller than before with a black background around,with texture shown at 256x16 size (?strange). This seems strange to me, don't you think? Maybe we have a fast showing of konami frame then clearing then showing of a wrong sized konami frames than black? could this cause flickering? (in this flickering i see an alternance with black background...)

And this Step Draw after means something?

The debug console shows Always that fbo destroying and following recreating as before, and after these if we go ahead by prims we don't have again the fbo destroying/recreating event;

Stepping by frames I see black frames alternated with konami frames, and when konami fades out, I see black frames alternated with Climax logo...

Thinking on your question (does it Always texture from the konami logo), why so it show black alternated frames also with the CLIMAX logo?..... Sorry for my little knowledge in field of Low level Framebuffer/graphics programming... but for: maybe it's drawing to a lower part of the framebuffer and setting the address specially, you mean the framebuffer is divided into sort of "substrates", and you think that the software is not drawing to a "standard" higher part of the framebuffer, but into a special addressed (lower) part of it, that the emu by default doesn't read? So in this case should we have "only" to add an exception to manage this special address and draw the correct texture (at least in this specific game, i know it's a bad solution although)?!?
Or In the last case why could the access be staggering?

How can we found the answer to these questions? where we can search further? in the disassembler? in what source file we must concentrate our efforts? texture-drawing or interpreter?

Thanks in advance, Marco.

VIRGINKLM commented 10 years ago

You know about this thing that every emulator has "that one game" that is stubborn and is bugged from since the emulator's start and keep being bugged even after years of it's development? I have a strong feeling "that one game" on PPSSPP is SH:Origins (and Shattered Memories). It feels so tough to debug. I'd be so happy if somebody would step in and find a way to debug this game, it feels like it would (hands down) be one of PPSSPP's milestones.

mtmarco commented 10 years ago

I think I have to agree with you @VIRGINKLM , because seeing how good the emu can run god of war, obscure, and other commercial titles, you understand that this game is, for the architecture of the emu itself, that has evolved in complexity till the actual build, a "black beast" of the emu.... however i'm curious about what an user has said in a previous post, about a PPSSPP iOS version running the game without flickering.... perhaps if it's true there one could find an answer to this bug.... However the main problem that remains is : if the ge debugger isn't enough to debug/find the problem, what debugging instrument can we use here? direct source debug? My idea it's that if i know the source file that processes the instructions/opcodes (i think it should be core.cpp or hle.cpp) one can try to inhibite the minimal graphic primitive that draws the black frame, skipping that frame, or perhaps doubling the previous correct frame... or as unknown said we have to find where is the "lost" frame, so we can draw it in place of the black frame...

I would debug all this if i better know the source code architecture.... i'm getting lost between source file.... we have hundreds of source files between headers, cpp, resources etc... without counting the multiplatform orientation of the emu, that makes super generic/virtualized each class...... I mean i want to know the skeleton of the emu: the pipeline in which the game isos passes in then are read, the eboot is read, interpretated, where the instruction are decoded to a triangle or display primitive and where the transformation, rendering process is actually realized.!

hope you've got the idea.

unknownbrackets commented 10 years ago

So, to clarify things a bit.

Almost every game (there are exceptions) for the PSP does the following to draw graphics:

  1. Toggle the target framebuffer (e.g. usually between 0x04000000 and 0x040088000.)
  2. Enqueue a display list (commands, this is what you're stepping through.) 2.1. In this list, clear the framebuffer picked in step 1. 2.2. Draw to the framebuffer picked in step 1.
  3. Wait for the enqueued display list (running on the GPU) to finish.
  4. Swap buffers, so that the framebuffer picked in step 1 is now active.

It's completely normal that it clears the framebuffer to black every time. Almost every single game does this. However, if it swaps buffers after doing that, then that is weird.

Now, let me explain the buttons you're pressing:

One thing I'm still not clear on would be: is the game actually alternating between framebuffers like most games do? What are the addresses? These should be the targets shown in the debugger under "Color: ADDR (WxH) fmt F".

There are a few things we don't support that it could be doing:

A. It could draw the second frame with a high Y coordinate onto the first framebuffer, but then set the displayed framebuffer to something that "doesn't exist". Breath of Fire 3 does this. For example:

What OpenGL sees:

Frame 1:
+------+ <-- start of memory at 0x04000000
|AAAAAA|
|AAAAAA|
|      | <-- start of memory at 0x04088000
|      |
+------+

Frame 2:
+------+
|AAAAAA| <-- start of memory at 0x04000000
|AAAAAA|
|BBBBBB| <-- start of memory at 0x04088000
|BBBBBB|
+------+

What OpenGL is asked to display:
+------+
|AAAAAA| <-- start of memory at 0x04000000
|AAAAAA|
|BBBBBB| <-- ignored because Y > 272
|BBBBBB| <-- ignored because Y > 272
+------+

+------+
|XXXXXX| <-- start of memory at 0x04088000 (does not exist in OpenGL)
|XXXXXX|
+------+

B. Staggering. Rockman DASH does something like this, but more complex.

What OpenGL sees:
+------------+
|AAAAAABBBBBB| <-- start of memory at 0x04000000
|AAAAAABBBBBB|
+------------+

What OpenGL is asked to display:
+------------+
|AAAAAABBBBBB| <-- start of memory at 0x04000000
|AAAAAABBBBBB| <-- (B is ignored because X > 480)
+------------+

+------+
|XXXXXX| <-- start of memory at 0x04088800 (does not exist in OpenGL)
|XXXXXX|
+------+

Note that this should be (due to memory wrapping):
|XXXXXXAAAAAA| <-- (not part of framebuffer, just for clarity - 0x04000000 starts in middle)
+------------+
|BBBBBBAAAAAA| <-- start of memory at 0x04000800
|BBBBBBXXXXXX| <-- (A and X are ignored because X > 480)
+------------+

C. Copying. It could simply be rendering a frame, and then copying this frame to another framebuffer instead of actually rendering it. There are many variations of this.

If it's copying, the best way is to use CPU memory breakpoints. It could be using memcpy(), sceDmacMemcpy(), sceKernelMemcpy(), or a GE block transfer. All of these are tracked by memory breakpoints.

Once we know the address of the two framebuffers, we can set a breakpoint. Using the Dissasembly window, pause emulation, and then click "Breakpoint". Enter in the address and then set 0x1000 for the range (we could do higher but this should catch it.) Then resume emulation.

If it writes to this memory from the CPU or a GE block transfer, it will trip.

If that is the case, there's already a pull request attempting to address some of that sort of functionality. Several games do this for different reasons, but usually not during normal rendering. Vempire does, though.

-[Unknown]

mtmarco commented 10 years ago

Interesting considerations @unknownbrackets . Now I've checked/compared each value Stepping by Prims into the GE Debugger. And i've managed to see 2 slightly different cycles of 3 steps. After this i'll try the Disassembly thing to see if we are in Copying case.

A) FIRST COLUMN of GE-->Display List (cpu/memory address?):

08eb4720 08e50628 --> BLACK FRAME 08e54430

08e546e0 08e52468 --> KONAMI/CLIMAX LOGO 08eb4470

08eb4720 08e50628 08e54430

08e546e0 08e52468 08eb4470

...repeat

3 prims cycle->black/logo frame

B) Framebuffer addresses: 1-> 0x0404c000 (512x512) fmt 3 / black reduced size logo above the framebuffer addres; after this prim we get black frame or CLIMAX(/KONAMI) LOGO rendered alternatively 2-> 0x040d4000 (960x544) fmt 0 / vertices highlight around the texture/logo 3-> 0x0404c000 (960x544) fmt 3 / still vertices highlighted

then repeat the cycle

C) SECOND/THIRD GE COLUMN AND PRIM DESCRIPTION IN THE CYCLE:

    (3 PRIMs) CYCLE with BLACK FRAME rendered

1a)04050004 04050004: DrawPrim type 5: TRIANGLE_FAN count: 4 vaddr= 08eb46cc
    - Current image above -Color: address- is the black reduced size logo
            - After this prim black frame is rendered

1b)0406001E 0406001e: DrawPrim type 6: RECTANGLES count: 30 vaddr= 08e507c0
    - Current image above Color: address is the correct logo NOT highlighted
    - After this prim we get red highlight on the logo (black frame is still rendered)

1c)04060020 04060020: DrawPrim type 6: RECTANGLES count: 32 vaddr= 08e54298
    - Current image above Color: address is the logo highlighted
    - After this prim we get again the black reduced size logo

(3 PRIMs) CYCLE with LOGO FRAME rendered

2a)04050004 04050004: DrawPrim type 5: TRIANGLE_FAN count: 4 vaddr= 08e5468c
    - Current image above Color: address (framebuffer address) is the black reduced size logo
    - After this prim we get CORRECT LOGO FRAME

2b)0406001E 0406001e: DrawPrim type 6: RECTANGLES count: 30 vaddr= 08e52600
    - Current image above Color: address is the correct logo HIGHLIGHTED
    - After this prim we continue in having red highlight on the logo (rendering still remains on the LOGO)

2c)04060020 04060020: DrawPrim type 6: RECTANGLES count: 32 vaddr= 08eb42d8
    - Current image above Color: address is the logo highlighted
    - After this prim we get again the black reduced size logo

Then the whole cycle repeats.

So these are my results analyzing addresses/textures/primitives from the GE Debugger:

-> we have a cycle of 3 Primitives that should ALWAYS clear the FrameBuffer and Draw the Konami/Climax logo
-> in this 3 Prims cycle, we actually have an alternation of 3 Prims that clear and draws effectively the Logo, and the next 3 Prims (the very same prims: type 5: triangle_fan and then two type 6: rectangles) that instead clear and draws the black frame.

What's changing in all these 3 prims alternation are mainly some details:

1)ADDRESSES: the vaddr= of each of the 3 prims are different when we are Drawing the REAL LOGO, in respect of when we are Drawing the black frame.

2)The First GE Debugger column (we can see on the left 3 hex values columns, I think this is a memory address, don't know if it's cpu instruction pointer, or other) takes always the same 3 values for the FIRST 3 PRIMS that draws the LOGO, but takes other 3 values(repeated) for the OTHER 3 PRIMS that draws the BLACK frame.

3)We have always the same 2 Framebuffer alternating: 2 times(at start and end of cycle) 0x0404c000, with 2 different resolutions:(512x512) and (960x544), always fmt 3,  and 1 time (in the middle) 0x040d4000 (960x544) fmt 0. (no difference between the 2 cycles)

4) Last difference is in the PREVIEW IMAGE above the Framebuffer address (Color: addr(res) fmt f):
    ->in the Cycle in which we draw the Black Frame, we have a sequence of 1)black reduced size logo,2)correct logo not HIGHLIGHTED,3)correct logo HIGHLIGHTED

    ->in the Cycle in which we draw the CORRECT LOGO, we have a sequence of 1)black reduced size logo,2)correct logo HIGHLIGHTED,3)correct logo HIGHLIGHTED

Last thing: as for the current Texture in the GE Debugger, we can see always the same 3 Images: 1)an alpha transparent bar, with address Texture: 0x08d46a10 (256x16) 2)CORRECT LOGO with address 0x0404c000 (512x512) 3)CORRECT LOGO with address 0x0404c000 (512x512)

....That's all I can examinate from the GE Debugger, staying in the Display List.... obviously i've not perfectly analyzed as here flags, lighting, texture, settings, vertices, etc.

From what results from this, rethinking to your considerations, i Think that we were supposed to have a repeating of the same instructions, a unique cycle of 3 prims that clear/draws the correct logo, while the other 3 prims cycle should be incorrect, and pheraps caused by one of the causes you've exposed.

We can see however some main difference between these 2 cycles in the vAddresses, in the GE Debugger First column (memory/cpu addresses), and into the VERTICES HIGHLIGHT in the second step of the correct logo rendering, and the non HIGHLIGHT in the second step of the BLACK frame rendering...... what could this mean?

Thinking about all these informations, my next step will be to try the Disassembly window with the two framebuffer addresses 0x0404c000 and 0x040d4000, checking if we can catch a write to these memory addresses.

unknownbrackets commented 10 years ago

The VADDR is the vertex address. Its value is not important. But, the Vertices column shows what it points to, and this is important.

Is it using the same x/y/z coordinates both ways?

-[Unknown]

mtmarco commented 10 years ago

@unknownbrackets about your explanation, while the A case seems more clear, i got a bit confused in the last part of the B (staggering) case, when you say that should be XXXXAAAA / BBBBAAAA / BBBBXXXX , for the memory wrapping... these X now are other non significant data you mean? A ->frame1 data, B-> frame2 data? right?

Why OpenGL skips x>480 and y>272, these are PSP native wxh right? so it's because you preset the driver to read and render frames of that size in memory? And in this case why a PSP game would write to an higher X or Y? Erorr interpretating the ELF binary? or special cases of a game having strange behaviour?

thx 4 each info:)

mtmarco commented 10 years ago

Ok here's a bunch of Screenshots, in which i've catched the Vertices(x,y,z,u,v,color) tabs.

HERE IS THE "famous" CYCLE:

CYCLE 1 1) STEP 1 BEFORE IT DRAWS BLACK FRAME

step1-black

2) STEP 2 WITH BLACK FRAME (no highlight)

step2-black

3) STEP 3 WITH BLACK FRAME (vertex highlight)

step3-black

CYCLE 2

 1) STEP 1 BEFORE IT DRAWS THE CORRECT LOGO

step1-logo

 2) STEP 2 WITH CORRECT LOGO (vertex highlight)

Here I put 2 screens to scroll all the vertices: a) step2a-logo b) step2b-logo

  3) STEP 3 WITH CORRECT LOGO (vertex highlight)

a) step3a-logo b) step3b-logo c) step3c-logo

CYCLE 1 first repetition: (HERE I'VE SCROLLED ALL THE VERTICES OF BLACK FRAME SITUATION)

  1) STEP 1

step1-black-firstrepeat

   2) STEP 2

a) step2a-black-firstrepeat b) step2b-black-firstrepeat c) step2c-black-firstrepeat

  3) STEP 3

a) step3a-black-firstrepeat b) step3b-black-firstrepeat c) step3c-black-firstrepeat

SOME STRANGE THINGS HAPPENED AFTER SOME REPETITIONS: A strange version of the second step of the first cycle (black frame rendered):

a) step2b-black-secondrepeat b) step2c-black-secondrepeat

As you can see here at the same second step we have a Framebuffer address equivalent but an higher resolution : 1024x512 fmt 0 in place of 960x544 fmt 0, and is change also the texture....

However in this vertices view the main thing I'm seeing is that comparing the 2 CYCLES, in the SECOND STEP of the CORRECT LOGO RENDERING, we have x,y coordinates not exceeding 480x272 (and equal to u,v coord), in the SECOND STEP of the Black Frame rendering we exceed the X dimension: X reaches the value of 960.0, while U and V remains within 480x272.... so X>480, are we in Staggering case???

mtmarco commented 10 years ago

@unknownbrackets so the answer is it's not pointing to the sames xyz coords...

mtmarco commented 10 years ago

@unknownbrackets i'm using NOTICE_LOG to intercept variables. Now where am I expected to find the two framebuffers (for this game 0x0404c000 and 0x040d4000) and where are the vaddress, and the first column address of the Display list? My objective is to distinguish between the two different address cases (black frame and normal logo).

I'm trying to intercept into GLES_GPU.cpp, under FastRunLoop()-> list.pc that is an unsigned int.... i want to find those hex values (display list values). Does I need to convert the list integer value to hex, to extract these instructions?

edit: ok i've seen the list.pc is the pointer to each single display list item; how can I inhibite an instruction to prevent will be send in the queue?

unknownbrackets commented 10 years ago

The Execute_XYZ() funcs can have their insides commented out.

Also, the vertices are possibly not trustworthy when not on a PRIM command. So when it's not highlighting, they may be incorrect (since that is the only time they are used, so the game doesn't need to make sure they're always 100% correct - vertex type, etc. - until then.)

It is suspicious that the framebuffers are different dimensions and that the X/Y go over, though... that's weird.

-[Unknown]

brujo5 commented 10 years ago

looks better on iphone 5S img_0613

brujo5 commented 10 years ago

At the beginning when enter in the house,the screen goes white.unplayable at this part. Also when use lintern some parts of the characters dissapear. Strange but silent hill shattered memories looks now much better than this.

unknownbrackets commented 10 years ago

Does this still flicker with the latest git build?

-[Unknown]

dbz400 commented 10 years ago

No flickering anymore now .(Just wonder if need the block transfer on to get graphics)

unknownbrackets commented 10 years ago

I don't know, but if it's just the interleaved rendering, it shouldn't need it.

-[Unknown]

brujo5 commented 10 years ago

working perfect on iphone 5S.

the white screen when enter in the mansion is still present in recent build.but can fix easy.when the screen goes white,presed triangle button for map show then press triangle button again,close map and the white screen i fixed.

daniel229 commented 10 years ago

White screen soon come back after pressing triangle button on desktop. Here is the video.(rename jpg to mp4) 01-muxed

unknownbrackets commented 10 years ago

It sounds like that's a pretty separate issue.

-[Unknown]

hyperspeedgx commented 10 years ago

@unknownbrackets the simulate block transfers fixed almost all graphical effects in Silent Hill Origins, the only issue left is that the Flashlight doesn't produce lighting in scenario, however on characters and some objects it works ok.

FlashlightON (Flashlight should do lightning in scenario too) flashlighton

unknownbrackets commented 10 years ago

I think the torch/lintern/flashlight thing is #6265.

-[Unknown]

alphazombieelite commented 10 years ago

Some-what unrelated but still relevant(Atleast, I think so), I had the screen flickering in Shattered memories too, Turned on soft rendering and the flickering stopped, however the frames that i was getting dropped to like.. 5

blackman91 commented 10 years ago

Using the latest version of ppsspp:

Ok I found a way to play through the game without any lag and without screen flickering, use the default settings but disable autoframe and select 2 for frameskipping and try to play without turning on the flashlight, if you turn on the flashlight the frame rate drops a lot this also happens in cutscenes where the flashlight is on, so when you start the game put the brightness to the max, do this also in your tv and you can play the game without using the flashlight. The ppsspp devs could add an option to disable the flashlight effects in future realeases. The flashlight slowing down the game also happens in silent hill shattered memories.

blackman91 commented 10 years ago

Ok I managed to play the game at 100% speed with this settings: frameskipping off, autoframe off, disable stencil test ticked. The frame rate stills drops a lot when turning on the flashlight but I can play without using it with the brightness to max.

Nekrose commented 9 years ago

Hello everyone! I was silently following this issue because i wanted to find a fix for the torch bug and the flickering screen... but this game, as many of you already said, is really hard to debub completely. However, i'm still playing and enjoying it, even though it has a couple of bugs (Torch bug, flickering screen and audio cracks). My current build is the one below (I'm italian, so i've got the italian version of the PPSSPP 0.9.9.1, but you should be able to understand all the settings in the screenshots)

silent hill - origins settings 1 silent hill - origins settings 2 silent hill - origins settings 3 silent hill - origins settings 4 silent hill - origins settings 5

PremLaSeraphim commented 8 years ago

Hello everyone. Here is my best settings to fix the graphical issues:

Best Graphic Settings for Silent Hill Origin PPSSPP

Show FPS counter: None Show debug statistic: uncheck

Software rendering: uncheck

Hope it will help. Thank you :-)