UAV Counters

You can use unordered-access-view (UAV) counters to associate a 32-bit atomic counter with an unordered-access-view (UAV).

Differences in UAV counters from Direct3D 11 to Direct3D 12

Direct3D 12 apps and Direct3D 11 apps both use the same high-level shader language (HLSL) shader functions to access the UAV counters.

  • IncrementCounter
  • DecrementCounter
  • Append
  • Consume

Direct3D 12

In Direct3D 12, the 32-bit values are allocated by the application, so the 32-bit values can be read and written by either the CPU or the GPU, just like any other Direct3D 12 resource.

Direct3D 11

Outside of the shaders, with Direct3D 11 you need to call API methods in order to access the counters (for example, ID3D11DeviceContext::CopyStructureCount).

Using UAV counters

Your app is responsible for allocating 32-bits of storage for UAV counters. This storage can be allocated in a different resource as the one that contains data accessible via the UAV.

Refer to CreateUnorderedAccessView, D3D12_BUFFER_UAV_FLAGS and D3D12_BUFFER_UAV.

If pCounterResource is specified in the call to CreateUnorderedAccessView, then there is a counter associated with the UAV. In this case:

  • StructureByteStride must be greater than zero
  • Format must be DXGI_FORMAT_UNKNOWN
  • The RAW flag must not be set
  • Both of the resources must be buffers
  • CounterOffsetInBytes must be a multiple of 4 bytes
  • CounterOffsetInBytes must be within the range of the counter resource
  • pDesc cannot be NULL
  • pResource cannot be NULL

And note the following use cases:

  • If pCounterResource is not specified, then CounterOffsetInBytes must be 0.
  • If the RAW flag is set then the format must be DXGI_FORMAT_R32_TYPELESS and the UAV resource must be a buffer.
  • If pCounterResource is not set, then CounterOffsetInBytes must be 0.
  • If the RAW flag is not set and StructureByteStride = 0, then the format must be a valid UAV format.

Direct3D 12 removes the distinction between append and counter UAVs (although the distinction still exists in HLSL bytecode).

The core runtime will validate these restrictions inside of CreateUnorderedAccessView.

During Draw/Dispatch, the counter resource must be in the state D3D12_RESOURCE_STATE_UNORDERED_ACCESS. Also, within a single Draw/Dispatch call, it is invalid for an application to access the same 32-bit memory location via two separate UAV counters. The debug layer will issue errors if either of these is detected.

There are no "SetUnorderedAccessViewCounterValue" or "CopyStructureCount" methods because apps can simply copy data to and from the counter value directly.

Dynamic indexing of UAVs with counters is supported.

If a shader attempts to access the counter of a UAV that does not have an associated counter, then the debug layer will issue a warning, and a GPU page fault will occur causing the apps’s device to be removed.

UAV counters are supported in all heap types (default, upload, readback).