aboutsummaryrefslogtreecommitdiff
path: root/contrib/DirectX-Headers-1.618.2/include/directx/d3dx12_resource_helpers.h
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/DirectX-Headers-1.618.2/include/directx/d3dx12_resource_helpers.h')
-rw-r--r--contrib/DirectX-Headers-1.618.2/include/directx/d3dx12_resource_helpers.h612
1 files changed, 612 insertions, 0 deletions
diff --git a/contrib/DirectX-Headers-1.618.2/include/directx/d3dx12_resource_helpers.h b/contrib/DirectX-Headers-1.618.2/include/directx/d3dx12_resource_helpers.h
new file mode 100644
index 0000000..5c1c980
--- /dev/null
+++ b/contrib/DirectX-Headers-1.618.2/include/directx/d3dx12_resource_helpers.h
@@ -0,0 +1,612 @@
1//*********************************************************
2//
3// Copyright (c) Microsoft Corporation.
4// Licensed under the MIT License (MIT).
5//
6//*********************************************************
7
8#pragma once
9
10#ifndef __cplusplus
11#error D3DX12 requires C++
12#endif
13
14#include "d3dx12_property_format_table.h"
15#include "d3d12.h"
16#include "d3dx12_core.h"
17//------------------------------------------------------------------------------------------------
18template <typename T, typename U, typename V>
19inline void D3D12DecomposeSubresource( UINT Subresource, UINT MipLevels, UINT ArraySize, _Out_ T& MipSlice, _Out_ U& ArraySlice, _Out_ V& PlaneSlice ) noexcept
20{
21 MipSlice = static_cast<T>(Subresource % MipLevels);
22 ArraySlice = static_cast<U>((Subresource / MipLevels) % ArraySize);
23 PlaneSlice = static_cast<V>(Subresource / (MipLevels * ArraySize));
24}
25
26//------------------------------------------------------------------------------------------------
27// Row-by-row memcpy
28inline void MemcpySubresource(
29 _In_ const D3D12_MEMCPY_DEST* pDest,
30 _In_ const D3D12_SUBRESOURCE_DATA* pSrc,
31 SIZE_T RowSizeInBytes,
32 UINT NumRows,
33 UINT NumSlices) noexcept
34{
35 for (UINT z = 0; z < NumSlices; ++z)
36 {
37 auto pDestSlice = static_cast<BYTE*>(pDest->pData) + pDest->SlicePitch * z;
38 auto pSrcSlice = static_cast<const BYTE*>(pSrc->pData) + pSrc->SlicePitch * LONG_PTR(z);
39 for (UINT y = 0; y < NumRows; ++y)
40 {
41 memcpy(pDestSlice + pDest->RowPitch * y,
42 pSrcSlice + pSrc->RowPitch * LONG_PTR(y),
43 RowSizeInBytes);
44 }
45 }
46}
47
48//------------------------------------------------------------------------------------------------
49// Row-by-row memcpy
50inline void MemcpySubresource(
51 _In_ const D3D12_MEMCPY_DEST* pDest,
52 _In_ const void* pResourceData,
53 _In_ const D3D12_SUBRESOURCE_INFO* pSrc,
54 SIZE_T RowSizeInBytes,
55 UINT NumRows,
56 UINT NumSlices) noexcept
57{
58 for (UINT z = 0; z < NumSlices; ++z)
59 {
60 auto pDestSlice = static_cast<BYTE*>(pDest->pData) + pDest->SlicePitch * z;
61 auto pSrcSlice = (static_cast<const BYTE*>(pResourceData) + pSrc->Offset) + pSrc->DepthPitch * ULONG_PTR(z);
62 for (UINT y = 0; y < NumRows; ++y)
63 {
64 memcpy(pDestSlice + pDest->RowPitch * y,
65 pSrcSlice + pSrc->RowPitch * ULONG_PTR(y),
66 RowSizeInBytes);
67 }
68 }
69}
70
71//------------------------------------------------------------------------------------------------
72// Returns required size of a buffer to be used for data upload
73inline UINT64 GetRequiredIntermediateSize(
74 _In_ ID3D12Resource* pDestinationResource,
75 _In_range_(0,D3D12_REQ_SUBRESOURCES) UINT FirstSubresource,
76 _In_range_(0,D3D12_REQ_SUBRESOURCES-FirstSubresource) UINT NumSubresources) noexcept
77{
78#if defined(_MSC_VER) || !defined(_WIN32)
79 const auto Desc = pDestinationResource->GetDesc();
80#else
81 D3D12_RESOURCE_DESC tmpDesc;
82 const auto& Desc = *pDestinationResource->GetDesc(&tmpDesc);
83#endif
84 UINT64 RequiredSize = 0;
85
86 ID3D12Device* pDevice = nullptr;
87 pDestinationResource->GetDevice(IID_ID3D12Device, reinterpret_cast<void**>(&pDevice));
88 pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, 0, nullptr, nullptr, nullptr, &RequiredSize);
89 pDevice->Release();
90
91 return RequiredSize;
92}
93
94//------------------------------------------------------------------------------------------------
95// All arrays must be populated (e.g. by calling GetCopyableFootprints)
96inline UINT64 UpdateSubresources(
97 _In_ ID3D12GraphicsCommandList* pCmdList,
98 _In_ ID3D12Resource* pDestinationResource,
99 _In_ ID3D12Resource* pIntermediate,
100 _In_range_(0,D3D12_REQ_SUBRESOURCES) UINT FirstSubresource,
101 _In_range_(0,D3D12_REQ_SUBRESOURCES-FirstSubresource) UINT NumSubresources,
102 UINT64 RequiredSize,
103 _In_reads_(NumSubresources) const D3D12_PLACED_SUBRESOURCE_FOOTPRINT* pLayouts,
104 _In_reads_(NumSubresources) const UINT* pNumRows,
105 _In_reads_(NumSubresources) const UINT64* pRowSizesInBytes,
106 _In_reads_(NumSubresources) const D3D12_SUBRESOURCE_DATA* pSrcData) noexcept
107{
108 // Minor validation
109#if defined(_MSC_VER) || !defined(_WIN32)
110 const auto IntermediateDesc = pIntermediate->GetDesc();
111 const auto DestinationDesc = pDestinationResource->GetDesc();
112#else
113 D3D12_RESOURCE_DESC tmpDesc1, tmpDesc2;
114 const auto& IntermediateDesc = *pIntermediate->GetDesc(&tmpDesc1);
115 const auto& DestinationDesc = *pDestinationResource->GetDesc(&tmpDesc2);
116#endif
117 if (IntermediateDesc.Dimension != D3D12_RESOURCE_DIMENSION_BUFFER ||
118 IntermediateDesc.Width < RequiredSize + pLayouts[0].Offset ||
119 RequiredSize > SIZE_T(-1) ||
120 (DestinationDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER &&
121 (FirstSubresource != 0 || NumSubresources != 1)))
122 {
123 return 0;
124 }
125
126 BYTE* pData;
127 HRESULT hr = pIntermediate->Map(0, nullptr, reinterpret_cast<void**>(&pData));
128 if (FAILED(hr))
129 {
130 return 0;
131 }
132
133 for (UINT i = 0; i < NumSubresources; ++i)
134 {
135 if (pRowSizesInBytes[i] > SIZE_T(-1)) return 0;
136 D3D12_MEMCPY_DEST DestData = { pData + pLayouts[i].Offset, pLayouts[i].Footprint.RowPitch, SIZE_T(pLayouts[i].Footprint.RowPitch) * SIZE_T(pNumRows[i]) };
137 MemcpySubresource(&DestData, &pSrcData[i], static_cast<SIZE_T>(pRowSizesInBytes[i]), pNumRows[i], pLayouts[i].Footprint.Depth);
138 }
139 pIntermediate->Unmap(0, nullptr);
140
141 if (DestinationDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER)
142 {
143 pCmdList->CopyBufferRegion(
144 pDestinationResource, 0, pIntermediate, pLayouts[0].Offset, pLayouts[0].Footprint.Width);
145 }
146 else
147 {
148 for (UINT i = 0; i < NumSubresources; ++i)
149 {
150 const CD3DX12_TEXTURE_COPY_LOCATION Dst(pDestinationResource, i + FirstSubresource);
151 const CD3DX12_TEXTURE_COPY_LOCATION Src(pIntermediate, pLayouts[i]);
152 pCmdList->CopyTextureRegion(&Dst, 0, 0, 0, &Src, nullptr);
153 }
154 }
155 return RequiredSize;
156}
157
158//------------------------------------------------------------------------------------------------
159// All arrays must be populated (e.g. by calling GetCopyableFootprints)
160inline UINT64 UpdateSubresources(
161 _In_ ID3D12GraphicsCommandList* pCmdList,
162 _In_ ID3D12Resource* pDestinationResource,
163 _In_ ID3D12Resource* pIntermediate,
164 _In_range_(0,D3D12_REQ_SUBRESOURCES) UINT FirstSubresource,
165 _In_range_(0,D3D12_REQ_SUBRESOURCES-FirstSubresource) UINT NumSubresources,
166 UINT64 RequiredSize,
167 _In_reads_(NumSubresources) const D3D12_PLACED_SUBRESOURCE_FOOTPRINT* pLayouts,
168 _In_reads_(NumSubresources) const UINT* pNumRows,
169 _In_reads_(NumSubresources) const UINT64* pRowSizesInBytes,
170 _In_ const void* pResourceData,
171 _In_reads_(NumSubresources) const D3D12_SUBRESOURCE_INFO* pSrcData) noexcept
172{
173 // Minor validation
174#if defined(_MSC_VER) || !defined(_WIN32)
175 const auto IntermediateDesc = pIntermediate->GetDesc();
176 const auto DestinationDesc = pDestinationResource->GetDesc();
177#else
178 D3D12_RESOURCE_DESC tmpDesc1, tmpDesc2;
179 const auto& IntermediateDesc = *pIntermediate->GetDesc(&tmpDesc1);
180 const auto& DestinationDesc = *pDestinationResource->GetDesc(&tmpDesc2);
181#endif
182 if (IntermediateDesc.Dimension != D3D12_RESOURCE_DIMENSION_BUFFER ||
183 IntermediateDesc.Width < RequiredSize + pLayouts[0].Offset ||
184 RequiredSize > SIZE_T(-1) ||
185 (DestinationDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER &&
186 (FirstSubresource != 0 || NumSubresources != 1)))
187 {
188 return 0;
189 }
190
191 BYTE* pData;
192 HRESULT hr = pIntermediate->Map(0, nullptr, reinterpret_cast<void**>(&pData));
193 if (FAILED(hr))
194 {
195 return 0;
196 }
197
198 for (UINT i = 0; i < NumSubresources; ++i)
199 {
200 if (pRowSizesInBytes[i] > SIZE_T(-1)) return 0;
201 D3D12_MEMCPY_DEST DestData = { pData + pLayouts[i].Offset, pLayouts[i].Footprint.RowPitch, SIZE_T(pLayouts[i].Footprint.RowPitch) * SIZE_T(pNumRows[i]) };
202 MemcpySubresource(&DestData, pResourceData, &pSrcData[i], static_cast<SIZE_T>(pRowSizesInBytes[i]), pNumRows[i], pLayouts[i].Footprint.Depth);
203 }
204 pIntermediate->Unmap(0, nullptr);
205
206 if (DestinationDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER)
207 {
208 pCmdList->CopyBufferRegion(
209 pDestinationResource, 0, pIntermediate, pLayouts[0].Offset, pLayouts[0].Footprint.Width);
210 }
211 else
212 {
213 for (UINT i = 0; i < NumSubresources; ++i)
214 {
215 const CD3DX12_TEXTURE_COPY_LOCATION Dst(pDestinationResource, i + FirstSubresource);
216 const CD3DX12_TEXTURE_COPY_LOCATION Src(pIntermediate, pLayouts[i]);
217 pCmdList->CopyTextureRegion(&Dst, 0, 0, 0, &Src, nullptr);
218 }
219 }
220 return RequiredSize;
221}
222
223//------------------------------------------------------------------------------------------------
224// Heap-allocating UpdateSubresources implementation
225inline UINT64 UpdateSubresources(
226 _In_ ID3D12GraphicsCommandList* pCmdList,
227 _In_ ID3D12Resource* pDestinationResource,
228 _In_ ID3D12Resource* pIntermediate,
229 UINT64 IntermediateOffset,
230 _In_range_(0,D3D12_REQ_SUBRESOURCES) UINT FirstSubresource,
231 _In_range_(0,D3D12_REQ_SUBRESOURCES-FirstSubresource) UINT NumSubresources,
232 _In_reads_(NumSubresources) const D3D12_SUBRESOURCE_DATA* pSrcData) noexcept
233{
234 UINT64 RequiredSize = 0;
235 const auto MemToAlloc = static_cast<UINT64>(sizeof(D3D12_PLACED_SUBRESOURCE_FOOTPRINT) + sizeof(UINT) + sizeof(UINT64)) * NumSubresources;
236 if (MemToAlloc > SIZE_MAX)
237 {
238 return 0;
239 }
240 void* pMem = HeapAlloc(GetProcessHeap(), 0, static_cast<SIZE_T>(MemToAlloc));
241 if (pMem == nullptr)
242 {
243 return 0;
244 }
245 auto pLayouts = static_cast<D3D12_PLACED_SUBRESOURCE_FOOTPRINT*>(pMem);
246 auto pRowSizesInBytes = reinterpret_cast<UINT64*>(pLayouts + NumSubresources);
247 auto pNumRows = reinterpret_cast<UINT*>(pRowSizesInBytes + NumSubresources);
248
249#if defined(_MSC_VER) || !defined(_WIN32)
250 const auto Desc = pDestinationResource->GetDesc();
251#else
252 D3D12_RESOURCE_DESC tmpDesc;
253 const auto& Desc = *pDestinationResource->GetDesc(&tmpDesc);
254#endif
255 ID3D12Device* pDevice = nullptr;
256 pDestinationResource->GetDevice(IID_ID3D12Device, reinterpret_cast<void**>(&pDevice));
257 pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, IntermediateOffset, pLayouts, pNumRows, pRowSizesInBytes, &RequiredSize);
258 pDevice->Release();
259
260 const UINT64 Result = UpdateSubresources(pCmdList, pDestinationResource, pIntermediate, FirstSubresource, NumSubresources, RequiredSize, pLayouts, pNumRows, pRowSizesInBytes, pSrcData);
261 HeapFree(GetProcessHeap(), 0, pMem);
262 return Result;
263}
264
265//------------------------------------------------------------------------------------------------
266// Heap-allocating UpdateSubresources implementation
267inline UINT64 UpdateSubresources(
268 _In_ ID3D12GraphicsCommandList* pCmdList,
269 _In_ ID3D12Resource* pDestinationResource,
270 _In_ ID3D12Resource* pIntermediate,
271 UINT64 IntermediateOffset,
272 _In_range_(0,D3D12_REQ_SUBRESOURCES) UINT FirstSubresource,
273 _In_range_(0,D3D12_REQ_SUBRESOURCES-FirstSubresource) UINT NumSubresources,
274 _In_ const void* pResourceData,
275 _In_reads_(NumSubresources) const D3D12_SUBRESOURCE_INFO* pSrcData) noexcept
276{
277 UINT64 RequiredSize = 0;
278 const auto MemToAlloc = static_cast<UINT64>(sizeof(D3D12_PLACED_SUBRESOURCE_FOOTPRINT) + sizeof(UINT) + sizeof(UINT64)) * NumSubresources;
279 if (MemToAlloc > SIZE_MAX)
280 {
281 return 0;
282 }
283 void* pMem = HeapAlloc(GetProcessHeap(), 0, static_cast<SIZE_T>(MemToAlloc));
284 if (pMem == nullptr)
285 {
286 return 0;
287 }
288 auto pLayouts = static_cast<D3D12_PLACED_SUBRESOURCE_FOOTPRINT*>(pMem);
289 auto pRowSizesInBytes = reinterpret_cast<UINT64*>(pLayouts + NumSubresources);
290 auto pNumRows = reinterpret_cast<UINT*>(pRowSizesInBytes + NumSubresources);
291
292#if defined(_MSC_VER) || !defined(_WIN32)
293 const auto Desc = pDestinationResource->GetDesc();
294#else
295 D3D12_RESOURCE_DESC tmpDesc;
296 const auto& Desc = *pDestinationResource->GetDesc(&tmpDesc);
297#endif
298 ID3D12Device* pDevice = nullptr;
299 pDestinationResource->GetDevice(IID_ID3D12Device, reinterpret_cast<void**>(&pDevice));
300 pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, IntermediateOffset, pLayouts, pNumRows, pRowSizesInBytes, &RequiredSize);
301 pDevice->Release();
302
303 const UINT64 Result = UpdateSubresources(pCmdList, pDestinationResource, pIntermediate, FirstSubresource, NumSubresources, RequiredSize, pLayouts, pNumRows, pRowSizesInBytes, pResourceData, pSrcData);
304 HeapFree(GetProcessHeap(), 0, pMem);
305 return Result;
306}
307
308//------------------------------------------------------------------------------------------------
309// Stack-allocating UpdateSubresources implementation
310template <UINT MaxSubresources>
311inline UINT64 UpdateSubresources(
312 _In_ ID3D12GraphicsCommandList* pCmdList,
313 _In_ ID3D12Resource* pDestinationResource,
314 _In_ ID3D12Resource* pIntermediate,
315 UINT64 IntermediateOffset,
316 _In_range_(0,MaxSubresources) UINT FirstSubresource,
317 _In_range_(1,MaxSubresources-FirstSubresource) UINT NumSubresources,
318 _In_reads_(NumSubresources) const D3D12_SUBRESOURCE_DATA* pSrcData) noexcept
319{
320 UINT64 RequiredSize = 0;
321 D3D12_PLACED_SUBRESOURCE_FOOTPRINT Layouts[MaxSubresources];
322 UINT NumRows[MaxSubresources];
323 UINT64 RowSizesInBytes[MaxSubresources];
324
325#if defined(_MSC_VER) || !defined(_WIN32)
326 const auto Desc = pDestinationResource->GetDesc();
327#else
328 D3D12_RESOURCE_DESC tmpDesc;
329 const auto& Desc = *pDestinationResource->GetDesc(&tmpDesc);
330#endif
331 ID3D12Device* pDevice = nullptr;
332 pDestinationResource->GetDevice(IID_ID3D12Device, reinterpret_cast<void**>(&pDevice));
333 pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, IntermediateOffset, Layouts, NumRows, RowSizesInBytes, &RequiredSize);
334 pDevice->Release();
335
336 return UpdateSubresources(pCmdList, pDestinationResource, pIntermediate, FirstSubresource, NumSubresources, RequiredSize, Layouts, NumRows, RowSizesInBytes, pSrcData);
337}
338
339//------------------------------------------------------------------------------------------------
340// Stack-allocating UpdateSubresources implementation
341template <UINT MaxSubresources>
342inline UINT64 UpdateSubresources(
343 _In_ ID3D12GraphicsCommandList* pCmdList,
344 _In_ ID3D12Resource* pDestinationResource,
345 _In_ ID3D12Resource* pIntermediate,
346 UINT64 IntermediateOffset,
347 _In_range_(0,MaxSubresources) UINT FirstSubresource,
348 _In_range_(1,MaxSubresources-FirstSubresource) UINT NumSubresources,
349 _In_ const void* pResourceData,
350 _In_reads_(NumSubresources) const D3D12_SUBRESOURCE_INFO* pSrcData) noexcept
351{
352 UINT64 RequiredSize = 0;
353 D3D12_PLACED_SUBRESOURCE_FOOTPRINT Layouts[MaxSubresources];
354 UINT NumRows[MaxSubresources];
355 UINT64 RowSizesInBytes[MaxSubresources];
356
357#if defined(_MSC_VER) || !defined(_WIN32)
358 const auto Desc = pDestinationResource->GetDesc();
359#else
360 D3D12_RESOURCE_DESC tmpDesc;
361 const auto& Desc = *pDestinationResource->GetDesc(&tmpDesc);
362#endif
363 ID3D12Device* pDevice = nullptr;
364 pDestinationResource->GetDevice(IID_ID3D12Device, reinterpret_cast<void**>(&pDevice));
365 pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, IntermediateOffset, Layouts, NumRows, RowSizesInBytes, &RequiredSize);
366 pDevice->Release();
367
368 return UpdateSubresources(pCmdList, pDestinationResource, pIntermediate, FirstSubresource, NumSubresources, RequiredSize, Layouts, NumRows, RowSizesInBytes, pResourceData, pSrcData);
369}
370
371//------------------------------------------------------------------------------------------------
372constexpr bool D3D12IsLayoutOpaque( D3D12_TEXTURE_LAYOUT Layout ) noexcept
373{ return Layout == D3D12_TEXTURE_LAYOUT_UNKNOWN || Layout == D3D12_TEXTURE_LAYOUT_64KB_UNDEFINED_SWIZZLE; }
374
375//------------------------------------------------------------------------------------------------
376template< typename T >
377inline T D3DX12Align(T uValue, T uAlign)
378{
379 // Assert power of 2 alignment
380 D3DX12_ASSERT(0 == (uAlign & (uAlign - 1)));
381 T uMask = uAlign - 1;
382 T uResult = (uValue + uMask) & ~uMask;
383 D3DX12_ASSERT(uResult >= uValue);
384 D3DX12_ASSERT(0 == (uResult % uAlign));
385 return uResult;
386}
387
388//------------------------------------------------------------------------------------------------
389template< typename T >
390inline T D3DX12AlignAtLeast(T uValue, T uAlign)
391{
392 T aligned = D3DX12Align(uValue, uAlign);
393 return aligned > uAlign ? aligned : uAlign;
394}
395
396inline const CD3DX12_RESOURCE_DESC1* D3DX12ConditionallyExpandAPIDesc(
397 D3D12_RESOURCE_DESC1& LclDesc,
398 const D3D12_RESOURCE_DESC1* pDesc,
399 const bool tightAlignmentSupported = false,
400 const bool alignAsCommitted = false)
401{
402 return D3DX12ConditionallyExpandAPIDesc(static_cast<CD3DX12_RESOURCE_DESC1&>(LclDesc), static_cast<const CD3DX12_RESOURCE_DESC1*>(pDesc), tightAlignmentSupported, alignAsCommitted);
403}
404
405#if defined(D3D12_SDK_VERSION) && (D3D12_SDK_VERSION >= 606)
406//------------------------------------------------------------------------------------------------
407// The difference between D3DX12GetCopyableFootprints and ID3D12Device::GetCopyableFootprints
408// is that this one loses a lot of error checking by assuming the arguments are correct
409inline bool D3DX12GetCopyableFootprints(
410 _In_ const D3D12_RESOURCE_DESC1& ResourceDesc,
411 _In_range_(0, D3D12_REQ_SUBRESOURCES) UINT FirstSubresource,
412 _In_range_(0, D3D12_REQ_SUBRESOURCES - FirstSubresource) UINT NumSubresources,
413 UINT64 BaseOffset,
414 _Out_writes_opt_(NumSubresources) D3D12_PLACED_SUBRESOURCE_FOOTPRINT* pLayouts,
415 _Out_writes_opt_(NumSubresources) UINT* pNumRows,
416 _Out_writes_opt_(NumSubresources) UINT64* pRowSizeInBytes,
417 _Out_opt_ UINT64* pTotalBytes)
418{
419 constexpr UINT64 uint64_max = ~0ull;
420 UINT64 TotalBytes = uint64_max;
421 UINT uSubRes = 0;
422
423 bool bResourceOverflow = false;
424 TotalBytes = 0;
425
426 const DXGI_FORMAT Format = ResourceDesc.Format;
427
428 CD3DX12_RESOURCE_DESC1 LresourceDesc;
429 const CD3DX12_RESOURCE_DESC1& resourceDesc = *D3DX12ConditionallyExpandAPIDesc(LresourceDesc, &ResourceDesc);
430
431 // Check if its a valid format
432 D3DX12_ASSERT(D3D12_PROPERTY_LAYOUT_FORMAT_TABLE::FormatExists(Format));
433
434 // D3DX12GetCopyableFootprints does not support buffers with width larger than UINT_MAX.
435 if (ResourceDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER && ResourceDesc.Width >= UINT_MAX)
436 {
437 return false;
438 }
439
440 const UINT WidthAlignment = D3D12_PROPERTY_LAYOUT_FORMAT_TABLE::GetWidthAlignment( Format );
441 const UINT HeightAlignment = D3D12_PROPERTY_LAYOUT_FORMAT_TABLE::GetHeightAlignment( Format );
442 const UINT16 DepthAlignment = UINT16( D3D12_PROPERTY_LAYOUT_FORMAT_TABLE::GetDepthAlignment( Format ) );
443
444 for (; uSubRes < NumSubresources; ++uSubRes)
445 {
446 bool bOverflow = false;
447 UINT Subresource = FirstSubresource + uSubRes;
448
449 D3DX12_ASSERT(resourceDesc.MipLevels != 0);
450 UINT subresourceCount = resourceDesc.MipLevels * resourceDesc.ArraySize() * D3D12_PROPERTY_LAYOUT_FORMAT_TABLE::GetPlaneCount(resourceDesc.Format);
451
452 if (Subresource > subresourceCount)
453 {
454 break;
455 }
456
457 TotalBytes = D3DX12Align< UINT64 >( TotalBytes, D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT );
458
459 UINT MipLevel, ArraySlice, PlaneSlice;
460 D3D12DecomposeSubresource(Subresource, resourceDesc.MipLevels, resourceDesc.ArraySize(), /*_Out_*/MipLevel, /*_Out_*/ArraySlice, /*_Out_*/PlaneSlice);
461
462 const UINT64 Width = D3DX12AlignAtLeast<UINT64>(resourceDesc.Width >> MipLevel, WidthAlignment);
463 const UINT Height = D3DX12AlignAtLeast(resourceDesc.Height >> MipLevel, HeightAlignment);
464 const UINT16 Depth = D3DX12AlignAtLeast<UINT16>(resourceDesc.Depth() >> MipLevel, DepthAlignment);
465
466 // Adjust for the current PlaneSlice. Most formats have only one plane.
467 DXGI_FORMAT PlaneFormat;
468 UINT32 MinPlanePitchWidth, PlaneWidth, PlaneHeight;
469 D3D12_PROPERTY_LAYOUT_FORMAT_TABLE::GetPlaneSubsampledSizeAndFormatForCopyableLayout(PlaneSlice, Format, (UINT)Width, Height, /*_Out_*/ PlaneFormat, /*_Out_*/ MinPlanePitchWidth, /* _Out_ */ PlaneWidth, /*_Out_*/ PlaneHeight);
470
471 D3D12_SUBRESOURCE_FOOTPRINT LocalPlacement = {};
472 auto& Placement = pLayouts ? pLayouts[uSubRes].Footprint : LocalPlacement;
473 Placement.Format = PlaneFormat;
474 Placement.Width = PlaneWidth;
475 Placement.Height = PlaneHeight;
476 Placement.Depth = Depth;
477
478 // Calculate row pitch
479 UINT MinPlaneRowPitch = 0;
480 D3D12_PROPERTY_LAYOUT_FORMAT_TABLE::CalculateMinimumRowMajorRowPitch(PlaneFormat, MinPlanePitchWidth, MinPlaneRowPitch);
481
482 // Formats with more than one plane choose a larger pitch alignment to ensure that each plane begins on the row
483 // immediately following the previous plane while still adhering to subresource alignment restrictions.
484 static_assert( D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT >= D3D12_TEXTURE_DATA_PITCH_ALIGNMENT
485 && ((D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT % D3D12_TEXTURE_DATA_PITCH_ALIGNMENT) == 0),
486 "D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT must be >= and evenly divisible by D3D12_TEXTURE_DATA_PITCH_ALIGNMENT." );
487
488 Placement.RowPitch = D3D12_PROPERTY_LAYOUT_FORMAT_TABLE::Planar(Format)
489 ? D3DX12Align< UINT >( MinPlaneRowPitch, D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT )
490 : D3DX12Align< UINT >( MinPlaneRowPitch, D3D12_TEXTURE_DATA_PITCH_ALIGNMENT );
491
492 if (pRowSizeInBytes)
493 {
494 UINT PlaneRowSize = 0;
495 D3D12_PROPERTY_LAYOUT_FORMAT_TABLE::CalculateMinimumRowMajorRowPitch(PlaneFormat, PlaneWidth, PlaneRowSize);
496
497 pRowSizeInBytes[uSubRes] = PlaneRowSize;
498 }
499
500 // Number of rows (accounting for block compression and additional planes)
501 UINT NumRows = 0;
502 if (D3D12_PROPERTY_LAYOUT_FORMAT_TABLE::Planar(Format))
503 {
504 NumRows = PlaneHeight;
505 }
506 else
507 {
508 D3DX12_ASSERT(Height % HeightAlignment == 0);
509 NumRows = Height / HeightAlignment;
510 }
511
512 if (pNumRows)
513 {
514 pNumRows[uSubRes] = NumRows;
515 }
516
517 // Offsetting
518 if (pLayouts)
519 {
520 pLayouts[uSubRes].Offset = (bOverflow ? uint64_max : TotalBytes + BaseOffset);
521 }
522
523 const UINT16 NumSlices = Depth;
524 const UINT64 SubresourceSize = (NumRows * NumSlices - 1) * Placement.RowPitch + MinPlaneRowPitch;
525
526 // uint64 addition with overflow checking
527 TotalBytes = TotalBytes + SubresourceSize;
528 if(TotalBytes < SubresourceSize)
529 {
530 TotalBytes = uint64_max;
531 }
532 bResourceOverflow = bResourceOverflow || bOverflow;
533 }
534
535 // Overflow error
536 if (bResourceOverflow)
537 {
538 TotalBytes = uint64_max;
539 }
540
541
542 if (pLayouts)
543 {
544 memset( pLayouts + uSubRes, -1, sizeof( *pLayouts ) * (NumSubresources - uSubRes) );
545 }
546 if (pNumRows)
547 {
548 memset(pNumRows + uSubRes, -1, sizeof(*pNumRows) * (NumSubresources - uSubRes));
549 }
550 if (pRowSizeInBytes)
551 {
552 memset(pRowSizeInBytes + uSubRes, -1, sizeof(*pRowSizeInBytes) * (NumSubresources - uSubRes));
553 }
554 if (pTotalBytes)
555 {
556 *pTotalBytes = TotalBytes;
557 }
558 if(TotalBytes == uint64_max)
559 {
560 return false;
561 }
562 return true;
563}
564
565//------------------------------------------------------------------------------------------------
566inline D3D12_RESOURCE_DESC1 D3DX12ResourceDesc0ToDesc1(D3D12_RESOURCE_DESC const& desc0)
567{
568 D3D12_RESOURCE_DESC1 desc1;
569 desc1.Dimension = desc0.Dimension;
570 desc1.Alignment = desc0.Alignment;
571 desc1.Width = desc0.Width;
572 desc1.Height = desc0.Height;
573 desc1.DepthOrArraySize = desc0.DepthOrArraySize;
574 desc1.MipLevels = desc0.MipLevels;
575 desc1.Format = desc0.Format;
576 desc1.SampleDesc.Count = desc0.SampleDesc.Count;
577 desc1.SampleDesc.Quality = desc0.SampleDesc.Quality;
578 desc1.Layout = desc0.Layout;
579 desc1.Flags = desc0.Flags;
580 desc1.SamplerFeedbackMipRegion.Width = 0;
581 desc1.SamplerFeedbackMipRegion.Height = 0;
582 desc1.SamplerFeedbackMipRegion.Depth = 0;
583 return desc1;
584}
585
586//------------------------------------------------------------------------------------------------
587inline bool D3DX12GetCopyableFootprints(
588 _In_ const D3D12_RESOURCE_DESC& pResourceDesc,
589 _In_range_(0, D3D12_REQ_SUBRESOURCES) UINT FirstSubresource,
590 _In_range_(0, D3D12_REQ_SUBRESOURCES - FirstSubresource) UINT NumSubresources,
591 UINT64 BaseOffset,
592 _Out_writes_opt_(NumSubresources) D3D12_PLACED_SUBRESOURCE_FOOTPRINT* pLayouts,
593 _Out_writes_opt_(NumSubresources) UINT* pNumRows,
594 _Out_writes_opt_(NumSubresources) UINT64* pRowSizeInBytes,
595 _Out_opt_ UINT64* pTotalBytes)
596{
597 // From D3D12_RESOURCE_DESC to D3D12_RESOURCE_DESC1
598 D3D12_RESOURCE_DESC1 desc = D3DX12ResourceDesc0ToDesc1(pResourceDesc);
599 return D3DX12GetCopyableFootprints(
600 *static_cast<CD3DX12_RESOURCE_DESC1*>(&desc),// From D3D12_RESOURCE_DESC1 to CD3DX12_RESOURCE_DESC1
601 FirstSubresource,
602 NumSubresources,
603 BaseOffset,
604 pLayouts,
605 pNumRows,
606 pRowSizeInBytes,
607 pTotalBytes);
608}
609
610#endif // D3D12_SDK_VERSION >= 606
611
612