@@ -2011,6 +2011,29 @@ inline void MemcpySubresource(
20112011 }
20122012}
20132013
2014+ //------------------------------------------------------------------------------------------------
2015+ // Row-by-row memcpy
2016+ inline void MemcpySubresource (
2017+ _In_ const D3D12_MEMCPY_DEST * pDest ,
2018+ _In_ const void * pResourceData ,
2019+ _In_ const D3D12_SUBRESOURCE_INFO * pSrc ,
2020+ SIZE_T RowSizeInBytes ,
2021+ UINT NumRows ,
2022+ UINT NumSlices ) noexcept
2023+ {
2024+ for (UINT z = 0 ; z < NumSlices ; ++ z )
2025+ {
2026+ auto pDestSlice = static_cast < BYTE * > (pDest -> pData ) + pDest -> SlicePitch * z ;
2027+ auto pSrcSlice = (static_cast < const BYTE * > (pResourceData ) + pSrc -> Offset ) + pSrc -> DepthPitch * ULONG_PTR (z );
2028+ for (UINT y = 0 ; y < NumRows ; ++ y )
2029+ {
2030+ memcpy (pDestSlice + pDest -> RowPitch * y ,
2031+ pSrcSlice + pSrc -> RowPitch * ULONG_PTR (y ),
2032+ RowSizeInBytes );
2033+ }
2034+ }
2035+ }
2036+
20142037//------------------------------------------------------------------------------------------------
20152038// Returns required size of a buffer to be used for data upload
20162039inline UINT64 GetRequiredIntermediateSize (
@@ -2087,6 +2110,65 @@ inline UINT64 UpdateSubresources(
20872110 return RequiredSize ;
20882111}
20892112
2113+ //------------------------------------------------------------------------------------------------
2114+ // All arrays must be populated (e.g. by calling GetCopyableFootprints)
2115+ inline UINT64 UpdateSubresources (
2116+ _In_ ID3D12GraphicsCommandList * pCmdList ,
2117+ _In_ ID3D12Resource * pDestinationResource ,
2118+ _In_ ID3D12Resource * pIntermediate ,
2119+ _In_range_ (0 ,D3D12_REQ_SUBRESOURCES ) UINT FirstSubresource ,
2120+ _In_range_ (0 ,D3D12_REQ_SUBRESOURCES - FirstSubresource ) UINT NumSubresources ,
2121+ UINT64 RequiredSize ,
2122+ _In_reads_ (NumSubresources ) const D3D12_PLACED_SUBRESOURCE_FOOTPRINT * pLayouts ,
2123+ _In_reads_ (NumSubresources ) const UINT * pNumRows ,
2124+ _In_reads_ (NumSubresources ) const UINT64 * pRowSizesInBytes ,
2125+ _In_ const void * pResourceData ,
2126+ _In_reads_ (NumSubresources ) const D3D12_SUBRESOURCE_INFO * pSrcData ) noexcept
2127+ {
2128+ // Minor validation
2129+ auto IntermediateDesc = pIntermediate -> GetDesc ();
2130+ auto DestinationDesc = pDestinationResource -> GetDesc ();
2131+ if (IntermediateDesc .Dimension != D3D12_RESOURCE_DIMENSION_BUFFER ||
2132+ IntermediateDesc .Width < RequiredSize + pLayouts [0 ].Offset ||
2133+ RequiredSize > SIZE_T (-1 ) ||
2134+ (DestinationDesc .Dimension == D3D12_RESOURCE_DIMENSION_BUFFER &&
2135+ (FirstSubresource != 0 || NumSubresources != 1 )))
2136+ {
2137+ return 0 ;
2138+ }
2139+
2140+ BYTE * pData ;
2141+ HRESULT hr = pIntermediate -> Map (0 , nullptr , reinterpret_cast < void * * > (& pData ));
2142+ if (FAILED (hr ))
2143+ {
2144+ return 0 ;
2145+ }
2146+
2147+ for (UINT i = 0 ; i < NumSubresources ; ++ i )
2148+ {
2149+ if (pRowSizesInBytes [i ] > SIZE_T (-1 )) return 0 ;
2150+ D3D12_MEMCPY_DEST DestData = { pData + pLayouts [i ].Offset , pLayouts [i ].Footprint .RowPitch , SIZE_T (pLayouts [i ].Footprint .RowPitch ) * SIZE_T (pNumRows [i ]) };
2151+ MemcpySubresource (& DestData , pResourceData , & pSrcData [i ], static_cast < SIZE_T > (pRowSizesInBytes [i ]), pNumRows [i ], pLayouts [i ].Footprint .Depth );
2152+ }
2153+ pIntermediate -> Unmap (0 , nullptr );
2154+
2155+ if (DestinationDesc .Dimension == D3D12_RESOURCE_DIMENSION_BUFFER )
2156+ {
2157+ pCmdList -> CopyBufferRegion (
2158+ pDestinationResource , 0 , pIntermediate , pLayouts [0 ].Offset , pLayouts [0 ].Footprint .Width );
2159+ }
2160+ else
2161+ {
2162+ for (UINT i = 0 ; i < NumSubresources ; ++ i )
2163+ {
2164+ CD3DX12_TEXTURE_COPY_LOCATION Dst (pDestinationResource , i + FirstSubresource );
2165+ CD3DX12_TEXTURE_COPY_LOCATION Src (pIntermediate , pLayouts [i ]);
2166+ pCmdList -> CopyTextureRegion (& Dst , 0 , 0 , 0 , & Src , nullptr );
2167+ }
2168+ }
2169+ return RequiredSize ;
2170+ }
2171+
20902172//------------------------------------------------------------------------------------------------
20912173// Heap-allocating UpdateSubresources implementation
20922174inline UINT64 UpdateSubresources (
@@ -2099,7 +2181,7 @@ inline UINT64 UpdateSubresources(
20992181 _In_reads_ (NumSubresources ) const D3D12_SUBRESOURCE_DATA * pSrcData ) noexcept
21002182{
21012183 UINT64 RequiredSize = 0 ;
2102- UINT64 MemToAlloc = static_cast < UINT64 > (sizeof (D3D12_PLACED_SUBRESOURCE_FOOTPRINT ) + sizeof (UINT ) + sizeof (UINT64 )) * NumSubresources ;
2184+ auto MemToAlloc = static_cast < UINT64 > (sizeof (D3D12_PLACED_SUBRESOURCE_FOOTPRINT ) + sizeof (UINT ) + sizeof (UINT64 )) * NumSubresources ;
21032185 if (MemToAlloc > SIZE_MAX )
21042186 {
21052187 return 0 ;
@@ -2110,8 +2192,8 @@ inline UINT64 UpdateSubresources(
21102192 return 0 ;
21112193 }
21122194 auto pLayouts = static_cast < D3D12_PLACED_SUBRESOURCE_FOOTPRINT * > (pMem );
2113- UINT64 * pRowSizesInBytes = reinterpret_cast < UINT64 * > (pLayouts + NumSubresources );
2114- UINT * pNumRows = reinterpret_cast < UINT * > (pRowSizesInBytes + NumSubresources );
2195+ auto pRowSizesInBytes = reinterpret_cast < UINT64 * > (pLayouts + NumSubresources );
2196+ auto pNumRows = reinterpret_cast < UINT * > (pRowSizesInBytes + NumSubresources );
21152197
21162198 auto Desc = pDestinationResource -> GetDesc ();
21172199 ID3D12Device * pDevice = nullptr ;
@@ -2124,6 +2206,44 @@ inline UINT64 UpdateSubresources(
21242206 return Result ;
21252207}
21262208
2209+ //------------------------------------------------------------------------------------------------
2210+ // Heap-allocating UpdateSubresources implementation
2211+ inline UINT64 UpdateSubresources (
2212+ _In_ ID3D12GraphicsCommandList * pCmdList ,
2213+ _In_ ID3D12Resource * pDestinationResource ,
2214+ _In_ ID3D12Resource * pIntermediate ,
2215+ UINT64 IntermediateOffset ,
2216+ _In_range_ (0 ,D3D12_REQ_SUBRESOURCES ) UINT FirstSubresource ,
2217+ _In_range_ (0 ,D3D12_REQ_SUBRESOURCES - FirstSubresource ) UINT NumSubresources ,
2218+ _In_ const void * pResourceData ,
2219+ _In_reads_ (NumSubresources ) D3D12_SUBRESOURCE_INFO * pSrcData ) noexcept
2220+ {
2221+ UINT64 RequiredSize = 0 ;
2222+ auto MemToAlloc = static_cast < UINT64 > (sizeof (D3D12_PLACED_SUBRESOURCE_FOOTPRINT ) + sizeof (UINT ) + sizeof (UINT64 )) * NumSubresources ;
2223+ if (MemToAlloc > SIZE_MAX )
2224+ {
2225+ return 0 ;
2226+ }
2227+ void * pMem = HeapAlloc (GetProcessHeap (), 0 , static_cast < SIZE_T > (MemToAlloc ));
2228+ if (pMem == nullptr )
2229+ {
2230+ return 0 ;
2231+ }
2232+ auto pLayouts = reinterpret_cast < D3D12_PLACED_SUBRESOURCE_FOOTPRINT * > (pMem );
2233+ auto pRowSizesInBytes = reinterpret_cast < UINT64 * > (pLayouts + NumSubresources );
2234+ auto pNumRows = reinterpret_cast < UINT * > (pRowSizesInBytes + NumSubresources );
2235+
2236+ auto Desc = pDestinationResource -> GetDesc ();
2237+ ID3D12Device * pDevice = nullptr ;
2238+ pDestinationResource -> GetDevice (IID_ID3D12Device , reinterpret_cast < void * * > (& pDevice ));
2239+ pDevice -> GetCopyableFootprints (& Desc , FirstSubresource , NumSubresources , IntermediateOffset , pLayouts , pNumRows , pRowSizesInBytes , & RequiredSize );
2240+ pDevice -> Release ();
2241+
2242+ UINT64 Result = UpdateSubresources (pCmdList , pDestinationResource , pIntermediate , FirstSubresource , NumSubresources , RequiredSize , pLayouts , pNumRows , pRowSizesInBytes , pResourceData , pSrcData );
2243+ HeapFree (GetProcessHeap (), 0 , pMem );
2244+ return Result ;
2245+ }
2246+
21272247//------------------------------------------------------------------------------------------------
21282248// Stack-allocating UpdateSubresources implementation
21292249template < UINT MaxSubresources >
@@ -2132,8 +2252,8 @@ inline UINT64 UpdateSubresources(
21322252 _In_ ID3D12Resource * pDestinationResource ,
21332253 _In_ ID3D12Resource * pIntermediate ,
21342254 UINT64 IntermediateOffset ,
2135- _In_range_ (0 , MaxSubresources ) UINT FirstSubresource ,
2136- _In_range_ (1 , MaxSubresources - FirstSubresource ) UINT NumSubresources ,
2255+ _In_range_ (0 ,MaxSubresources ) UINT FirstSubresource ,
2256+ _In_range_ (1 ,MaxSubresources - FirstSubresource ) UINT NumSubresources ,
21372257 _In_reads_ (NumSubresources ) const D3D12_SUBRESOURCE_DATA * pSrcData ) noexcept
21382258{
21392259 UINT64 RequiredSize = 0 ;
@@ -2150,6 +2270,33 @@ inline UINT64 UpdateSubresources(
21502270 return UpdateSubresources (pCmdList , pDestinationResource , pIntermediate , FirstSubresource , NumSubresources , RequiredSize , Layouts , NumRows , RowSizesInBytes , pSrcData );
21512271}
21522272
2273+ //------------------------------------------------------------------------------------------------
2274+ // Stack-allocating UpdateSubresources implementation
2275+ template < UINT MaxSubresources >
2276+ inline UINT64 UpdateSubresources (
2277+ _In_ ID3D12GraphicsCommandList * pCmdList ,
2278+ _In_ ID3D12Resource * pDestinationResource ,
2279+ _In_ ID3D12Resource * pIntermediate ,
2280+ UINT64 IntermediateOffset ,
2281+ _In_range_ (0 ,MaxSubresources ) UINT FirstSubresource ,
2282+ _In_range_ (1 ,MaxSubresources - FirstSubresource ) UINT NumSubresources ,
2283+ _In_ const void * pResourceData ,
2284+ _In_reads_ (NumSubresources ) D3D12_SUBRESOURCE_INFO * pSrcData ) noexcept
2285+ {
2286+ UINT64 RequiredSize = 0 ;
2287+ D3D12_PLACED_SUBRESOURCE_FOOTPRINT Layouts [MaxSubresources ];
2288+ UINT NumRows [MaxSubresources ];
2289+ UINT64 RowSizesInBytes [MaxSubresources ];
2290+
2291+ auto Desc = pDestinationResource -> GetDesc ();
2292+ ID3D12Device * pDevice = nullptr ;
2293+ pDestinationResource -> GetDevice (IID_ID3D12Device , reinterpret_cast < void * * > (& pDevice ));
2294+ pDevice -> GetCopyableFootprints (& Desc , FirstSubresource , NumSubresources , IntermediateOffset , Layouts , NumRows , RowSizesInBytes , & RequiredSize );
2295+ pDevice -> Release ();
2296+
2297+ return UpdateSubresources (pCmdList , pDestinationResource , pIntermediate , FirstSubresource , NumSubresources , RequiredSize , Layouts , NumRows , RowSizesInBytes , pResourceData , pSrcData );
2298+ }
2299+
21532300//------------------------------------------------------------------------------------------------
21542301inline constexpr bool D3D12IsLayoutOpaque ( D3D12_TEXTURE_LAYOUT Layout ) noexcept
21552302{ return Layout == D3D12_TEXTURE_LAYOUT_UNKNOWN || Layout == D3D12_TEXTURE_LAYOUT_64KB_UNDEFINED_SWIZZLE ; }
0 commit comments