Search code examples
direct3d12

How to get the size of a resource in Direct 3D 12?


How to get the size of an entire resource regardless of subresource count in Direct 3D 12? What I mean by "the size of an entire resource" is the number of bytes an entire resource is mapped to its heap. In other words, if a resource consists of multiple subresources, the total number of bytes of all subresources.

The reason is I'd want to check the size of texture pixel data and upload resource before copying using ID3D12Resource::Map. Also, I'd want to check the size of upload resource and default resource before copying (recording) such as ID3D12GraphicsCommandList::CopyResource or ID3D12GraphicsCommandList::CopyBufferRegion.

What I know so far is ID3D12Device::GetResourceAllocationInfo and ID3D12Device::GetCopyableFootprints.

For example, I had a texture which has resource desc, which dimension is D3D12_RESOURCE_DIMENSION_TEXTURE2D, width and height 210 respectively, format DXGI_FORMAT_B8G8R8A8_UNORM.

ID3D12Device::GetCopyableFootprints resulted pTotalBytes of 214856 (= 1024(row pitch) * 209 + 840(last row)).

ID3D12Device::GetResourceAllocationInfo resulted SizeInBytes of 262144 and alignment of 65536.

ID3D12Device::GetCopyableFootprints seems to be what I want. If this is right, does passing 0 FirstSubresource, 1 NumSubresources, 0 BaseOffset for ID3D12Device::GetCopyableFootprints always gives total number of bytes of all subresources of a resource?


Solution

  • You have to provide the proper number of sub resources to get the full size of the resource via D3D12Device::GetCopyableFootprints. The value from ID3D12Device::GetResourceAllocationInfo for SizeInBytes is the number you need for allocating a heap big enough to hold the entire resource.

    The total number of sub resources for a resource is deterministic from the description of the resource, and how to compute this number is very easy.

    UINT ArraySize = (Dimension != D3D12_RESOURCE_DIMENSION_TEXTURE3D)
        ? DepthOrArraySize : 1u;
    UINT numSubresources = MipLevels * ArraySize * PlaneCount;
    

    Note for planar formats, you must also multiply by the number of planes in the format given from D3D12_FEATURE_DATA_FORMAT_INFO.PlaneCount via CheckFeatureSupport. Unless you are using video formats or depth/stencil formats, they are not planar (i.e. PlaneCount above is 1).

    Note I updated an answer I gave in this thread. I had forgotten that DirectXTex has each miplevel of a slice of a volume texture as it's own image, but Direct3D does not.

    You may want to take a look at Direct Tool Kit for DX12 and in particular ResourceUploadBatch.