Abstracting (DX12/NewAPI) Resource Transitions

The new generation of low-level rendering APIs introduced the concept of “Resource Transitions“: The API user is responsible for keeping track how a memory resource is used and make explicit transitions in the command-list. Most common example: Use a texture as rendertarget and vice versa.
(This is definitely true for DirectX12 and Mantle, but I do not know for sure about the upcoming Vulkan-API… although it would surprise me if they handle it differently)

How to handle this concept in a render abstraction?

  • No abstraction, pass burden of transition to user
    • Pro:
      • Highlevel renderer should know best, most resources don’t need any transition anyways
      • Zero extra overhead
      • If something goes wrong, the debug layer should be able to do the hard validation work
    • Con:
      • Tedious to keep track
      • May want to implement automatism anyway
      • Error prone: Old APIs don’t care, debug layer of new API might miss something
  • Go single-threaded and record resource usage (always only one)
    • Pro
      • Trivial way to remove all resource transitions from userland
    • Con
      • Defeats an important point of the new APIs!
  • Create extra command lists at submission to fill in unknown transitions
    • Excellent explanation here
    • Pro
      • Fully automatic and still multi-threaded, no locks
    • Con
      • Requires two levels of resource state tracking
      • Need to create command lists on the fly (or pre-cached) – how costly is that?
  • Record command lists multi-threaded in custom data structure without sending any commands to the API. When all lists are ready, missing resource transition infos can be propagated. Only then the API-side command lists are generated
    • Has anybody tried that?
    • Pro
      • Manual recording needs may be necessary to emulate multi-threading with old APIs anyway
    • Con
      • Requires multiple threading barriers
      • Two step recording introduces a lot of overhead

In DirectX12 resource transitions are a special form of Resource Barriers.
Resource barriers in general were already in place in the old APIs, e.g. the infamous glMemoryBarrier. A common usage example are unordered access views, where the question weather caches need to be flushed or not depends entirely on the shader operating on it (usage example here). None of the discussed approaches is able to abstract such UAV Barriers entirely away, without generating too many of them. More or less the same goes for Aliasing Barriers (different resources on the same memory).


For the ClearSight project I am torn between the “no abstraction” and the “command list fill-in” which sounds reasonable to me (and hey, a guy on the official DX12 edu channel told us about it!). Automating the process or resource transitions sounds very attractive is probably a must-have for every serious render-abstraction. However, I don’t think it is trivial to implement in a robust and fast fashion. And as I mentioned it cannot abstract all resource barriers.

So for now I will just pass the burden to the user. I am curious how much extra work this actually means to the implementer of a high level rendering pipeline. I suspect that it should be fairly simple since most transitions are made deliberately. Assuming the API debug layer catches all missing transitions, it should also make it easier to see where unnecessary overhead was introduced:
An automatic system may fill in all transitions, but does not report where the graphics programmer did not intend to perform transitions.

Advertisements

DirectX12 Overview Diagram

I made an overview diagram of the most important parts of Direct3D12 and how they work together. Most notably missing are Bundles. Making this diagram helped me to get an better overview and how things are interconnected.

If you find any mistakes or have ideas to enhance it I will gladly improve it Posted Image.

dx12 overview v1

First steps with Direct3D12

Background & Motivation

The last few months I was pretty busy with my master’s thesis, which was a OpenGL 4.5 based project. Now that I’m on free foot again, it is time to try something new. I have some experience in D3D11 but its been a while.

Since there are already a lot of useful resources, I won’t write a full “First Triangle” tutorial but rather link to others. This post just sums up my first steps & insights. Maybe its useful for someone else too.

Preparation & Prerequisites:

  • Windows 10
  • Visual Studio 2015
    • There is a free Community Edition
  • Windows 10 SDK (not included in Visual Studio!)
  • A driver that supports DX12
    • Nvidia: Fermi or newer
    • AMD: GCN 1.0 or newer
    • Intel: Haswell or newer
    • if you have a Fermi+IvyBridge “Optimus” combination like my laptop, you are out of luck. Looks like there is no way to get it running >.<

What’s New, Overview

Scrapped from here and some other places where I found things that were especially interesting to me.

  • The new lowlevel API itself.
    • There is no Map/Lock-Discard and SubResource anymore! It is like using D3D11’s NO_OVERWRITE or OpenGL4.5 persistent mapping all the time. That means you need to pipeline updates yourself.
    • No reference counting for actual memory, only for interfaces.
    • There is only one large state object that contains everything: The Pipeline State Object (PSO)
    • Command Lists that are submited to the GPU instead of (one or more) immediate or deferred contexts
    • “Bundles” allow to record certain commands a bit like Display Lists in old OpenGL
    • …………..
  • It is finally possible to perform asynchronous readbacks
  • A few new hardware features, exposed as well in DX11.3
  • There is an open source header with C++ helper structs. Its called d3dx12.h but has not much in common with the good old D3DX from the DX9 days. You can find such functionallity in github repos like DirectXTex

Pitfalls

Porting to Direct3D12 might be hard and does not guarantee that your application will run faster. Aras gave recently a talk about the issues you might encounter (siggraph15). Accordingly, its like porting from loose constants to constant buffers – you need a lot more “global” information about your rendering process.

External Resources

Here are some useful links to get started:

I have an overview diagram of D3D12 in the making and will publish it as soon as I have a bit more experience. Stay tuned! Posted Image