d3d/archive/D3D11_3_FunctionalSpec.htm [5200:5606]: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

The following APIs allow manipulation and querying of tile mappings. Update calls only affect the tiles identified in the call, and others are left as defined previously.

Any given tile from a Tile Pool can be mapped to multiple locations in a Resource and even multiple Resources. This includes tiles in a Resource that have an implementation chosen layout, described earlier, where multiple mipmaps are packed together into a single tile. The catch is that if data is written to the tile via one mapping, but read via a differently configured mapping, the results are undefined. Careful use of this flexibility can still be useful for an application though, like sharing a tile between resources that will not be used simultaneously, where the contents of the tile are always initialized through the same Resource mapping as they will be subsequently read from. Similarly a tile mapped to hold the packed mipmaps of multiple different Resources with the same surface dimensions will work fine - the data will appear the same in both mappings.

Changes to tile assignments for a Resource can be made at any time in an immediate or deferred context.

// --------------------------------------------------------------------------------------------------------------------------------
// Data Structures for Manipulating Tile Mappings
// --------------------------------------------------------------------------------------------------------------------------------

// For manipulating tile mappings, regions in tiled resources are described by a combination of:
// (1) tiled resource coordinate (defining the corner of a region) and
// (2) tile region size (defining the size of a region)
//
// These are separated into two structs rather than one so that the various APIs
// that use them can use different combinations of the parts.

typedef struct D3D11_TILED_RESOURCE_COORDINATE
{
    // Coordinate values below index tiles (not pixels or bytes).
    UINT X; // Used for buffer, 1D, 2D, 3D
    UINT Y; // Used for 2D, 3D
    UINT Z; // Used for 3D
    UINT Subresource; // indexes into mips, arrays. Used for 1D, 2D, 3D
    // For mipmaps that use nonstandard tiling and/or are packed, any subresource
    // value that indicates any of the packed mips all refer to the same tile.
};

typedef struct D3D11_TILE_REGION_SIZE
{
    UINT NumTiles;
    BOOL bUseBox; // TRUE: Uses width/height/depth parameters below to define the region.
                  //   width*height*depth must match NumTiles above.  (While
                  //   this looks like redundant information, the application likely has to know
                  //   how many tiles are involved anyway.)
                  //   The downside to using the box parameters is that one update region cannot
                  //   span mipmaps (though it can span array slices via the depth parameter).
                  //
                  // FALSE: Ignores width/height/depth parameters - NumTiles just traverses tiles in
                  //   the resource linearly across x, then y, then z (as applicable) then spilling over
                  //   mips/arrays in subresource order.  Useful for just mapping an entire resource
                  //   at once, for example.
                  //
                  // In either case, the starting location for the region within the resource
                  // is specified as a separate parameter outside this struct, using x,y,z coordinates
                  // regardless of whether bUseBox above is TRUE or FALSE.
                  //
                  // When the region includes mipmaps that are packed with nonstandard tiling,
                  // bUseBox must be FALSE, since tile dimensions are not standard and the application
                  // only knows a count of how many tiles are consumed by the packed area (which is per
                  // array slice).  The corresponding (separate) starting location parameter uses x to
                  // offset into the flat range of tiles in this case, and y,z coordinates must be 0.

    UINT Width;   // In tiles, used for buffer, 1D, 2D, 3D
    UINT16 Height; // In tiles, used for 2D, 3D
    UINT16 Depth; // In tiles, used for 3D or arrays.  For arrays, advancing in depth jumps to next slice
                  // of same mip size, which is not contiguous in the subresource counting space
                  // if there are multiple mips.
};

typedef enum D3D11_TILE_MAPPING_FLAG
{
    D3D11_TILE_MAPPING_NO_OVERWRITE = 0x00000001,
} D3D11_TILE_MAPPING_FLAG;

typedef enum D3D11_TILE_RANGE_FLAG
{
    D3D11_TILE_RANGE_NULL = 0x00000001,
    D3D11_TILE_RANGE_SKIP = 0x00000002,
    D3D11_TILE_RANGE_REUSE_SINGLE_TILE = 0x00000004,
} D3D11_TILE_RANGE_FLAG;

// --------------------------------------------------------------------------------------------------------------------------------
// UpdateTileMappings
// --------------------------------------------------------------------------------------------------------------------------------
// UpdateTileMappings adds/removes/changes mappings of tile locations in Tiled Resources to memory locations in a Tile Pool.
// The API has several modes of operation to enable a few common tasks to be efficiently described.
//
// The basic orgainization of the parameters is as follows:
//
//      (1) Tiled Resource whose mappings are being updated
//      (2) Set of Tile Regions on the Tiled Resource whose mappings to update.
//      (3) Tile Pool providing memory where tile mappings can go.
//      (4) Set of Tile Ranges where mappings are going: to the Tile Pool in (3), to NULL, and/or other options.
//      (5) Flags parameter for overall options
//
// More detailed breakdown of the parameters:
//
// (1) Tiled Resource whose mappings are being updated - resource created with the D3D11_RESOURCE_MISC_TILED flag.
//     Mappings start off all NULL when a resource is initially created.
//
// (2) Set of Tile Regions on the Tiled Resource whose mappings to update.  One API call can update many mappings,
//     but an application can make multiple calls as well if that is more convenient (with a bit more API call overhead).
//     NumTiledResourceRegions specifies how many regions there are, pTiledResourceRegionStartCoordinates and
//     pTiledResourceRegionSizes are each arrays identifying the start location and extend of each region.
//     If NumTiledResourceRegions is 1, then for convenience either or both of the arrays describing the regions can
//     be NULL.  NULL for pTiledResourceRegionStartCoordinates means the start coordinate is all 0's, and NULL for
//     pTiledResourceRegionSizes identifies a default region that is the full set of tiles for the entire Tiled Resource,
//     including all mipmaps and/or array slices.
//
//     If pTiledResourceRegionStartCoordinates is not NULL and pTiledResourceRegionSizes is NULL, then the region
//     size defaults to 1 tile for all regions.  This makes it easy to define mappings for a set of individual tiles
//     each at disparate locations by providing an array of locations in pTiledResourceRegionStartCoordinates without
//     having to send an array of pTiledResourceRegionSizes all set to 1.
//
//     The updates are applied from first region to last, so if regions
//     overlap in a single call, the updates later in the list overwrite the areas overlapping with previous updates.
//
// (3) Tile Pool providing memory where mappings are pointing to.  A Tiled Resource can point to a single Tile Pool
//     at a time.  If a new Tile Pool is specified (for the first time or different
//     from the last time a Tile Pool was specified), all existing tile mappings for the Tiled Resource are cleared
//     and the new set of mappings in the current call are applied for the new Tile Pool.
//     If no Tile Pool is specified (NULL), or the same one as a previous call to UpdateTileMappings is provided,
//     the call just adds the new mappings to existing ones (overwriting on overlap).
//     If the call is only defining NULL mappings, no Tile Pool needs to be specified, since it doesn't matter.
//     But if one is specified anyway it takes the same behavior as described above when providing a Tile Pool.
//
// (4) Set of Tile Ranges where mappings are going to.  Each given Tile Range can specify one of a few types of
//     ranges: a range of tiles in a Tile Pool (default), a count of tiles in the Tiled Resource to map to
//     to a single tile in a Tile Pool (sharing the tile), a count of tile mappings to in the Tiled Resource to skip
//     and leave as they are, or a count of tiles in the Tile Pool to map to NULL.
//
//     NumRanges specifies the number of Tile Ranges, where the total tiles identified across all ranges
//     must match the total number of tiles in the Tile Regions from the Tiled Resource described above.
//     Mappings are defined by iterating through the tiles in the Tile Regions in sequential order - x then y
//     then z order for box regions - while walking through the set of Tile Ranges in sequential order.
//     The breakdown of Tile Regions doesn't have to line up with the breakdown of Tile Ranges
//     - all that matters is the total number of tiles on both sides is equal so that each Tiled Resource tile
//     specified has a mapping specified.
//
//     pRangeFlags, pTilePoolStartOffsets and pRangeTileCounts are all arrays, of size NumRanges, describing the Tile
//     Ranges.  If pRangeFlags is NULL, all ranges are sequential tiles in the Tile Pool, otherwise for each range i
//     pRangeFlags[i] identifies how the mappings in that range of tiles work:
//
//     If pRangeFlags[i] is 0, that range defines sequential tiles in the Tile Pool, with the number of tiles being
//     pRangeTileCounts[i] and the starting location pTilePoolStartOffsets[i].  If NumRanges is 1, pRangeTileCounts
//     can be NULL and defaults to the total number of tiles specified by all the Tile Regions.
//
//     If pRangeFlags[i] is D3D11_TILE_RANGE_REUSE_SINGLE_TILE, pTilePoolStartOffsets[i] identifies the single
//     tile in the Tile Pool to map to, and pRangeTileCounts[i] specifies how many tiles from the Tile Regions to
//     map to that Tile Pool location.  If NumRanges is 1, pRangeTileCounts can be NULL and defaults to the total
//     number of tiles specified by all the Tile Regions.
//
//     If pRangeFlags[i] is D3D11_TILE_RANGE_NULL, pRangeTileCounts[i] specifies how many tiles from the Tile Regions
//     to map to NULL.  If NumRanges is 1, pRangeTileCounts can be NULL and defaults to the total
//     number of tiles specified by all the Tile Regions. pTilePoolStartOffsets[i] is ignored for NULL mappings.
//
//     If pRangeFlags[i] is D3D11_TILE_RANGE_SKIP, pRangeTileCounts[i] specifies how many tiles from the Tile Regions
//     to skip over and leave existing mappings unchanged for.  This can be useful if a Tile Region conveniently
//     bounds an area of Tile Mappings to update except with some exceptions that need to be left the same as
//     whatever they were mapped to before. pTilePoolStartOffsets[i] is ignored for SKIP mappings.
//
//  (5) Flags: D3D11_TILE_MAPPING_NO_OVERWRITE 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, E_INVALIDARG, E_OUTOFMEMORY or DXGI_ERROR_DEVICE_REMOVED.  E_OUTOFMEMORY 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).
//
// Validation remarks:
//
// The tile regions specified must entirely fit in the tiled resource or behavior is undefined (debug layer will emit an error).
// The number of tiles in the tile regions must match the number of tiles in all the tile ranges otherwise the
// call is dropped with E_INVALIDARG.  Other parameter arrors also result in the call being dropped with E_INVALIDARG - the
// debug layer provides explanations.
//

HRESULT
ID3D11DeviceContext2::
UpdateTileMappings( _In_ ID3D11Resource* pTiledResource,
                    _In_ UINT NumTiledResourceRegions,
                    _In_reads_opt_(NumTiledResourceRegions) const D3D11_TILED_RESOURCE_COORDINATE* pTiledResourceRegionStartCoordinates,
                    _In_reads_opt_(NumTiledResourceRegions) const D3D11_TILE_REGION_SIZE* pTiledResourceRegionSizes,
                    _In_opt_ ID3D11Buffer* pTilePool,
                    _In_ UINT NumRanges,
                    _In_reads_opt_(NumRanges) const UINT* pRangeFlags,
                    _In_reads_opt_(NumRanges) const UINT* pTilePoolStartOffsets,  // 0 based tile offsets
                                                                                  // counting in tiles (not bytes)
                    _In_reads_opt_(NumRanges) const UINT* pRangeTileCounts,
                    _In_ UINT Flags
                    );

// ----------------------------------------------------------
// Here are some examples of common UpdateTileMappings cases:
// ----------------------------------------------------------
//
// ----------------------------------------------
// Clearing an entire surface's mappings to 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,0,D3D11_TILE_MAPPING_NO_OVERWRITE);
//
// -------------------------------------------
// Mapping a region of tiles to a single tile:
// -------------------------------------------
// - 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);
//
// ----------------------------------------------------------
// Defining mappings for a set of disjoint individual tiles:
// ----------------------------------------------------------
// - 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);
//
// -----------------------------------------------------------------------------------
// Complex example - defining mappings for regions with some skips, some NULL mappings
// -----------------------------------------------------------------------------------
// - This complex example hard codes the parameter arrays, whereas in practice the
//   application would likely configure the paramaters 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 writen to the dest, though the implementation may be able to do better.
//
// If the dest resource has a different tile pool than the source, any existing mappings in the dest are cleared to NULL
// and the mappings from the source are applied.  This maintains the rule that a given resource can have mappings into
// only one tile pool at a time.
//
// 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).
//

HRESULT
ID3D11DeviceContext2::
CopyTileMappings( _In_ ID3D11Resource* pDestTiledResource,
                  _In_ const D3D11_TILED_RESOURCE_COORDINATE* pDestRegionStartCoordinate,
                  _In_ ID3D11Resource* pSourceTiledResource,
                  _In_ const D3D11_TILED_RESOURCE_COORDINATE* pSourceRegionStartCoordinate,
                  _In_ const D3D11_TILE_REGION_SIZE* pTileRegionSize,
                  _In_UINT Flags
                    // The only flag that can be specified is:
                    // D3D11_TILE_MAPPING_NO_OVERWRITE (see definition under UpdateTileMappings)
                 );
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



d3d/archive/images/d3d11/D3D11_3_FunctionalSpec.htm [4599:5005]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

The following APIs allow manipulation and querying of tile mappings. Update calls only affect the tiles identified in the call, and others are left as defined previously.

Any given tile from a Tile Pool can be mapped to multiple locations in a Resource and even multiple Resources. This includes tiles in a Resource that have an implementation chosen layout, described earlier, where multiple mipmaps are packed together into a single tile. The catch is that if data is written to the tile via one mapping, but read via a differently configured mapping, the results are undefined. Careful use of this flexibility can still be useful for an application though, like sharing a tile between resources that will not be used simultaneously, where the contents of the tile are always initialized through the same Resource mapping as they will be subsequently read from. Similarly a tile mapped to hold the packed mipmaps of multiple different Resources with the same surface dimensions will work fine - the data will appear the same in both mappings.

Changes to tile assignments for a Resource can be made at any time in an immediate or deferred context.

// --------------------------------------------------------------------------------------------------------------------------------
// Data Structures for Manipulating Tile Mappings
// --------------------------------------------------------------------------------------------------------------------------------

// For manipulating tile mappings, regions in tiled resources are described by a combination of:
// (1) tiled resource coordinate (defining the corner of a region) and
// (2) tile region size (defining the size of a region)
//
// These are separated into two structs rather than one so that the various APIs
// that use them can use different combinations of the parts.

typedef struct D3D11_TILED_RESOURCE_COORDINATE
{
    // Coordinate values below index tiles (not pixels or bytes).
    UINT X; // Used for buffer, 1D, 2D, 3D
    UINT Y; // Used for 2D, 3D
    UINT Z; // Used for 3D
    UINT Subresource; // indexes into mips, arrays. Used for 1D, 2D, 3D
    // For mipmaps that use nonstandard tiling and/or are packed, any subresource
    // value that indicates any of the packed mips all refer to the same tile.
};

typedef struct D3D11_TILE_REGION_SIZE
{
    UINT NumTiles;
    BOOL bUseBox; // TRUE: Uses width/height/depth parameters below to define the region.
                  //   width*height*depth must match NumTiles above.  (While
                  //   this looks like redundant information, the application likely has to know
                  //   how many tiles are involved anyway.)
                  //   The downside to using the box parameters is that one update region cannot
                  //   span mipmaps (though it can span array slices via the depth parameter).
                  //
                  // FALSE: Ignores width/height/depth parameters - NumTiles just traverses tiles in
                  //   the resource linearly across x, then y, then z (as applicable) then spilling over
                  //   mips/arrays in subresource order.  Useful for just mapping an entire resource
                  //   at once, for example.
                  //
                  // In either case, the starting location for the region within the resource
                  // is specified as a separate parameter outside this struct, using x,y,z coordinates
                  // regardless of whether bUseBox above is TRUE or FALSE.
                  //
                  // When the region includes mipmaps that are packed with nonstandard tiling,
                  // bUseBox must be FALSE, since tile dimensions are not standard and the application
                  // only knows a count of how many tiles are consumed by the packed area (which is per
                  // array slice).  The corresponding (separate) starting location parameter uses x to
                  // offset into the flat range of tiles in this case, and y,z coordinates must be 0.

    UINT Width;   // In tiles, used for buffer, 1D, 2D, 3D
    UINT16 Height; // In tiles, used for 2D, 3D
    UINT16 Depth; // In tiles, used for 3D or arrays.  For arrays, advancing in depth jumps to next slice
                  // of same mip size, which is not contiguous in the subresource counting space
                  // if there are multiple mips.
};

typedef enum D3D11_TILE_MAPPING_FLAG
{
    D3D11_TILE_MAPPING_NO_OVERWRITE = 0x00000001,
} D3D11_TILE_MAPPING_FLAG;

typedef enum D3D11_TILE_RANGE_FLAG
{
    D3D11_TILE_RANGE_NULL = 0x00000001,
    D3D11_TILE_RANGE_SKIP = 0x00000002,
    D3D11_TILE_RANGE_REUSE_SINGLE_TILE = 0x00000004,
} D3D11_TILE_RANGE_FLAG;

// --------------------------------------------------------------------------------------------------------------------------------
// UpdateTileMappings
// --------------------------------------------------------------------------------------------------------------------------------
// UpdateTileMappings adds/removes/changes mappings of tile locations in Tiled Resources to memory locations in a Tile Pool.
// The API has several modes of operation to enable a few common tasks to be efficiently described.
//
// The basic orgainization of the parameters is as follows:
//
//      (1) Tiled Resource whose mappings are being updated
//      (2) Set of Tile Regions on the Tiled Resource whose mappings to update.
//      (3) Tile Pool providing memory where tile mappings can go.
//      (4) Set of Tile Ranges where mappings are going: to the Tile Pool in (3), to NULL, and/or other options.
//      (5) Flags parameter for overall options
//
// More detailed breakdown of the parameters:
//
// (1) Tiled Resource whose mappings are being updated - resource created with the D3D11_RESOURCE_MISC_TILED flag.
//     Mappings start off all NULL when a resource is initially created.
//
// (2) Set of Tile Regions on the Tiled Resource whose mappings to update.  One API call can update many mappings,
//     but an application can make multiple calls as well if that is more convenient (with a bit more API call overhead).
//     NumTiledResourceRegions specifies how many regions there are, pTiledResourceRegionStartCoordinates and
//     pTiledResourceRegionSizes are each arrays identifying the start location and extend of each region.
//     If NumTiledResourceRegions is 1, then for convenience either or both of the arrays describing the regions can
//     be NULL.  NULL for pTiledResourceRegionStartCoordinates means the start coordinate is all 0's, and NULL for
//     pTiledResourceRegionSizes identifies a default region that is the full set of tiles for the entire Tiled Resource,
//     including all mipmaps and/or array slices.
//
//     If pTiledResourceRegionStartCoordinates is not NULL and pTiledResourceRegionSizes is NULL, then the region
//     size defaults to 1 tile for all regions.  This makes it easy to define mappings for a set of individual tiles
//     each at disparate locations by providing an array of locations in pTiledResourceRegionStartCoordinates without
//     having to send an array of pTiledResourceRegionSizes all set to 1.
//
//     The updates are applied from first region to last, so if regions
//     overlap in a single call, the updates later in the list overwrite the areas overlapping with previous updates.
//
// (3) Tile Pool providing memory where mappings are pointing to.  A Tiled Resource can point to a single Tile Pool
//     at a time.  If a new Tile Pool is specified (for the first time or different
//     from the last time a Tile Pool was specified), all existing tile mappings for the Tiled Resource are cleared
//     and the new set of mappings in the current call are applied for the new Tile Pool.
//     If no Tile Pool is specified (NULL), or the same one as a previous call to UpdateTileMappings is provided,
//     the call just adds the new mappings to existing ones (overwriting on overlap).
//     If the call is only defining NULL mappings, no Tile Pool needs to be specified, since it doesn't matter.
//     But if one is specified anyway it takes the same behavior as described above when providing a Tile Pool.
//
// (4) Set of Tile Ranges where mappings are going to.  Each given Tile Range can specify one of a few types of
//     ranges: a range of tiles in a Tile Pool (default), a count of tiles in the Tiled Resource to map to
//     to a single tile in a Tile Pool (sharing the tile), a count of tile mappings to in the Tiled Resource to skip
//     and leave as they are, or a count of tiles in the Tile Pool to map to NULL.
//
//     NumRanges specifies the number of Tile Ranges, where the total tiles identified across all ranges
//     must match the total number of tiles in the Tile Regions from the Tiled Resource described above.
//     Mappings are defined by iterating through the tiles in the Tile Regions in sequential order - x then y
//     then z order for box regions - while walking through the set of Tile Ranges in sequential order.
//     The breakdown of Tile Regions doesn't have to line up with the breakdown of Tile Ranges
//     - all that matters is the total number of tiles on both sides is equal so that each Tiled Resource tile
//     specified has a mapping specified.
//
//     pRangeFlags, pTilePoolStartOffsets and pRangeTileCounts are all arrays, of size NumRanges, describing the Tile
//     Ranges.  If pRangeFlags is NULL, all ranges are sequential tiles in the Tile Pool, otherwise for each range i
//     pRangeFlags[i] identifies how the mappings in that range of tiles work:
//
//     If pRangeFlags[i] is 0, that range defines sequential tiles in the Tile Pool, with the number of tiles being
//     pRangeTileCounts[i] and the starting location pTilePoolStartOffsets[i].  If NumRanges is 1, pRangeTileCounts
//     can be NULL and defaults to the total number of tiles specified by all the Tile Regions.
//
//     If pRangeFlags[i] is D3D11_TILE_RANGE_REUSE_SINGLE_TILE, pTilePoolStartOffsets[i] identifies the single
//     tile in the Tile Pool to map to, and pRangeTileCounts[i] specifies how many tiles from the Tile Regions to
//     map to that Tile Pool location.  If NumRanges is 1, pRangeTileCounts can be NULL and defaults to the total
//     number of tiles specified by all the Tile Regions.
//
//     If pRangeFlags[i] is D3D11_TILE_RANGE_NULL, pRangeTileCounts[i] specifies how many tiles from the Tile Regions
//     to map to NULL.  If NumRanges is 1, pRangeTileCounts can be NULL and defaults to the total
//     number of tiles specified by all the Tile Regions. pTilePoolStartOffsets[i] is ignored for NULL mappings.
//
//     If pRangeFlags[i] is D3D11_TILE_RANGE_SKIP, pRangeTileCounts[i] specifies how many tiles from the Tile Regions
//     to skip over and leave existing mappings unchanged for.  This can be useful if a Tile Region conveniently
//     bounds an area of Tile Mappings to update except with some exceptions that need to be left the same as
//     whatever they were mapped to before. pTilePoolStartOffsets[i] is ignored for SKIP mappings.
//
//  (5) Flags: D3D11_TILE_MAPPING_NO_OVERWRITE 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, E_INVALIDARG, E_OUTOFMEMORY or DXGI_ERROR_DEVICE_REMOVED.  E_OUTOFMEMORY 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).
//
// Validation remarks:
//
// The tile regions specified must entirely fit in the tiled resource or behavior is undefined (debug layer will emit an error).
// The number of tiles in the tile regions must match the number of tiles in all the tile ranges otherwise the
// call is dropped with E_INVALIDARG.  Other parameter arrors also result in the call being dropped with E_INVALIDARG - the
// debug layer provides explanations.
//

HRESULT
ID3D11DeviceContext2::
UpdateTileMappings( _In_ ID3D11Resource* pTiledResource,
                    _In_ UINT NumTiledResourceRegions,
                    _In_reads_opt_(NumTiledResourceRegions) const D3D11_TILED_RESOURCE_COORDINATE* pTiledResourceRegionStartCoordinates,
                    _In_reads_opt_(NumTiledResourceRegions) const D3D11_TILE_REGION_SIZE* pTiledResourceRegionSizes,
                    _In_opt_ ID3D11Buffer* pTilePool,
                    _In_ UINT NumRanges,
                    _In_reads_opt_(NumRanges) const UINT* pRangeFlags,
                    _In_reads_opt_(NumRanges) const UINT* pTilePoolStartOffsets,  // 0 based tile offsets
                                                                                  // counting in tiles (not bytes)
                    _In_reads_opt_(NumRanges) const UINT* pRangeTileCounts,
                    _In_ UINT Flags
                    );

// ----------------------------------------------------------
// Here are some examples of common UpdateTileMappings cases:
// ----------------------------------------------------------
//
// ----------------------------------------------
// Clearing an entire surface's mappings to 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,0,D3D11_TILE_MAPPING_NO_OVERWRITE);
//
// -------------------------------------------
// Mapping a region of tiles to a single tile:
// -------------------------------------------
// - 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);
//
// ----------------------------------------------------------
// Defining mappings for a set of disjoint individual tiles:
// ----------------------------------------------------------
// - 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);
//
// -----------------------------------------------------------------------------------
// Complex example - defining mappings for regions with some skips, some NULL mappings
// -----------------------------------------------------------------------------------
// - This complex example hard codes the parameter arrays, whereas in practice the
//   application would likely configure the paramaters 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 writen to the dest, though the implementation may be able to do better.
//
// If the dest resource has a different tile pool than the source, any existing mappings in the dest are cleared to NULL
// and the mappings from the source are applied.  This maintains the rule that a given resource can have mappings into
// only one tile pool at a time.
//
// 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).
//

HRESULT
ID3D11DeviceContext2::
CopyTileMappings( _In_ ID3D11Resource* pDestTiledResource,
                  _In_ const D3D11_TILED_RESOURCE_COORDINATE* pDestRegionStartCoordinate,
                  _In_ ID3D11Resource* pSourceTiledResource,
                  _In_ const D3D11_TILED_RESOURCE_COORDINATE* pSourceRegionStartCoordinate,
                  _In_ const D3D11_TILE_REGION_SIZE* pTileRegionSize,
                  _In_UINT Flags
                    // The only flag that can be specified is:
                    // D3D11_TILE_MAPPING_NO_OVERWRITE (see definition under UpdateTileMappings)
                 );
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -