Sign in to follow this  
Seabolt

Vulkan What are your opinions on DX12/Vulkan/Mantle?

Recommended Posts

https://github.com/boreal-games/magma

 

Decided to write my own comprehensive Mantle headers and loading library so I can use Mantle while waiting for Vulkan.  So far I've filled out [tt]mantle.h[/tt], [tt]mantleDbg.h[/tt], and [tt]mantleWsiWinExt.h[/tt].

 

There are a couple minor issues that I've discovered so far:

  • [tt]grWsiWinGetDisplays[/tt] thinks the output array you pass into it is zero-length
  • The Windows WSI error code values haven't been determined for the aforementioned reason
  • I could only get the functions working for the 64-bit DLLs so far, seems to be a calling convention issue

Over the next few days I'll be writing the other extensions, like the DMA queue extension.

Edited by Boreal Games

Share this post


Link to post
Share on other sites

otherwise I'll just end up adding the same amount of abstraction that DX11 does already, kind of defeating the point.

Porting such that your Direct3D 12 implementation mimics that of Direct3D 11 will leave you will 50% the final performance of Direct3D 11 on Direct3D 12. In other words, definitely do not model your graphics pipeline around that of Direct3D 11 inside Direct3D 12.
 
As for the porting itself, I rather enjoy it.  I am working on Metal right now, and you get a sense of pride each time you re-implement a part of the system in a stable and reliable manner while getting the same results as on every other platform.  I like having a single interface that produces the same results reliably across many API’s.
Naturally, I am an engine programmer, so your mental tolerance for this kind of low-level handling may vary.
 
 
L. Spiro Edited by L. Spiro

Share this post


Link to post
Share on other sites

Porting such that your Direct3D 12 implementation mimics that of Direct3D 11 will leave you will 50% the final performance of Direct3D 11 on Direct3D 12. In other words, definitely do not model your graphics pipeline around that of Direct3D 11 inside Direct3D 12.

It's obviously not ideal, but probably still better performance than just sticking with D3D11. MS showed off a naive port of Futuremark's engine, where there'd just shoe-horned D3D12 into their D3D11-oriented engine (by replacing their D3D11 redundant state removal / caching code with a D3D12 PSO hashmap) and still got ~2x the performance of the original D3D11 version.

Share this post


Link to post
Share on other sites
My numbers are coming from our naïve initial port of our engine for this demo (which did at least largely the same thing Futuremark claims they did):
http://www.rockpapershotgun.com/2015/05/05/square-enix-directx-12-tech-demo-witch-chapter-0-cry/

I don’t trust any company that says they got great performance just by shoehorning.


L. Spiro

Share this post


Link to post
Share on other sites

It is just me, or with this new APIs (at least with D3D12 and after you learned the new basis) writing code and implement things feels more natural and less artificial then older APIs with a higher level of abstraction? Yeah, it is not sill like writing general code that will run on the CPU only, but it feels kinda closer.. Or probably it is just because these API are shorter and you have to remember less calls and structures XD

Edited by Alessio1989

Share this post


Link to post
Share on other sites

It is just me, or with this new APIs (at least with D3D12 and after you learned the new basis) writing code and implement things feels more natural and less artificial then older APIs with a higher level of abstraction?

I agree. I think that's because there is less member and structures ; at least with OpenGL there are often several way to have the same result with very subtle difference.

For instance to create a buffer there are 2 functions, glBufferData and glBufferStorage, which can be used to upload data, and you have 1 function to upload data to a specific range (glBufferSubData), you have 2 functions to map the data (glMapBuffer and glMapBufferRange), there are 2 ways to define VAO (one that binds underlying storage and another one that split the vertex description and the buffer mapping), and so on...

 

With DX12 creation and upload are completly decoupled, there is a single mapping function. There is also an upload function but I never used it so far. It's much nicer.

 

The only "not so natural" things that may come from DX12 is that you need to avoid modifying resources when they are used by a command list. I do this by having dual command allocator and constant buffer that are swapped when a frame is finished.

Share this post


Link to post
Share on other sites

The only "not so natural" things that may come from DX12 is that you need to avoid modifying resources when they are used by a command list. I do this by having dual command allocator and constant buffer that are swapped when a frame is finished.

I find this to be a really natural change to, as it's just the result of being honest about parallel programming :)
All the old APIs have tried really hard to pretend that your grqphics code is single threaded - that your function calls have an immediate result.
In truth all CPU+GPU programming is "multithreaded", so an honest API should reflect that.
When using the old APIs, which hide these details, it's very easy to do horribly slow operations, like accidentally read from write-combined memory regions or synchronize the CPU/GPU to lock a resource. To use these old APIs effectively, you really had to actually know what was happening behind their lies and work with the reality -- e.g. this means that in D3D11 you should already be taking care to avoid modifying a resource that is in use! Lot's of engines already use double buffering or ring buffering on D3D11, which is much more natural now on D3D12.

I do this by having dual command allocator and constant buffer that are swapped when a frame is finished.

You are supposed to use signals.
Double buffering works fine, as long as you can guarantee that the gpu has finished the previous frame before the CPU begins using that buffer... Which requires the use of a signal, yeah :)

We use the same strategy on D3D9/D3D11 for transient vertex data - CPU writes into unsynchronized buffers (NOOVERWRITE flag), swapping which one is used per frame (or which range of the buffer is used each frame). The CPU then just has to wait on an event signalling that the GPU has finished the previous frame.

Share this post


Link to post
Share on other sites
You are supposed to use signals.


L. Spiro

 

Sure, I use signal to wait for frame N to be completed when frame N+1 last command list has been submitted.

I assume that it's still necessary to keep command queue filled so that gpu is always busy.

Share this post


Link to post
Share on other sites

I was just wondering, since game engines like DICE support already support mantle, wouldn't those engines be more likely to switch to Vulkan rather than DirectX 12, since Vulkan is based on Mantle?

Then, they would have a big competitive avantage over other games because they could run on Windows 7 and 8, and not just Windows 10. From the looks of it Vulkan seems to set to be released soon. Imagination Tech already has their GPUs working with Vulkan.

Edited by Ed Welch

Share this post


Link to post
Share on other sites

That's going to depend on the on-the-ground realities of driver and operating system support, when the dust finally settles. Remember, GL sounds like a great cross platform Direct3D killer on paper but doesn't live up to that in reality. We still don't know how Vulkan in real life will be. I expect that major engines, including DICE/Frostbite, will simply support both.

Edited by Promit

Share this post


Link to post
Share on other sites

Direct3D 12 is based on Mantle and some reports say it will replace it.
Vulcan may or may not be is based on (or rather inspired by) Mantle (couldn’t double-check while on my phone).


L. Spiro

Edited by L. Spiro

Share this post


Link to post
Share on other sites

Direct3D 12 is based on Mantle and some reports say it will replace it.
Vulcan may or may not be based on Mantle.


L. Spiro

 

There has never been any mention of D3D12 being based off of Mantle, nor did Microsoft ever make any statement about that. 

AMD however has stated that they provided Khronos with Mantle to use as a base, and from what I can see they pretty much did draw inspiration from it.

Share this post


Link to post
Share on other sites

There has never been any mention of D3D12 being based off of Mantle

“Based off” might be a slightly inaccurate choice of words (since I was just using the words he used), but no need to get pedantic.
http://www.extremetech.com/gaming/177407-microsoft-hints-that-directx-12-will-imitate-and-destroy-amds-mantle

“Imitate” and “inspired by” are words often used (same words used to describe Vulkan’s relationship with Mantle).


L. Spiro

Edited by L. Spiro

Share this post


Link to post
Share on other sites

That is indeed a much more reasonable way to look at it. 

 

I like to see it as AMD lighting a fire under both Microsoft and Krohnos's asses by showing them that developers do truly want and need new and better ways to interact with graphics hardware on PC. If you want to call that Microsoft being inspired by AMD that's totally valid, but the APIs themselves while sharing certain concepts (just like previous versions of DirectX and OpenGL shared concepts) are very very different.

Share this post


Link to post
Share on other sites

I like to see it as AMD lighting a fire under both Microsoft and Krohnos's asses by showing them that developers do truly want and need new and better ways to interact with graphics hardware on PC.

That’? how I see it.


L. Spiro

Share this post


Link to post
Share on other sites

I was just wondering, since game engines like DICE support already support mantle, wouldn't those engines be more likely to switch to Vulkan rather than DirectX 12, since Vulkan is based on Mantle?
Then, they would have a big competitive avantage over other games because they could run on Windows 7 and 8, and not just Windows 10. From the looks of it Vulkan seems to set to be released soon. Imagination Tech already has their GPUs working with Vulkan.

These guys already support half a dozen different APIs. It's cheap for them to internally support both (and then game teams can choose whether to ship both/either/neither based on practical realities at the time).

Also Dx12 isn't just Windows10; it's also Xbone. Console games likely make more money for EA than PC, so optimizing for Xbone is probably important to them.

Off the top of my head, the full list of current APIs (as in, there's a justification for using them for a product right now) is:
Dx9(PC), Dx9.x(360), GCM(Ps3), GNM(Ps4), GXM(PsVita), Dx11(PC), Dx11.x(Xbone), Dx12(PC), Dx12.x(Xbone), GL3(PC), GL4(PC), Mantle(PC), Vulkan(PC), GL|ES2(Mobile), GL|ES3(Mobile), Metal(iOS).
At this point, adding one item to that list seems like a small task! :lol:
[edit]..aaand I forgot Nintendo, add two more![/edit]

Direct3D 12 is based on Mantle and some reports say it will replace it.
Vulcan may or may not be is based on (or rather inspired by) Mantle (couldn’t double-check while on my phone).

Vulkan is very much Mantle derived. Lots of the example Vulkan code that's been shown off so far would compile perfectly fine under the Mantle SDK if you just replace the "vk" prefixes with "gr" :D
I'd go as far to say that Vulkan 1.0 will be thr first public release of Mantle! :lol:

Share this post


Link to post
Share on other sites

Just for laughs...

 

uGgcRYG.jpg

 

Don't know how much is old this page on Mantle manual, but the DX SDK page was there when I joined to the DX12 EAP on October 2014..

 

Anyway looking at the early private DX12 EAP docs the D3D12 API has changed a lot from it announcement to the current public version..

Edited by Alessio1989

Share this post


Link to post
Share on other sites


Don't know how much is old this page on Mantle manual, but the DX SDK page was there when I joined to the DX12 EAP on October 2014..

 

I'm in both the Mantle beta program and the DX12 EAP, the mantle documentation has been around for quite a bit longer as far as I'm aware.

Share this post


Link to post
Share on other sites

Apple has announced their upcoming OS X version El Capitan. Thought that it would be relevant to this thread, as it will bring support for their Metal API to OS X.

 

I have no details, but apparently there has been claims of 50 % improvement in performance and 40 % reduction in CPU usage.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this  

  • Forum Statistics

    • Total Topics
      628285
    • Total Posts
      2981837
  • Similar Content

    • By mellinoe
      Hi all,
      First time poster here, although I've been reading posts here for quite a while. This place has been invaluable for learning graphics programming -- thanks for a great resource!
      Right now, I'm working on a graphics abstraction layer for .NET which supports D3D11, Vulkan, and OpenGL at the moment. I have implemented most of my planned features already, and things are working well. Some remaining features that I am planning are Compute Shaders, and some flavor of read-write shader resources. At the moment, my shaders can just get simple read-only access to a uniform (or constant) buffer, a texture, or a sampler. Unfortunately, I'm having a tough time grasping the distinctions between all of the different kinds of read-write resources that are available. In D3D alone, there seem to be 5 or 6 different kinds of resources with similar but different characteristics. On top of that, I get the impression that some of them are more or less "obsoleted" by the newer kinds, and don't have much of a place in modern code. There seem to be a few pivots:
      The data source/destination (buffer or texture) Read-write or read-only Structured or unstructured (?) Ordered vs unordered (?) These are just my observations based on a lot of MSDN and OpenGL doc reading. For my library, I'm not interested in exposing every possibility to the user -- just trying to find a good "middle-ground" that can be represented cleanly across API's which is good enough for common scenarios.
      Can anyone give a sort of "overview" of the different options, and perhaps compare/contrast the concepts between Direct3D, OpenGL, and Vulkan? I'd also be very interested in hearing how other folks have abstracted these concepts in their libraries.
    • By GuyWithBeard
      Hi,
      In Vulkan you have render passes where you specify which attachments to render to and which to read from, and subpasses within the render pass which can depend on each other. If one subpass needs to finish before another can begin you specify that with a subpass dependency.
      In my engine I don't currently use subpasses as the concept of the "render pass" translates roughly to setting a render target and clearing it followed by a number of draw calls in DirectX, while there isn't really any good way to model subpasses in DX. Because of this, in Vulkan, my frame mostly consists of a number of render passes each with one subpass.
      My question is, do I have to specify dependencies between the render passes or is that needed only if you have multiple subpasses?
      In the Vulkan Programming Guide, chapter 13 it says: "In the example renderpass we set up in Chapter 7, we used a single subpass with no dependencies and a single set of outputs.”, which suggests that you only need dependencies between subpasses, not between render passes. However, the (excellent) tutorials at vulkan-tutorial.com have you creating a subpass dependency to "external subpasses" in the chapter on "Rendering and presentation", under "Subpass dependencies": https://vulkan-tutorial.com/Drawing_a_triangle/Drawing/Rendering_and_presentation even if they are using only one render pass with a single subpass.
      So, in short; If I have render pass A, with a single subpass, rendering to an attachment and render pass B, also with a single subpass, rendering to that same attachment, do I have to specify subpass dependencies between the two subpasses of the render passes, in order to make render pass A finish before B can begin, or are they handled implicitly by the fact that they belong to different render passes?
      Thanks!
    • By mark_braga
      I am looking at the SaschaWillems subpass example for getting some insight into subpass depdendencies but its hard to understand whats going on without any comments. Also there is not a lot of documentation on subpass dependencies overall.
      Looking at the code, I can see that user specifies the src subpass, dst subpass and src state, dst state. But there is no mention of which resource the dependency is on. Is a subpass dependency like a pipeline barrier. If yes, how does it issue the barrier? Is the pipeline barrier issued on all attachments in the subpass with the input src and dst access flags? Any explanation will really clear a lot of doubts on subpass dependencies.
      Thank you
    • By mark_braga
      I need to index into a texture array using indices which are not dynamically uniform. This works fine on NVIDIA chips but you can see the artifacts on AMD due to the wavefront problem. This means, a lot of pixel invocations get the wrong index value. I know you fix this by using NonUniformResourceIndex in hlsl. Is there an equivalent for Vulkan glsl?
      This is the shader code for reference. As you can see, index is an arbitrary value for each pixel and is not dynamically uniform. I fix this for hlsl by using NonUniformResourceIndex(index)
      layout(set = 0, binding = 0) uniform sampler textureSampler; layout(set = 0, binding = 1) uniform texture2D albedoMaps[256]; layout(location = 0) out vec4 oColor; void main() { uint index = calculate_arbitrary_texture_index(); vec2 texCoord = calculate_texcoord(); vec4 albedo = texture(sampler2D(albedoMaps[index], textureSampler), texCoord); oColor = albedo; } Thank you
    • By Mercesa
      As the title says, I am explicitly creating a too small descriptor pool, which should NOT support the resources I am going to allocate from it.
       
      std::array<vk::DescriptorPoolSize, 3> type_count; // Initialize our pool with these values type_count[0].type = vk::DescriptorType::eCombinedImageSampler; type_count[0].descriptorCount = 0; type_count[1].type = vk::DescriptorType::eSampler; type_count[1].descriptorCount = 0; type_count[2].type = vk::DescriptorType::eUniformBuffer; type_count[2].descriptorCount = 0; vk::DescriptorPoolCreateInfo createInfo = vk::DescriptorPoolCreateInfo() .setPNext(nullptr) .setMaxSets(iMaxSets) .setPoolSizeCount(type_count.size()) .setPPoolSizes(type_count.data()); pool = aDevice.createDescriptorPool(createInfo);  
      I have an allocation function which looks like this, I am allocating a uniform, image-combined sampler and a regular sampler. Though if my pool is empty this should not work?
      vk::DescriptorSetAllocateInfo alloc_info[1] = {}; alloc_info[0].pNext = NULL; alloc_info[0].setDescriptorPool(pool); alloc_info[0].setDescriptorSetCount(iNumToAllocate); alloc_info[0].setPSetLayouts(&iDescriptorLayouts); std::vector<vk::DescriptorSet> tDescriptors; tDescriptors.resize(iNumToAllocate); iDevice.allocateDescriptorSets(alloc_info, tDescriptors.data());  
  • Popular Now