On 9/10/2018 at 11:19 PM, lawnjelly said:
At the risk of stating the obvious, and not mentioning any names, but some would say that the primary raison d'etre of some of these is precisely TO make cross platform development hard, and vendor lock-in both for developers and players. ![:) :)](https://uploads.gamedev.net/emoticons/medium.smile.webp)
Sorry to be blunt, but that's just conspiracy theory tin foil hat stuff.
On 9/10/2018 at 11:00 PM, elgun said:
OpenGL, Direct3D, GNM, LibGCM, OpenGLES, Vulkan, Mantle, Metal
Story time. Let's start at the start, with GL.
OpenGL is meant to be the "open"/"portable" API, but it's just terrible.
Seriously, who though that this was a good idea:
//Instead of:
void DoThing(int foo);
...
DoThing(42);
//We should have:
enum SlotType { PARAMETER_ONE }
namespace internal {
int g_parameterOne;
}
void BindSlot( SlotType );
void SetSlotValue( int );
void DoThing();
...
BindSlot(PARAMETER_ONE);
SetSlotValue(42);
DoThing();
If anyone ever did this kind of thing in an API ever again, they'd be slapped for such insanity. GL gets a pass because it grew out of 1980's supercomputers... and no one knew how to make a graphics API in the 80's, or what the future market for GPU's was even going to look like (originally -- a completely separate cluster of computers running over a network was probably more what they were thinking of!). Then after that ugly start, they just kept tacking more and more stuff onto that legacy for decades, mutating it into a horrible mess of conflicting ideas. It's an indefensibly bad, failure of an API, which is why we have others now. As a side note, when trying to bring GL to mobiles, it wasn't portable enough, so we got OpenGL|ES as a spin-off.
In the early days of Windows, a stupid company organisation issue / politics / schism meant that one team who wanted OpenGL, wasn't allowed to have it, so they bought out a different graphics company and re-branded their tech as D3D, and we ended up with two APIs on windows. GL was overseen by a committee who were constantly required to make stupid decisions because that's how committees work, while MS was able to be a "benevolent dictator" and completely rewrite D3D from scratch whenever they felt like it. By the time we got OpenGL v2.0 (which, incidentally, didn't actually throw out any of the v1.0 stuff!), we also had D3D v9 (that's a lot of rewrites!).
Game consoles were traditionally used by developers who were used to porting all their OS-level systems to new APIs, so they weren't demanding to use something like OpenGL everywhere. Game consoles also tend to be under-powered (if not at launch, then definitely at the end of their shelf-life), so devs prefer slim, efficient APIs rather than bloated portable ones.
Sony's PS3 API, GCM, was a very slim driver for NVidia's G71 architecture. It was incredibly low-level compared to PC API's at the time (D3D9, OpenGL2), and allowed developers to extract amazing efficiency out of that GPU. For example -- you can play GTA5 on a PS3, but there's no way you can possibly play GTA5 on a GeForce 7900GT (same chip). Microsoft responded to this low-level console API by modifying D3D9 into D3D9.x, which was based on the PC API, but slimmed down and massively extended into an unholy demon that powers the Xbox360.
We had the API war for a while - D3D9 vs GL2, D3D10 vs GL3, D3D11 vs GL4...
D3D11 was extremely mature and for a while, Microsoft was happy to say that it was going to be the final version of D3D (with just minor extensions added over time -- 11.1, 11.2, etc)... During this time Microsoft had been acting as the Quality Assurance mechanism on D3D drivers (shipped by Intel, NVidia, AMD), making sure that their drivers all behaved properly and implemented the D3D spec correctly. Meanwhile, GL's comittee had no such equivalent in the real world, so driver quality from Intel/AMD/NVidia varied greatly, including which features actually worked, which features were fast, and what shader code was allowed. To put on a tin foil hat, you could say that we actually had the different hardware companies trying to use game developers as pawns to damage each other's reputations -- e.g. NVidia would accept invalid shader code that they knew would (correctly) crash an AMD GPU, to make people think that AMD was buggy, when actually it was their competition playing dirty. Anyway, at this point it was pretty much accepted that D3D had beaten GL in the "API war" -- GL was now much more rarely used than D3D in big games, due to complexity, reliability, portability across hardware, driver issues, etc... D3D11 was the king.
Then a new generation of consoles came out, and as is their tradition, Sony created a new API, GNM, that was incredibly low-level compared to PC API's at the time (D3D11, OpenGL4) and was basically a very slim driver for AMD's GCN architecture. Again, Microsoft responded by creating another unholy demon -- D3D11.x, which powered the XboxOne. Side note: Because GNM is so low-level, they also created a wrapper around it called GNMX, which made it a lot closer to a D3D11 level of abstraction, making it easier to port games from D3D11 to PS4. Sony has also provided examples of wrappers around GCM/GNM that implement parts of GL|ES to help people who are trying to port mobile games to PS3/PS4.
Game studios who were enjoying these low-level APIs started petitioning for such a thing to exist on PC's. Microsoft again claimed that D3D11 was good enough for everyone, and Khronos (GL's committee) said that OpenGL5 could fill this gap and everyone laughed. Several big game studios worked with AMD to create Mantle, which was a proof-of-concept, low-level, cross-platform, cross-vendor (it was actually designed to be something that NV/Intel could implement, not just AMD-only) API for PC, proving that such a thing could be a good idea and work well enough to displace D3D11.
Microsoft immediately got to work designing D3D12 (as an answer to Mantle on PC, and D3D12.x to replace D3D11.x).
Apple immediately got to work designing Metal as a replacement for OpenGL / OpenGL|ES on their platforms, because GL is shit.
Khronos were still fiddling with OpenGL5 ideas so AMD dumped the Mantle spec in their laps and said "make this", so they did, and they renamed it Vulkan, after letting Intel/NVidia/Qualcomm/etc tweak the design slightly.
Mantle was very quickly retired, because it had served it's purpose of forcing change. It's gone now.
Metal was the first low-level API to be released in the mainstream, followed by D3D12, and finally Vulkan a year later.
So we end up with this situation where there's no clear winner. Depending on what platforms you care about, you might be able to pick a single API and use it on all your platforms, if you're lucky... But there's no true cross platform solution, so it's up to you to write your low-level rendering code in a portable style, where you can write multiple back-ends for different APIs.
Platform|Vulkan| GL | GLES | D3D | Metal | Custom |
PS3 | No | No | Emu* | No | No | Yes |
PS4 | No | No | Emu* | No | No | Yes |
Xb360 | No | No | No | Yes*| No | Yes |
XbOne | No | No | No | Yes*| No | Yes |
WiiU/Wii| No | No | No | No | No | Yes |
Switch | Yes | Yes | Yes | Emu | No | Yes | <- wow!
Windows | Yes | Yes | Emu | Yes | No | No |
Linux | Yes | Yes | Yes* | Emu | No | No |
Android | Yes | No | Yes | Emu | No | No |
MacOS | Emu | Old | Emu | Emu*| Yes | No |
iOS | Emu | No | Old | Emu*| Yes | No |
Custom = an API designed just for that platform. Old = Yes, but no longer updated/supported. Emu = some kind of emulated / translated support. * = important caveats / should almost be 'No' or 'Emu'.
On 9/10/2018 at 11:00 PM, elgun said:
Even shading languages are different. You must create source-to-source transpiler for solving this problem.
We used the exact same HLSL code on PS3 (GCM), Xb360 (D3D9), PS4 (GNM) and XbOne (D3D11).
Official support for using HLSL to write shaders for Vulkan exists now as a work-in-progress.
It's only OpenGL and Metal that require shader translation
On 9/10/2018 at 11:00 PM, elgun said:
This makes cross platform game development very hard. Because you must learn all of them, and create abstraction layer on top of them.
Use someone else's abstraction
I've worked in this role at a games company, and would estimate about two man-months to port a game to a new API, which is not that much money when it comes to the total development cost of a game.