1/* 2 * Copyright © Microsoft Corporation 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 * IN THE SOFTWARE. 22 */ 23 24#ifndef D3D12_UTIL_H 25#define D3D12_UTIL_H 26 27//------------------------------------------------------------------------------------------------ 28template <typename T, typename U, typename V> 29inline void D3D12DecomposeSubresource( UINT Subresource, UINT MipLevels, UINT ArraySize, _Out_ T& MipSlice, _Out_ U& ArraySlice, _Out_ V& PlaneSlice ) noexcept 30{ 31 MipSlice = static_cast<T>(Subresource % MipLevels); 32 ArraySlice = static_cast<U>((Subresource / MipLevels) % ArraySize); 33 PlaneSlice = static_cast<V>(Subresource / (MipLevels * ArraySize)); 34} 35 36//------------------------------------------------------------------------------------------------ 37constexpr UINT D3D12CalcSubresource( UINT MipSlice, UINT ArraySlice, UINT PlaneSlice, UINT MipLevels, UINT ArraySize ) noexcept 38{ 39 return MipSlice + ArraySlice * MipLevels + PlaneSlice * MipLevels * ArraySize; 40} 41 42//------------------------------------------------------------------------------------------------ 43struct CD3DX12_RESOURCE_BARRIER : public D3D12_RESOURCE_BARRIER 44{ 45 CD3DX12_RESOURCE_BARRIER() = default; 46 explicit CD3DX12_RESOURCE_BARRIER(const D3D12_RESOURCE_BARRIER &o) noexcept : 47 D3D12_RESOURCE_BARRIER(o) 48 {} 49 static inline CD3DX12_RESOURCE_BARRIER Transition( 50 _In_ ID3D12Resource* pResource, 51 D3D12_RESOURCE_STATES stateBefore, 52 D3D12_RESOURCE_STATES stateAfter, 53 UINT subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES, 54 D3D12_RESOURCE_BARRIER_FLAGS flags = D3D12_RESOURCE_BARRIER_FLAG_NONE) noexcept 55 { 56 CD3DX12_RESOURCE_BARRIER result = {}; 57 D3D12_RESOURCE_BARRIER &barrier = result; 58 result.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; 59 result.Flags = flags; 60 barrier.Transition.pResource = pResource; 61 barrier.Transition.StateBefore = stateBefore; 62 barrier.Transition.StateAfter = stateAfter; 63 barrier.Transition.Subresource = subresource; 64 return result; 65 } 66 static inline CD3DX12_RESOURCE_BARRIER Aliasing( 67 _In_ ID3D12Resource* pResourceBefore, 68 _In_ ID3D12Resource* pResourceAfter) noexcept 69 { 70 CD3DX12_RESOURCE_BARRIER result = {}; 71 D3D12_RESOURCE_BARRIER &barrier = result; 72 result.Type = D3D12_RESOURCE_BARRIER_TYPE_ALIASING; 73 barrier.Aliasing.pResourceBefore = pResourceBefore; 74 barrier.Aliasing.pResourceAfter = pResourceAfter; 75 return result; 76 } 77 static inline CD3DX12_RESOURCE_BARRIER UAV( 78 _In_ ID3D12Resource* pResource) noexcept 79 { 80 CD3DX12_RESOURCE_BARRIER result = {}; 81 D3D12_RESOURCE_BARRIER &barrier = result; 82 result.Type = D3D12_RESOURCE_BARRIER_TYPE_UAV; 83 barrier.UAV.pResource = pResource; 84 return result; 85 } 86}; 87 88//------------------------------------------------------------------------------------------------ 89struct CD3DX12_RESOURCE_DESC : public D3D12_RESOURCE_DESC 90{ 91 CD3DX12_RESOURCE_DESC() = default; 92 explicit CD3DX12_RESOURCE_DESC( const D3D12_RESOURCE_DESC& o ) noexcept : 93 D3D12_RESOURCE_DESC( o ) 94 {} 95 CD3DX12_RESOURCE_DESC( 96 D3D12_RESOURCE_DIMENSION dimension, 97 UINT64 alignment, 98 UINT64 width, 99 UINT height, 100 UINT16 depthOrArraySize, 101 UINT16 mipLevels, 102 DXGI_FORMAT format, 103 UINT sampleCount, 104 UINT sampleQuality, 105 D3D12_TEXTURE_LAYOUT layout, 106 D3D12_RESOURCE_FLAGS flags ) noexcept 107 { 108 Dimension = dimension; 109 Alignment = alignment; 110 Width = width; 111 Height = height; 112 DepthOrArraySize = depthOrArraySize; 113 MipLevels = mipLevels; 114 Format = format; 115 SampleDesc.Count = sampleCount; 116 SampleDesc.Quality = sampleQuality; 117 Layout = layout; 118 Flags = flags; 119 } 120 static inline CD3DX12_RESOURCE_DESC Buffer( 121 const D3D12_RESOURCE_ALLOCATION_INFO& resAllocInfo, 122 D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE ) noexcept 123 { 124 return CD3DX12_RESOURCE_DESC( D3D12_RESOURCE_DIMENSION_BUFFER, resAllocInfo.Alignment, resAllocInfo.SizeInBytes, 125 1, 1, 1, DXGI_FORMAT_UNKNOWN, 1, 0, D3D12_TEXTURE_LAYOUT_ROW_MAJOR, flags ); 126 } 127 static inline CD3DX12_RESOURCE_DESC Buffer( 128 UINT64 width, 129 D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE, 130 UINT64 alignment = 0 ) noexcept 131 { 132 return CD3DX12_RESOURCE_DESC( D3D12_RESOURCE_DIMENSION_BUFFER, alignment, width, 1, 1, 1, 133 DXGI_FORMAT_UNKNOWN, 1, 0, D3D12_TEXTURE_LAYOUT_ROW_MAJOR, flags ); 134 } 135 static inline CD3DX12_RESOURCE_DESC Tex1D( 136 DXGI_FORMAT format, 137 UINT64 width, 138 UINT16 arraySize = 1, 139 UINT16 mipLevels = 0, 140 D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE, 141 D3D12_TEXTURE_LAYOUT layout = D3D12_TEXTURE_LAYOUT_UNKNOWN, 142 UINT64 alignment = 0 ) noexcept 143 { 144 return CD3DX12_RESOURCE_DESC( D3D12_RESOURCE_DIMENSION_TEXTURE1D, alignment, width, 1, arraySize, 145 mipLevels, format, 1, 0, layout, flags ); 146 } 147 static inline CD3DX12_RESOURCE_DESC Tex2D( 148 DXGI_FORMAT format, 149 UINT64 width, 150 UINT height, 151 UINT16 arraySize = 1, 152 UINT16 mipLevels = 0, 153 UINT sampleCount = 1, 154 UINT sampleQuality = 0, 155 D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE, 156 D3D12_TEXTURE_LAYOUT layout = D3D12_TEXTURE_LAYOUT_UNKNOWN, 157 UINT64 alignment = 0 ) noexcept 158 { 159 return CD3DX12_RESOURCE_DESC( D3D12_RESOURCE_DIMENSION_TEXTURE2D, alignment, width, height, arraySize, 160 mipLevels, format, sampleCount, sampleQuality, layout, flags ); 161 } 162 static inline CD3DX12_RESOURCE_DESC Tex3D( 163 DXGI_FORMAT format, 164 UINT64 width, 165 UINT height, 166 UINT16 depth, 167 UINT16 mipLevels = 0, 168 D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE, 169 D3D12_TEXTURE_LAYOUT layout = D3D12_TEXTURE_LAYOUT_UNKNOWN, 170 UINT64 alignment = 0 ) noexcept 171 { 172 return CD3DX12_RESOURCE_DESC( D3D12_RESOURCE_DIMENSION_TEXTURE3D, alignment, width, height, depth, 173 mipLevels, format, 1, 0, layout, flags ); 174 } 175 inline UINT16 Depth() const noexcept 176 { return (Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D ? DepthOrArraySize : 1u); } 177 inline UINT16 ArraySize() const noexcept 178 { return (Dimension != D3D12_RESOURCE_DIMENSION_TEXTURE3D ? DepthOrArraySize : 1u); } 179 inline UINT CalcSubresource(UINT MipSlice, UINT ArraySlice, UINT PlaneSlice) noexcept 180 { return D3D12CalcSubresource(MipSlice, ArraySlice, PlaneSlice, MipLevels, ArraySize()); } 181}; 182inline bool operator==( const D3D12_RESOURCE_DESC& l, const D3D12_RESOURCE_DESC& r ) noexcept 183{ 184 return l.Dimension == r.Dimension && 185 l.Alignment == r.Alignment && 186 l.Width == r.Width && 187 l.Height == r.Height && 188 l.DepthOrArraySize == r.DepthOrArraySize && 189 l.MipLevels == r.MipLevels && 190 l.Format == r.Format && 191 l.SampleDesc.Count == r.SampleDesc.Count && 192 l.SampleDesc.Quality == r.SampleDesc.Quality && 193 l.Layout == r.Layout && 194 l.Flags == r.Flags; 195} 196inline bool operator!=( const D3D12_RESOURCE_DESC& l, const D3D12_RESOURCE_DESC& r ) noexcept 197{ return !( l == r ); } 198 199 200//------------------------------------------------------------------------------------------------ 201struct CD3DX12_HEAP_PROPERTIES : public D3D12_HEAP_PROPERTIES 202{ 203 CD3DX12_HEAP_PROPERTIES() = default; 204 explicit CD3DX12_HEAP_PROPERTIES(const D3D12_HEAP_PROPERTIES &o) noexcept : 205 D3D12_HEAP_PROPERTIES(o) 206 {} 207 CD3DX12_HEAP_PROPERTIES( 208 D3D12_CPU_PAGE_PROPERTY cpuPageProperty, 209 D3D12_MEMORY_POOL memoryPoolPreference, 210 UINT creationNodeMask = 1, 211 UINT nodeMask = 1 ) noexcept 212 { 213 Type = D3D12_HEAP_TYPE_CUSTOM; 214 CPUPageProperty = cpuPageProperty; 215 MemoryPoolPreference = memoryPoolPreference; 216 CreationNodeMask = creationNodeMask; 217 VisibleNodeMask = nodeMask; 218 } 219 explicit CD3DX12_HEAP_PROPERTIES( 220 D3D12_HEAP_TYPE type, 221 UINT creationNodeMask = 1, 222 UINT nodeMask = 1 ) noexcept 223 { 224 Type = type; 225 CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; 226 MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; 227 CreationNodeMask = creationNodeMask; 228 VisibleNodeMask = nodeMask; 229 } 230 bool IsCPUAccessible() const noexcept 231 { 232 return Type == D3D12_HEAP_TYPE_UPLOAD || Type == D3D12_HEAP_TYPE_READBACK || (Type == D3D12_HEAP_TYPE_CUSTOM && 233 (CPUPageProperty == D3D12_CPU_PAGE_PROPERTY_WRITE_COMBINE || CPUPageProperty == D3D12_CPU_PAGE_PROPERTY_WRITE_BACK)); 234 } 235}; 236inline bool operator==( const D3D12_HEAP_PROPERTIES& l, const D3D12_HEAP_PROPERTIES& r ) noexcept 237{ 238 return l.Type == r.Type && l.CPUPageProperty == r.CPUPageProperty && 239 l.MemoryPoolPreference == r.MemoryPoolPreference && 240 l.CreationNodeMask == r.CreationNodeMask && 241 l.VisibleNodeMask == r.VisibleNodeMask; 242} 243inline bool operator!=( const D3D12_HEAP_PROPERTIES& l, const D3D12_HEAP_PROPERTIES& r ) noexcept 244{ return !( l == r ); } 245 246#endif