텍스처를 타일형 리소스로 만들게 되면
void GetResourceTiling(
[in] ID3D11Resource *pTiledResource, // 정보를 가져올 타일형 리소스
[out] UINT *pNumTilesForEntireResource, // 리소스에서 사용하는 총 타일의 수
[out] D3D11_PACKED_MIP_DESC *pPackedMipDesc, // Packed 된 밉맵 정보
[out] D3D11_TILE_SHAPE *pStandardTileShapeForNonPackedMips, // 타일의 텍셀 너비, 높이, 깊이
[in, out] UINT *pNumSubresourceTilings, // 하위 리소스의 타일 수
[in] UINT FirstSubresourceTilingToGet, // 가져올 하위 리소스 타일의 수
[out] D3D11_SUBRESOURCE_TILING *pSubresourceTilingsForNonPackedMips // 하위 리소스 타일의 정보
);
ID2D11Device2로 부터 타일에 대한 정보를 가지고 올 수 있다.
D3D11_BUFFER_DESC _tilePoolDesc;
ZeroMemory(&_tilePoolDesc, sizeof(_tilePoolDesc));
_tilePoolDesc.ByteWidth = TILE_POOL_NUM * 65536; // 64 kb 크기의 타일을 생성할 타일 갯수만큼
_tilePoolDesc.Usage = D3D11_USAGE_DEFAULT;
_tilePoolDesc.MiscFlags = D3D11_RESOURCE_MISC_TILE_POOL;
device->CreateBuffer(&_tilePoolDesc, nullptr, &m_TilePool);
타일형 리소스를 사용하기 위해선 실제로 물리적인 메모리를 가지고있는 타일풀을 만들어 주어야한다. D3D11_RESOURCE_MISC_TILE_POOL 를 사용하여 버퍼를 만들면 타일 풀로 사용 할 수 있게된다.
HRESULT UpdateTileMappings(
[in] ID3D11Resource *pTiledResource,
[in] UINT NumTiledResourceRegions,
[in] const D3D11_TILED_RESOURCE_COORDINATE *pTiledResourceRegionStartCoordinates,
[in] const D3D11_TILE_REGION_SIZE *pTiledResourceRegionSizes,
[in] ID3D11Buffer *pTilePool,
UINT NumRanges,
const UINT *pRangeFlags,
const UINT *pTilePoolStartOffsets,
const UINT *pRangeTileCounts,
[in] UINT Flags);
타일풀을 만들게 되면 이제 타일풀의 버퍼를 타일에 맵핑 할 수 있다. ID3D11DeviceContext2의 UpdateTileMappings를 통해 각 타일에 어느 타일풀을 맵핑 할지 정해주면된다. 지금 타일풀을 하나로 만들었기 때문에 타일풀을 매핑할때 offsets 값을 통해 매핑할 타일풀의 위치를 선택 할 수 있다.
typedef struct D3D11_TILED_RESOURCE_COORDINATE {
UINT X; // 매핑할 타일의 x 위치
UINT Y; // 매핑할 타일의 y 위치
UINT Z; // 매핑할 타일의 z 위치
UINT Subresource; // mipmap 및 배열에 대한 하위 리소스 인덱스 값
} D3D11_TILED_RESOURCE_COORDINATE;
매핑할 타일의 위치는 2차원 좌표계를 생각하고 위치를 정해주면된다.
typedef struct D3D11_TILE_REGION_SIZE {
UINT NumTiles; // 타일 영억의 타일 수
BOOL bUseBox; // 타일의 박스 여부
UINT Width; // 타일로 된 영역의 너비
UINT16 Height; // 타일로 된 영역의 높이
UINT16 Depth; // 타일로 된 영역의 깊이
} D3D11_TILE_REGION_SIZE;
그러나 이전에 우리는 하나의 타일에 들어가게되는 압축된 밉맵에 관해 알고 있다. bUseBox 값을 True로 주게 되면 width와 height, depth 값을 사용 하여 타일형 리소스의 지역을 박스의 크기만큼 매핑 할 수 있다. False를 주게 되면 위의 세개의 값을 무시하고 NunTiles 멤버를 사용하여 리소스의 타일을 하위 밉맵 순서로 분산시켜 매핑 한다.
이제 타일형 리소스에 물리적인 메모리가 있는 타일 풀을 매핑시켰다. 그러면 타일풀에 있는 타일의 콘텐츠를 업데이트 하면된다.
void UpdateTiles(
[in] ID3D11Resource *pDestTiledResource, // 업데이트할 타일형 리소스 포인터
[in] const D3D11_TILED_RESOURCE_COORDINATE *pDestTileRegionStartCoordinate, // 업데이트할 타일의 구역
[in] const D3D11_TILE_REGION_SIZE *pDestTileRegionSize, // 타일풀의 정보
[in] const void *pSourceTileData, // 원본 타일 데이터
[in] UINT Flags // D3D11_TILE_COPY_NO_OVERWRITE
);
// DX11의 경우에는 리소스 배리어가 내부적으로 감추어져있으나 타일형 리소스의 경우에는 노출되어 있다.
_pContext2->TiledResourceBarrier(nullptr, nullptr);
_pContext2->UpdateTiles(m_pTiledResource, &_trc, _trs, src, D3D11_TILE_COPY_NO_OVERWITE);
압축되지 않은 밉맵의 타일들에 대해 이미지를 업데이트 할 경우에는 위 함수를 사용하여 업데이트하면 된다.
void CopyTiles(
[in] ID3D11Resource *pTiledResource,
[in] const D3D11_TILED_RESOURCE_COORDINATE *pTileRegionStartCoordinate,
[in] const D3D11_TILE_REGION_SIZE *pTileRegionSize,
[in] ID3D11Buffer *pBuffer,
[in] UINT64 BufferStartOffsetInBytes,
[in] UINT Flags
);
또 다른 방식으로 버퍼에서 복사하는 방법이 있으나 그래픽 메모리의 크기를 줄이기 위해 사용하려 하기때문에 버퍼에서 버퍼로 복사하는 것은 의미가 별로 없다, 그러나 GPU 생성 정보를 타일로 사용하려는 경우에는 유용할 수 있다.
_pContext->UpdateSubresource(m_TiledResource, mipLv, nullptr, src, rowPitch, slicePitch, D3D11_COPY_NO_OVERWRITE);
압축된 밉맵의 타일의 경우에는 UpdateTiles를 사용하여 데이터를 업데이트하기 어렵기때문에 일반 텍스처를 업데이트 할때와 같이 UpdateSubresource를 사용하여 업데이트 해준다.
'DirectX11' 카테고리의 다른 글
Tiled Resources (1) (0) | 2023.07.03 |
---|---|
Texture Compression(Block Compression) (0) | 2023.06.27 |
GPU Instancing (0) | 2023.06.22 |
Voxel GI - Cone Tracing (0) | 2023.05.25 |
Voxel GI - Voxelize (0) | 2023.05.25 |