Contents

Resource Management

A resource's description establishes how the application may use its storage. For example, a texture used as a render target, sampled by a shader, and copied back to the CPU needs the usage flags for all three operations. Memory placement determines CPU access, while synchronization and lifetime management determine when the data can be accessed or the storage released.

Resource usages

BufferUsages and TextureUsages are flag enums for declaring resource roles. Assign them to BufferDesc.Usages and TextureDesc.Usages, respectively. When a resource serves several roles, combine the required members with |.

Buffer usages

Usage Role
None No buffer usage flags are declared.
Vertex Vertex attributes fetched for drawing.
Index Indices used by indexed drawing.
Indirect Arguments read by indirect draw or dispatch commands.
Constant Shader parameters read through a constant-buffer binding.
StorageReadOnly Buffer data accessed through a read-only shader binding.
StorageReadWrite Buffer data accessed through a read/write shader binding.
TransferSrc Source data for a GPU copy.
TransferDst Destination storage for a GPU copy.

Texture usages

Usage Role
None No texture usage flags are declared.
Sampled Texture data read through a sampled-texture binding.
Storage Texture data accessed through a storage-texture binding for shader reads or writes.
ColorAttachment A color attachment in a render pass.
DepthStencilAttachment A depth/stencil attachment in a render pass.
TransferSrc Source image data for a GPU copy.
TransferDst Destination image storage for a GPU copy.

The transfer flags describe a resource's role as the source or destination of a GPU copy. Whether the CPU can access the storage directly is a separate memory-placement choice.

Usage flags declare the roles a texture may have. Moving between those roles requires the corresponding layout and synchronization, and its format must support the requested uses on the selected device.

CPU access and memory placement

The Residency field of BufferDesc specifies the intended CPU access to the allocation:

Residency Typical role Intended CPU access
GpuOnly Static geometry and GPU working data None
CpuReadOnly Readback data produced by the GPU Read-only
CpuWriteOnly Data supplied or updated by the CPU Write-only

Residency expresses CPU access requirements, including on systems where the CPU and GPU share physical memory. The triangle uses CpuWriteOnly to initialize its small vertex buffer directly. For larger static geometry, an upload into GPU-only storage may be more suitable.

Textures created directly through the context use GPU storage. TextureDesc therefore has no residency field; the application exchanges texture data with CPU memory through uploads and downloads.

For CPU-accessible buffers, Map() provides the address through which the CPU reads or writes data. Mapping and Unmap() do not wait for GPU work: the application must wait for a GPU write before reading its result, or for outstanding GPU accesses before modifying the same bytes.

Immediate and recorded transfers

Uploads copy CPU data into a GPU resource; downloads copy resource data into CPU memory. The methods on buffers and textures complete this transfer before returning:

Method Transfer behavior
Buffer.Upload Copies directly into mapped memory for CpuWriteOnly. Otherwise, submits the upload to the transfer queue and waits for it to finish.
Buffer.Download Copies directly from mapped memory for CpuReadOnly. Otherwise, submits the download to the transfer queue and waits for it to finish.
Texture.Upload / Texture.Download Submits the copy and its texture transitions to the graphics queue, then waits for completion. The selected subresource is left in the requested final layout.

Before calling these methods, resolve any conflicting accesses on other queues. A wait inside the method covers its own transfer; it does not establish a dependency on another queue. The direct mapped-memory paths rely entirely on the caller to wait for conflicting GPU accesses.

To submit transfers together with other GPU work, record them with CommandBuffer.Upload or CommandBuffer.Download. Upload sources and download destinations have different lifetime requirements:

  • During an upload call, the library copies the source data into temporary upload storage, called staging memory. The GPU later reads from this storage, so the application's source pointer is needed only until the call returns.
  • A download first copies GPU data into internal readback storage. The library then copies it to the supplied CPU destination when it reclaims the completed command buffer. Calling Wait() on the download's submission value completes both steps. Keep the destination allocated, and managed memory pinned, until that call returns.

For texture transfers, row stride is the byte distance between successive rows of CPU data; slice stride is the distance between successive depth slices. These values let the transfer copy the CPU data into or out of the texture's GPU storage. Synchronization explains why GPU completion and delivery to a download destination are separate steps.

Heap allocation

Use a Heap when the application needs to manage allocation itself. A heap provides storage in which resources are placed at explicit byte offsets; the application chooses those offsets and tracks the occupied regions.

For each resource, call context.GetSizeAndAlignment with the buffer or texture description that will be used to create it. Reserve the returned size at an offset that is a multiple of the returned alignment, within the heap's bounds and without overlapping another live allocation. Texture sizes may include backend-specific padding, so pixel count and bytes per pixel alone are insufficient to calculate their allocation size.

A buffer placed in a heap must specify the same residency as that heap. For texture storage, use a GPU-only heap.

Resources placed in a heap depend on its storage for their entire lifetime. After their final GPU use, release the resources before releasing the heap.

Views and backing resources

A BufferView describes a region of a buffer and how its data is interpreted. A TextureView selects a subresource range and a compatible texture type and format. Both refer to existing storage, with the usages declared when that storage was created. View ranges describe access; they do not provide consistent shader bounds checking across backends.

A resource's own handle provides its default view. Create a separate view to select a different region or compatible interpretation. Keep both the view and its backing resource alive until the GPU has finished using them; a resource handle does not retain either object. When replacing either one, update any constants containing the old resource handle.

Search documentation

Search tutorials, concepts, samples, and the API reference.