Skip to main content
GameDev.net gamedev.net
Using GameDev.net for your class this semester?
Learn more →
🔒 Locked

Depth Testing

Started by Calin Feb 18 at 1:58 PM 25 replies 2.1k views
Original Post
Calin
Calin

What goes into the formula if you want to add Depth Testing to your scene?

I took a snippet of code from the Depth Testing tutorial in the DirectX SDK and placed it in another tutorial hopping it will enable Depth Testing. Adding the code didn't produce the expected result. This is the code snipped is question

// Create depth stencil texture
   D3D10_TEXTURE2D_DESC descDepth;
   descDepth.Width = width;
   descDepth.Height = height;
   descDepth.MipLevels = 1;
   descDepth.ArraySize = 1;
   descDepth.Format = DXGI_FORMAT_D32_FLOAT;
   descDepth.SampleDesc.Count = 1;
   descDepth.SampleDesc.Quality = 0;
   descDepth.Usage = D3D10_USAGE_DEFAULT;
   descDepth.BindFlags = D3D10_BIND_DEPTH_STENCIL;
   descDepth.CPUAccessFlags = 0;
   descDepth.MiscFlags = 0;
   hr = g_pd3dDevice->CreateTexture2D(&descDepth, NULL, &g_pDepthStencil);
   if (FAILED(hr))
       return hr;
   // Create the depth stencil view
   D3D10_DEPTH_STENCIL_VIEW_DESC descDSV;
   descDSV.Format = descDepth.Format;
   descDSV.ViewDimension = D3D10_DSV_DIMENSION_TEXTURE2D;
   descDSV.Texture2D.MipSlice = 0;
   hr = g_pd3dDevice->CreateDepthStencilView(g_pDepthStencil, &descDSV, &g_pDepthStencilView);
   if (FAILED(hr))
       return hr;

   //g_pd3dDevice->OMSetRenderTargets( 1, &g_pRenderTargetView, NULL );
   g_pd3dDevice->OMSetRenderTargets(1, &g_pRenderTargetView, g_pDepthStencilView);

Do I have to change other things as well?

Without depth testing the scene looks like this, obviously incorrect perspective

After adding the snippet it looks like this

I can get the grid of boxes displayed with a correct perspective if I edit and add the grid to the tutorial with basic animations (the one that uses depth testing) but the tutorial has so many variables and parameters I can't figure out what's different, what else is required to get to work in the other tutorials.

My project`s facebook page is “DreamLand Page”
JoeJ
JoeJ
glEnable(GL_DEPTH_TEST);

Done.

It's never too late to break free ;D

RmbRT
RmbRT

@JoeJ Sick pwn.

But since Windows is becoming more and more unbearable, and windows games get more and more stable emulation on linux via Proton, and since Windows supports OpenGL anyway, might as well use that. The ratio of people playing games via Linux will only increase in the next few years, so you might as well drop the dedicated Windows-only renderer from the game, and just write the portable OpenGL renderer that will make your game run everywhere. GL 4.6 is superior to DX anyway. Forgot what exactly it was, but I just remember some DX folks were jealous of some GL 4.6 feature that was super helpful. And beyond that, everyone uses Vulkan anyway.

Walk with God.
taby
taby

To be fair, D3D 12 has hardware support for ray/path tracing, which is not trivial to move over to OpenGL 4.x.

JoeJ
JoeJ

taby said:
To be fair, D3D 12 has hardware support for ray/path tracing, which is not trivial to move over to OpenGL 4.x.

Path tracing is not a HW feature, but just an algorithm to simulate real world lighting using ray tracing. (Journalists constantly get this wrong, thus i wanna mention.)

However, the list is much longer afaik:

Ray tracing
Mesh shaders
Variable rate shading
Work graphs
Upscaling and frame generation provided by GPU vendors

Afaik, you don't get any of these latest features from high level APIs such as DX11 or OpenGL.
(NV does provides extensions for mesh shaders for example, but i guess neither AMD nor Intel follows)
Which is why i would not recommend to use high level APIs for games at all. They are abandoned, receive no more optimizations from driver devs, and will at some point just die out. Which is sad but true.

But as said in Calins blog post, i have recommended OpenGL 1.x to him specifically because:
It still runs and will continue to do so for a decade or more.
It is by far the simplest way to draw basic stuff, because it has an ‘immediate mode’. (Maybe some ancient DirectX had this too, but afaik it no longer runs on modern OS.)
He does not care about graphics or related optimization, and he has no assets either. He only wants to visualize RTS units and maps for work on AI, and OpenGL 1 is perfect for that, imo.

Though, he worked with DirectX before, so likely he wants to stick at that.

EDIT:

OpenGL 1 really is just a graphics API,
while all the newer options are mainly APIs to communicate with GPUs efficiently, coming at the price of ‘annoying’ complexity.

JoeJ
JoeJ

RmbRT said:
GL 4.6 is superior to DX anyway.

I doubt this, mainly because DX11 has support for CPU multithreading, afaik.
Though, neither DX11 nor OpenGL have multiple GPU queues, so async compute isn't possible with either, afaik.

RmbRT
RmbRT

JoeJ said:

RmbRT said:
GL 4.6 is superior to DX anyway.

I doubt this, mainly because DX11 has support for CPU multithreading, afaik.
Though, neither DX11 nor OpenGL have multiple GPU queues, so async compute isn't possible with either, afaik.

But when you have indirect render, why do you need multiple CPU threads? When your entire game renders in one drawcall, who cares what thread that came from?

JoeJ said:
But as said in Calins blog post, i have recommended OpenGL 1.x to him specifically because: It still runs and will continue to do so for a decade or more. It is by far the simplest way to draw basic stuff, because it has an ‘immediate mode’. (Maybe some ancient DirectX had this too, but afaik it no longer runs on modern OS.) He does not care about graphics or related optimization, and he has no assets either. He only wants to visualize RTS units and maps for work on AI, and OpenGL 1 is perfect for that, imo.

Immediate mode rendering is still a dominant use case of graphics anyway. GUI is usually rendered that way, etc. That's why GL_STREAM_DRAW exists even in later GL versions. 2D games are also mostly immediate-mode rendered.

Walk with God.
taby
taby

Did you forget that I wrote my own path tracer from scratch? Yes, due to its reliance on ray tracing, it is inherently hardware accelerated.

JoeJ
JoeJ

RmbRT said:
But when you have indirect render, why do you need multiple CPU threads? When your entire game renders in one drawcall, who cares what thread that came from?

That's true, yes.
Imo, MT rendering is only need by those not competent at GPU driven, but i don't wanna say that loud. Doom 2016 was an example of an efficient MT engine, for example.

taby said:
Did you forget that I wrote my own path tracer from scratch?

No, but still there is no need to mention path tracing in context of lacking GPU HW features context, since only the ray tracing building block has acceleration.
The term is now completely abused by marketing, and generally misunderstood by the public since ‘realtime path tracing’ is around (which rarely looks like actual path tracing at all).
Sorry for the nitpicking.

RmbRT
RmbRT

Skyrim ran on OpenGL 3.3-era hardware. I haven't yet seen an indie make a game that looks better than Skyrim, so why would an indie need more GPU features than Skyrim? And they already get free perf via the GPU-driven rendering functionality and compute shaders that Skyrim couldn't even use. And hardware that is over a decade newer, so more powerful.

Raytracing / pathtracing is not needed for games, and since it requires vendor-specific HW features & data structures, it's just a pain. Once there is a new HW vendor with a different acceleration structure or something in HW, your game no longer runs on that new HW vendor. So your code is forever locked to GPUs with that specific HW mechanism to achieve the same feature. You're locking down your game to a specific hardware, which I think is dumb.

VRS is a crutch for when you can't write a pixel shader that you can afford once per pixel… so it's a programmer problem IMO. Upscaling and frame gen is also a cheap crutch for when you are unable to build a game that just runs smoothly at 1080p. Again, a programmer problem.

Mesh shaders and Work graphs I don't know enough about. Mesh shaders sound like they'd be neat as an opt-in feature to increase graphical details, but I think not having them should not be game-breaking. So I think they're probably alright or even neat, but definitely not essential. Work graphs sound like manual execution scheduling?

Also regarding OpenGL extensions for non-standard features: Often, one vendor gets the extension officially ratified and then other vendors go and implement the same extension which officially carries that other vendor's name. The name of the extension does not mean that it is only for that HW vendor, or the absence of a vendor-specific extension name doesn't mean that vendor doesn't expose that feature. I think I saw extensions for mesh shaders and for raytracing on my steam deck (AMD GPU) via glxinfo, but I might be misremembering.

P.S.: I had another thought on multithreaded rendering. If you already use CPU-driven rendering, it would most likely be faster to serialise the draw calls into one or more buffers on the application side anyway, and then have one thread go over those command buffers and issue those in one tight loop. Even if you only use one thread, it should be faster than directly calling into GL, since you get worse branch prediction and worse out-of-order execution and all that. You can generate those command buffers in multiple threads if you want, and then have one thread suck up all the branch misses and other overhead that comes from the GL calls, without that also affecting the work done between the GL calls. Again, even on one core and one thread, that approach should already be faster and more SIMD-friendly, etc.. And with multiple threads preparing those command buffers, you get even faster. And then you end up limited purely by how many draw calls you can issue from the main thread per frame, without having to account for the actual logic cost that goes into preparing the arguments for those draw calls.

Function calls generally aren't as OOO-friendly as linear code, even if they have no branches. If you have a tight loop of only the stuff that generates the rendering commands, without actually issuing them, then that loop achieves much higher efficiency, less register pressure, etc. Also, most applications call into GL via function pointers loaded from static variables, so you get guaranteed branch mispredicts on those calls. A process that bakes a command buffer could instead generate fully baked JIT code that already contains the final call address.

Walk with God.
JoeJ
JoeJ

RmbRT said:
I haven't yet seen an indie make a game that looks better than Skyrim

Totally subjective. It's the opposite to me. Skyrim looks terrible to me, and most indie UE4 games looked way better.

RmbRT said:
And they already get free perf via the GPU-driven rendering functionality and compute shaders

It's not for free.
E.g., you want Web support so you need your engine to work with out those features.
You will also have content which works fine with that restricted feature set.

You are ambitious to make a second branch to support newer features and low level API as well,
which will be a lot of work, basically a second engine entirely, doing everything different.
But for the game you already have it will show little or no benefit, since it already runs fine with the restricted engine.

So chances are you'll decide to work on something else instead, or you do it for a future game with richer content, eventually dropping support for web / old HW at this point.

I bet a beer this is what will happen… ; )

RmbRT said:
Raytracing / pathtracing is not needed for games, and since it requires vendor-specific HW features & data structures, it's just a pain.

It's not your problem the data structures are vendor specific, all vendors support the same APIs.

Your problem is actually that you have no access to those data structures at all.
It's our data, so it should be specified at least by vendor extensions, so we can modify it if needed, or use it for some other things as well.
Spatial acceleration structures are generally useful, but the amateur API designers at Microsoft did not think about that, and they did not realize their blackboxing made fine grained LOD for RT completely impossible either.
DXR API is the biggest failure in history of GPUs. All they did was adopting NVs Optix API, following classic offline rendering usecases and not asking any devs for feedback before it was too late.

Maybe RT is too expensive to be that useful for games, but the real reason it's almost useless is a lack of any flexibility exposed by APIs.
Well, at least NV has learned a lesson and they expose enough extensions to support Nanite now, so assuming other adopt this too, the situation bight become acceptable in a distant future. But i'm sure only the newest GPU will get those extensions, so i do not regret having not bought any RT GPU yet, since it's all just garbage til yet. >:(

RmbRT said:
VRS is a crutch for when you can't write a pixel shader that you can afford once per pixel… so it's a programmer problem IMO. Upscaling and frame gen is also a cheap crutch for when you are unable to build a game that just runs smoothly at 1080p. Again, a programmer problem.

Which programmers? You mean those few left, but all working just for Epic?

Current 'game devs' are not responsible for any gfx progress / optimization / innovation anymore. That's all Epics or Nvidias job.

No wonder everybody thinks game devs are lazy and fail at their job. It's probably true.

RmbRT said:
Mesh shaders sound like they'd be neat as an opt-in feature to increase graphical details, but I think not having them should not be game-breaking.

Yep. I don't know any game which requires mesh shaders, since you can do anything it does with the old pipelines too.
It's certainly not a game changer at all, but surely a nice feature.

Regarding VRR, it only makes sense for forward pixel shaders afaict.
For deferred compute shading i could just implement the feature myself easily, so maybe it's a bit of a marketing gag.
But i might be wrong, having mostly ignored it.

RmbRT said:
I think I saw extensions for mesh shaders and for raytracing on my steam deck (AMD GPU) via glxinfo, but I might be misremembering.

There are RT extensions for OGL? I did not know that.

RmbRT
RmbRT

JoeJ said:
It's not for free. E.g., you want Web support so you need your engine to work with out those features. You will also have content which works fine with that restricted feature set.

Of course. I was talking about all the other people out there who are not targeting web compatibility. Those people can rely on the availability of lots of goodies like GPU-driven rendering, etc. Which is free performance compared to CPU-driven, for those use cases, without having to do anything super obscure.

JoeJ said:
But for the game you already have it will show little or no benefit, since it already runs fine with the restricted engine.

So chances are you'll decide to work on something else instead, or you do it for a future game with richer content, eventually dropping support for web / old HW at this point.

I bet a beer this is what will happen… ; )

I'm not taking that bet because I also think that's exactly how it will go. Maybe if I end up making millions and no longer have any need to do profitable work ever again, I'll get around to making a vulkan backend so my game runs at 1000FPS or something on the latest flagship dGPU. But at that point, I'd rather build an OS.

JoeJ said:
Which programmers? You mean those few left, but all working just for Epic?

Those working for Epic, and those in the Engine department at game studios that just outsourced the responsibility to those Epic programmers (pun intended ;)).

JoeJ said:
a marketing gag

Yeah, I think it's pretty useless. You already get VRR with MSAA, at least inside triangles. And you don't want VRR across triangle edges anyway. You could easily take a half-width, 2x MSAA rendered image and simply use its subsamples as actual pixels of a VRR rendered image. Anyway, just make your game run fast and then you don't need this obscure feature. I'm 100% certain this is just a band-aid because of all the bad choices made beforehand.

JoeJ said:
There are RT extensions for OGL? I did not know that.

GL_EXT_raytracing. Also, mesh shaders are also officially supported via: GL_EXT_mesh_shader. There are tons of funky extensions to OpenGL, like GL_INTEL_blackhole_render (also supported on my AMD iGPU).

Walk with God.
JoeJ
JoeJ

Ha, wow. Then i agree OGL is superior to DX11. \:D/

Industry people mostly hate the Khronos 'extension hell', saying it's not robust and subject of driver bugs / inconsistent support.
But i think it's the right way.

RmbRT
RmbRT

The only thing that makes OpenGL bad is that it is too chatty in its API, and still has the 1990's GPU HW architecture as the mental model of how to talk to GPUs. The bindless variants for the API that came later on are a good step forward. But the general philosophy of having a high level API that lets you describe what you want to achieve, which only covers the essential and easy to implement functionality, and then having more advanced functionality behind an extension, gives a lot of freedom to HW manufacturers and driver authors. For example GL will never have mandatory AI upscaling as a HW feature. You'd need an extension to access that functionality. Which means a core GL compliant GPU is not forced to have that. Neither would you need raytracing circuitry on a GL4.6 compliant GPU. But you could add it, and then it could be accessed through the GL extension. Meanwhile, for all perpituity, DX12+ compliant GPUs will need raytracing HW support.

Exposing too many specifics in the core standard may be great for targeting latest gen HW directly, but once the trend in HW design shifts, all those specifics in the specs will introduce terrible friction. The friction of GL is not because it is abstract, but because it still targets specifics of how 90's GPUs were built, with the global VAO an the texture units and all that. But the high-levelness of GL is actually its one saving virtue.

And yes, it is uncomfortable to not be certain whether an end user has a certain HW / driver feature (see this tutorial I made as an example of how annoying heterogeneous hardware is). But if you simply use DX12 and force HW raytracing support, then of course you know the end user has that feature. But you also just massively cut down on the potential number of end users. You could also simply use OpenGL and insist on using the raytracing extension, and simply refuse to launch at all if it is not supported. Same thing. If there was a similarly abstract API for conveying to the GPU what and how to render, without constraining the GPU's architecture, and also being less chatty than OpenGL (although again, with GPU-driven, that's no longer much of an issue), then you'd have the ideal graphics API that can talk to low end and high end GPUs and progressively opt into more features via standardised extensions. And the driver or backend for that API can decide how a specifc GPU can get the requested work done the best. If you want to get specific, then you also want to know the actual hardware you are targeting, and probably want to use a vendor-specific API for just that architecture by that one vendor. I don't think it makes sense to have something that is vendor-agnostic, but also highly specific (and therefore constraining how the GPU is allowed to solve the task) like Vulkan. Rather than Vulkan, I'd like to have a better OpenGL, plus vendor-specific implementations using their native APIs.

GPU-driven is great, but only if you can guarantee that the HW supports it. But even GL2 or GL3 could benefit from a better designed API with equivalent functionality, which could cut down on the application-side friction and driver-side friction by a lot. Which of course would require rewriting the drivers and the user applications, but no change in the HW would be needed.

And such a “clean GL” could still be emulated via regular GL on systems without direct driver support, and you could still emulate regular GL through that “clean GL” by simply having a compatibility layer between those APIs. Just like how GL drivers are nowadays using Vulkan under the hood.

Also, the driver bugs in GL vs. DX is because those vendors just don't care about GL as much as they do about DX. Probably also a financial incentive to be correctly DX compliant, but no financial incentive to be GL compliant.

Walk with God.
JoeJ
JoeJ

RmbRT said:
Rather than Vulkan, I'd like to have a better OpenGL, plus vendor-specific implementations using their native APIs.

The first API i had used was Glide from 3dfx. It was super simple, even simpler than OGL 1.

Out of curiosity i have also read the specs of AMDs Mantle API, which caused both DX12 and VK to happen.
And that's very simple too, although it had more features as well. Great features which would help me a lot.

So an interesting idea would be to go back to vendor APIs instead trying for a general but compromised and complicated API for all.
If there would be only NV and AMD, i would certainly prefer that.
But there is Intel and now Qualcomm too, which is too much.

I do not believe in a modern high level API like you do. You propose vendor implementations of building blocks, but you don't know which building blocks are needed to back future innovations, so this is as short termed as the current low level APIs might be.
I guess we have to deal with it, which is ok.

But what's not ok is that GPUs are not easily available to general purpose programming. There is Cuda, but it's vendor locked. There is OpenCL, but it was killed from the boycott of that same vendor.
So while every computer has some GPU, it's used almost only for games, which is a shame for the whole tech industry.

Anyway, i expect big changes. I would not wonder if in few years it's Chinese companies who dictate tech and APIs, and maybe Europe decides to build our own chips too, beside the weapons. Breaking some US monopols might turn out a good thing, who knows.

RmbRT
RmbRT

JoeJ said:
but you don't know which building blocks are needed to back future innovations

I don't need to know. I want an API that lets me render triangles, lines and points, manage vertex buffers and textures, etc., with programmable shaders. That's the absolute basics of graphics and it gets 99% of the job done. The core API should be conservative in what features it offers, so that it is highly portable and lightweight to implement, and it should make sure that driver implementations will be very lightweight and efficient, too. Then, vendors can propose extensions to the standard, which will be accessible via an extension querying system or something. That includes stuff like mesh shaders, raytracing, whatever else you might need. So that you can get 100% of the job done in a HW-agnostic manner with that API, with as little design-wise friction as possible. When someone innovates the HW, then maybe more of the workload shifts away from the core feature set and into the extensions, so be it. Not a problem. This API is there to get good performance on a wide range of HW.

And then if you want a very device-specific optimised build, you directly use the HW manufacturer's API. Most applications should be able to get by without vendor-specific builds, even most games. And if your game really wants to squeeze every last % of efficiency out of a specific HW generation, you should ship per-device builds anyway. Just like you might want to ship CPU-specific builds that utilise some ISA extension that just one vendor supports or something, which might require a restructuring of data types for that to work best, etc.. Once you ship builds that explicitly target a specific hardware, then having high level APIs just prevents you from telling the machine what to do exactly. And since you are already going through the efforts of shipping a HW-specific build, you should already know exactly what is best. This is when the ability to issue detailed instructions is important.

But when you explcitly don't know what the HW is exactly and what exactly is the best way for it to get the work done, then high level APIs are best. Which is when you write generic code that should run well everywhere that you haven't yet written a targeted optimised build for. So the aim of a general / vendor-agnostic API should be to easily get the job done, and to leave as much of the specifics of what exactly the HW does to achieve the work, up to the driver author. But it should never aim to replace vendor-specific APIs.

When working with a specific vendor & HW gen in mind, then you can architect the entire program around specifics of that hardware. Such as choosing the parameters of an algorithm so that on a specific architecture, you get maximum occupancy, or that you optimise to fit within a certain number of registers, or when you start counting cycles & throughput and execution ports and all that, and design your formulas/algorithms around those.

Ideally, though, the general API would let you write select parts of the program using a vendor-specific API, so that you don't have to rewrite everything for every optimised build. Just like HW-specific inline-assembly in an #ifdef, without having to write the entire program in HW-specific assembly. It should not be that hard to design an API that fulfills all these goals. I'm certain I could come up with a fairly good design for that high-level API (or at least better than OpenGL), as the weak points of OpenGL are fairly obvious after 30 years of legacy cruft.

JoeJ said:
general purpose programming

They were able to make C run on devices that were way more heterogeneous than GPUs are nowadays. No uniform register size, not even uniform byte size, non-uniform address size, function pointers aren't even guaranteed to be the same size as data pointers. Yet they managed to make such a language. Making the C of GPGPUs is basically just a matter of whether you get access to all the device specs so that you can roll your own assembler for all those devices. But since the GPU vendors love locking you into using their proprietary tech stacks, that's probably not going to happen. But for example Cuda on the surface is generic enough to also be implemented on other GPUs. As long as it isn't illegal to build a different backend for it. But then it's no longer a technical problem, but a legal problem.

Anyway, I would put GPGPU functionality as separate from the graphics API, although maybe so that a GPGPU framework can also interact with the graphics API and vice-versa. Wouldn't be too hard to pull off.

JoeJ said:
and maybe Europe decides to build our own chips too

I'd welcome more heterogeneous competition on the HW side. But hopefully, they don't have to compete on who fits a badly designed API the best. I want to see vendor-specific, open and transparent APIs, so that I can without much trouble build my own competitor to OpenGL, where I just have to use their vendor-specific library to build a backend for my library.

I guess my roadmap just changed to making my own clean version of GL, which maps to GL without too much friction, to then making a minimal linux distro that runs that, to then giving it vendor-specific implementations or maybe doing a vulkan implementation first, and then looking at completing my ISA & compiler and making my own FPGA hardware. Or maybe the compiler stuff comes some time earlier along the way. And of course the game comes before the distro, or I'll go broke.

Walk with God.
SBD
SBD

@Calin

This page gives you a rundown of how you configure depth/stencil testing:

https://learn.microsoft.com/en-us/windows/win32/direct3d11/d3d10-graphics-programming-guide-depth-stencil

Two things you may be missing;

You need to create and bind the depth render state:

CreateDepthStencilState(...)
OMSetDepthStencilState(...)

You need to clear the depth buffer every frame before rendering:

ClearDepthStencilView(...);
JoeJ
JoeJ

RmbRT said:
Making the C of GPGPUs is basically just a matter of…

OpenCL already does use the C language, even supporting pointers, so this already exists.
It's not enough, though. You need to add some keywords to sync thread execution and memory. All APIs do this the exact same way.

What's missing / different across APIs is global control flow, since ‘shaders’ or ‘kernels’ are always only one function. But we need to call many functions in order, reading former results from VRAM and writing new results to VRAM as well for the next function call.
All APIs support to call a functions from CPU, synchronizing the wait until all results are in memory, then calling the next function.
Problem: Often the amount of work needed to be done depends on former results, so we need to download this result to CPU just to call the next function. But synchronizing CPU / GPU this way is slow, which is the primary problem.

Indirect dispatch addresses this by allowing to write and read the work size to GPU buffers, so the CPU does not need to know it.

The next step (VK/DX12) was command buffers / lists, which allow to prerecord all required function calls and memory barriers to GPU memory. So the CPU no longer needs to call many functions in order, but rather just one call to let the GPU processing the whole pipeline.

That's pretty good. But the problem is: You need to prerecord all potential calls and barriers which can happen, but often the worksize for a call is zero, so time is wasted on overhead and memory barriers which are not needed. I guess i have about 100 such cases per frame in the GI system.
Mantle allowed to skip over parts in the command list.
VK got a similar feature later called conditional draws. But while those ‘draws’ can include compute dispatches too, the feature does not allow to skip memory barriers, so it's useless. Idk why such things happen. Either the API designers are idiots or some HW vendor could not support the required features (which is unlikely, since they could just execute the barriers silently if so).
DX12 has similar features but the same problem - no conditional barriers.

So that's a good example to illustrate what's the problem with general API design. It seems the designers are not able to figure out what functionality is essential in time, or they can't agree on them, and they release rushed and broken APIs.
Then it takes 10 years until they extend the APIs to solve the problem, but only partially, adding just bloat and complexity.
After another 10 years somebody like AMD manages to push a true solution, which i think Work Graphs finally is, but it's supported on only the very latest GPUs of all vendors.
So it takes another 10 years until we can put in on min specs.

That's the problem with APIs. Not which language they use for shaders, or how nice and clean or simple the API feels.
I guess if you would design an API, you would forget some essential stuff too, causing the same mess.

RmbRT said:
Anyway, I would put GPGPU functionality as separate from the graphics API,

There we have it. Your API is already useless.

Gfx and GP must be handled by the same API, so we can control which async GP stuff executes in parallel to lightweight rendering work such as rendering shadow maps for example.

There already is interop for OpenGL with CUDA/OpenCL, but this does not give you any control over such optimizations.
Low level APIs properly solve this with multiple GPU queues and cross synchronization between them.

Beside the rant, those low level APIs are pretty good, and i don't see how they could make it much easier.
Making it easier via abstractions is our job, i'm afraid. So you can make your own OGL style API on top of VK, but you don't need vendor APIs for that. Afaik, nvapi only exists because DX lacks extensions. For VK NV just releases extensions like other vendors do as well.

RmbRT said:
I'd welcome more heterogeneous competition on the HW side.

Well, afaik Europes most ‘modern’ chip fab is in Germany, and they can make 45 nm chips.
We have a long way to go until we need to worry about competition at all… <: )

RmbRT
RmbRT

JoeJ said:
There we have it. Your API is already useless.

For doing anything other than graphics, yes. It is intentionally incomplete in scope. But if there is a GPGPU framework that can natively integrate with the GL, such as by offering opportunities to hook external general compute calls into the command buffer, or exposing GL memory to such a general compute framework, then you can use any compute framework you want to access the internals of the graphics, without the GL having to also fulfill the role of nailing a GPGPU API specification as well. So the GPGPU specs/framework can evolve independently from the GL specs, but there is a reliable interface between them that lets you call out to the GPGPU, or to expose your memory to it, or maybe also to let the GPGPU inject memory into the GL. Wouldn't be hard to put into the GL specs. And then you could use CUDA, or OpenCL or anything else and hook it up to the GL.

JoeJ said:
There already is interop for OpenGL with CUDA/OpenCL, but this does not give you any control over such optimizations. Low level APIs properly solve this with multiple GPU queues and cross synchronization between them.

That's because the integration between those is too coarse. The GL needs to be intentionally designed so that it can integrate well with other foreign workloads on the GPU. Such as including scheduling primitives, passing memory access, etc. But OpenGL wasn't made to offer that interface to other things on the GPU, so you can't do it well with OpenGL. Other stuff like Vulkan probably lets you do it well because it has all these required concepts like synchronisation and memory management built in.

JoeJ said:
Making it easier via abstractions is our job, i'm afraid. So you can make your own OGL style API on top of VK, but you don't need vendor APIs for that.

Yeah, I figure VK is sufficient. But I think vendor-specific APIs might allow me to do an even better job than with VK. Not that I seriously plan to do all that back-breaking work anytime soon. I got way more interesting projects lined up that will probably already be too large for me. One example where the vendor API would be superior, though, is as you mentioned in the ability to conditionally skip workloads, including synchronisation barriers, which VK does not offer.

JoeJ said:
Idk why such things happen. Either the API designers are idiots or some HW vendor could not support the required features (which is unlikely, since they could just execute the barriers silently if so).

The HW vendors also push useless HW features that nobody wants. They are not game developers nor trying to program actually useful software. They're trying to sell shiny HW with proprietary features so that you get forced to buy their HW to use the software you own, because that software relies on proprietary HW features. At no point do they have an incentive to create a useful open system that is vendor-agnostic and will basically make all GPUs interchangeable. And they also do not have an incentive to make your life easier as a developer.

JoeJ said:
That's the problem with APIs. Not which language they use for shaders, or how nice and clean or simple the API feels. I guess if you would design an API, you would forget some essential stuff too, causing the same mess.

Yeah I'd also make mistakes, which is why core spec revisions exist. But I can use GL as a reference and all the known mistakes it made, and at least not make those mistakes again. Which would already be a net improvement. Also, by “the C of GPGPU” I didn't mean letting literal C run on GPGPUs. That's dumb. I meant, a lingua franca of GPGPUs which lets me access all the features that they have in common, such as all the problems you noted, and all the things you want to instruct the GPU with. You'd have language constructs for stuff like per-execution ifs vs. per-group ifs (“if any” or “if all”, basically), you'd have barriers, you'd have stuff for controlling the work group size or what it's called, indirect dispatch functionality, etc. All right in the language. Then you could start to actually write complete GPGPU programs in a vendor-agnostic way.

Walk with God.
JoeJ
JoeJ

RmbRT said:
then you can use any compute framework you want to access the internals of the graphics, without the GL having to also fulfill the role of nailing a GPGPU API specification as well.

Makes little sense, because if you have a gfx API with shaders, dispatch and sync, you already have everything you need to expose compute too, which you need for modern gfx anyway.

It's true that Cuda or OpenCL 2 have some more features than compute via gfx API, but then the proper solution is to add those features to the gfx api as well. (Eventually Work Graphs give us feature parity again, but i still did not read up the specs.)

Splitting gfx and compute APIs really makes no sense for game dev. Remembering OGL+OCL interop it's just hacky patchwork which did not even work as specified in many cases.

It would be nice if we could write GPGPU stuff with some future C++ revision, to make GPU more accessible and code maintainable. But that's another topic. For game engine runtime i would still use compute shaders.

RmbRT said:
The HW vendors also push useless HW features that nobody wants.

Agreed, but this does not explain API design failures which just hurt anybody across all involved industries.
But well, mistakes just happen, and it's not a larger number of them.

RmbRT said:
Then you could start to actually write complete GPGPU programs in a vendor-agnostic way.

Yeah, it would not be any difficult at all. And we already have it: OpenCL. But nobody used it, so it died.
Cuda was to much of a success, and companies preferred to depend on NV over porting their code to an open standard.
This way NV could afford to boycott OpenCL 2 on consumer HW (although Quadro drivers had support), to give it a death stab.
Finally OpenCL 3 was a step back, making new features (device side enqueue) of version 2 optional, without introducing new features.
So NV proudly announced to support (parts of) version 3, since at this point it was clear it's dead and no more competition to Cuda.

Btw, Microsoft tried it too with AMP, but i guess you never heard about this API, since nobody cared about it.

At this point my only hope is including GPGPU support to C++ itself. Any other attempt won't see adoption.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.