Opengl for zsnes under win.
Moderator: ZSNES Mods
-
- Romhacking God
- Posts: 922
- Joined: Wed Jul 28, 2004 11:27 pm
- Contact:
Not to really go off topic, but I have a question about this. D3D has support for Bilinear, Anisotropic, Point, Gaussian, etc.. that can be set via the IDirect3DDevice9::SetSamplerState Method.funkyass wrote:Using hardware video memory with DirectX is just as fast as opengl, and can be used for all filters, rather than how snes9x, and I presume zsnes handled it.
How would you handle adding something like the 2xSAI or Eagle filters? I assume you have to pass the algorithm over your texture in memory? I've got a D3D 2d platformer engine up and running and would like to know how I would go about doing something like that.
[url=http://transcorp.romhacking.net]TransCorp[/url] - Home of the Dual Orb 2, Cho Mahou Tairyku Wozz, and Emerald Dragon SFC/SNES translations.
[url=http://www.romhacking.net]ROMhacking.net[/url] - The central hub of the ROM hacking community.
[url=http://www.romhacking.net]ROMhacking.net[/url] - The central hub of the ROM hacking community.
I don't mess around with non-dx6 functionality in snes9x, no need to really.
But, in the currenty version of snes9x(tho there isn't a GUI option for it, set Use Hardware Video Memory to 1 in the registry). ddcaps is set like so:
and poof, bilinear filtering to everything that snes9x would write to its screen buffer.
But, in the currenty version of snes9x(tho there isn't a GUI option for it, set Use Hardware Video Memory to 1 in the registry). ddcaps is set like so:
Code: Select all
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY;
The D3D filters apply to textures and their mip-maps, and when you send a DrawPrimitive command where the source and dest are different sizes. The actual filtering code is part of the video card itself, so you can't add 2xsai/eagle here. 2xSAI and Eagle are software-based filters that are applied to the entire output image.Not to really go off topic, but I have a question about this. D3D has support for Bilinear, Anisotropic, Point, Gaussian, etc.. that can be set via the IDirect3DDevice9::SetSamplerState Method.
How would you handle adding something like the 2xSAI or Eagle filters?
Textures are designed to be loaded into video memory once, and stay there. A texture that changes every frame really shouldn't even be a texture, but a surface instead. For 2xsai, you'd want to render the image to a software buffer (no polygons or z-buffering unless you write the code to do it yourself from scratch), apply 2xsai/eagle to that, and then copy that image from your RAM buffer into the surface. The surface can preside in RAM or Video RAM. It is preferable to have the surface be in system RAM for this case, as accessing Video RAM is "slow as hell". Better to only send system->VRAM via a blit one time if possible.
As far as the idea of applying 2xsai/eagle to an image that uses DrawPrimitive and the like, I doubt it's possible. It may be, but as DrawPrimitive and SetTextureStageState commands are really just creating a list of commands between BeginScene and EndScene to render, you can't really grab the finalized image from VRAM, filter it, and then send it back to VRAM to display. At least not that I'm aware of.
I imagine you're using quad-based polygons to draw your current sprites in your 2d platformer. Try making that use CopyRect(s) instead, and render it all to a surface. There are plenty of APIs in the D3DX helper library to load BMPs as surfaces. You'll lose the ability to use diffuse colors and alpha keys this way, but you should still be able to use color keys for transparency. Once you've finished rendering the scene, lock the surface and get a pointer to it, then use 2xsai on that, and then copy the surface to the screen.
Ah yes, legacy DirectDraw. DDSCAPS_VIDEOMEMORY is the assumed default if you don't specify a different type (like DDSCAPS_SYSTEMMEMORY).ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY;
Basically, reading from/writing to video memory is a lot slower than via system memory. But in the case of snes9x/zsnes, you're only blitting a fully rendered screen into the DD surface one time, so there's virtually no performance loss (as a system RAM surface would have to be copied to video RAM as well, anyway).
And of course, the video ram->screen surface transfer will perform bilinear filtering on the image automatically. I find the effect annoying, as ATI/nVidia use really poor quality filters.
---
For what it's worth, there is no image quality benefit -at all- to using D3D/OpenGL/Glide/whatever over DirectDraw in SNES emulators!! The only thing that would even be possible would be copying the tiledata and sprites to VRAM (as textures or whatnot), which would make many SNES tricks impossible; such as HDMA effects, palette changes, etc.
The only thing any of these APIs can offer is cross-platform capabilities or crappy third-rate image filters when blitting to the screen. Since everyone likes the hqnx and 2xsai filters more anyway, all the arguments about this are pointless.
DirectDraw works fine on windows and requires minimal code, OpenGL works fine on linux. Either way, you're not getting any special advantages, so to the end user, it really doesn't matter what you use.
Actually there is a benefit to using D3D over DDraw. With D3D you can specify what type of filtering to do when you stretch the image fullscreen.
With D3D you tell it to stretch full screen and use point filtering(no filtering), and it also gives you options for bilinear or bicubic filtering(although I don't think current cards support bicubic). There's a reason why MAME is going to be switching over to D3D only in the future.
With D3D you tell it to stretch full screen and use point filtering(no filtering), and it also gives you options for bilinear or bicubic filtering(although I don't think current cards support bicubic). There's a reason why MAME is going to be switching over to D3D only in the future.
That's exactly what I said. Nearly everyone prefers hq2x/2xsai to the D3D filters, because the D3D ones are low quality. Filtering the image with hq2x only takes 10-20% at most of the total CPU power required by the emulator, compared to none for a lousy video card based bilinear filter.Actually there is a benefit to using D3D over DDraw. With D3D you can specify what type of filtering to do when you stretch the image fullscreen.
Here are the defined filter types:
D3DTEXF_NONE, D3DTEXF_POINT, D3DTEXF_LINEAR, D3DTEXF_ANISOTROPIC, D3DTEXF_PYRAMIDALQUAD, D3DTEXF_GAUSSIANQUAD
None and point are mostly the same (since point is a nearest neighbor algorithm anyway), and linear is bilinear filtering; which is the same as using a video memory blit with DirectDraw.
The rest of the filters are designed for 3d polygons only. Useless for SNES filtering. I've also not heard of a bicubic filter for D3D, but even if it had one, it wouldn't make much difference compared to bilinear.
Back to the point, though. Everyone thinks these different 3d acceleration APIs can be used to enhance/accelerate SNES graphics. They can't. It doesn't matter which one you use, you'll get nothing worthwhile out of it. If you really want to enhance SNES graphics, come up with a mode7 renderer that adapts to the current displayed resolution. That's about the only real noticeable difference you can make.
-
- Romhacking God
- Posts: 922
- Joined: Wed Jul 28, 2004 11:27 pm
- Contact:
Right.. the texture shouldn't change. My engine uses textured quads, but I only use one texture at the moment that contains ALL my tiles. It's say 256x256 containing 64 tiles(I'm obviously not using that many at this time). That's loaded as a texture once and stays put. I use texture transformation matricies to draw a 32x32 portion of the texture to a quad. It's really very efficient for doing 2d tiling in D3D. There is absolutely no locking of any video memory for any reasons aside from the initial load in my engine.byuusan wrote:The D3D filters apply to textures and their mip-maps, and when you send a DrawPrimitive command where the source and dest are different sizes. The actual filtering code is part of the video card itself, so you can't add 2xsai/eagle here. 2xSAI and Eagle are software-based filters that are applied to the entire output image.Not to really go off topic, but I have a question about this. D3D has support for Bilinear, Anisotropic, Point, Gaussian, etc.. that can be set via the IDirect3DDevice9::SetSamplerState Method.
How would you handle adding something like the 2xSAI or Eagle filters?
Textures are designed to be loaded into video memory once, and stay there. A texture that changes every frame really shouldn't even be a texture, but a surface instead. For 2xsai, you'd want to render the image to a software buffer (no polygons or z-buffering unless you write the code to do it yourself from scratch), apply 2xsai/eagle to that, and then copy that image from your RAM buffer into the surface. The surface can preside in RAM or Video RAM. It is preferable to have the surface be in system RAM for this case, as accessing Video RAM is "slow as hell". Better to only send system->VRAM via a blit one time if possible.
As far as the idea of applying 2xsai/eagle to an image that uses DrawPrimitive and the like, I doubt it's possible. It may be, but as DrawPrimitive and SetTextureStageState commands are really just creating a list of commands between BeginScene and EndScene to render, you can't really grab the finalized image from VRAM, filter it, and then send it back to VRAM to display. At least not that I'm aware of.
I imagine you're using quad-based polygons to draw your current sprites in your 2d platformer. Try making that use CopyRect(s) instead, and render it all to a surface. There are plenty of APIs in the D3DX helper library to load BMPs as surfaces. You'll lose the ability to use diffuse colors and alpha keys this way, but you should still be able to use color keys for transparency. Once you've finished rendering the scene, lock the surface and get a pointer to it, then use 2xsai on that, and then copy the surface to the screen.
I've been doing a little research. It turns out in D3D9 you can use all your draw primitives, and then get a handle to the backbuffer as a surface to mangle to your liking before presenting the scene. You could render your scene using your standard draw primitives and apply a filter to the final backbuffer. At least this is my understanding. I haven't actually tried it yet.
The drawback to this is you are forced to lock the backbuffer surface when applying the filter. I'm thinking this will cause noticable slowdown.. although.. the backbuffer is essentially locked when anything draws on it and this is only done once per frame.
You can actually also get a handle to the front buffer as well. The docs say this is the only way to get a screenshot of a final antialiased image.
Another way of implementing 2xSAI would be via a pixel shader according to some other people on the net. I don't know about using those though, so I can't validate that.
The more I read, the more things I find D3D can actually do.
Several PSX D3D plugins such as Pete's also apply the 2xSAI filter.
I'm not sure how they went about doing it.
Really.. the benefits of using D3D or OpenGL far outweigh the minor inconveniences of not using it. I would say ANY modern graphics venture should use one or the other(or something like SDL that uses it for you.) D3D can do anything DirectDraw can do and do it better in most cases.
[url=http://transcorp.romhacking.net]TransCorp[/url] - Home of the Dual Orb 2, Cho Mahou Tairyku Wozz, and Emerald Dragon SFC/SNES translations.
[url=http://www.romhacking.net]ROMhacking.net[/url] - The central hub of the ROM hacking community.
[url=http://www.romhacking.net]ROMhacking.net[/url] - The central hub of the ROM hacking community.
Re: Opengl for zsnes under win.
Back on topic, thanks I will merge your changes into the latest CVS.wah_wah_69 wrote:Hi I've added support for opengl in the win version of zsnes, thanks for the recent work related to mingw use.
I just adapted the linux gl code changing the gl_start/gl_end as needed, in the file winlink.cpp I changed the calls to drawscreen to gl_drawwin.
Gl_start is called in the initwinvideo function I left the directx code untouched as I don't know directx.
Bilinear filtering is on by default, if you change the resolution and/or filter function the picture of the game will be showed in a corner if the display is bigger and if the display is smaller the picture will not be completely shown (there are some vars to be updated when you change resolutions).
Speed? , well it seems to be slower than directx but as I said before I left the directx code untouched and just avoided calling drawscreen, I get ~86 fps while with the official build I get "A0" (100 fps , vsync is turned on).
So is there any use for opengl at all ?
The filter functions could be implemented with shaders (I've been told xmame already does this) , opengl could be used in mode 3 (I think snes9x already does it ).
I based my changes in a cvs checkout from saturday past week , I tried to checkout today and it seemed to be disabled for anon. users.
get it here:http://www.telefonica.net/web2/wahwah69/gl_zsnes.zip (includes both binary and sources)
Ah yes, DrawPrimitive renders to the backbuffer. However, you'd have to read the entire screen from VRAM, apply 2xsai, and then write it all back. Your application will bottleneck on RAM<>VRAM bandwidth. You'll get 10 frames per second doing this, regardless of CPU speed, if you're lucky.I've been doing a little research. It turns out in D3D9 you can use all your draw primitives, and then get a handle to the backbuffer as a surface to mangle to your liking before presenting the scene.
Check out those video playback screen capture programs. They're always extremely choppy, and they only read the video RAM. But that's about what kind of performance you can expect, even at 320x240x16bpp.
Locking the frontbuffer is possible, that's actually the one I was saying wasn't technically supported. The access to it is deprecated and they say you should never use it, but you can.
Not for SNES emulators. All you get is more filters, none of which are any good (nor better than the DDraw one). And D3D initialization/memory requirements are actually higher than DDraw. D3D in SNES emulators is like using a chainsaw to open a can of soup. Sure it works, but why go through all that trouble?Really.. the benefits of using D3D or OpenGL far outweigh the minor inconveniences of not using it. I would say ANY modern graphics venture should use one or the other(or something like SDL that uses it for you.) D3D can do anything DirectDraw can do and do it better in most cases.
To try and stay on topic, let's take the 2D game stuff to PM/email if you don't mind. If you'd like, I'll send you my D3D library, it comes with a sample RPG that does everything you'd expect an RPG to do and gets about 800fps on my low-end Radeon 7500. It's the result of several months of research into D3D on my part. Maybe it can give you some ideas for your platformer.
Do you realise that reading from video memory is very very slow?Nightcrawler wrote: I've been doing a little research. It turns out in D3D9 you can use all your draw primitives, and then get a handle to the backbuffer as a surface to mangle to your liking before presenting the scene. You could render your scene using your standard draw primitives and apply a filter to the final backbuffer. At least this is my understanding. I haven't actually tried it yet.
Re: Opengl for zsnes under win.
Why? It's slower that the current code.pagefault wrote: Back on topic, thanks I will merge your changes into the latest CVS.
MaxSt.
Though I sense sarcasim in this I'll say this:
While Glide would be a fast method to use in rendering on 3Dfx cards, they do have good performance with DirectX and also Glide does effect everything rendered. Glide forces fullscreen by default. There is no Windowing allowed.
While OpenGL would be a good choice of a rendering method the fact remains ZSnes doesn't really need it on the Windows port. The DirectDraw rendering method is fully functional on just about any card that will support DirectDraw in hardware which is roughly 99.9% of them. OpenGL support is however questionable among some graphics chip vendors. Some have full support, some have partial support, others have little or no support at all. This should be considered.
While Glide would be a fast method to use in rendering on 3Dfx cards, they do have good performance with DirectX and also Glide does effect everything rendered. Glide forces fullscreen by default. There is no Windowing allowed.
While OpenGL would be a good choice of a rendering method the fact remains ZSnes doesn't really need it on the Windows port. The DirectDraw rendering method is fully functional on just about any card that will support DirectDraw in hardware which is roughly 99.9% of them. OpenGL support is however questionable among some graphics chip vendors. Some have full support, some have partial support, others have little or no support at all. This should be considered.
No use for Opengl in 2D emulators?
Do you stll say that there is not even the tiniest little bit of use in Opengl support, Max?
http://vogons.zetafleet.com/viewtopic.php?t=8011Moe wrote: Uhm, well, actually there is.
It's sitting on my Harddisk.
I will post it soon, it does Hq2x (well, actually, Hq<any>x) entirely on the GPU, using a Radeon 9500/GeForce 5600 class card or better. It handles any scaling factor, including aspect ratio correction and non-integral numbers, though it will probably start to look bad at more than 16x scaling, and it is a bit questionable around 1x-1.2x scaling.
The look: gorgeous. Better than my current hq2x patch. The speed: impressive (I'm doing 320x200 -> 1280x800 with it), but on the above mentioned cards not fit for frameskip=0.
Do you stll say that there is not even the tiniest little bit of use in Opengl support, Max?
-
- ZSNES Developer
- Posts: 6747
- Joined: Tue Dec 28, 2004 6:47 am
Glide isn't that worthwhile to maintain... well, the Snes9x devs removed that code a while back. It's a dead end, and as you said, they have decent DX drivers (their OpenGL driver was still in its infant stages).While Glide would be a fast method to use in rendering on 3Dfx cards, they do have good performance with DirectX and also Glide does effect everything rendered. Glide forces fullscreen by default. There is no Windowing allowed.
If OpenGL was implemented better in ZSNES (or so I'm told).. it would be beneficial to have a 2nd (API) mode to support. OpenGL support is very lacking for some vendors for sure (I can't imagine integrated graphics having good OpenGL drivers). Though, the best way to get the most effective support is supported a reasonable lowest common denominator (whatever version of the OpenGL spec is best representative of what the emulator needs to render video and/ors its filters).While OpenGL would be a good choice of a rendering method the fact remains ZSnes doesn't really need it on the Windows port. The DirectDraw rendering method is fully functional on just about any card that will support DirectDraw in hardware which is roughly 99.9% of them. OpenGL support is however questionable among some graphics chip vendors. Some have full support, some have partial support, others have little or no support at all. This should be considered.
-
- Dark Wind
- Posts: 1271
- Joined: Thu Jul 29, 2004 8:58 pm
- Location: Texas
- Contact:
Actually Glide does provide for windowed rendering, at least on VSA-100 cards, it's just the drivers weren't finished.Deathlike2 wrote:While Glide would be a fast method to use in rendering on 3Dfx cards, they do have good performance with DirectX and also Glide does effect everything rendered. Glide forces fullscreen by default. There is no Windowing allowed.
I don't know if the latest drivers have this or not.
[u][url=http://bash.org/?577451]#577451[/url][/u]
-
- Dark Wind
- Posts: 1271
- Joined: Thu Jul 29, 2004 8:58 pm
- Location: Texas
- Contact:
Give me it. Now.bohdy wrote:No use for Opengl in 2D emulators?
http://vogons.zetafleet.com/viewtopic.php?t=8011Moe wrote: Uhm, well, actually there is.
It's sitting on my Harddisk.
I will post it soon, it does Hq2x (well, actually, Hq<any>x) entirely on the GPU, using a Radeon 9500/GeForce 5600 class card or better. It handles any scaling factor, including aspect ratio correction and non-integral numbers, though it will probably start to look bad at more than 16x scaling, and it is a bit questionable around 1x-1.2x scaling.
The look: gorgeous. Better than my current hq2x patch. The speed: impressive (I'm doing 320x200 -> 1280x800 with it), but on the above mentioned cards not fit for frameskip=0.
Do you stll say that there is not even the tiniest little bit of use in Opengl support, Max?
[u][url=http://bash.org/?577451]#577451[/url][/u]
The guy has his own implementation, which is not exactly an HQ algorithm.bohdy wrote:No use for Opengl in 2D emulators?
http://vogons.zetafleet.com/viewtopic.php?t=8011
Do you stll say that there is not even the tiniest little bit of use in Opengl support, Max?
If it "handles any scaling factor", it's not an HQ alrorithm.
Of maybe he means "hq2x + bilinear after that" for higher resolutions.
Which is not that exciting, because any decent CPU can handle hq2x easily.
MaxSt.
Its true that its not exactly your hq2x algo; the guy modified it to be "faster" (not sure it it is or not myself) for his original dosbox patch. He also added adaptivity to it to improve visual quality, so he seems to have a good understanding of it. Now I would guess he has modified it again for the fragment version. I doubt that it is just 2x+bilinear because he says it looks better.
When he posts it, you could try it yourself and make up your mind, although I would guess you would have some other nitpicks. You can be quite stubbornly negative you know that, Max?
When he posts it, you could try it yourself and make up your mind, although I would guess you would have some other nitpicks. You can be quite stubbornly negative you know that, Max?

Color comparison is just a small part of the algorithm.bohdy wrote:He also added adaptivity to it to improve visual quality, so he seems to have a good understanding of it.
Well, I'm sure it's 2x+bilinear. But we'll see.bohdy wrote:I doubt that it is just 2x+bilinear because he says it looks better.
I'm not stubbornly negative. I can change my position, but first I should see some evidence.bohdy wrote:You can be quite stubbornly negative you know that, Max?
MaxSt.
Re: Opengl for zsnes under win.
Because not all cards have the best directdraw support and in higher resolutions using 3d scaling works much faster than 2d on these cards. Plus it allows support of new filters that work on 3d hardware. Plus if someone has gone to the trouble of porting this code obviously there is demand for it.MaxSt wrote:Why? It's slower that the current code.pagefault wrote: Back on topic, thanks I will merge your changes into the latest CVS.
MaxSt.
-
- Romhacking God
- Posts: 922
- Joined: Wed Jul 28, 2004 11:27 pm
- Contact:
The backbuffer does not have to be in video memory.MaxSt wrote:Do you realise that reading from video memory is very very slow?Nightcrawler wrote: I've been doing a little research. It turns out in D3D9 you can use all your draw primitives, and then get a handle to the backbuffer as a surface to mangle to your liking before presenting the scene. You could render your scene using your standard draw primitives and apply a filter to the final backbuffer. At least this is my understanding. I haven't actually tried it yet.
[url=http://transcorp.romhacking.net]TransCorp[/url] - Home of the Dual Orb 2, Cho Mahou Tairyku Wozz, and Emerald Dragon SFC/SNES translations.
[url=http://www.romhacking.net]ROMhacking.net[/url] - The central hub of the ROM hacking community.
[url=http://www.romhacking.net]ROMhacking.net[/url] - The central hub of the ROM hacking community.
Re: Opengl for zsnes under win.
Quite the opposite.pagefault wrote:Because not all cards have the best directdraw support and in higher resolutions using 3d scaling works much faster than 2d on these cards.
DirectDraw - good support.
OpenGL - bad support.
There is no such thing.pagefault wrote:Plus it allows support of new filters that work on 3d hardware.
All currect hardware is limited to only 2 magnification filters - point filtering and bilinear filtering.
No other hardware magnification filters exist.
MaxSt.