Differences with Direct3D 11 resources
Resources in D3D12 are similar to resources in D3D11, although there are a couple of differences:
Resource updates in D3D11 is done through the
ID3D11DeviceContext, meaning it is updated at the point in the command list where
UpdateSubresource is called. In D3D12,
UpdateSubresource is part of
ID3D12Resource, and is updated directly. This has synchronization implications elaborated upon in the Synchronization chapter.
Resource states are no longer handled implicitly. Frequently depth buffers and other resources have different layouts optimal for depth testing, and for sampling in a shader for eg shadow mapping. In Direct3D 11, this was done implicitly in order to ensure the layout was in the proper layout for the current usage. In Direct3D 12, these transitions are not handled implicitly, meaning the resources may either be in a suboptimal or invalid layout for the current purpose when not transitioned properly. This is done to allow the user to avoid redundant transitions, and to reduce load on the driver to deduce when resource transitions are to occur.
In Direct3D 11, limited device memory was for the most part managed by the runtime. When device memory started to run out, resource data would be migrated to main memory in order to prevent device memory from completely running out. In Direct3D 12 on the other hand, all memory the application uses is to be managed by the application. Every application gets a certain memory budget and will need to maneuver within this memory budget. While more memory can be requested using the
SetVideoMemoryReservation function of
IDXGIAdapter3, the OS may not be able to grant the requested amount of memory.
In order to maneuver within this memory budget, the
ID3D12Device interface contains the
MakeResident functions, allowing committed resources and heaps to be made unavailable for the GPU, thus removing the resources from device local memory. The evicted data is written to disk, and when calling
MakeResident all data is recovered.
In addition to creating resources manually, Direct3D 12 offers the ability to create a heap, where resources are created in the heap. This allows multiple resources to have close to one another, overlap resource memory, and to evict multiple resources at the same time when device memory becomes scarce.
A resource barrier is an object that allows the application can be used for the following:
- Transitioning resource layouts, ensuring the format is compatible with the next use of the resource
- Specifying aliasing between two resources. When two resources point to the same piece of memory, this barrier is to be used to make sure both resources use the last updated data
- Ensuring UAV accesses are visible to the next command in the list. When a draw call is performing UAV writes, these UAV writes may not have completed before the next call. This barrier is heavily encouraged when using UAVs, as the results can be very random and very different on a per platform basis when not handled properly.