123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602 |
- //*********************************************************
- //
- // Copyright (c) Microsoft Corporation.
- // Licensed under the MIT License (MIT).
- //
- //*********************************************************
- #pragma once
- #ifndef __cplusplus
- #error D3DX12 requires C++
- #endif
- #include "d3d12.h"
- #include "d3dx12_core.h"
- #include "d3dx12_property_format_table.h"
- //------------------------------------------------------------------------------------------------
- template <typename T, typename U, typename V>
- inline void D3D12DecomposeSubresource( UINT Subresource, UINT MipLevels, UINT ArraySize, _Out_ T& MipSlice, _Out_ U& ArraySlice, _Out_ V& PlaneSlice ) noexcept
- {
- MipSlice = static_cast<T>(Subresource % MipLevels);
- ArraySlice = static_cast<U>((Subresource / MipLevels) % ArraySize);
- PlaneSlice = static_cast<V>(Subresource / (MipLevels * ArraySize));
- }
- //------------------------------------------------------------------------------------------------
- // Row-by-row memcpy
- inline void MemcpySubresource(
- _In_ const D3D12_MEMCPY_DEST* pDest,
- _In_ const D3D12_SUBRESOURCE_DATA* pSrc,
- SIZE_T RowSizeInBytes,
- UINT NumRows,
- UINT NumSlices) noexcept
- {
- for (UINT z = 0; z < NumSlices; ++z)
- {
- auto pDestSlice = static_cast<BYTE*>(pDest->pData) + pDest->SlicePitch * z;
- auto pSrcSlice = static_cast<const BYTE*>(pSrc->pData) + pSrc->SlicePitch * LONG_PTR(z);
- for (UINT y = 0; y < NumRows; ++y)
- {
- memcpy(pDestSlice + pDest->RowPitch * y,
- pSrcSlice + pSrc->RowPitch * LONG_PTR(y),
- RowSizeInBytes);
- }
- }
- }
- //------------------------------------------------------------------------------------------------
- // Row-by-row memcpy
- inline void MemcpySubresource(
- _In_ const D3D12_MEMCPY_DEST* pDest,
- _In_ const void* pResourceData,
- _In_ const D3D12_SUBRESOURCE_INFO* pSrc,
- SIZE_T RowSizeInBytes,
- UINT NumRows,
- UINT NumSlices) noexcept
- {
- for (UINT z = 0; z < NumSlices; ++z)
- {
- auto pDestSlice = static_cast<BYTE*>(pDest->pData) + pDest->SlicePitch * z;
- auto pSrcSlice = (static_cast<const BYTE*>(pResourceData) + pSrc->Offset) + pSrc->DepthPitch * ULONG_PTR(z);
- for (UINT y = 0; y < NumRows; ++y)
- {
- memcpy(pDestSlice + pDest->RowPitch * y,
- pSrcSlice + pSrc->RowPitch * ULONG_PTR(y),
- RowSizeInBytes);
- }
- }
- }
- //------------------------------------------------------------------------------------------------
- // Returns required size of a buffer to be used for data upload
- inline UINT64 GetRequiredIntermediateSize(
- _In_ ID3D12Resource* pDestinationResource,
- _In_range_(0,D3D12_REQ_SUBRESOURCES) UINT FirstSubresource,
- _In_range_(0,D3D12_REQ_SUBRESOURCES-FirstSubresource) UINT NumSubresources) noexcept
- {
- #if defined(_MSC_VER) || !defined(_WIN32)
- const auto Desc = pDestinationResource->GetDesc();
- #else
- D3D12_RESOURCE_DESC tmpDesc;
- const auto& Desc = *pDestinationResource->GetDesc(&tmpDesc);
- #endif
- UINT64 RequiredSize = 0;
- ID3D12Device* pDevice = nullptr;
- pDestinationResource->GetDevice(IID_ID3D12Device, reinterpret_cast<void**>(&pDevice));
- pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, 0, nullptr, nullptr, nullptr, &RequiredSize);
- pDevice->Release();
- return RequiredSize;
- }
- //------------------------------------------------------------------------------------------------
- // All arrays must be populated (e.g. by calling GetCopyableFootprints)
- inline UINT64 UpdateSubresources(
- _In_ ID3D12GraphicsCommandList* pCmdList,
- _In_ ID3D12Resource* pDestinationResource,
- _In_ ID3D12Resource* pIntermediate,
- _In_range_(0,D3D12_REQ_SUBRESOURCES) UINT FirstSubresource,
- _In_range_(0,D3D12_REQ_SUBRESOURCES-FirstSubresource) UINT NumSubresources,
- UINT64 RequiredSize,
- _In_reads_(NumSubresources) const D3D12_PLACED_SUBRESOURCE_FOOTPRINT* pLayouts,
- _In_reads_(NumSubresources) const UINT* pNumRows,
- _In_reads_(NumSubresources) const UINT64* pRowSizesInBytes,
- _In_reads_(NumSubresources) const D3D12_SUBRESOURCE_DATA* pSrcData) noexcept
- {
- // Minor validation
- #if defined(_MSC_VER) || !defined(_WIN32)
- const auto IntermediateDesc = pIntermediate->GetDesc();
- const auto DestinationDesc = pDestinationResource->GetDesc();
- #else
- D3D12_RESOURCE_DESC tmpDesc1, tmpDesc2;
- const auto& IntermediateDesc = *pIntermediate->GetDesc(&tmpDesc1);
- const auto& DestinationDesc = *pDestinationResource->GetDesc(&tmpDesc2);
- #endif
- if (IntermediateDesc.Dimension != D3D12_RESOURCE_DIMENSION_BUFFER ||
- IntermediateDesc.Width < RequiredSize + pLayouts[0].Offset ||
- RequiredSize > SIZE_T(-1) ||
- (DestinationDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER &&
- (FirstSubresource != 0 || NumSubresources != 1)))
- {
- return 0;
- }
- BYTE* pData;
- HRESULT hr = pIntermediate->Map(0, nullptr, reinterpret_cast<void**>(&pData));
- if (FAILED(hr))
- {
- return 0;
- }
- for (UINT i = 0; i < NumSubresources; ++i)
- {
- if (pRowSizesInBytes[i] > SIZE_T(-1)) return 0;
- D3D12_MEMCPY_DEST DestData = { pData + pLayouts[i].Offset, pLayouts[i].Footprint.RowPitch, SIZE_T(pLayouts[i].Footprint.RowPitch) * SIZE_T(pNumRows[i]) };
- MemcpySubresource(&DestData, &pSrcData[i], static_cast<SIZE_T>(pRowSizesInBytes[i]), pNumRows[i], pLayouts[i].Footprint.Depth);
- }
- pIntermediate->Unmap(0, nullptr);
- if (DestinationDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER)
- {
- pCmdList->CopyBufferRegion(
- pDestinationResource, 0, pIntermediate, pLayouts[0].Offset, pLayouts[0].Footprint.Width);
- }
- else
- {
- for (UINT i = 0; i < NumSubresources; ++i)
- {
- const CD3DX12_TEXTURE_COPY_LOCATION Dst(pDestinationResource, i + FirstSubresource);
- const CD3DX12_TEXTURE_COPY_LOCATION Src(pIntermediate, pLayouts[i]);
- pCmdList->CopyTextureRegion(&Dst, 0, 0, 0, &Src, nullptr);
- }
- }
- return RequiredSize;
- }
- //------------------------------------------------------------------------------------------------
- // All arrays must be populated (e.g. by calling GetCopyableFootprints)
- inline UINT64 UpdateSubresources(
- _In_ ID3D12GraphicsCommandList* pCmdList,
- _In_ ID3D12Resource* pDestinationResource,
- _In_ ID3D12Resource* pIntermediate,
- _In_range_(0,D3D12_REQ_SUBRESOURCES) UINT FirstSubresource,
- _In_range_(0,D3D12_REQ_SUBRESOURCES-FirstSubresource) UINT NumSubresources,
- UINT64 RequiredSize,
- _In_reads_(NumSubresources) const D3D12_PLACED_SUBRESOURCE_FOOTPRINT* pLayouts,
- _In_reads_(NumSubresources) const UINT* pNumRows,
- _In_reads_(NumSubresources) const UINT64* pRowSizesInBytes,
- _In_ const void* pResourceData,
- _In_reads_(NumSubresources) const D3D12_SUBRESOURCE_INFO* pSrcData) noexcept
- {
- // Minor validation
- #if defined(_MSC_VER) || !defined(_WIN32)
- const auto IntermediateDesc = pIntermediate->GetDesc();
- const auto DestinationDesc = pDestinationResource->GetDesc();
- #else
- D3D12_RESOURCE_DESC tmpDesc1, tmpDesc2;
- const auto& IntermediateDesc = *pIntermediate->GetDesc(&tmpDesc1);
- const auto& DestinationDesc = *pDestinationResource->GetDesc(&tmpDesc2);
- #endif
- if (IntermediateDesc.Dimension != D3D12_RESOURCE_DIMENSION_BUFFER ||
- IntermediateDesc.Width < RequiredSize + pLayouts[0].Offset ||
- RequiredSize > SIZE_T(-1) ||
- (DestinationDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER &&
- (FirstSubresource != 0 || NumSubresources != 1)))
- {
- return 0;
- }
- BYTE* pData;
- HRESULT hr = pIntermediate->Map(0, nullptr, reinterpret_cast<void**>(&pData));
- if (FAILED(hr))
- {
- return 0;
- }
- for (UINT i = 0; i < NumSubresources; ++i)
- {
- if (pRowSizesInBytes[i] > SIZE_T(-1)) return 0;
- D3D12_MEMCPY_DEST DestData = { pData + pLayouts[i].Offset, pLayouts[i].Footprint.RowPitch, SIZE_T(pLayouts[i].Footprint.RowPitch) * SIZE_T(pNumRows[i]) };
- MemcpySubresource(&DestData, pResourceData, &pSrcData[i], static_cast<SIZE_T>(pRowSizesInBytes[i]), pNumRows[i], pLayouts[i].Footprint.Depth);
- }
- pIntermediate->Unmap(0, nullptr);
- if (DestinationDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER)
- {
- pCmdList->CopyBufferRegion(
- pDestinationResource, 0, pIntermediate, pLayouts[0].Offset, pLayouts[0].Footprint.Width);
- }
- else
- {
- for (UINT i = 0; i < NumSubresources; ++i)
- {
- const CD3DX12_TEXTURE_COPY_LOCATION Dst(pDestinationResource, i + FirstSubresource);
- const CD3DX12_TEXTURE_COPY_LOCATION Src(pIntermediate, pLayouts[i]);
- pCmdList->CopyTextureRegion(&Dst, 0, 0, 0, &Src, nullptr);
- }
- }
- return RequiredSize;
- }
- //------------------------------------------------------------------------------------------------
- // Heap-allocating UpdateSubresources implementation
- inline UINT64 UpdateSubresources(
- _In_ ID3D12GraphicsCommandList* pCmdList,
- _In_ ID3D12Resource* pDestinationResource,
- _In_ ID3D12Resource* pIntermediate,
- UINT64 IntermediateOffset,
- _In_range_(0,D3D12_REQ_SUBRESOURCES) UINT FirstSubresource,
- _In_range_(0,D3D12_REQ_SUBRESOURCES-FirstSubresource) UINT NumSubresources,
- _In_reads_(NumSubresources) const D3D12_SUBRESOURCE_DATA* pSrcData) noexcept
- {
- UINT64 RequiredSize = 0;
- const auto MemToAlloc = static_cast<UINT64>(sizeof(D3D12_PLACED_SUBRESOURCE_FOOTPRINT) + sizeof(UINT) + sizeof(UINT64)) * NumSubresources;
- if (MemToAlloc > SIZE_MAX)
- {
- return 0;
- }
- void* pMem = HeapAlloc(GetProcessHeap(), 0, static_cast<SIZE_T>(MemToAlloc));
- if (pMem == nullptr)
- {
- return 0;
- }
- auto pLayouts = static_cast<D3D12_PLACED_SUBRESOURCE_FOOTPRINT*>(pMem);
- auto pRowSizesInBytes = reinterpret_cast<UINT64*>(pLayouts + NumSubresources);
- auto pNumRows = reinterpret_cast<UINT*>(pRowSizesInBytes + NumSubresources);
- #if defined(_MSC_VER) || !defined(_WIN32)
- const auto Desc = pDestinationResource->GetDesc();
- #else
- D3D12_RESOURCE_DESC tmpDesc;
- const auto& Desc = *pDestinationResource->GetDesc(&tmpDesc);
- #endif
- ID3D12Device* pDevice = nullptr;
- pDestinationResource->GetDevice(IID_ID3D12Device, reinterpret_cast<void**>(&pDevice));
- pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, IntermediateOffset, pLayouts, pNumRows, pRowSizesInBytes, &RequiredSize);
- pDevice->Release();
- const UINT64 Result = UpdateSubresources(pCmdList, pDestinationResource, pIntermediate, FirstSubresource, NumSubresources, RequiredSize, pLayouts, pNumRows, pRowSizesInBytes, pSrcData);
- HeapFree(GetProcessHeap(), 0, pMem);
- return Result;
- }
- //------------------------------------------------------------------------------------------------
- // Heap-allocating UpdateSubresources implementation
- inline UINT64 UpdateSubresources(
- _In_ ID3D12GraphicsCommandList* pCmdList,
- _In_ ID3D12Resource* pDestinationResource,
- _In_ ID3D12Resource* pIntermediate,
- UINT64 IntermediateOffset,
- _In_range_(0,D3D12_REQ_SUBRESOURCES) UINT FirstSubresource,
- _In_range_(0,D3D12_REQ_SUBRESOURCES-FirstSubresource) UINT NumSubresources,
- _In_ const void* pResourceData,
- _In_reads_(NumSubresources) const D3D12_SUBRESOURCE_INFO* pSrcData) noexcept
- {
- UINT64 RequiredSize = 0;
- const auto MemToAlloc = static_cast<UINT64>(sizeof(D3D12_PLACED_SUBRESOURCE_FOOTPRINT) + sizeof(UINT) + sizeof(UINT64)) * NumSubresources;
- if (MemToAlloc > SIZE_MAX)
- {
- return 0;
- }
- void* pMem = HeapAlloc(GetProcessHeap(), 0, static_cast<SIZE_T>(MemToAlloc));
- if (pMem == nullptr)
- {
- return 0;
- }
- auto pLayouts = static_cast<D3D12_PLACED_SUBRESOURCE_FOOTPRINT*>(pMem);
- auto pRowSizesInBytes = reinterpret_cast<UINT64*>(pLayouts + NumSubresources);
- auto pNumRows = reinterpret_cast<UINT*>(pRowSizesInBytes + NumSubresources);
- #if defined(_MSC_VER) || !defined(_WIN32)
- const auto Desc = pDestinationResource->GetDesc();
- #else
- D3D12_RESOURCE_DESC tmpDesc;
- const auto& Desc = *pDestinationResource->GetDesc(&tmpDesc);
- #endif
- ID3D12Device* pDevice = nullptr;
- pDestinationResource->GetDevice(IID_ID3D12Device, reinterpret_cast<void**>(&pDevice));
- pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, IntermediateOffset, pLayouts, pNumRows, pRowSizesInBytes, &RequiredSize);
- pDevice->Release();
- const UINT64 Result = UpdateSubresources(pCmdList, pDestinationResource, pIntermediate, FirstSubresource, NumSubresources, RequiredSize, pLayouts, pNumRows, pRowSizesInBytes, pResourceData, pSrcData);
- HeapFree(GetProcessHeap(), 0, pMem);
- return Result;
- }
- //------------------------------------------------------------------------------------------------
- // Stack-allocating UpdateSubresources implementation
- template <UINT MaxSubresources>
- inline UINT64 UpdateSubresources(
- _In_ ID3D12GraphicsCommandList* pCmdList,
- _In_ ID3D12Resource* pDestinationResource,
- _In_ ID3D12Resource* pIntermediate,
- UINT64 IntermediateOffset,
- _In_range_(0,MaxSubresources) UINT FirstSubresource,
- _In_range_(1,MaxSubresources-FirstSubresource) UINT NumSubresources,
- _In_reads_(NumSubresources) const D3D12_SUBRESOURCE_DATA* pSrcData) noexcept
- {
- UINT64 RequiredSize = 0;
- D3D12_PLACED_SUBRESOURCE_FOOTPRINT Layouts[MaxSubresources];
- UINT NumRows[MaxSubresources];
- UINT64 RowSizesInBytes[MaxSubresources];
- #if defined(_MSC_VER) || !defined(_WIN32)
- const auto Desc = pDestinationResource->GetDesc();
- #else
- D3D12_RESOURCE_DESC tmpDesc;
- const auto& Desc = *pDestinationResource->GetDesc(&tmpDesc);
- #endif
- ID3D12Device* pDevice = nullptr;
- pDestinationResource->GetDevice(IID_ID3D12Device, reinterpret_cast<void**>(&pDevice));
- pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, IntermediateOffset, Layouts, NumRows, RowSizesInBytes, &RequiredSize);
- pDevice->Release();
- return UpdateSubresources(pCmdList, pDestinationResource, pIntermediate, FirstSubresource, NumSubresources, RequiredSize, Layouts, NumRows, RowSizesInBytes, pSrcData);
- }
- //------------------------------------------------------------------------------------------------
- // Stack-allocating UpdateSubresources implementation
- template <UINT MaxSubresources>
- inline UINT64 UpdateSubresources(
- _In_ ID3D12GraphicsCommandList* pCmdList,
- _In_ ID3D12Resource* pDestinationResource,
- _In_ ID3D12Resource* pIntermediate,
- UINT64 IntermediateOffset,
- _In_range_(0,MaxSubresources) UINT FirstSubresource,
- _In_range_(1,MaxSubresources-FirstSubresource) UINT NumSubresources,
- _In_ const void* pResourceData,
- _In_reads_(NumSubresources) const D3D12_SUBRESOURCE_INFO* pSrcData) noexcept
- {
- UINT64 RequiredSize = 0;
- D3D12_PLACED_SUBRESOURCE_FOOTPRINT Layouts[MaxSubresources];
- UINT NumRows[MaxSubresources];
- UINT64 RowSizesInBytes[MaxSubresources];
- #if defined(_MSC_VER) || !defined(_WIN32)
- const auto Desc = pDestinationResource->GetDesc();
- #else
- D3D12_RESOURCE_DESC tmpDesc;
- const auto& Desc = *pDestinationResource->GetDesc(&tmpDesc);
- #endif
- ID3D12Device* pDevice = nullptr;
- pDestinationResource->GetDevice(IID_ID3D12Device, reinterpret_cast<void**>(&pDevice));
- pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, IntermediateOffset, Layouts, NumRows, RowSizesInBytes, &RequiredSize);
- pDevice->Release();
- return UpdateSubresources(pCmdList, pDestinationResource, pIntermediate, FirstSubresource, NumSubresources, RequiredSize, Layouts, NumRows, RowSizesInBytes, pResourceData, pSrcData);
- }
- //------------------------------------------------------------------------------------------------
- constexpr bool D3D12IsLayoutOpaque( D3D12_TEXTURE_LAYOUT Layout ) noexcept
- { return Layout == D3D12_TEXTURE_LAYOUT_UNKNOWN || Layout == D3D12_TEXTURE_LAYOUT_64KB_UNDEFINED_SWIZZLE; }
- //------------------------------------------------------------------------------------------------
- template< typename T >
- inline T D3DX12Align(T uValue, T uAlign)
- {
- // Assert power of 2 alignment
- D3DX12_ASSERT(0 == (uAlign & (uAlign - 1)));
- T uMask = uAlign - 1;
- T uResult = (uValue + uMask) & ~uMask;
- D3DX12_ASSERT(uResult >= uValue);
- D3DX12_ASSERT(0 == (uResult % uAlign));
- return uResult;
- }
- //------------------------------------------------------------------------------------------------
- template< typename T >
- inline T D3DX12AlignAtLeast(T uValue, T uAlign)
- {
- T aligned = D3DX12Align(uValue, uAlign);
- return aligned > uAlign ? aligned : uAlign;
- }
- inline const CD3DX12_RESOURCE_DESC1* D3DX12ConditionallyExpandAPIDesc(
- D3D12_RESOURCE_DESC1& LclDesc,
- const D3D12_RESOURCE_DESC1* pDesc)
- {
- return D3DX12ConditionallyExpandAPIDesc(static_cast<CD3DX12_RESOURCE_DESC1&>(LclDesc), static_cast<const CD3DX12_RESOURCE_DESC1*>(pDesc));
- }
- #if defined(D3D12_SDK_VERSION) && (D3D12_SDK_VERSION >= 606)
- //------------------------------------------------------------------------------------------------
- // The difference between D3DX12GetCopyableFootprints and ID3D12Device::GetCopyableFootprints
- // is that this one loses a lot of error checking by assuming the arguments are correct
- inline bool D3DX12GetCopyableFootprints(
- _In_ const D3D12_RESOURCE_DESC1& ResourceDesc,
- _In_range_(0, D3D12_REQ_SUBRESOURCES) UINT FirstSubresource,
- _In_range_(0, D3D12_REQ_SUBRESOURCES - FirstSubresource) UINT NumSubresources,
- UINT64 BaseOffset,
- _Out_writes_opt_(NumSubresources) D3D12_PLACED_SUBRESOURCE_FOOTPRINT* pLayouts,
- _Out_writes_opt_(NumSubresources) UINT* pNumRows,
- _Out_writes_opt_(NumSubresources) UINT64* pRowSizeInBytes,
- _Out_opt_ UINT64* pTotalBytes)
- {
- constexpr UINT64 uint64_max = ~0ull;
- UINT64 TotalBytes = uint64_max;
- UINT uSubRes = 0;
- bool bResourceOverflow = false;
- TotalBytes = 0;
- const DXGI_FORMAT Format = ResourceDesc.Format;
- CD3DX12_RESOURCE_DESC1 LresourceDesc;
- const CD3DX12_RESOURCE_DESC1& resourceDesc = *D3DX12ConditionallyExpandAPIDesc(LresourceDesc, &ResourceDesc);
- // Check if its a valid format
- D3DX12_ASSERT(D3D12_PROPERTY_LAYOUT_FORMAT_TABLE::FormatExists(Format));
- const UINT WidthAlignment = D3D12_PROPERTY_LAYOUT_FORMAT_TABLE::GetWidthAlignment( Format );
- const UINT HeightAlignment = D3D12_PROPERTY_LAYOUT_FORMAT_TABLE::GetHeightAlignment( Format );
- const UINT16 DepthAlignment = UINT16( D3D12_PROPERTY_LAYOUT_FORMAT_TABLE::GetDepthAlignment( Format ) );
- for (; uSubRes < NumSubresources; ++uSubRes)
- {
- bool bOverflow = false;
- UINT Subresource = FirstSubresource + uSubRes;
- D3DX12_ASSERT(resourceDesc.MipLevels != 0);
- UINT subresourceCount = resourceDesc.MipLevels * resourceDesc.ArraySize() * D3D12_PROPERTY_LAYOUT_FORMAT_TABLE::GetPlaneCount(resourceDesc.Format);
- if (Subresource > subresourceCount)
- {
- break;
- }
- TotalBytes = D3DX12Align< UINT64 >( TotalBytes, D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT );
- UINT MipLevel, ArraySlice, PlaneSlice;
- D3D12DecomposeSubresource(Subresource, resourceDesc.MipLevels, resourceDesc.ArraySize(), /*_Out_*/MipLevel, /*_Out_*/ArraySlice, /*_Out_*/PlaneSlice);
- const UINT64 Width = D3DX12AlignAtLeast<UINT64>(resourceDesc.Width >> MipLevel, WidthAlignment);
- const UINT Height = D3DX12AlignAtLeast(resourceDesc.Height >> MipLevel, HeightAlignment);
- const UINT16 Depth = D3DX12AlignAtLeast<UINT16>(resourceDesc.Depth() >> MipLevel, DepthAlignment);
- // Adjust for the current PlaneSlice. Most formats have only one plane.
- DXGI_FORMAT PlaneFormat;
- UINT32 MinPlanePitchWidth, PlaneWidth, PlaneHeight;
- D3D12_PROPERTY_LAYOUT_FORMAT_TABLE::GetPlaneSubsampledSizeAndFormatForCopyableLayout(PlaneSlice, Format, (UINT)Width, Height, /*_Out_*/ PlaneFormat, /*_Out_*/ MinPlanePitchWidth, /* _Out_ */ PlaneWidth, /*_Out_*/ PlaneHeight);
- D3D12_SUBRESOURCE_FOOTPRINT LocalPlacement;
- auto& Placement = pLayouts ? pLayouts[uSubRes].Footprint : LocalPlacement;
- Placement.Format = PlaneFormat;
- Placement.Width = PlaneWidth;
- Placement.Height = PlaneHeight;
- Placement.Depth = Depth;
- // Calculate row pitch
- UINT MinPlaneRowPitch = 0;
- D3D12_PROPERTY_LAYOUT_FORMAT_TABLE::CalculateMinimumRowMajorRowPitch(PlaneFormat, MinPlanePitchWidth, MinPlaneRowPitch);
- // Formats with more than one plane choose a larger pitch alignment to ensure that each plane begins on the row
- // immediately following the previous plane while still adhering to subresource alignment restrictions.
- static_assert( D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT >= D3D12_TEXTURE_DATA_PITCH_ALIGNMENT
- && ((D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT % D3D12_TEXTURE_DATA_PITCH_ALIGNMENT) == 0),
- "D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT must be >= and evenly divisible by D3D12_TEXTURE_DATA_PITCH_ALIGNMENT." );
- Placement.RowPitch = D3D12_PROPERTY_LAYOUT_FORMAT_TABLE::Planar(Format)
- ? D3DX12Align< UINT >( MinPlaneRowPitch, D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT )
- : D3DX12Align< UINT >( MinPlaneRowPitch, D3D12_TEXTURE_DATA_PITCH_ALIGNMENT );
- if (pRowSizeInBytes)
- {
- UINT PlaneRowSize = 0;
- D3D12_PROPERTY_LAYOUT_FORMAT_TABLE::CalculateMinimumRowMajorRowPitch(PlaneFormat, PlaneWidth, PlaneRowSize);
- pRowSizeInBytes[uSubRes] = PlaneRowSize;
- }
- // Number of rows (accounting for block compression and additional planes)
- UINT NumRows = 0;
- if (D3D12_PROPERTY_LAYOUT_FORMAT_TABLE::Planar(Format))
- {
- NumRows = PlaneHeight;
- }
- else
- {
- D3DX12_ASSERT(Height % HeightAlignment == 0);
- NumRows = Height / HeightAlignment;
- }
- if (pNumRows)
- {
- pNumRows[uSubRes] = NumRows;
- }
- // Offsetting
- if (pLayouts)
- {
- pLayouts[uSubRes].Offset = (bOverflow ? uint64_max : TotalBytes + BaseOffset);
- }
- const UINT16 NumSlices = Depth;
- const UINT64 SubresourceSize = (NumRows * NumSlices - 1) * Placement.RowPitch + MinPlaneRowPitch;
- // uint64 addition with overflow checking
- TotalBytes = TotalBytes + SubresourceSize;
- if(TotalBytes < SubresourceSize)
- {
- TotalBytes = uint64_max;
- }
- bResourceOverflow = bResourceOverflow || bOverflow;
- }
- // Overflow error
- if (bResourceOverflow)
- {
- TotalBytes = uint64_max;
- }
- if (pLayouts)
- {
- memset( pLayouts + uSubRes, -1, sizeof( *pLayouts ) * (NumSubresources - uSubRes) );
- }
- if (pNumRows)
- {
- memset(pNumRows + uSubRes, -1, sizeof(*pNumRows) * (NumSubresources - uSubRes));
- }
- if (pRowSizeInBytes)
- {
- memset(pRowSizeInBytes + uSubRes, -1, sizeof(*pRowSizeInBytes) * (NumSubresources - uSubRes));
- }
- if (pTotalBytes)
- {
- *pTotalBytes = TotalBytes;
- }
- if(TotalBytes == uint64_max)
- {
- return false;
- }
- return true;
- }
- //------------------------------------------------------------------------------------------------
- inline D3D12_RESOURCE_DESC1 D3DX12ResourceDesc0ToDesc1(D3D12_RESOURCE_DESC const& desc0)
- {
- D3D12_RESOURCE_DESC1 desc1;
- desc1.Dimension = desc0.Dimension;
- desc1.Alignment = desc0.Alignment;
- desc1.Width = desc0.Width;
- desc1.Height = desc0.Height;
- desc1.DepthOrArraySize = desc0.DepthOrArraySize;
- desc1.MipLevels = desc0.MipLevels;
- desc1.Format = desc0.Format;
- desc1.SampleDesc.Count = desc0.SampleDesc.Count;
- desc1.SampleDesc.Quality = desc0.SampleDesc.Quality;
- desc1.Layout = desc0.Layout;
- desc1.Flags = desc0.Flags;
- desc1.SamplerFeedbackMipRegion.Width = 0;
- desc1.SamplerFeedbackMipRegion.Height = 0;
- desc1.SamplerFeedbackMipRegion.Depth = 0;
- return desc1;
- }
- //------------------------------------------------------------------------------------------------
- inline bool D3DX12GetCopyableFootprints(
- _In_ const D3D12_RESOURCE_DESC& pResourceDesc,
- _In_range_(0, D3D12_REQ_SUBRESOURCES) UINT FirstSubresource,
- _In_range_(0, D3D12_REQ_SUBRESOURCES - FirstSubresource) UINT NumSubresources,
- UINT64 BaseOffset,
- _Out_writes_opt_(NumSubresources) D3D12_PLACED_SUBRESOURCE_FOOTPRINT* pLayouts,
- _Out_writes_opt_(NumSubresources) UINT* pNumRows,
- _Out_writes_opt_(NumSubresources) UINT64* pRowSizeInBytes,
- _Out_opt_ UINT64* pTotalBytes)
- {
- // From D3D12_RESOURCE_DESC to D3D12_RESOURCE_DESC1
- D3D12_RESOURCE_DESC1 desc = D3DX12ResourceDesc0ToDesc1(pResourceDesc);
- return D3DX12GetCopyableFootprints(
- *static_cast<CD3DX12_RESOURCE_DESC1*>(&desc),// From D3D12_RESOURCE_DESC1 to CD3DX12_RESOURCE_DESC1
- FirstSubresource,
- NumSubresources,
- BaseOffset,
- pLayouts,
- pNumRows,
- pRowSizeInBytes,
- pTotalBytes);
- }
- #endif // D3D12_SDK_VERSION >= 606
|