gonetz / GLideN64

A new generation, open-source graphics plugin for N64 emulators.
Other
754 stars 175 forks source link

[Feature Request] Add support for frame buffer extension API #808

Closed gonetz closed 8 years ago

gonetz commented 8 years ago

Need to implement the following extension to Zilmar's specs:

/** Function: FrameBufferRead Purpose: This function is called to notify the dll that the frame buffer memory is beening read at the given address. DLL should copy content from its render buffer to the frame buffer in N64 RDRAM DLL is responsible to maintain its own frame buffer memory addr list DLL should copy 4KB block content back to RDRAM frame buffer. Emulator should not call this function again if other memory is read within the same 4KB range input: addr rdram address val val size 1 = wxUint8, 2 = wxUint16, 4 = wxUint32 output: none ***/ EXPORT void CALL FBRead(wxUint32 addr)

/** Function: FrameBufferWriteList Purpose: This function is called to notify the dll that the frame buffer has been modified by CPU at the given address. input: FrameBufferModifyEntry plist size = size of the plist, max = 1024 output: none **/ EXPORT void CALL FBWList(FrameBufferModifyEntry *plist, wxUint32 size)

/** Function: FrameBufferWrite Purpose: This function is called to notify the dll that the frame buffer has been modified by CPU at the given address. input: addr rdram address val val size 1 = wxUint8, 2 = wxUint16, 4 = wxUint32 output: none ***/ EXPORT void CALL FBWrite(wxUint32 addr, wxUint32 size)

/**** Function: FBGetFrameBufferInfo Purpose: This function is called by the emulator core to retrieve frame buffer information from the video plugin in order to be able to notify the video plugin about CPU frame buffer read/write operations

size: = 1 byte = 2 word (16 bit) <-- this is N64 default depth buffer format = 4 dword (32 bit)

when frame buffer information is not available yet, set all values in the FrameBufferInfo structure to 0

input: FrameBufferInfo pinfo[6] pinfo is pointed to a FrameBufferInfo structure which to be filled in by this function output: Values are return in the FrameBufferInfo structure Plugin can return up to 6 frame buffer info ****/ EXPORT void CALL FBGetFrameBufferInfo(void *p)

weinerschnitzel commented 8 years ago

I think filtering near addresses in the plugin is appropriate since it is still responsible for maintaining an address list. 1964 should also filter these addresses or if a more appropriate fix is possible, do that.

But considering the latest stable release of 1964 is 1.1, i think it should be assumed the regular user has that and not an experimental build until 1964 gets more organized development.

@gonetz Can you think of any consequences other plugins that deviate from specification have? Would it be better to have an option between Read Full Buffer, and Process FBReads by API spec? As far as I can tell, the emulator cannot be trusted and reading the full buffer is the more efficient and safe solution. It should be default, while strictly following API should be enabled for debugging purposes. Not sure if it is useful as a GUI option or if adds clutter.

Would filtering addresses work along side "Read Full Buffer?"

Lastly, can anyone else confirm Banjo Kazooie is broken with FB Read/Writes enabled in 1964?

gonetz commented 8 years ago

@purplemarshmallow I've fixed 2 issues in fb copy. It may fix the bug reported here: https://github.com/gonetz/GLideN64/issues/808#issuecomment-163348853

Please test it. I don't know how to get into the lab.

copy from RDRAM will be fixed later.

purplemarshmallow commented 8 years ago

Yes it does fix this bug but there is a regression. Bomberman64's intros don't look properly anymore they now have stripes in them.

I feel bad for saying this after a lot of work has gone into this but maybe following 1964's specifications closely is not a good idea. Apart from the fact that it's more complicated I'm not sure if it can work as good as Glide64's FBread implementation. Imagine a bad scenario a game can read a buffer backwards from the highest to the lowest address. Glide64 will have no problem but how will GLideN64 react? I don't know about such case but it's possible.

gonetz commented 8 years ago

Don't jump to conclusions. Current implementation is not intended for end users. It is tool to reveal current issues with FBInfo support on emulator's side. As a tool it must follow the specification. End user functionality can be tuned to get best result, but we must get the whole picture to know what is the best.

Imagine a bad scenario a game can read a buffer backwards from the highest to the lowest address. Glide64 will have no problem but how will GLideN64 react?

GLideN64 will read requested chunk of data. Addresses order does not matter.

Bomberman64's intros don't look properly anymore they now have stripes in them.

I'm afraid it is caused by my optimization for 1964. You may revert commit https://github.com/gonetz/GLideN64/commit/7ee37b32a6bfcb91a3f5325a1fa8fbf9519a49c2 and check if it fix the regression. The optimization is not quite correct anyway, as it does not follow the FBInfo specification.

gonetz commented 8 years ago

Yes, the regression is caused by the optimization for 1964. The optimization breaks function's specification, so the result. Plugin should not attempt to fix emulator's bugs.

gonetz commented 8 years ago

I reverted the optimization commit. Bomberman64 intro works perfect with weinerschnitzel's build of 1964. It does not work this well with Mupen64, but it is issue of Mupen64.

purplemarshmallow commented 8 years ago

Yes the correct implementation will uncover emulator issues. And later it can be tested more and it will decide which implementation is best.

gonetz commented 8 years ago

I've fixed issues with FBWrite. Work on FBInfo is mostly completed.

Things left to do:

  1. add config options to use either FBInfo or regular RDRAM copy. Otherwise these functionalities will conflict with each other.
  2. Tune FBRead performance. I think the following will be the best: * for color buffer copy the whole buffer at first FBRead command and ignore the rest (as other plugins do) * for depth buffer copy only requested chunk of data.
  3. Add GUI controls.
purplemarshmallow commented 8 years ago

Is FBWrite implemented? When I tested pills in Dr. Mario did not show up at all even if I enable copy from RDRAM. Also no numbers in JFG. This does work with Rice Video + 1964.

AmbientMalice commented 8 years ago

Sorry to interrupt, but I have a few questions.

How much performance gain will selective depth buffer copies gain? For example, when a typical game checks a lens flare, does it only check a small area of the screen? This seems like a possibly huge performance boost, assuming the emulator-side checking isn't too demanding.

Will FBWrite fix the missing red dot in Pokemon Snap without affecting the rest of the image?

purplemarshmallow commented 8 years ago

How much performance gain will selective depth buffer copies gain? For example, when a typical game checks a lens flare, does it only check a small area of the screen? This seems like a possibly huge performance boost, assuming the emulator-side checking isn't too demanding.

gonetz compared performance and found that it works much faster. There was a comment with accurate numbers but I can't find it

Will FBWrite fix the missing red dot in Pokemon Snap without affecting the rest of the image?

Yes and it will also fix the rain and the numbers in Jet Force Gemini the loading bar in Quake II and other effects.

AmbientMalice commented 8 years ago

@purplemarshmallow That's wonderful news, and hopefully demonstrating these performance and accuracy enhancements will show Zilmar the benefits of adding support to PJ64 for the plugin spec extension. I'm actually quite excited by the prospect of Pokemon Snap running flawlessly, and with reasonable requirements, on normal N64 emulators. It's a huge step forward.

gonetz commented 8 years ago

Is FBWrite implemented?

Yes. I've checked Dr.Mario with Mupen64 and with Mupen64Plus - both work fine. I noticed that FBInfo is somewhere broken in Mupen64Plus: F-1 Pole Position menu backgrounds work with Mupen64, but not with Mupen64Plus.

Also, FBWrite implementation needs further improvements. Currently it writes all buffer line where FBWrite address points. Thus numbers in Jet Force Gemini do not look well - the numbers itself are ok, but other part of the image is low-res.

gonetz compared performance and found that it works much faster. There was a comment with accurate numbers but I can't find it

It was in PJ64 thread. As I remember, read of single 4kb chunk is circa 8 times faster than read of the whole buffer. Thus, if game needs 2-3 chunks of data from the depth buffer, read by chunks will be faster.

I almost finished with config options, update will be within an hour.

gonetz commented 8 years ago

Done.

Test binary: https://drive.google.com/file/d/0B0YqMPjGo3B2RThsM2VrWXl3SHM/view?usp=sharing

pass: fbinfo

AmbientMalice commented 8 years ago

Is FBWrite not supported currently? I can't see any option for it with the Zilmar spec build in 1964.

edit: It seems to be working in mupen64plus, at least for Snap. The effect isn't perfect, with a section of the circle missing. But it's there.

snap_me_like_a_twig

AmbientMalice commented 8 years ago

Quake II loading bar doesn't seem to be working.

edit:

Okay, so switching buffer swap methods during the loadscreen shows the load bar is actually being rendered. But somehow it isn't being updated onscreen over the static image. Maybe there's an issue with the loadscreen because there are no display lists?

loader

gonetz commented 8 years ago

FBWrite not called for Quake II. I tried Mupen64 and 1964, no calls.

purplemarshmallow commented 8 years ago

Okay, so switching buffer swap methods during the loadscreen shows the load bar is actually being rendered

If you open the config dialog this will set CHANGED_CPU_FB_WRITE and the plugin will switch to cfb mode and display RDRAM content.

FBWrite not called for Quake II. I tried Mupen64 and 1964, no calls.

Maybe both emulators work incorrectly here, maybe GLideN64 does not send the buffer to the emulator.

There is a regression. Quake II loadscreen looks wrong in cfb mode. Looked correct before. Something goes wrong in Quake II's loadscreen now gliden64_quake_ii_002

Also the "render framebuffer as texture" option does not seem to be working anymore. But the only game where it worked correctly was Dr. Mario. This option was more a Dr. Mario specific hack.

purplemarshmallow commented 8 years ago

Another regression. In Pokemon Snap pictures are incorrect. Using per-frame sync copy color and PJ64. Worked correctly before. Savestate: https://drive.google.com/file/d/0B7Y6r4SpC_QQOW5MeXhUMzJmNmc/view?usp=sharing

gliden64_pokemon_snap_000

theboy181 commented 8 years ago

Im testing with 1964 (modded by Weiner) with the build Gonetz just uploaded. I cant seem to get any of the new settings figured out for Dr. Mario and Pokemon Snap.

Can someone please upload the correct settings via screenshot?

:)

purplemarshmallow commented 8 years ago

Pokemon Snap's camera detection does not work for 1964 there are core issues you have to use Mupen.

FBwrite does not seem to work at the moment in Dr.Mario but works with Rice Video.

LegendOfDragoon commented 8 years ago

@purplemarshmallow what kind of core issues?

purplemarshmallow commented 8 years ago

camera detection does not work even with a software renderer not sure why. It's a problem in the 1964 core other emulators work.

purplemarshmallow commented 8 years ago

The regression from Quake II also affects Superman64. Both games have 32 bit framebuffers. I think copy from RDRAM now works incorrectly in 32bit fb games. gliden64_superman_000

LegendOfDragoon commented 8 years ago

camera detection does not work even with a software renderer not sure why. It's a problem in the 1964 core other emulators work.

Good to know. It turns out that I already fixed the problem in my fork of 1964. Does it work in PJ64 1.6? It only works in PJ64 2.2 if I have delay DP interrupt enabled. pokemon snap

purplemarshmallow commented 8 years ago

@LegendOfDragoon is it this commit? https://github.com/LegendOfDragoon/1964-X/commit/6ec7c650c458e5d6e3fb600ee477009a07a9ef82 I remember 1964 always had some problems without RSP. Tetrisphere had no input. I will check this out.

A bit unrelated but do you have your optimized angrylion fork published somewhere or is it not ready yet?

LegendOfDragoon commented 8 years ago

I remember 1964 always had some problems without RSP.

I'll need to look into that.

@LegendOfDragoon is it this commit? LegendOfDragoon/1964-X@6ec7c65

Yes. DP interrupt will be delayed as long as you select any of the Delay DMA options, aside from "No", for timing control.

A bit unrelated but do you have your optimized angrylion fork published somewhere or is it not ready yet?

There's some bugs I cannot track down, so I decided that I will have to rewrite the fork eventually. Maybe when I start the rewrite, I'll make a repository. The rewrite should be even faster though, since I'll be bound by less limitations. The code will be more original.

purplemarshmallow commented 8 years ago

I remember 1964 always had some problems without RSP.

I was wrong. I meant it has problems with RSP and most likely you already fixed it. But I haven't got your version of 1964 working yet.

gonetz commented 8 years ago

I think copy from RDRAM now works incorrectly in 32bit fb games.

Yep, i did a simple mistake when rewrote the code. Fixed.

AmbientMalice commented 8 years ago

There seems to be a bit of a green problem.

test

Also, I notice that turning off EnableCopyColorToRDRAM seems to break things, when AFAIK it shouldn't because FBInfo is enabled.

Major League Baseball featuring Ken Griffey Jr. w/colortoRDRAM angel_okay

w-out/colortoRDRAM angel_bad

gonetz commented 8 years ago

There seems to be a bit of a green problem.

What game is it?

Also, I notice that turning off EnableCopyColorToRDRAM seems to break things, when AFAIK it shouldn't because FBInfo is enabled.

I'll check it.

AmbientMalice commented 8 years ago

What game is it?

Superman 64.

DerekTurtleRoe commented 8 years ago

@gonetz @AmbientMalice

What game is it?

It's Superman 64. But "game" isn't really a very good description. More like...well, not game, anyway.

AmbientMalice commented 8 years ago

mupen64plus seems to be having quite a few problems. Bomberman screens not working. Quake II pause backdrop missing. Both work with 1964. Games like DK64 and Banjo are freezing on all emulators.

edit: Also, Major League Baseball seems way buggier with mupen64plus.

purplemarshmallow commented 8 years ago

There seems to be a bit of a green problem.

It's a regression, a side effect from https://github.com/gonetz/GLideN64/commit/1466e162f354d0403f111f0d356278f58a5d49ab But without this commit the Titus logo and the websites do not appear.

On real hardware it's slightly green. But GLideN64 copies this color every frame over and over again and it gets more intense.

gonetz commented 8 years ago

Also, Major League Baseball seems way buggier with mupen64plus.

Yes, it is ok with 1964 but heavy flickers with mupen64plus

gonetz commented 8 years ago

I've changed 'copy from RDRAM' code: now it writes only those pixels, which were reported by FBWrite. JFG numbers look much better.

Test binary: removed

gonetz commented 8 years ago

Another regression. In Pokemon Snap pictures are incorrect.

Yes, I see. Thanks for the save!

gonetz commented 8 years ago

Pokemon Snap fixed. Now works as with master.

New test binary: https://drive.google.com/file/d/0B0YqMPjGo3B2cGlqcGpaajdKYVE/view?usp=sharing

purplemarshmallow commented 8 years ago

FBwrite now works much better. The red dot in Pokemon Snap is now round. But Dr.Mario still shows no pills gliden64_pokemon_snap_000

Some games still freeze unfortunately like 1080 or Conker (tested with Mupen 0.5.1). With Glide64 it does not freeze.

My commit should be corrected to work with emulator notifications. In VI.cpp

if (pBuffer == NULL)
gDP.changed |= CHANGED_CPU_FB_WRITE;

This usually means the CPU started rendering on it's own anywhere in RDRAM. Emulator notifications can't detect it but this code can it should stay.

else if (!pBuffer->isValid()) {
            gDP.changed |= CHANGED_CPU_FB_WRITE;
            if (config.frameBufferEmulation.copyToRDRAM == 0)
                pBuffer->copyRdram();

This is more a workaround for not having emulator notifications. Maybe make this optional in the "without emulator help" section? I don't think it should be enabled if there are emulator notifications. I tested Conker I got ingame with a savestate and it conflicts with the FBwrite implementation.

AmbientMalice commented 8 years ago

I notice the setting to disable Fbinfo doesn't seem to be working in Zilmar spec builds. It just keeps disabling every time the window is closed.

gonetz commented 8 years ago

But Dr.Mario still shows no pills

Works fine for me with Mupen64

gonetz commented 8 years ago

I notice the setting to disable Fbinfo doesn't seem to be working in Zilmar spec builds. It just keeps disabling every time the window is closed.

I added that setting after the main work was made and forgot to save it to ini in GUI. Fixed.

theboy181 commented 8 years ago

Does this build not support Hires_Texture?

gonetz commented 8 years ago

It does not touch hires textures at all. Hires textures must work as with master.

purplemarshmallow commented 8 years ago

But Dr.Mario still shows no pills

Works fine for me with Mupen64

I can't get it working, no pills for me. Also in Jet Force Gemini I get the correct numbers at character selection but ingame it does not work anymore (tested with Mupen, 1964 can't get ingame with fbinfo enabled). If you aim the CPU draws lines and squares. I fear this bug still haunts the plugin #603

gonetz commented 8 years ago

I can't get it working, no pills for me.

Use my build, reset settings to defaults. It must work.

Also in Jet Force Gemini I get the correct numbers at character selection but ingame it does not work anymore

Where are the numbers used ingame? I thought they displayed only on character selection.

My commit should be corrected to work with emulator notifications.

Could you provide a working patch?

AmbientMalice commented 8 years ago

Dr Mario pills are missing for me. On certain settings, I see them momentarily flicker as they fall.

AmbientMalice commented 8 years ago

The numbers in Jet Force Gemini aren't rendering correctly. They're supposed to be a steady scrolling readout. GLideN64 is rendering them as intermittent flickers of numbers with nothing in between.

purplemarshmallow commented 8 years ago

They're supposed to be a steady scrolling readout. GLideN64 is rendering them as intermittent flickers of numbers with nothing in between.

Try 1964 think this is Mupen's fault

ingame the CPU draws many things, lines, squares around enemies and also the rain. This does not work at the moment. gliden64_jet_force_gemini_000 njfe0000

Could you provide a working patch?

What kind of patch should I provide? Should I introduce the new setting as suggested?