What's new

angrylion's Per-Pixel RDP with OpenGL

Iconoclast

New member
Now that I'm able to give posting here another chance, I decided that it seemed easier on everybody to have the rest of the development downloadable via the forum here. I'm sorry that it was inconveniencing people in so many issues when I was trying to make it work with the PJ forum. For those who haven't known, a group of developers after the MAME N64 drivers started to do more reverse-engineering of the RDP after ziggy released his nice, accelerated OpenGL fork of MESS RDP at his z64gl thread. Since then, angrylion has done several hardware tests and reversing to verify his maintained C implementation of various informative sources. (I have also done a few tests myself to confirm 100% bit-by-bit graphical accuracy, with help from dsx and ExtremeDude2 who were able to capture pixel-by-pixel real N64 screenshots, both with and without the video DAC filtering.)

So what about my own fork of it here? Well, only 2 reasons really drove me to do my own fork. In the end, the biggest reason is that angrylion's original plugin uses Microsoft DirectDraw, which of course on Windows has excellent blitting acceleration support but also is constricted to a couple unfortunate circumstances of GPU-defined graphical behavior with their closed specifications. I was happy to practice some basic, primitive OpenGL code to rewrite the plugin to force visual correctness, eventually having Linux releases (starting now). The other reason is that, from time to time, I like to staticize the C code (which includes but is not limited to SIMD vectorization, for example MMX :p).

In an older generation of working on the plugin, performance and getting the plugin to work at full speed was the top priority. I hope that with this release, I have focused on enough portability, standards-compliance, compatibility etc. issues that I can look at making the plugin faster again. Not much in the way of speed has changed since the last download, except that my OpenGL blitting code is much faster now (GL 1.5 buffer mapping extensions to VRAM, if your hardware supports it), but if everyone is happy otherwise I can start to look at speed again finally.

The `/bin` folder has 32- and 64-bit Windows and Linux releases, but I only advise installing the 32-bit Windows plugin until we are able to test out a working 64-bit version of zilmar's plugin specifications. If you're on Linux, it's even better to try just executing `./make.sh` in the source folder instead of using my pre-compiled binary release.
 

Attachments

  • vigl_20150424.7z
    364.6 KB · Views: 5,385
  • vigl_20150427.7z
    365.4 KB · Views: 3,456
  • vigl_20150613.7z
    381.9 KB · Views: 11,157
Last edited:

AIO

New member
Thanks for releasing :D . Perhaps it's time for me to start learning more about the RDP.

Just briefly tested. Works good :satisfied . Nice work :) .
 
OP
Iconoclast

Iconoclast

New member
Graphics Processing Settings

gfx_settings.png


Screen resolution formula is the method for maintaining the emulated screen size of the video output in windowed mode.

  • VI register layout: Simply do video output at the native resolution of the digital-to-analog conversion, after all processing by the RCP's video interface has completed. In NTSC mode, the native resolution is 640x240 non-interlaced, with a final result of 640x480. To experiment, I have arranged it so that this plugin outputs video at 640x576 if it detects from the RCP registers that the game is running with a PAL configuration. This is the most accurate of the 3 settings.
  • DP frame buffer: Automatically adjust the emulator window size to match the estimated frame buffer width and height. As an example, Mario64 on NTSC still has a final output resolution of 640x480, but the frame buffer storage in RDRAM (sent in this case after microcode processing and rendering by the RDP from the RSP) is 320x240, 16 bits per pixel. If you would rather have the "raw" video card data stored on a real N64 without the finished processing for video output adjustments, then you would select this option instead and disable the video DAC filters. Note that this, ultimately, is a hack for testing, experiment, and personal appeal. It is not necessarily accurate to select this option.
  • User-defined: Enables the screen size text input form immediately to the right so that you can specify a forced screen resolution.
Bypass DAC filters: Draws the unmodified frame buffer pixels at a faster rate by ignoring several filtering bits of the VI status register, VI_CONTROL_REG. This, again, is a hack, but it is useful to study the raw image rendered by the RDP video card in the RCP before raster effects like VI filtering happen which can make studying microcode results slightly harder.

Force NN: Formerly known as "Alternate TV size emulation". In the absence of your own certainty, it is best to make sure that this option stays on. When it is on, the plugin is guaranteed to always use point-sampled (or nearest-neighbor) sampling when drawing the final video output, which results in low-res pixilation when a 320x240 frame buffer is scaled up to fit the 640x480 resolution, for clearer studying of the individual pixels. If you decide to turn it off (or did not correctly install `rdp_conf.bin', which turns it on), OpenGL will use linear math on the pixels when the VI-filtered 640x240 image is stretched vertically to fit your 640x480 screen, which results in an alternative TV screen appearance that happens much of the time on normal TV video output and hides the low-res look a little through a bi-linear sort of effect (which people usually will look at as blur).

Refresh stepping: Every time a vertical interrupt is generated, pause emulation.

Iteration leaping: Skip every N iterations of routine graphics processing, which mostly is comprised of updating the 640x480 screen (refreshing) and, optionally, vector rendering by the geometry engine to 3-D triangles.
  • Refresh: Skip this many iterations of calling UpdateScreen in the plugin system. You can use this setting to make emulation go faster by not sending [possibly unchanged] video images to OpenGL for drawing to the screen. For example, Super Mario 64 runs at 30 FPS, but updates at the standard 60 VI/s NTSC refresh rate. This basically means that for every 2 vertical interrupts sent for OpenGL to update the emulator screen, only 1 of them has a changed, new image. Therefore, since FPS = 30, then (60/30) - 1 = 1, the most optimal setting for this game. Note that the most accurate value for this setting is always 0, of course. The idea is that speed can go up by changing it to something which makes no visual difference while playing a game, but if you have it set to the wrong value at any point in the game, you will experience lag in the video. Note also that the FPS can easily change between multiple values in the same game. Note also that the performance effect of using this hack to increase emulation speed is more significant when VI filters are being emulated--when DAC filtering is bypassed, the latency of updating the screen just by itself is so much less, so the improvement on speed when using this option also becomes less.
  • Triangles: Most of the non-triangle RDP commands are pretty optimized. The triangle RDP commands are by far the most complex, easily, to the point where a re-compiler core would make no positive difference over interpreting the RDP CPU. Even several simpler RDP commands, such as rectangle filling and texturing, are built on top of 3-D triangle rendering. If you change this value, you can skip rendering every N triangles. Note that this is also a hack, like the above, except that there is no way to set it to a nonzero value and not see a major visual change in the resulting graphics (missing/alternating/flickering triangles). The exception is when a game does no triangle rendering at all anyway, in which case changing this setting has neither a visual effect nor a speed effect. It is, however, much better at increasing emulation speed up to full speed than setting the refresh skip, so this is useful for when games force you to sit through logos, demos, or make you wait in other ways where you don't need perfect graphics to get by.

Graphics microcode detection: Not implemented and quite possibly may never be implemented. It is an integrated part of the configuration file specifications I wrote up, `rdp_conf.bin', which reserves space for future vendors of this plugin (most likely not me) to implement graphics microcode in HLE assortments of knowing which LLE RSP and LLE RDP commands are going to get executed. HLE is not physically outside the scope of this plugin's design, but it is far more practical for me to focus on LLE. If somebody else implements HLE to this plugin, they can use this option.

Graphics Device Context Status

gfx_context.png


This tab displays information about your video card's support for the OpenGL specifications.

GL_VERSION: As long as this is 2.0 or later, you have nothing to worry about.
GL_VENDOR: The provider of your video drivers' implementation of OpenGL. This could be:

  • a proprietary GPU manufacturer (ATI, Intel, NVIDIA, etc.)
  • a free software implementation of OpenGL (i.e., Mesa3D, which is common on GNU)
  • "Microsoft Corporation", which means you are using OPENGL32.DLL's core implementation of OpenGL without any installable client drivers running on top of it by NVIDIA, ATI or whoever, and GL_VERSION is set probably to 1.1. If you have a terrible emulation speed, this is why.

GL_RENDERER: The name of your OpenGL video driver, as hard-coded into your video driver files.

GL_EXT_bgra? Only useful on CPUs needing BGRA pixel little endianness to ensure direct VRAM copies.
GL_ARB_vertex_buffer_object? Keep permanent texture rectangle vertex coordinates on physical VRAM.
GL_ARB_pixel_buffer_object? Able to use server-side OpenGL VRAM for pixel transfers (huge speed-up).
GL_ARB_vertex_program? If you have this extension, modern OpenGL programming (3.0+) is feasible.

"Diagnose" button: Click this to log basic information about your GL context communications over GDI.

"Write DRAM" button: Click this while emulation is running, to export RDRAM to a binary file, named after "RCP_", followed by VI_ORIGIN_REG and VI_STATUS_REG, then ".bin". You can use a utility like PixD to view the RDRAM file as a pixel map in an image display, which I have attached to this post.
 

Attachments

  • PixD.zip
    86.3 KB · Views: 2,000
Last edited:

Shonumi

EmuTalk Member
I get this when trying to compile it on Linux:

Code:
bash-4.2# ./make.sh 
Compiling C source code...
Assembling compiled sources...
Linking assembled object files...
ld: obj/main.o: relocation R_X86_64_32S against `.bss' can not be used when making a shared object; recompile with -fPIC
obj/main.o: could not read symbols: Bad value
strip: 'obj/vigl.so': No such file

Probably irrelevant but I'm running Slackware 14.1.

To fix this, I just add "fPIC" to FLAGS_x86. Will test in a bit.

EDIT: So, can Mupen64Plus use this plugin? This is what I get:

Code:
UI-Console: attached to core library 'Mupen64Plus Core' version 2.0.0
UI-Console:             Includes support for Dynamic Recompiler.
Core Error: Unable to open rom database file '(null)'.
Core: Goodname: Mupen64Plus (unknown rom)
Core: Name: Mupen64Plus         
Core: MD5: DBF04773EC2B8ADF8A94DB7E3E461138
Core: CRC: ddba4de5 b107004a
Core: Imagetype: .v64 (byteswapped)
Core: Rom size: 1048576 bytes (or 1 Mb or 8 Megabits)
Core: Version: 1444
Core: Manufacturer: 0
Core: Country: Demo
UI-Console Status: Cheat codes disabled.
UI-Console Error: dlopen('./vigl.so') failed: ./vigl.so: undefined symbol: glDrawElements
UI-Console Error: Specified Video plugin not found: ./vigl.so
Core Status: Rom closed.

Just trying to run the demo that comes with Mupe64Plus.
 
Last edited:
OP
Iconoclast

Iconoclast

New member
I get this when trying to compile it on Linux:

Code:
bash-4.2# ./make.sh 
Compiling C source code...
Assembling compiled sources...
Linking assembled object files...
ld: obj/main.o: relocation R_X86_64_32S against `.bss' can not be used when making a shared object; recompile with -fPIC
obj/main.o: could not read symbols: Bad value
strip: 'obj/vigl.so': No such file

Probably irrelevant but I'm running Slackware 14.1.

To fix this, I just add "fPIC" to FLAGS_x86. Will test in a bit.

You're right. When I compiled the 64-bit Linux build, I had to add -fPIC to the C flags. This however, last I checked when compiling my RSP plugin as a 64-bit plugin, minces the optimization of several functions for some reason. I'm not really acquainted at all with the details, but to be safe I prefer to avoid specifying -fPIC unless it's needed (which unfortunately, it may be). Although, the Windows MinGW 64-bit build did not need -fPIC.

Maybe I should just add a FLAGS_x64 alternative which is similar to FLAGS_x86 but defines -fPIC instead of -msse2.

EDIT: So, can Mupen64Plus use this plugin? This is what I get:

Code:
UI-Console: attached to core library 'Mupen64Plus Core' version 2.0.0
UI-Console:             Includes support for Dynamic Recompiler.
Core Error: Unable to open rom database file '(null)'.
Core: Goodname: Mupen64Plus (unknown rom)
Core: Name: Mupen64Plus         
Core: MD5: DBF04773EC2B8ADF8A94DB7E3E461138
Core: CRC: ddba4de5 b107004a
Core: Imagetype: .v64 (byteswapped)
Core: Rom size: 1048576 bytes (or 1 Mb or 8 Megabits)
Core: Version: 1444
Core: Manufacturer: 0
Core: Country: Demo
UI-Console Status: Cheat codes disabled.
UI-Console Error: dlopen('./vigl.so') failed: ./vigl.so: undefined symbol: glDrawElements
UI-Console Error: Specified Video plugin not found: ./vigl.so
Core Status: Rom closed.

Just trying to run the demo that comes with Mupe64Plus.

>dlopen('./vigl.so') failed: ./vigl.so: undefined symbol: glDrawElements
That's a pretty interesting error, considering that glDrawElements has been core to the internal OpenGL specifications for all versions back as far as 1.1. (Only OpenGL 1.0 lacked a core implementation of that command.) It's difficult for me to guess based just on that where the problem could be.

I am not in contact with most version of Mupen64Plus, except the libretro port of it to a core under RetroArch (which uses no plugin system at all), so I did not test it. I used Mupen64 0.5 on Linux to test the plugin (which unfortunately is 32-bit only) and various other emulators for testing the Windows port. From what I hear, Mupen64Plus 1.5 (?) does still share the same (albeit flawed) plugin specifications as the other emulators we have access to, so I am not sure offhand why it would not work on that older version of Mupen64Plus. How might I obtain an installation of it so that I can test?
 

V1del

New member
Shonumi's trying to run on 2.0 which has the new spec which definitely won't work right now. Mupen64Plus 1.5 should still work I haven't tested yet either though and am somewhat busy with finals week and stuff so not really going to be looking into that for at least 2 weeks. As for where to obtain 1.5 https://github.com/mupen64plus/mupen64plus-oldsvn
 

weinerschnitzel

Surreal64 Nut
Iconoclast = DrCat/HatCat/BatCat/FatCat. Angrylion is another developer.
*Fanatic64, beating me to the punch!

Thanks Icono. I'm glad your back on EmuTalk. :)
 

Shonumi

EmuTalk Member
Yeah, I figured I could just use the git repo to backtrack to 1.5. I actually have the Slackware package for 1.5 on my laptop still. I'll try it with 1.5 later. Thanks for the work you've done Icono.
 

Predator82

New member
I´ve tested with Project64 2.2.0.3 & World Driver Championship

Works really good with my 3770k @ 3,9Ghz
36 VI/s with standard settings but 1024x78
42 VI/s when bypass is activated
46 VI/s when force is activated too

I´m missing to set more than 1024x1024 in screen size
And can it be done that the *.cfg will created where the *.dll is?

Angrylions:

GLideN64:
 
Last edited:
OP
Iconoclast

Iconoclast

New member
I've updated post #3 with a detailed explanation of the configuration options for the plugin.

Most of them do not have a GUI to edit them in the Linux build of the plugin...in Linux Mupen64 0.5 you would just click "Config" button for the plugin, and it toggles the VI filters and screen resolution formula between on/VI-based to off/FB-based, which I think is the most important reason to configure the plugin anyway. Any other configurations can be done through a hex editor on the `rdp_conf.bin' file, which is documented in config.c: `unsigned char cfg[32] = {'

Shonumi's trying to run on 2.0 which has the new spec which definitely won't work right now. Mupen64Plus 1.5 should still work I haven't tested yet either though and am somewhat busy with finals week and stuff so not really going to be looking into that for at least 2 weeks. As for where to obtain 1.5 https://github.com/mupen64plus/mupen64plus-oldsvn

It would be very exciting to finally have a 64-bit plugin system to test these plugins on, besides the 1.5 version of Mupen64Plus. Thanks again for the link, and I will try to test what I can.

For anyone who hasn't noticed, the 64-bit releases (either win/nix) of this plugin are smaller than the 32-bit releases. That only is a part of how important 64-bit is to RCP low-level emulation! We NEED a portable 64-bit plugin system! Right now, all I could do was take the initiative by releasing 64-bit builds anyway, but I hope that we'll be able to access also 64-bit forks of 1964 and Project64.

Yeah, I figured I could just use the git repo to backtrack to 1.5. I actually have the Slackware package for 1.5 on my laptop still. I'll try it with 1.5 later. Thanks for the work you've done Icono.

Actually have been meaning to get back on Slackware to do some more tests on that anyway. Most of the immediate testing I was able to do was on 32-bit since that was what Mupen64 0.5 was compiled to work on; I hope to ensure how 1.5 will work to use the plugin on Slackware as well on my laptop.

If worst came to worst, I guess I wouldn't mind macroing in some level of support for Mupen64Plus "API" and the newer plugin system they came up with, but that really is a last case resort to me because many of those changes after 1.5 were for the worse in terms of emulation relevance. I would rather no plugin system existed at all than to see competing conflicts like that arise, but it is a choice between two evils unfortunately, since zilmar, our primary mascot we have to thank for having any long-standing, time-tested plugin system to begin with, has imposed Win32 references on the original definitions.

I´ve tested with Project64 2.2.0.3 & World Driver Championship

Works really good with my 3770k @ 3,9Ghz
36 VI/s with standard settings but 1024x78
42 VI/s when bypass is activated
46 VI/s when force is activated too

Sounds good. On some GPUs, "Force NN" is faster, but it can depend.

Speed was not really one of my concerns with this release. From the beginning, it was meant to be, but I had tons of things to do and many requests which made me focus on the quality of the OpenGL rendering, visual sharpness, more features and fixes...though it should be a bit faster than the previous release of this plugin anyway.

I´m missing to set more than 1024x1024 in screen size

I made the maximum windowed mode 1024x1024. If you try to set greater than that in the GUI, it's clamped down to 1024.

I didn't think anyone would want a window size greater than 1024x1024? Sounds awfully big.
Why not enter full-screen mode if you want a screen so big? The Win32 full-screen code was mostly stuff I got from zilmar's CFB plugin, but it's very stable and works seamlessly, so perhaps just use that.

I made the limit 1024x1024 because that is the limit of several VI registers: VI_H_START_REG x2 - x1 < 1024, VI_V_START_REG y2 - y1 < 1024, VI_H_SYNC_REG < 1024 pixels ... basically 1024 is the common limit number here.

And can it be done that the *.cfg will created where the *.dll is?

Not really, because the plugin system doesn't tell us where the plugin directory is.

The only portable approach is to use the process directory. If you see any plugins storing INI files or whatever in the same folder as a DLL, then it's using some fixed approach which is not natural.
 
Last edited:

mendus

New member
Hi.
I was trying to check graphics on Ogre Battle 64 and I ended up with a crash.
Windows 8.1 using Project 64 2.2. Does it happen also to you or only in my end?

Quick edit: It happens when trying to get into a mission or training.
 
Last edited:
OP
Iconoclast

Iconoclast

New member
I am not finding this crashing, but then, I'm not all that familiar with this game either.

It sounds more like you could be having the crashing from something else that's coming from your installation of Project64 2.2, like the RSP recompiler plugin it comes with, or maybe it's RDB settings. If you try using a different LLE graphics plugin besides the one in this thread (such as z64gl, Jabo's or GlideN64 in LLE mode, ...) and still find this crashing, then I can only guess you don't have Project64 set up for this game to handle the extra stuff that gets executed with LLE graphics. Make sure you have the latest RDB file, and test the RSP interpreter if the need arises.
 

Ambient_Malice

New member
Hi.
I was trying to check graphics on Ogre Battle 64 and I ended up with a crash.
Windows 8.1 using Project 64 2.2. Does it happen also to you or only in my end?

Quick edit: It happens when trying to get into a mission or training.

PJ64 2.2 has 32 bit mode incorrectly enabled and an RSP regression that breaks OB64. Compiling latest source or grabbing a build from EmuCR will fix this.
 

iwasaperson

New member
I keep getting a bad microcode error on both Project64 1.6 in WINE with the 32 bit version, and Mupen64Plus 1.5 in Linux with the 64-bit version.

EDIT: Probably because I'm using an HLE RSP. Anyone know of a good LLE RSP plugin for M64P 1.5?

EDIT2: LLE fixed the issue in PJ64.
 
Last edited:
OP
Iconoclast

Iconoclast

New member
Correct--current builds need RSP set to LLE.

I have yet to release a RSP plugin on this forum. It has binary downloads for 32-bit and has 64-bit releases of the Mupen64Plus 2.0+ port, but Mupen64Plus 1.5 64-bit, which still uses the original plugin specifications layout by zilmar, has no 64-bit LLE RSP plugin available for it because I never believed we would get a 64-bit plugin system at the time (and understood less of the benefits). However, my sources to the RSP plugin seem to compile with -fPIC to 64-bit builds right out of the box from my GitHub for some time now; it's just that I haven't posted any release downloads.

Until then, the MAME RSP interpreter modified by ziggy and angrylion and the RSP re-compiler plugin by Jabo and zilmar have some LLE support.
 

Top