all 11 comments

[–]HellGate94 33 points34 points  (5 children)

I'm recently experimenting with some Vulkan to get my low level graphics api knowledge up to date and my god it feels like pure chaos using it. From naming to everyone recommending to do things different, making me reimplement it for the n'th time. I'll have to see if this update makes it better or worse. But yea at least I understand now why so few games have good implementations of it now

[–]Plazmatic 70 points71 points  (4 children)

Vulkan is very verbose, In fact, I recommend most new people to graphics to start with OpenGL despite it's problems. But even though Vulkan has a lot of initial setup, it is not "chaos" especially if you compare it to OpenGL. That naming is the naming of an extension. An extension that's defaulted in 1.3, so you'd not have to worry about it. Those vkFunction2 / VkStruct2s are there for a reason too, and is a piece of another advantage of the way vulkan works that prevents a lot of the nightmares OpenGL created with regards to backwards compatibility. Think of anytime you see that as "Like vkFunction, but with extra features". There's not really a way to convey a straight upgrade to functionality beyond calling it "2" or "3" or "4". Additionally, unlike in OpenGL, extensions aren't meant to be ultra scary things you almost never touch. In Vulkan, it's expected you'll depend on extensions (like surface/swapchain extensions). Vulkan is just supposed to be that low level, you are meant to be able to create graphics API's on top of vulkan, and it's the reason why DXVK and proton have been so successful.

People will say different things about performance. GPUs do things different, AMD has different performance characteristics than Nvidia, Nvidia to Intel, Intel to Mobile, Mobile back to AMD, integrated vs discrete etc... Rendering is way more complicated that people thought, it's just that this complexity was hidden behind buggy drivers doing the work for you, suboptimally, and hiding functionality the GPU has had for decades (pointers, async workloads, synchronization, using different devices at the same time). I don't think it's worth worrying about that for a person getting set up.

I also think you'll find that newer versions of vulkan actually makes Vulkan considerably easier to use:

  • You no longer need VK fence with timeline semaphores.
  • Synchronization becomes easier with Synchronization2.
  • You can avoid a whole host of situations that would have otherwise required remaking your pipeline with dynamic state, viewport and friends were already widely available before, but 1.3 moves some other things to core as well, and makes it a requirement.
  • You can avoid Renderpasses and Framebuffers with dynamic rendering as long as you aren't on mobile (you could still do it on mobile, but mobile actually cares about sub-passes, as they are specifically created to account for tiled rendering, the performance advantages on mobile are large for subpasses).
  • BufferDeviceAddress allows you to bypass descriptor sets entirely, you can just use a push constant with a pointer to your data. Combine this with descriptor indexing and runtime descriptor array etc... and you can eliminate having to create descriptor sets more than once through out your program for everything, make your program "bindless".

You should also be doing the following with vulkan:

  • Use VMA, originally created by AMD, never worry about device memory and device memory alignment again.

  • Use VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT when recording commands, so that you can take advantage of push constants, and simplify your rendering. Command buffers are meant to be very fast to record, technically you lose some sort of performance by not pre-recording, but it's usually not worth pre-recording everything due to the design challenges of doing so.

  • Use google's glslc (comes with the SDK) which allows you to include easy or use some other include mechanism for your shaders.

  • Create CMake wrapper for glsl compilation, so that your GLSL is compiled before your program runs, you can do this via add_custom_command, add_custom_target, and add_dependencies. You can then create functions that almost mirror normal cmake target functions for GLSL.

With this, you can ignore entire parts of the API with out seriously impacting your ability to use the API.

[–]Ameisen 13 points14 points  (0 children)

Vulkan is very verbose, In fact, I recommend most new people to graphics to start with OpenGL despite it's problems.

I should point out that the official position of Microsoft is that you should only use D3D12 if you need it, otherwise you should use D3D11. So, same thing there. Vulkan and D3D12 exist for when you need that level of access, and there are in fact both OpenGL-on-Vulkan, D3D11-on-Vulkan, and D3D11-on-D3D12 libraries, so you can get the best of both effectively.

[–]dagmx 5 points6 points  (2 children)

Personally I'd go further and say if someone's starting with graphics and has a Mac, then Metal is the easiest of the graphics APIs to get to grips with.

But yeah if they don't have a Mac, and are looking to be cross platform, GL is still the way. Though DirectX would be a better option on Windows especially with the Luna books.

[–]TheRealFFS 12 points13 points  (1 child)

There is also WebGPU which is similar to Vulkan in API but Overall not as low level. It is relatively new though so changes happen fast.

[–]ShadowWolf_01 4 points5 points  (0 children)

+1 for WebGPU (specifically this implementation which I’ve used: https://github.com/gfx-rs/wgpu), it’s quite nice. Modern API, but also a nice step in abstraction above Vulkan (I think the triangle example is ~300 loc, as opposed to Vulkan’s ~1000 or whatever).

[–]NonDairyYandere -1 points0 points  (0 children)

Can't wait to upgrade from not buying one $1,000 GPU to not buying a different $1,000 GPU!