ExecuteTileMappings provides GPU-driven tile mapping. The GPU or CPU can
write tile mapping commands into a GPU-accessible argument buffer, which is
later executed on a dedicated tile mapping queue between
ExecuteCommandLists submissions.
The operation resembles ID3D12CommandQueue::UpdateTileMappings, but is
batched across multiple source tile pools and destination reserved resources.
The input is a token-based command stream that can be generated by application
shaders or CPU code without a command signature.
The application sizes, allocates, manages, and can reuse the input buffers. Each mapping token refers to application-selected indices in registered tile pool and reserved-resource layout tables.
ExecuteTileMappings requires Tiled Resources Tier 5. Tier 5 is a superset of
Tiers 1 through 4 and adds ExecuteTileMappings support.
Two creation-time flags determine whether a reserved resource or heap is
eligible for ExecuteTileMappings:
D3D12_RESOURCE_FLAG_ALLOW_EXECUTE_TILE_MAPPINGS makes a reserved resource
eligible only for ExecuteTileMappings. A resource created with this flag
cannot be used with UpdateTileMappings or CopyTileMappings. A reserved
resource created without this flag cannot be registered for
ExecuteTileMappings.D3D12_HEAP_FLAG_ALLOW_EXECUTE_TILE_MAPPINGS makes a heap eligible only for
ExecuteTileMappings. A heap created with this flag cannot be used with
UpdateTileMappings. A heap created without this flag cannot be registered
for ExecuteTileMappings.The heap flag does not prevent the heap from being used for placed resources.
typedef enum D3D12_RESOURCE_FLAGS
{
// Existing values omitted.
D3D12_RESOURCE_FLAG_ALLOW_EXECUTE_TILE_MAPPINGS = 0x1000,
} D3D12_RESOURCE_FLAGS;
typedef enum D3D12_HEAP_FLAGS
{
// Existing values omitted.
D3D12_HEAP_FLAG_ALLOW_EXECUTE_TILE_MAPPINGS = 0x8000,
} D3D12_HEAP_FLAGS;
Every mapping token occupies eight DWORDs. TokenType identifies the token
layout, MappingType identifies how source tiles are selected, and
SubresourceIndex selects the destination subresource.
typedef enum D3D12_EXECUTETILEMAPPINGS_TOKEN_TYPES : UINT
{
D3D12_EXECUTETILEMAPPINGS_TOKEN_TYPE_NO_OPERATION = 1,
D3D12_EXECUTETILEMAPPINGS_TOKEN_TYPE_LINEAR_MAPPING = 128,
D3D12_EXECUTETILEMAPPINGS_TOKEN_TYPE_BOX_MAPPING = 129,
} D3D12_EXECUTETILEMAPPINGS_TOKEN_TYPES;
struct D3D12_EXECUTETILEMAPPINGS_MAPPING_TOKEN_HEADER
{
UINT TokenType : 8;
UINT MappingType : 8;
UINT SubresourceIndex : 16;
};
typedef enum D3D12_EXECUTETILEMAPPINGS_MAPPING_TYPES
{
D3D12_EXECUTETILEMAPPINGS_MAPPING_TYPE_INCREMENTING_TILE_INDICES = 0,
D3D12_EXECUTETILEMAPPINGS_MAPPING_TYPE_NULL = 1,
D3D12_EXECUTETILEMAPPINGS_MAPPING_TYPE_SKIP = 2,
D3D12_EXECUTETILEMAPPINGS_MAPPING_TYPE_REUSE_SINGLE_TILE = 3,
D3D12_EXECUTETILEMAPPINGS_MAPPING_TYPE_TILE_INDEX_LIST = 4,
} D3D12_EXECUTETILEMAPPINGS_MAPPING_TYPES;
struct D3D12_EXECUTETILEMAPPINGS_LINEAR_MAPPING_TOKEN
{
D3D12_EXECUTETILEMAPPINGS_MAPPING_TOKEN_HEADER Header;
UINT TilePoolBaseOffsetInTiles;
UINT SubresourceBaseOffsetInTiles;
UINT TileCount;
UINT _Padding;
UINT TilePoolLayoutIndex;
UINT ResourceLayoutIndex;
UINT TileListOffsetDwords;
};
struct D3D12_EXECUTETILEMAPPINGS_BOX_MAPPING_TOKEN
{
D3D12_EXECUTETILEMAPPINGS_MAPPING_TOKEN_HEADER Header;
UINT TilePoolBaseOffsetInTiles;
UINT16 X;
UINT16 Y;
UINT16 Z;
UINT16 Width;
UINT16 Height;
UINT16 Depth;
UINT TilePoolLayoutIndex;
UINT ResourceLayoutIndex;
UINT TileListOffsetDwords;
};
typedef enum D3D12_FEATURE
{
// Existing values omitted.
D3D12_FEATURE_EXECUTE_TILE_MAPPINGS,
} D3D12_FEATURE;
typedef struct D3D12_FEATURE_DATA_EXECUTE_TILE_MAPPINGS
{
UINT NodeIndex;
UINT MaxTilePoolLayoutIndexCount;
UINT MaxResourceLayoutIndexCount;
} D3D12_FEATURE_DATA_EXECUTE_TILE_MAPPINGS;
Applications query D3D12_FEATURE_EXECUTE_TILE_MAPPINGS through
ID3D12Device::CheckFeatureSupport. NodeIndex selects a D3D12 node and must
be less than ID3D12Device::GetNodeCount.
The returned maximums are the number of tile pool and reserved-resource layout slots supported for the selected node. On a supported node, both values are greater than zero. On an unsupported node, both values are zero.
The values are per physical adapter and are not aggregated across linked adapter members.
The query does not allocate or resize either table and returns the same hardware maximums for the lifetime of the device.
typedef enum D3D12_EXECUTE_TILE_MAPPINGS_FLAGS
{
D3D12_EXECUTE_TILE_MAPPINGS_FLAG_NONE = 0,
} D3D12_EXECUTE_TILE_MAPPINGS_FLAGS;
interface ID3D12TileMappingQueue : public ID3D12Pageable
{
void ExecuteTileMappings(
UINT MaxArgumentDwordCount,
ID3D12Resource* pArgumentBuffer,
UINT64 ArgumentBufferOffset,
_In_opt_ ID3D12Resource* pCountBuffer,
UINT64 CountBufferOffset,
_In_opt_ ID3D12Resource* pTileListBuffer,
UINT64 TileListBufferOffset,
D3D12_EXECUTE_TILE_MAPPINGS_FLAGS Flags);
HRESULT Signal(
ID3D12Fence* pFence,
UINT64 Value);
HRESULT Wait(
ID3D12Fence* pFence,
UINT64 Value);
};
Each initialized physical adapter has one dedicated tile mapping queue.
interface ID3D12DeviceN : ID3D12DeviceNm1
{
HRESULT GetTileMappingQueue(
UINT NodeIndex,
REFIID riid,
void** ppQueue);
HRESULT InitializeExecuteTileMappingLayoutTables(
UINT NodeIndex,
UINT TilePoolLayoutIndexCount,
UINT ResourceLayoutIndexCount);
HRESULT RegisterResourceLayouts(
UINT NodeIndex,
UINT NumResources,
_In_reads_(NumResources)
ID3D12Resource** pReservedResourceArray,
_In_reads_(NumResources)
const UINT* pResourceLayoutIndexArray);
HRESULT RegisterHeapLayouts(
UINT NodeIndex,
UINT NumHeaps,
_In_reads_(NumHeaps)
ID3D12Heap** pHeapArray,
_In_reads_(NumHeaps)
const UINT* pTilePoolLayoutIndexArray);
HRESULT UnregisterResourceLayouts(
UINT NodeIndex,
UINT NumResources,
_In_reads_(NumResources)
ID3D12Resource** pReservedResourceArray);
HRESULT UnregisterHeapLayouts(
UINT NodeIndex,
UINT NumHeaps,
_In_reads_(NumHeaps)
ID3D12Heap** pHeapArray);
};
The driver must report at least DDI version 0124 to support this feature.
typedef enum D3D12DDI_TILED_RESOURCES_TIER
{
D3D12DDI_TILED_RESOURCES_TIER_NOT_SUPPORTED = 0,
D3D12DDI_TILED_RESOURCES_TIER_1 = 1,
D3D12DDI_TILED_RESOURCES_TIER_2 = 2,
D3D12DDI_TILED_RESOURCES_TIER_3 = 3,
D3D12DDI_TILED_RESOURCES_TIER_4 = 4,
D3D12DDI_TILED_RESOURCES_TIER_5 = 5,
} D3D12DDI_TILED_RESOURCES_TIER;
The runtime requires
TiledResourcesTier >= D3D12DDI_TILED_RESOURCES_TIER_5.
typedef enum D3D12DDICAPS_TYPE
{
// Existing values omitted.
D3D12DDICAPS_TYPE_EXECUTE_TILE_MAPPINGS_0124,
} D3D12DDICAPS_TYPE;
typedef struct D3D12DDI_FEATURE_DATA_EXECUTE_TILE_MAPPINGS_0124
{
UINT NodeIndex;
UINT MaxTilePoolLayoutIndexCount;
UINT MaxResourceLayoutIndexCount;
BOOL UMDOnlySupport;
} D3D12DDI_FEATURE_DATA_EXECUTE_TILE_MAPPINGS_0124;
The runtime translates this capability to
D3D12_FEATURE_DATA_EXECUTE_TILE_MAPPINGS. Capabilities can be queried for
each candidate node. If UMDOnlySupport is FALSE, the reported maximums
must remain within the limits of the underlying implementation.
// Addition to D3D12DDI_RESOURCE_FLAGS_0003
D3D12DDI_RESOURCE_FLAG_0124_ALLOW_EXECUTE_TILE_MAPPINGS = 0x20000,
// Addition to D3D12DDI_HEAP_FLAGS
D3D12DDI_HEAP_FLAG_0124_ALLOW_EXECUTE_TILE_MAPPINGS = 0x1000,
The runtime passes these creation flags to the driver and enforces the separation from legacy tile mapping DDIs:
D3D12DDI_RESOURCE_FLAG_0124_ALLOW_EXECUTE_TILE_MAPPINGS is never passed to
pfnUpdateTileMappings or pfnCopyTileMappings.D3D12DDI_HEAP_FLAG_0124_ALLOW_EXECUTE_TILE_MAPPINGS is never
passed to pfnUpdateTileMappings.D3D10DDI_H(D3D12DDI_HTILEMAPPINGQUEUE_0124)
// Addition to D3D12DDI_HANDLETYPE
D3D12DDI_HT_0124_TILEMAPPINGQUEUE = 51,
// Addition to D3D12DDI_TABLE_TYPE
D3D12DDI_TABLE_TYPE_0124_TILE_MAPPING_QUEUE_FUNCS = 40,
The following types are defined in d3dukmdt.h. Their numeric values and
memory layouts match the API types, so the runtime does not translate argument
buffer contents.
typedef enum _D3DDDI_EXECUTETILEMAPPINGS_TOKEN_TYPES : UINT
{
D3DDDI_EXECUTETILEMAPPINGS_TOKEN_TYPE_NO_OPERATION = 1,
D3DDDI_EXECUTETILEMAPPINGS_TOKEN_TYPE_LINEAR_MAPPING = 128,
D3DDDI_EXECUTETILEMAPPINGS_TOKEN_TYPE_BOX_MAPPING = 129,
} D3DDDI_EXECUTETILEMAPPINGS_TOKEN_TYPES;
typedef enum _D3DDDI_EXECUTETILEMAPPINGS_MAPPING_TYPES
{
D3DDDI_EXECUTETILEMAPPINGS_MAPPING_TYPE_INCREMENTING_TILE_INDICES = 0,
D3DDDI_EXECUTETILEMAPPINGS_MAPPING_TYPE_NULL = 1,
D3DDDI_EXECUTETILEMAPPINGS_MAPPING_TYPE_SKIP = 2,
D3DDDI_EXECUTETILEMAPPINGS_MAPPING_TYPE_REUSE_SINGLE_TILE = 3,
D3DDDI_EXECUTETILEMAPPINGS_MAPPING_TYPE_TILE_INDEX_LIST = 4,
} D3DDDI_EXECUTETILEMAPPINGS_MAPPING_TYPES;
typedef enum _D3DDDI_EXECUTE_TILE_MAPPINGS_FLAGS
{
D3DDDI_EXECUTE_TILE_MAPPINGS_FLAG_NONE = 0,
} D3DDDI_EXECUTE_TILE_MAPPINGS_FLAGS;
typedef struct _D3DDDI_EXECUTETILEMAPPINGS_MAPPING_TOKEN_HEADER
{
UINT TokenType : 8;
UINT MappingType : 8;
UINT SubresourceIndex : 16;
} D3DDDI_EXECUTETILEMAPPINGS_MAPPING_TOKEN_HEADER;
typedef struct _D3DDDI_EXECUTETILEMAPPINGS_LINEAR_MAPPING_TOKEN
{
D3DDDI_EXECUTETILEMAPPINGS_MAPPING_TOKEN_HEADER Header;
UINT TilePoolBaseOffsetInTiles;
UINT SubresourceBaseOffsetInTiles;
UINT TileCount;
UINT _Padding;
UINT TilePoolLayoutIndex;
UINT ResourceLayoutIndex;
UINT TileListOffsetDwords;
} D3DDDI_EXECUTETILEMAPPINGS_LINEAR_MAPPING_TOKEN;
typedef struct _D3DDDI_EXECUTETILEMAPPINGS_BOX_MAPPING_TOKEN
{
D3DDDI_EXECUTETILEMAPPINGS_MAPPING_TOKEN_HEADER Header;
UINT TilePoolBaseOffsetInTiles;
UINT16 X;
UINT16 Y;
UINT16 Z;
UINT16 Width;
UINT16 Height;
UINT16 Depth;
UINT TilePoolLayoutIndex;
UINT ResourceLayoutIndex;
UINT TileListOffsetDwords;
} D3DDDI_EXECUTETILEMAPPINGS_BOX_MAPPING_TOKEN;
typedef struct _D3DDDI_QUERIED_RESOURCE_MAPPING
{
UINT SourceLayoutId;
UINT SourceOffsetInTiles;
} D3DDDI_QUERIED_RESOURCE_MAPPING;
For mapping queries, the runtime translates SourceLayoutId to
TilePoolLayoutIndex and SourceOffsetInTiles to
TilePoolOffsetInTiles.
typedef SIZE_T (APIENTRY*
PFND3D12DDI_CALCPRIVATETILEMAPPINGQUEUESIZE_0124)(
D3D12DDI_HDEVICE hDevice,
UINT NodeIndex);
typedef HRESULT (APIENTRY*
PFND3D12DDI_CREATETILEMAPPINGQUEUE_0124)(
D3D12DDI_HDEVICE hDevice,
UINT NodeIndex,
D3D12DDI_HTILEMAPPINGQUEUE_0124 hDrvTileMappingQueue);
typedef VOID (APIENTRY*
PFND3D12DDI_DESTROYTILEMAPPINGQUEUE_0124)(
D3D12DDI_HDEVICE hDevice,
D3D12DDI_HTILEMAPPINGQUEUE_0124 hDrvTileMappingQueue);
typedef HRESULT (APIENTRY*
PFND3D12DDI_INITIALIZEEXECUTETILEMAPPINGLAYOUTTABLES_0124)(
D3D12DDI_HDEVICE hDevice,
UINT NodeIndex,
UINT TilePoolLayoutIndexCount,
UINT ResourceLayoutIndexCount);
typedef HRESULT (APIENTRY*
PFND3D12DDI_REGISTERRESOURCELAYOUTS_0124)(
D3D12DDI_HDEVICE hDevice,
UINT NodeIndex,
UINT NumResources,
_In_reads_(NumResources)
const D3D12DDI_HRESOURCE* pReservedResourceArray,
_In_reads_(NumResources)
const UINT* pResourceLayoutIndexArray);
typedef HRESULT (APIENTRY*
PFND3D12DDI_REGISTERHEAPLAYOUTS_0124)(
D3D12DDI_HDEVICE hDevice,
UINT NodeIndex,
UINT NumHeaps,
_In_reads_(NumHeaps)
const D3D12DDI_HHEAP* pHeapArray,
_In_reads_(NumHeaps)
const UINT* pTilePoolLayoutIndexArray);
typedef HRESULT (APIENTRY*
PFND3D12DDI_UNREGISTERRESOURCELAYOUTS_0124)(
D3D12DDI_HDEVICE hDevice,
UINT NodeIndex,
UINT NumResourceLayoutIndices,
_In_reads_(NumResourceLayoutIndices)
const UINT* pResourceLayoutIndexArray);
typedef HRESULT (APIENTRY*
PFND3D12DDI_UNREGISTERHEAPLAYOUTS_0124)(
D3D12DDI_HDEVICE hDevice,
UINT NodeIndex,
UINT NumTilePoolLayoutIndices,
_In_reads_(NumTilePoolLayoutIndices)
const UINT* pTilePoolLayoutIndexArray);
typedef HRESULT (APIENTRY*
PFND3D12DDI_QUERYREGISTEREDRESERVEDRESOURCEMAPPINGS_0124)(
D3D12DDI_HDEVICE hDevice,
UINT NodeIndex,
D3D12DDI_HRESOURCE hReservedResource,
UINT64 ResourceMappingStartOffset,
UINT64 ResourceMappingsCount,
UINT64 ResourceMappingsOutputOffset,
D3D12DDI_HRESOURCE hResourceMappingsOutput);
typedef VOID (APIENTRY*
PFND3D12DDI_EXECUTETILEMAPPINGS_0124)(
D3D12DDI_HTILEMAPPINGQUEUE_0124 hDrvTileMappingQueue,
UINT MaxArgumentDwordCount,
D3D12DDI_HRESOURCE hArgumentBuffer,
UINT64 ArgumentBufferOffset,
D3D12DDI_HRESOURCE hCountBuffer,
UINT64 CountBufferOffset,
D3D12DDI_HRESOURCE hTileListBuffer,
UINT64 TileListBufferOffset,
D3DDDI_EXECUTE_TILE_MAPPINGS_FLAGS Flags);
The device function table adds:
PFND3D12DDI_CALCPRIVATETILEMAPPINGQUEUESIZE_0124
pfnCalcPrivateTileMappingQueueSize;
PFND3D12DDI_CREATETILEMAPPINGQUEUE_0124
pfnCreateTileMappingQueue;
PFND3D12DDI_DESTROYTILEMAPPINGQUEUE_0124
pfnDestroyTileMappingQueue;
PFND3D12DDI_INITIALIZEEXECUTETILEMAPPINGLAYOUTTABLES_0124
pfnInitializeExecuteTileMappingLayoutTables;
PFND3D12DDI_REGISTERRESOURCELAYOUTS_0124
pfnRegisterResourceLayouts;
PFND3D12DDI_REGISTERHEAPLAYOUTS_0124
pfnRegisterHeapLayouts;
PFND3D12DDI_UNREGISTERRESOURCELAYOUTS_0124
pfnUnregisterResourceLayouts;
PFND3D12DDI_UNREGISTERHEAPLAYOUTS_0124
pfnUnregisterHeapLayouts;
PFND3D12DDI_QUERYREGISTEREDRESERVEDRESOURCEMAPPINGS_0124
pfnQueryRegisteredReservedResourceMappings;
The tile mapping queue uses its own function table:
typedef struct D3D12DDI_TILE_MAPPING_QUEUE_FUNCS_0124
{
PFND3D12DDI_EXECUTETILEMAPPINGS_0124 pfnExecuteTileMappings;
PFND3D12DDI_SIGNAL_FENCE pfnSignalFence;
PFND3D12DDI_WAIT_FOR_FENCE pfnWaitForFence;
} D3D12DDI_TILE_MAPPING_QUEUE_FUNCS_0124;
The runtime passes the argument, count, and tile-list resource handles,
offsets, and flags directly to pfnExecuteTileMappings. pfnSignalFence and
pfnWaitForFence provide GPU timeline synchronization for the tile mapping
queue.
After layout-table initialization succeeds, the runtime calls the queue size and creation DDIs when the application first requests the tile mapping queue for that physical adapter. The queue is destroyed with the D3D12 device.
An argument buffer contains one or more mapping tokens. Each token refers to a tile pool layout, a reserved-resource layout, and optionally an offset in a tile-list buffer.
Tokens in one ExecuteTileMappings call complete in an unspecified order.
Mappings in one call cannot overlap or otherwise depend on execution order.
Each call synchronizes at the end of its argument buffer, so subsequent calls
on the tile mapping queue complete in submission order.
Before unregistering a layout or destroying its registered object, the application must ensure that all tile mapping queue work referring to that layout has completed. A layout index can be reused only after unregistration completes.
InitializeExecuteTileMappingLayoutTables selects the actual number of tile
pool and resource layout slots for a node. Both counts must be greater than
zero and no greater than the corresponding maximums returned by
CheckFeatureSupport.
The first successful call for a physical adapter fixes both counts for the
lifetime of the device. A later call for that physical adapter fails, including
a call with the same counts. Physical adapters are initialized independently.
If an initialization attempt fails, a retry uses the same NodeIndex but can
select different counts.
After initialization, valid indices are from zero through IndexCount - 1.
GetTileMappingQueue, RegisterHeapLayouts, and RegisterResourceLayouts
fail for a physical adapter until initialization succeeds.
Referenced heaps, resources, and input buffers must be visible to the selected node.
RegisterHeapLayouts associates heaps with application-selected tile pool
layout indices. Each heap layout describes the entire heap. A heap must:
D3D12_HEAP_FLAG_ALLOW_EXECUTE_TILE_MAPPINGS.Indices and heaps must be unique within a registration call, each index must be within the initialized table, and neither the index nor heap can already be registered for the selected physical adapter.
Registration is batched and atomic: if any heap registration fails, no heap in the call is registered. After success, the selected index is stored for the physical adapter in the corresponding heap.
One heap can be registered independently with each physical adapter to which it is visible.
UnregisterHeapLayouts takes an array of registered heaps. Null, foreign,
duplicate, or unregistered heaps make the entire call fail without
unregistering any layout.
All ExecuteTileMappings work referring to the layouts must have completed,
and mappings from registered reserved resources to each heap must have been
removed before unregistration. Unregistration does not release the heap, and
the heap can be registered again later.
Destroying a heap unregisters any stored layouts before destruction completes.
RegisterResourceLayouts associates reserved resources with
application-selected resource layout indices. Each resource must:
D3D12_RESOURCE_FLAG_ALLOW_EXECUTE_TILE_MAPPINGS.Committed, placed, and shared resources cannot be registered.
Indices and resources must be unique within a registration call, each index must be within the initialized table, and neither the index nor resource can already be registered for the selected physical adapter.
Registration is batched and atomic: if any resource registration fails, no resource in the call is registered. After success, the selected index is stored for the physical adapter in the corresponding resource.
One resource can be registered independently with each physical adapter to which it is visible.
UnregisterResourceLayouts takes an array of registered reserved resources.
Null, foreign, duplicate, non-reserved, or unregistered resources make the
entire call fail without unregistering any layout.
All ExecuteTileMappings work referring to the layouts must have completed,
and all tiles in each reserved resource must be unmapped before
unregistration. Unregistration does not release the resource or its reserved
GPU virtual address range, and the resource can be registered again later.
Destroying a reserved resource unregisters any stored layouts before destruction completes.
The argument length in DWORDs is the lesser of MaxArgumentDwordCount and the
unsigned 32-bit value in the count buffer when a count buffer is supplied.
The argument buffer can be in:
GENERIC_READ; orGENERIC_READ or INDIRECT_ARGUMENT.The optional tile-list buffer contains unsigned 32-bit tile pool indices.
A NO_OPERATION token consumes one eight-DWORD token and performs no mapping.
A linear token maps a linear range of tiles in one reserved-resource subresource to tiles in a tile pool.
SubresourceBaseOffsetInTiles and TileCount identify the destination range.
The mapping must remain entirely within the selected subresource. For texture
subresources, linear tile coordinates use XYZ typewriter order: X first, then
Y, then Z. A mapping cannot spill into a subsequent subresource.
A box token maps a three-dimensional tile region in one reserved texture subresource.
X, Y, and Z identify the destination origin. Width, Height, and
Depth must be nonzero, and the complete box must fit in the selected
subresource. The mapping contains Width * Height * Depth tiles and proceeds
in XYZ typewriter order.
Box mappings are not valid for linear buffer layouts.
ExecuteTileMappings does not copy existing mappings from one location in a
reserved resource to another.
Each linear or box mapping uses one of these source selection modes:
INCREMENTING_TILE_INDICES: select consecutive tiles beginning at
TilePoolBaseOffsetInTiles.NULL: unmap the destination tiles. The tile pool is not accessed and
TilePoolBaseOffsetInTiles is ignored.SKIP: perform no mapping for the token.REUSE_SINGLE_TILE: map every destination tile to the one tile selected by
TilePoolBaseOffsetInTiles.TILE_INDEX_LIST: select tile indices from the tile-list buffer beginning
at TileListOffsetDwords. The list must contain one entry per destination
tile. TilePoolBaseOffsetInTiles is ignored.GetTileMappingQueue(NodeIndex) returns the dedicated tile mapping queue for
the corresponding initialized physical adapter.
ExecuteTileMappings does not run on a DIRECT, COMPUTE, or COPY command
queue. Those queues order work with the tile mapping queue through fence
Signal and Wait operations.
At the beginning of ExecuteTileMappings, the GPU performs pipeline and cache
flushes before consuming the argument buffer.
After the argument buffer completes, page table writes are flushed and GPU translation caches are invalidated before later work proceeds on the tile mapping queue.
Applications must ensure that simultaneous work on other queues does not
depend on resources or memory being remapped. ExecuteTileMappings does not
globally serialize command buffer execution across all queues.
The argument, count, and tile-list buffers cannot be protected resources.
Registered heaps and reserved resources are unaffected because
ExecuteTileMappings does not access their contents.
Invalid API parameters or invalid argument-buffer contents can cause device removal. When the debug layer is enabled, it reports mapping details through the info queue. Argument parsing and its errors occur asynchronously from the API call.
The runtime emits one
D3D12_MESSAGE_ID_EXECUTETILEMAPPINGS_EXECUTION_ERROR message:
ExecuteTileMappings error <code>: <canonical-name>; token byte offset <offset>
The offset is relative to ArgumentBufferOffset and is not a GPU virtual
address.
| Code | Name | Meaning |
|---|---|---|
| 128 | OUT_OF_RESOURCE_BOUNDS |
A linear mapping exceeds the destination resource, or a box exceeds the destination subresource dimensions. |
| 129 | OUT_OF_TILEPOOL_BOUNDS |
A mapping selects a tile beyond the tile pool. |
| 130 | UNEXPECTED_END_OF_BUFFER |
The effective argument length ends in the middle of a token. |
| 131 | INVALID_TOKEN |
A token cannot be decoded or has an invalid token type. |
| 132 | INVALID_TILEPOOL |
The tile pool layout is invalid, stale, uninitialized, or corrupted, or a selected source tile is unmapped. |
| 133 | INVALID_RESOURCE |
The resource layout is invalid, stale, uninitialized, or corrupted; the destination cannot be updated; or the subresource index is invalid. |
| 134 | INCOMPATIBLE_BOX_MAPPING |
A box mapping targets a linear buffer layout. |
PIX captures ExecuteTileMappings arguments similarly to existing GPU tile
mapping APIs. GPU-generated buffer contents might not be captured when the
work that generates them occurs before the capture window.
PIX can query the initial mapping state of a registered reserved resource:
#define D3D12_TILE_NOT_MAPPED UINT_MAX
struct D3D12_QUERIED_RESOURCE_MAPPING
{
UINT TilePoolLayoutIndex;
UINT TilePoolOffsetInTiles;
};
HRESULT ID3D12CommandQueueN::QueryRegisteredReservedResourceMappings(
ID3D12Resource* pReservedResource,
UINT64 ResourceMappingStartOffset,
UINT64 ResourceMappingsCount,
UINT64 ResourceMappingsOutputOffset,
ID3D12Resource* pResourceMappingsOutput);
For an unmapped tile, both fields are D3D12_TILE_NOT_MAPPED.
The source must be a registered reserved resource. The source range must not exceed the total tile count of the resource, and the output range must fit in the output buffer. Invalid parameters return failure.
PIX can issue multiple queries for large resources and convert the results to linear mapping tokens for capture playback.