ID3D11DeviceContext2::UpdateTileMappings 方法 (d3d11_2.h)

汇报平铺资源中的磁贴位置到磁贴池中的内存位置的映射。

语法

HRESULT UpdateTileMappings(
  [in]           ID3D11Resource                        *pTiledResource,
  [in]           UINT                                  NumTiledResourceRegions,
  [in, optional] const D3D11_TILED_RESOURCE_COORDINATE *pTiledResourceRegionStartCoordinates,
  [in, optional] const D3D11_TILE_REGION_SIZE          *pTiledResourceRegionSizes,
  [in, optional] ID3D11Buffer                          *pTilePool,
  [in]           UINT                                  NumRanges,
  [in, optional] const UINT                            *pRangeFlags,
  [in, optional] const UINT                            *pTilePoolStartOffsets,
  [in, optional] const UINT                            *pRangeTileCounts,
  [in]           UINT                                  Flags
);

参数

[in] pTiledResource

类型: ID3D11Resource*

指向平铺资源的指针。

[in] NumTiledResourceRegions

类型: UINT

平铺资源区域的数量。

[in, optional] pTiledResourceRegionStartCoordinates

类型: const D3D11_TILED_RESOURCE_COORDINATE*

描述平铺资源区域的起始坐标的 D3D11_TILED_RESOURCE_COORDINATE 结构的数组。 NumTiledResourceRegions 参数指定数组中D3D11_TILED_RESOURCE_COORDINATE结构的数目。

[in, optional] pTiledResourceRegionSizes

类型: const D3D11_TILE_REGION_SIZE*

描述平铺资源区域大小的 D3D11_TILE_REGION_SIZE 结构的数组。 NumTiledResourceRegions 参数指定数组中D3D11_TILE_REGION_SIZE结构的数目。

[in, optional] pTilePool

类型: ID3D11Buffer*

指向磁贴池的指针。

[in] NumRanges

类型: UINT

平铺池范围的数量。

[in, optional] pRangeFlags

类型: const UINT*

描述每个磁贴池范围的 D3D11_TILE_RANGE_FLAG 值的数组。 NumRanges 参数指定数组中的值数。

[in, optional] pTilePoolStartOffsets

类型: const UINT*

磁贴池中的偏移量数组。 这些是从 0 开始的磁贴偏移量,以磁贴 (而不是字节) 计数。

[in, optional] pRangeTileCounts

类型: const UINT*

磁贴数组。

值数组,指定每个磁贴池区域中的磁贴数。 NumRanges 参数指定数组中的值数。

[in] Flags

类型: UINT

使用按位 OR 运算组合的 D3D11_TILE_MAPPING_FLAGS 值的组合。

返回值

类型: HRESULT

如果成功,则返回S_OK;否则,返回下列值之一:

  • 如果各种条件(如无效标志)导致调用被删除,则返回 E_INVALIDARG 。调试层将发出错误。
  • 如果调用导致驱动程序必须为新的页表映射分配空间,但内存不足,则返回 E_OUTOFMEMORY 。如果在命令列表中调用此命令并且正在执行命令列表时出现内存不足,则将删除设备。 应用只需执行更新调用即可避免这种情况,这些调用更改命令列表中的平铺资源的现有映射 (这样驱动程序就不必分配页表内存,只需更改映射) 。
  • 如果视频卡已实际从系统中删除,或者视频卡的驱动程序升级,则返回DXGI_ERROR_DEVICE_REMOVED。

注解

在对 UpdateTileMappings 的单个调用中,可以将一个或多个资源磁贴范围映射到一个或多个磁贴池磁贴范围。

可以通过以下方式组织 UpdateTileMappings 的参数以执行更新:

  • 已更新其映射的平铺资源。 这是使用 D3D11_RESOURCE_MISC_TILED 标志创建的资源。 最初创建资源时,映射从所有 NULL 开始。
  • 映射已更新的平铺资源上的磁贴区域集。 如果更方便,还可以进行一次 UpdateTileMappings 调用来更新许多映射或多个调用,同时增加一点 API 调用开销。 NumTiledResourceRegions 指定有多少个区域, pTiledResourceRegionStartCoordinatespTiledResourceRegionSizes 是标识每个区域的起始位置和扩展的数组。 如果 NumTiledResourceRegions 为 1,为方便起见,描述区域的数组之一或两个可以为 NULL。 pTiledResourceRegionStartCoordinates 的 NULL 表示起始坐标全为 0,pTiledResourceRegionSizes 的 NULL 标识默认区域,即整个平铺资源(包括所有 mipmap 和/或数组切片)的完整磁贴集。 如果 pTiledResourceRegionStartCoordinates 不是 NULL 且 pTiledResourceRegionSizes 为 NULL,则所有区域的区域大小默认为 1 个磁贴。 这样,通过在 pTiledResourceRegionStartCoordinates 中提供位置数组,即可轻松地为位于不同位置的一组单独的磁贴定义映射,而无需发送 pTiledResourceRegionSizes 数组,全部设置为 1。

    更新从第一个区域应用到最后一个区域;因此,如果区域在单个调用中重叠,列表中稍后的更新将覆盖与以前的更新重叠的区域。

  • 提供磁贴映射可以进入的内存的磁贴池。 平铺资源可以一次指向单个磁贴池。 如果第一次 (指定了新的磁贴池,或者与上一次指定磁贴池) 不同,则会清除平铺资源的所有现有磁贴映射,并将为新磁贴池应用当前 UpdateTileMappings 调用中的新映射集。 如果未 (NULL) 指定任何磁贴池,或者提供与以前的 UpdateTileMappings 调用相同的磁贴池, 则 UpdateTileMappings 调用只会将新映射添加到现有映射, (重叠) 覆盖。 如果 UpdateTileMappings 仅定义 NULL 映射,则无需指定磁贴池,因为它无关紧要。 但是,如果仍然指定磁贴池,它的行为与之前提供磁贴池时所述的行为相同。
  • 映射所在的磁贴范围集。 每个给定的磁贴范围可以指定几种类型的范围之一:磁贴池中的一个图块区域 (默认) ,平铺资源中要映射到磁贴池中的单个磁贴的计数 (共享磁贴) ,平铺资源中要跳过和保留的磁贴映射计数, 或图块池中要映射到 NULL 的磁贴计数。NumRanges 指定磁贴范围的数目,其中跨所有区域标识的磁贴总数必须与前面所述的平铺资源中的磁贴区域中的磁贴总数匹配。 映射是通过按顺序循环访问图块区域中的图块(依次按 x、y 然后 z 顺序)来定义映射,同时按顺序遍历图块区域集。 磁贴区域的细分不必与磁贴范围的细目对齐,但两侧的磁贴总数必须相等,以便指定的每个平铺资源磁贴都具有指定的映射。

    pRangeFlagspTilePoolStartOffsetspRangeTileCounts 都是描述磁贴范围的数组,大小为 NumRanges。 如果 pRangeFlags 为 NULL,则所有区域都是磁贴池中的顺序磁贴;否则,对于每个区域 i,pRangeFlags[i] 标识该磁贴区域中的映射的工作原理:

    • 如果 pRangeFlags[i] 为 0,则该范围定义磁贴池中的顺序磁贴,磁贴数为 pRangeTileCounts[i] 和起始位置 pTilePoolStartOffsets[i]。 如果 NumRanges 为 1, 则 pRangeTileCounts 可以为 NULL,默认为由所有磁贴区域指定的磁贴总数。
    • 如果 pRangeFlags[i] D3D11_TILE_RANGE_REUSE_SINGLE_TILE,pTilePoolStartOffsets[i] 标识要映射到的磁贴池中的单个磁贴,pRangeTileCounts[i] 指定要从磁贴区域映射到该磁贴池位置的磁贴数。 如果 NumRanges 为 1, 则 pRangeTileCounts 可以为 NULL,默认为由所有磁贴区域指定的磁贴总数。
    • 如果 pRangeFlags[i] D3D11_TILE_RANGE_NULL,则 pRangeTileCounts[i] 指定要从磁贴区域映射到 NULL 的磁贴数。 如果 NumRanges 为 1, 则 pRangeTileCounts 可以为 NULL,默认为由所有磁贴区域指定的磁贴总数。 对于 NULL 映射,将忽略 pTilePoolStartOffsets[i]。
    • 如果 pRangeFlags[i] D3D11_TILE_RANGE_SKIP,则 pRangeTileCounts[i] 指定要跳过磁贴区域中的磁贴数量,并使现有映射保持不变。 如果磁贴区域方便地将磁贴映射区域绑定为要更新,除非有一些例外情况需要与以前映射到的磁贴区域保持一致,则这非常有用。 对于 SKIP 映射,将忽略 pTilePoolStartOffsets[i] 。
  • 用于整体选项的 Flags 参数。D3D11_TILE_MAPPING_NO_OVERWRITE 表示调用方承诺以前向可能仍在执行的设备提交的命令不会引用任何正在更新的磁贴区域。 这样,设备就无需刷新以前提交的工作即可进行磁贴映射更新。 如果应用通过更新平铺资源中仍被未完成命令引用的位置的磁贴映射来违反此承诺,则未定义的呈现行为结果包括某些体系结构可能会显著减速。 这类似于 Direct3D API 中其他位置存在的“不覆盖”概念,但应用于磁贴映射数据结构本身(在硬件中是页表)。 如果没有此标志,则要求必须先完成由此更新 TileMappings 调用指定的磁贴映射更新,然后任何后续 Direct3D 命令才能继续。
如果磁贴映射在应用将通过 RenderTargetViewDepthStencilView 呈现的平铺资源上发生更改,则应用必须使用固定函数 Clear API 清除所呈现区域内已更改的磁贴 (映射或不) 。 如果应用在这些情况下未清除,则应用在从平铺资源读取时会收到未定义的值。
注意 在 Direct3D 11.2 中,硬件现在可以支持仅深度格式的 ClearView 。 有关详细信息,请参阅 D3D11_FEATURE_DATA_D3D11_OPTIONS1
 
如果应用需要保留映射已更改的平铺资源中区域的现有内存内容,则应用可以先将磁贴映射已更改的内容复制到临时图面,例如使用 CopyTiles,发出所需的 Clear,然后复制回内容。

假设磁贴同时映射到多个平铺资源,并且磁贴内容通过其中一个平铺资源) (呈现、复制等任何方式进行操作。 然后,如果要通过任何其他平铺资源呈现同一磁贴,则必须首先清除磁贴,如前所述。

有关平铺资源的详细信息,请参阅 平铺资源

下面是常见 UpdateTileMappings 案例的 一些示例:

示例

清除整个图面到 NULL 的映射:

// - No-overwrite is specified, assuming it is known nothing else the GPU could be doing is referencing the previous mappings
// - NULL for pTiledResourceRegionStatCoordinates and pTiledResourceRegionSizes defaults to the entire resource
// - NULL for pTilePoolStartOffsets since it isn't needed for mapping tiles to NULL
// - NULL for pRangeTileCounts when NumRanges is 1 defaults to the same number of tiles as the tiled resource region (which is
//   the entire surface in this case)
//
// UINT RangeFlags = D3D11_TILE_MAPPING_NULL;
// pDeviceContext2->UpdateTileMappings(pTiledResource,1,NULL,NULL,NULL,1,&RangeFlags,NULL,NULL,D3D11_TILE_MAPPING_NO_OVERWRITE);

将磁贴区域映射到单个磁贴:

// - This maps a 2x3 tile region at tile offset (1,1) in a Tiled Resource to tile [12] in a Tile Pool
// 
// D3D11_TILED_RESOURCE_COORDINATE TRC;
// TRC.X = 1;
// TRC.Y = 1;
// TRC.Z = 0;
// TRC.Subresource = 0;
//
// D3D11_TILE_REGION_SIZE TRS;
// TRS.bUseBox = TRUE;
// TRS.Width = 2;
// TRS.Height = 3; 
// TRS.Depth = 1;
// TRS.NumTiles = TRS.Width * TRS.Height * TRS.Depth;
// 
// UINT RangeFlags = D3D11_TILE_MAPPING_REUSE_SINGLE_TILE;
// UINT StartOffset = 12;
// pDeviceContext2->UpdateTileMappings(pTiledResource,1,&TRC,&TRS,pTilePool,1,&RangeFlags,&StartOffset,
//                                     NULL,D3D11_TILE_MAPPING_NO_OVERWRITE);

为一组不连续的单个磁贴定义映射:

// - This can also be accomplished in multiple calls.  Using a single call to define multiple
//   a single call to define multiple mapping updates can reduce CPU call overhead slightly,
//   at the cost of having to pass arrays as parameters.
// - Passing NULL for pTiledResourceRegionSizes defaults to each region in the Tiled Resource
//   being a single tile.  So all that is needed are the coordinates of each one.
// - Passing NULL for Range Flags defaults to no flags (since none are needed in this case)
// - Passing NULL for pRangeTileCounts defaults to each range in the Tile Pool being size 1.
//   So all that is needed are the start offsets for each tile in the Tile Pool
//
// D3D11_TILED_RESOURCE_COORDINATE TRC[3];
// UINT StartOffsets[3];
// UINT NumSingleTiles = 3;
//
// TRC[0].X = 1;
// TRC[0].Y = 1; 
// TRC[0].Subresource = 0;
// StartOffsets[0] = 1;
//
// TRC[1].X = 4;
// TRC[1].Y = 7; 
// TRC[1].Subresource = 0;
// StartOffsets[1] = 4;
//
// TRC[2].X = 2;
// TRC[2].Y = 3; 
// TRC[2].Subresource = 0;
// StartOffsets[2] = 7;
//
// pDeviceContext2->UpdateTileMappings(pTiledResource,NumSingleTiles,&TRC,NULL,pTilePool,NumSingleTiles,NULL,StartOffsets,
//                                     NULL,D3D11_TILE_MAPPING_NO_OVERWRITE);

复杂示例 - 定义具有一些跳过和一些 NULL 映射的区域的映射:

// - This complex example hard codes the parameter arrays, whereas in practice the 
//   application would likely configure the parameters programatically or in a data driven way.
// - Suppose we have 3 regions in a Tiled Resource to configure mappings for, 2x3 at coordinate (1,1),
//   3x3 at coordinate (4,7), and 7x1 at coordinate (20,30)
// - The tiles in the regions are walked from first to last, in X then Y then Z order,
//   while stepping forward through the specified Tile Ranges to determine each mapping.
//   In this example, 22 tile mappings need to be defined.
// - Suppose we want the first 3 tiles to be mapped to a contiguous range in the Tile Pool starting at
//   tile pool location [9], the next 8 to be skipped (left unchanged), the next 2 to map to NULL, 
//   the next 5 to share a single tile (tile pool location [17]) and the remaining 
//   4 tiles to each map to to unique tile pool locations, [2], [9], [4] and [17]:
//
// D3D11_TILED_RESOURCE_COORDINATE TRC[3];
// D3D11_TILE_REGION_SIZE TRS[3];
// UINT NumRegions = 3;
// 
// TRC[0].X = 1;
// TRC[0].Y = 1; 
// TRC[0].Subresource = 0;
// TRS[0].bUseBox = TRUE;
// TRS[0].Width = 2;
// TRS[0].Height = 3; 
// TRS[0].NumTiles = TRS[0].Width * TRS[0].Height;
//
// TRC[1].X = 4;
// TRC[1].Y = 7; 
// TRC[1].Subresource = 0;
// TRS[1].bUseBox = TRUE;
// TRS[1].Width = 3;
// TRS[1].Height = 3; 
// TRS[1].NumTiles = TRS[1].Width * TRS[1].Height;
//
// TRC[2].X = 20;
// TRC[2].Y = 30; 
// TRC[2].Subresource = 0;
// TRS[2].bUseBox = TRUE;
// TRS[2].Width = 7;
// TRS[2].Height = 1; 
// TRS[2].NumTiles = TRS[2].Width * TRS[2].Height;
//
// UINT NumRanges = 8;
// UINT RangeFlags[8];
// UINT TilePoolStartOffsets[8];
// UINT RangeTileCounts[8];
//
// RangeFlags[0] = 0;
// TilePoolStartOffsets[0] = 9;
// RangeTileCounts[0] = 3;
//
// RangeFlags[1] = D3D11_TILE_MAPPING_SKIP;
// TilePoolStartOffsets[1] = 0; // offset is ignored for skip mappings
// RangeTileCounts[1] = 8;
//
// RangeFlags[2] = D3D11_TILE_MAPPING_NULL;
// TilePoolStartOffsets[2] = 0; // offset is ignored for NULL mappings
// RangeTileCounts[2] = 2;
//
// RangeFlags[3] = D3D11_TILE_MAPPING_REUSE_SINGLE_TILE;
// TilePoolStartOffsets[3] = 17; 
// RangeTileCounts[3] = 5;
//
// RangeFlags[4] = 0;
// TilePoolStartOffsets[4] = 2; 
// RangeTileCounts[4] = 1;
//
// RangeFlags[5] = 0;
// TilePoolStartOffsets[5] = 9; 
// RangeTileCounts[5] = 1;
//
// RangeFlags[6] = 0;
// TilePoolStartOffsets[6] = 4; 
// RangeTileCounts[6] = 1;
//
// RangeFlags[7] = 0;
// TilePoolStartOffsets[7] = 17; 
// RangeTileCounts[7] = 1;
//
// pDeviceContext2->UpdateTileMappings(pTiledResource,NumRegions,TRC,TRS,pTilePool,NumRanges,RangeFlags,
//                                     TilePoolStartOffsets,RangeTileCounts,D3D11_TILE_MAPPING_NO_OVERWRITE);

CopyTileMappings

// CopyTileMappings helps with tasks such as shifting mappings around within/across Tiled Resources, e.g. scrolling tiles.
// The source and dest region can overlap - the result of the copy in this case is as if the source was saved to a temp and then
// from there written to the dest, though the implementation may be able to do better. 
//
// The Flags field allows D3D11_TILE_MAPPING_NO_OVERWRITE to be specified, means the caller promises that previously 
//      submitted commands to the device that may still be executing do not reference any of the tile region being updated.
//      This allows the device to avoid having to flush previously submitted work in order to do the tile mapping 
//      update.  If the application violates this promise by updating tile mappings for locations in Tiled Resouces 
//      still being referenced by outstanding commands, undefined rendering behavior results, including the potential 
//      for significant slowdowns on some architectures.  This is like the "no overwrite" concept that exists 
//      elsewhere in the API, except applied to Tile Mapping data structure itself (which in hardware is a page table).
//      The absence of this flag requires that tile mapping updates specified by this call must be completed before any
//      subsequent D3D command can proceed.
//
// Return Values:
//
// Returns S_OK or E_INVALIDARG or E_OUTOFMEMORY.  The latter can happen if the call results in the driver having to 
// allocate space for new page table mappings but running out of memory.
//
// If out of memory occurs when this is called in a commandlist and the commandlist is being executed, the device will be removed.
// Applications can avoid this situation by only doing update calls that change existing mappings from Tiled Resources 
// within commandlists (so drivers will not have to allocate page table memory, only change the mapping).
//
// Various other basic conditions such as invalid flags or passing in non Tiled Resources result in call being dropped 
// with E_INVALIDARG.
// 
// Validation remarks:
//
// The dest and the source regions must each entirely fit in their resource or behavior is undefined 
// (debug layer will emit an error).

要求

要求
最低受支持的客户端 Windows 8.1 [桌面应用 |UWP 应用]
最低受支持的服务器 Windows Server 2012 R2 [桌面应用 |UWP 应用]
目标平台 Windows
标头 d3d11_2.h
Library D3D11.lib

另请参阅

ID3D11DeviceContext2