├── .gitattributes ├── .gitignore ├── DirectMLTest.cpp ├── DirectMLTest.sln ├── DirectMLTest.vcxproj ├── DirectMLTest.vcxproj.filters ├── DirectMLX.h ├── LICENSE.txt ├── README.md └── d3dx12.h /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Mono auto generated files 17 | mono_crash.* 18 | 19 | # Build results 20 | [Dd]ebug/ 21 | [Dd]ebugPublic/ 22 | [Rr]elease/ 23 | [Rr]eleases/ 24 | x64/ 25 | x86/ 26 | [Ww][Ii][Nn]32/ 27 | [Aa][Rr][Mm]/ 28 | [Aa][Rr][Mm]64/ 29 | bld/ 30 | [Bb]in/ 31 | [Oo]bj/ 32 | [Oo]ut/ 33 | [Ll]og/ 34 | [Ll]ogs/ 35 | 36 | # Visual Studio 2015/2017 cache/options directory 37 | .vs/ 38 | # Uncomment if you have tasks that create the project's static files in wwwroot 39 | #wwwroot/ 40 | 41 | # Visual Studio 2017 auto generated files 42 | Generated\ Files/ 43 | 44 | # MSTest test Results 45 | [Tt]est[Rr]esult*/ 46 | [Bb]uild[Ll]og.* 47 | 48 | # NUnit 49 | *.VisualState.xml 50 | TestResult.xml 51 | nunit-*.xml 52 | 53 | # Build Results of an ATL Project 54 | [Dd]ebugPS/ 55 | [Rr]eleasePS/ 56 | dlldata.c 57 | 58 | # Benchmark Results 59 | BenchmarkDotNet.Artifacts/ 60 | 61 | # .NET Core 62 | project.lock.json 63 | project.fragment.lock.json 64 | artifacts/ 65 | 66 | # ASP.NET Scaffolding 67 | ScaffoldingReadMe.txt 68 | 69 | # StyleCop 70 | StyleCopReport.xml 71 | 72 | # Files built by Visual Studio 73 | *_i.c 74 | *_p.c 75 | *_h.h 76 | *.ilk 77 | *.meta 78 | *.obj 79 | *.iobj 80 | *.pch 81 | *.pdb 82 | *.ipdb 83 | *.pgc 84 | *.pgd 85 | *.rsp 86 | *.sbr 87 | *.tlb 88 | *.tli 89 | *.tlh 90 | *.tmp 91 | *.tmp_proj 92 | *_wpftmp.csproj 93 | *.log 94 | *.vspscc 95 | *.vssscc 96 | .builds 97 | *.pidb 98 | *.svclog 99 | *.scc 100 | 101 | # Chutzpah Test files 102 | _Chutzpah* 103 | 104 | # Visual C++ cache files 105 | ipch/ 106 | *.aps 107 | *.ncb 108 | *.opendb 109 | *.opensdf 110 | *.sdf 111 | *.cachefile 112 | *.VC.db 113 | *.VC.VC.opendb 114 | 115 | # Visual Studio profiler 116 | *.psess 117 | *.vsp 118 | *.vspx 119 | *.sap 120 | 121 | # Visual Studio Trace Files 122 | *.e2e 123 | 124 | # TFS 2012 Local Workspace 125 | $tf/ 126 | 127 | # Guidance Automation Toolkit 128 | *.gpState 129 | 130 | # ReSharper is a .NET coding add-in 131 | _ReSharper*/ 132 | *.[Rr]e[Ss]harper 133 | *.DotSettings.user 134 | 135 | # TeamCity is a build add-in 136 | _TeamCity* 137 | 138 | # DotCover is a Code Coverage Tool 139 | *.dotCover 140 | 141 | # AxoCover is a Code Coverage Tool 142 | .axoCover/* 143 | !.axoCover/settings.json 144 | 145 | # Coverlet is a free, cross platform Code Coverage Tool 146 | coverage*.json 147 | coverage*.xml 148 | coverage*.info 149 | 150 | # Visual Studio code coverage results 151 | *.coverage 152 | *.coveragexml 153 | 154 | # NCrunch 155 | _NCrunch_* 156 | .*crunch*.local.xml 157 | nCrunchTemp_* 158 | 159 | # MightyMoose 160 | *.mm.* 161 | AutoTest.Net/ 162 | 163 | # Web workbench (sass) 164 | .sass-cache/ 165 | 166 | # Installshield output folder 167 | [Ee]xpress/ 168 | 169 | # DocProject is a documentation generator add-in 170 | DocProject/buildhelp/ 171 | DocProject/Help/*.HxT 172 | DocProject/Help/*.HxC 173 | DocProject/Help/*.hhc 174 | DocProject/Help/*.hhk 175 | DocProject/Help/*.hhp 176 | DocProject/Help/Html2 177 | DocProject/Help/html 178 | 179 | # Click-Once directory 180 | publish/ 181 | 182 | # Publish Web Output 183 | *.[Pp]ublish.xml 184 | *.azurePubxml 185 | # Note: Comment the next line if you want to checkin your web deploy settings, 186 | # but database connection strings (with potential passwords) will be unencrypted 187 | *.pubxml 188 | *.publishproj 189 | 190 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 191 | # checkin your Azure Web App publish settings, but sensitive information contained 192 | # in these scripts will be unencrypted 193 | PublishScripts/ 194 | 195 | # NuGet Packages 196 | *.nupkg 197 | # NuGet Symbol Packages 198 | *.snupkg 199 | # The packages folder can be ignored because of Package Restore 200 | **/[Pp]ackages/* 201 | # except build/, which is used as an MSBuild target. 202 | !**/[Pp]ackages/build/ 203 | # Uncomment if necessary however generally it will be regenerated when needed 204 | #!**/[Pp]ackages/repositories.config 205 | # NuGet v3's project.json files produces more ignorable files 206 | *.nuget.props 207 | *.nuget.targets 208 | 209 | # Microsoft Azure Build Output 210 | csx/ 211 | *.build.csdef 212 | 213 | # Microsoft Azure Emulator 214 | ecf/ 215 | rcf/ 216 | 217 | # Windows Store app package directories and files 218 | AppPackages/ 219 | BundleArtifacts/ 220 | Package.StoreAssociation.xml 221 | _pkginfo.txt 222 | *.appx 223 | *.appxbundle 224 | *.appxupload 225 | 226 | # Visual Studio cache files 227 | # files ending in .cache can be ignored 228 | *.[Cc]ache 229 | # but keep track of directories ending in .cache 230 | !?*.[Cc]ache/ 231 | 232 | # Others 233 | ClientBin/ 234 | ~$* 235 | *~ 236 | *.dbmdl 237 | *.dbproj.schemaview 238 | *.jfm 239 | *.pfx 240 | *.publishsettings 241 | orleans.codegen.cs 242 | 243 | # Including strong name files can present a security risk 244 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 245 | #*.snk 246 | 247 | # Since there are multiple workflows, uncomment next line to ignore bower_components 248 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 249 | #bower_components/ 250 | 251 | # RIA/Silverlight projects 252 | Generated_Code/ 253 | 254 | # Backup & report files from converting an old project file 255 | # to a newer Visual Studio version. Backup files are not needed, 256 | # because we have git ;-) 257 | _UpgradeReport_Files/ 258 | Backup*/ 259 | UpgradeLog*.XML 260 | UpgradeLog*.htm 261 | ServiceFabricBackup/ 262 | *.rptproj.bak 263 | 264 | # SQL Server files 265 | *.mdf 266 | *.ldf 267 | *.ndf 268 | 269 | # Business Intelligence projects 270 | *.rdl.data 271 | *.bim.layout 272 | *.bim_*.settings 273 | *.rptproj.rsuser 274 | *- [Bb]ackup.rdl 275 | *- [Bb]ackup ([0-9]).rdl 276 | *- [Bb]ackup ([0-9][0-9]).rdl 277 | 278 | # Microsoft Fakes 279 | FakesAssemblies/ 280 | 281 | # GhostDoc plugin setting file 282 | *.GhostDoc.xml 283 | 284 | # Node.js Tools for Visual Studio 285 | .ntvs_analysis.dat 286 | node_modules/ 287 | 288 | # Visual Studio 6 build log 289 | *.plg 290 | 291 | # Visual Studio 6 workspace options file 292 | *.opt 293 | 294 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 295 | *.vbw 296 | 297 | # Visual Studio LightSwitch build output 298 | **/*.HTMLClient/GeneratedArtifacts 299 | **/*.DesktopClient/GeneratedArtifacts 300 | **/*.DesktopClient/ModelManifest.xml 301 | **/*.Server/GeneratedArtifacts 302 | **/*.Server/ModelManifest.xml 303 | _Pvt_Extensions 304 | 305 | # Paket dependency manager 306 | .paket/paket.exe 307 | paket-files/ 308 | 309 | # FAKE - F# Make 310 | .fake/ 311 | 312 | # CodeRush personal settings 313 | .cr/personal 314 | 315 | # Python Tools for Visual Studio (PTVS) 316 | __pycache__/ 317 | *.pyc 318 | 319 | # Cake - Uncomment if you are using it 320 | # tools/** 321 | # !tools/packages.config 322 | 323 | # Tabs Studio 324 | *.tss 325 | 326 | # Telerik's JustMock configuration file 327 | *.jmconfig 328 | 329 | # BizTalk build output 330 | *.btp.cs 331 | *.btm.cs 332 | *.odx.cs 333 | *.xsd.cs 334 | 335 | # OpenCover UI analysis results 336 | OpenCover/ 337 | 338 | # Azure Stream Analytics local run output 339 | ASALocalRun/ 340 | 341 | # MSBuild Binary and Structured Log 342 | *.binlog 343 | 344 | # NVidia Nsight GPU debugger configuration file 345 | *.nvuser 346 | 347 | # MFractors (Xamarin productivity tool) working folder 348 | .mfractor/ 349 | 350 | # Local History for Visual Studio 351 | .localhistory/ 352 | 353 | # BeatPulse healthcheck temp database 354 | healthchecksdb 355 | 356 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 357 | MigrationBackup/ 358 | 359 | # Ionide (cross platform F# VS Code tools) working folder 360 | .ionide/ 361 | 362 | # Fody - auto-generated XML schema 363 | FodyWeavers.xsd -------------------------------------------------------------------------------- /DirectMLTest.cpp: -------------------------------------------------------------------------------- 1 | // DirectMLTest.cpp : This file contains the 'main' function. Program execution begins and ends there. 2 | // 3 | 4 | #include 5 | #undef max 6 | #undef min 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #include 18 | #include "d3dx12.h" 19 | 20 | #include 21 | 22 | #include 23 | #include 24 | 25 | #define DML_TARGET_VERSION_USE_LATEST 26 | #include // The DirectML header from the Windows SDK. 27 | #include "DirectMLX.h" 28 | 29 | #pragma comment(lib,"d3d12.lib") 30 | #pragma comment(lib,"dxgi.lib") 31 | #pragma comment(lib,"directml.lib") 32 | 33 | void THROW_IF_FAILED(HRESULT hr) 34 | { 35 | if (FAILED(hr)) throw; 36 | } 37 | class ML 38 | { 39 | public: 40 | CComPtr d3D12Device; 41 | CComPtr dmlDevice; 42 | CComPtr commandQueue; 43 | CComPtr commandAllocator; 44 | CComPtr commandList; 45 | CComPtr dmlCommandRecorder; 46 | CComPtr dmlCompiledOperator; 47 | CComPtr dmlOperatorInitializer; 48 | DML_BINDING_PROPERTIES initializeBindingProperties = {}, executeBindingProperties = {}; 49 | UINT descriptorCount = 0; 50 | CComPtr descriptorHeap; 51 | 52 | 53 | HRESULT InitializeDirect3D12() 54 | { 55 | CComPtr d3D12Debug; 56 | 57 | // Throws if the D3D12 debug layer is missing - you must install the Graphics Tools optional feature 58 | #if defined (_DEBUG) 59 | THROW_IF_FAILED(D3D12GetDebugInterface(IID_PPV_ARGS(&d3D12Debug))); 60 | d3D12Debug->EnableDebugLayer(); 61 | #endif 62 | 63 | CComPtr dxgiFactory; 64 | CreateDXGIFactory1(IID_PPV_ARGS(&dxgiFactory)); 65 | 66 | CComPtr dxgiAdapter; 67 | UINT adapterIndex{}; 68 | HRESULT hr{}; 69 | do 70 | { 71 | dxgiAdapter = nullptr; 72 | dxgiAdapter = 0; 73 | THROW_IF_FAILED(dxgiFactory->EnumAdapters(adapterIndex, &dxgiAdapter)); 74 | ++adapterIndex; 75 | 76 | d3D12Device = 0; 77 | hr = ::D3D12CreateDevice( 78 | dxgiAdapter, 79 | D3D_FEATURE_LEVEL_11_0, 80 | IID_PPV_ARGS(&d3D12Device)); 81 | if (hr == DXGI_ERROR_UNSUPPORTED) continue; 82 | THROW_IF_FAILED(hr); 83 | } while (hr != S_OK); 84 | 85 | D3D12_COMMAND_QUEUE_DESC commandQueueDesc{}; 86 | commandQueueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT; 87 | commandQueueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; 88 | 89 | commandQueue = 0; 90 | THROW_IF_FAILED(d3D12Device->CreateCommandQueue( 91 | &commandQueueDesc, 92 | IID_PPV_ARGS(&commandQueue))); 93 | 94 | commandAllocator = 0; 95 | THROW_IF_FAILED(d3D12Device->CreateCommandAllocator( 96 | D3D12_COMMAND_LIST_TYPE_DIRECT, 97 | IID_PPV_ARGS(&commandAllocator))); 98 | 99 | commandList = 0; 100 | THROW_IF_FAILED(d3D12Device->CreateCommandList( 101 | 0, 102 | D3D12_COMMAND_LIST_TYPE_DIRECT, 103 | commandAllocator, 104 | nullptr, 105 | IID_PPV_ARGS(&commandList))); 106 | 107 | return S_OK; 108 | } 109 | 110 | HRESULT CreateDML() 111 | { 112 | DML_CREATE_DEVICE_FLAGS dmlCreateDeviceFlags = DML_CREATE_DEVICE_FLAG_NONE; 113 | #if defined (_DEBUG) 114 | dmlCreateDeviceFlags |= DML_CREATE_DEVICE_FLAG_DEBUG; 115 | #endif 116 | return DMLCreateDevice(d3D12Device, dmlCreateDeviceFlags, IID_PPV_ARGS(&dmlDevice)); 117 | } 118 | 119 | 120 | HRESULT CreateCommandRecorder() 121 | { 122 | return dmlDevice->CreateCommandRecorder( 123 | IID_PPV_ARGS(&dmlCommandRecorder)); 124 | } 125 | 126 | void CloseExecuteResetWait() 127 | { 128 | THROW_IF_FAILED(commandList->Close()); 129 | 130 | ID3D12CommandList* commandLists[] = { commandList }; 131 | commandQueue->ExecuteCommandLists(ARRAYSIZE(commandLists), commandLists); 132 | 133 | CComPtr d3D12Fence; 134 | THROW_IF_FAILED(d3D12Device->CreateFence( 135 | 0, 136 | D3D12_FENCE_FLAG_NONE, 137 | IID_PPV_ARGS(&d3D12Fence))); 138 | 139 | auto hfenceEventHandle = ::CreateEvent(nullptr, true, false, nullptr); 140 | 141 | THROW_IF_FAILED(commandQueue->Signal(d3D12Fence, 1)); 142 | THROW_IF_FAILED(d3D12Fence->SetEventOnCompletion(1, hfenceEventHandle)); 143 | 144 | ::WaitForSingleObjectEx(hfenceEventHandle, INFINITE, FALSE); 145 | 146 | THROW_IF_FAILED(commandAllocator->Reset()); 147 | THROW_IF_FAILED(commandList->Reset(commandAllocator, nullptr)); 148 | CloseHandle(hfenceEventHandle); 149 | } 150 | 151 | auto CreateCompiledOperatorAbs(std::initializer_list j,UINT64* ts = 0) 152 | { 153 | dml::Graph graph(dmlDevice); 154 | dml::TensorDesc desc = { DML_TENSOR_DATA_TYPE_FLOAT32, j }; 155 | dml::Expression input1 = dml::InputTensor(graph, 0, desc); 156 | dml::Expression output = dml::Abs(input1); 157 | 158 | if (ts) 159 | *ts = desc.totalTensorSizeInBytes; 160 | return graph.Compile(DML_EXECUTION_FLAG_ALLOW_HALF_PRECISION_COMPUTATION, { output }); 161 | } 162 | 163 | 164 | auto CreateCompiledOperatorAdd(std::initializer_list j, UINT64* ts = 0) 165 | { 166 | dml::Graph graph(dmlDevice); 167 | 168 | auto desc1 = dml::TensorDesc(DML_TENSOR_DATA_TYPE_FLOAT32, j); 169 | auto input1 = dml::InputTensor(graph, 0, desc1); 170 | auto desc2 = dml::TensorDesc(DML_TENSOR_DATA_TYPE_FLOAT32, j); 171 | auto input2 = dml::InputTensor(graph, 1, desc2); 172 | 173 | auto output = dml::Add(input1,input2); 174 | if (ts) 175 | *ts = desc1.totalTensorSizeInBytes + desc2.totalTensorSizeInBytes; 176 | return graph.Compile(DML_EXECUTION_FLAG_ALLOW_HALF_PRECISION_COMPUTATION, { output }); 177 | } 178 | 179 | // Two input tensors 180 | auto CreateCompiledOperatorLinearRegression(UINT32 N, UINT64* ts = 0) 181 | { 182 | dml::Graph graph(dmlDevice); 183 | 184 | auto desc1 = dml::TensorDesc(DML_TENSOR_DATA_TYPE_FLOAT32, { 1,N }); 185 | auto desc2 = dml::TensorDesc(DML_TENSOR_DATA_TYPE_FLOAT32, { 1,N }); 186 | auto input1 = dml::InputTensor(graph, 0, desc1); 187 | auto input2 = dml::InputTensor(graph, 1, desc2); 188 | 189 | // Create first output tensor, calculate Sx by adding all first row of the tensor and going to the output tensor (in which , we will only take the last element as the sum) 190 | auto o1 = dml::CumulativeSummation(input1, 1, DML_AXIS_DIRECTION_INCREASING, false); 191 | 192 | // Sy, similarily 193 | auto o2 = dml::CumulativeSummation(input2, 1, DML_AXIS_DIRECTION_INCREASING, false); 194 | 195 | // xy, we calculate multiplication 196 | auto o3 = dml::Multiply(input1, input2); 197 | 198 | // Sxy 199 | auto o4 = dml::CumulativeSummation(o3, 1, DML_AXIS_DIRECTION_INCREASING, false); 200 | 201 | // x*x, we calculate multiplication 202 | auto o5 = dml::Multiply(input1, input1); 203 | 204 | // Sx2 205 | auto o6 = dml::CumulativeSummation(o5, 1, DML_AXIS_DIRECTION_INCREASING, false); 206 | 207 | auto d1 = desc1.totalTensorSizeInBytes; 208 | while (d1 % DML_MINIMUM_BUFFER_TENSOR_ALIGNMENT) 209 | d1++; 210 | auto d2 = desc2.totalTensorSizeInBytes; 211 | while (d2 % DML_MINIMUM_BUFFER_TENSOR_ALIGNMENT) 212 | d2++; 213 | 214 | if (ts) 215 | *ts = d1 + d2; 216 | return graph.Compile(DML_EXECUTION_FLAG_ALLOW_HALF_PRECISION_COMPUTATION, { o1,o2,o3,o4,o5,o6 }); 217 | } 218 | 219 | void CreateInitializer() 220 | { 221 | IDMLCompiledOperator* dmlCompiledOperators[] = { dmlCompiledOperator }; 222 | THROW_IF_FAILED(dmlDevice->CreateOperatorInitializer( 223 | ARRAYSIZE(dmlCompiledOperators), 224 | dmlCompiledOperators, 225 | IID_PPV_ARGS(&dmlOperatorInitializer))); 226 | 227 | } 228 | 229 | void SetDescriptorHeaps() 230 | { 231 | ID3D12DescriptorHeap* d3D12DescriptorHeaps[] = { descriptorHeap }; 232 | commandList->SetDescriptorHeaps(ARRAYSIZE(d3D12DescriptorHeaps), d3D12DescriptorHeaps); 233 | } 234 | 235 | void CreateHeap() 236 | { 237 | // You need to initialize an operator exactly once before it can be executed, and 238 | // the two stages require different numbers of descriptors for binding. For simplicity, 239 | // we create a single descriptor heap that's large enough to satisfy them both. 240 | initializeBindingProperties = dmlOperatorInitializer->GetBindingProperties(); 241 | executeBindingProperties = dmlCompiledOperator->GetBindingProperties(); 242 | descriptorCount = std::max( 243 | initializeBindingProperties.RequiredDescriptorCount, 244 | executeBindingProperties.RequiredDescriptorCount); 245 | 246 | // Create descriptor heaps. 247 | 248 | D3D12_DESCRIPTOR_HEAP_DESC descriptorHeapDesc{}; 249 | descriptorHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; 250 | descriptorHeapDesc.NumDescriptors = descriptorCount; 251 | descriptorHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; 252 | THROW_IF_FAILED(d3D12Device->CreateDescriptorHeap( 253 | &descriptorHeapDesc, 254 | IID_PPV_ARGS(&descriptorHeap))); 255 | 256 | // Set the descriptor heap(s). 257 | SetDescriptorHeaps(); 258 | } 259 | 260 | DML_BINDING_TABLE_DESC dmlBindingTableDesc{}; 261 | CComPtr dmlBindingTable; 262 | void CreateBindingTable() 263 | { 264 | dmlBindingTableDesc.Dispatchable = dmlOperatorInitializer; 265 | dmlBindingTableDesc.CPUDescriptorHandle = descriptorHeap->GetCPUDescriptorHandleForHeapStart(); 266 | dmlBindingTableDesc.GPUDescriptorHandle = descriptorHeap->GetGPUDescriptorHandleForHeapStart(); 267 | dmlBindingTableDesc.SizeInDescriptors = descriptorCount; 268 | 269 | THROW_IF_FAILED(dmlDevice->CreateBindingTable( 270 | &dmlBindingTableDesc, 271 | IID_PPV_ARGS(&dmlBindingTable))); 272 | 273 | } 274 | 275 | void ResetToExecute() 276 | { 277 | dmlBindingTableDesc.Dispatchable = dmlCompiledOperator; 278 | THROW_IF_FAILED(dmlBindingTable->Reset(&dmlBindingTableDesc)); 279 | } 280 | 281 | CComPtr temporaryBuffer; 282 | UINT64 temporaryResourceSize = 0; 283 | void CreateTemporaryResources() 284 | { 285 | temporaryResourceSize = std::max(initializeBindingProperties.TemporaryResourceSize, executeBindingProperties.TemporaryResourceSize); 286 | if (temporaryResourceSize != 0) 287 | { 288 | auto x1 = CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT); 289 | auto x2 = CD3DX12_RESOURCE_DESC::Buffer(temporaryResourceSize, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS); 290 | THROW_IF_FAILED(d3D12Device->CreateCommittedResource( 291 | &x1, 292 | D3D12_HEAP_FLAG_NONE, 293 | &x2, 294 | D3D12_RESOURCE_STATE_COMMON, 295 | nullptr, 296 | IID_PPV_ARGS(&temporaryBuffer))); 297 | 298 | RebindTemporary(); 299 | } 300 | } 301 | 302 | UINT64 persistentResourceSize = 0; 303 | CComPtr persistentBuffer; 304 | void CreatePersistentResources() 305 | { 306 | // Persistent sources 307 | persistentResourceSize = std::max(initializeBindingProperties.PersistentResourceSize, executeBindingProperties.PersistentResourceSize); 308 | if (persistentResourceSize != 0) 309 | { 310 | auto x1 = CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT); 311 | auto x2 = CD3DX12_RESOURCE_DESC::Buffer(persistentResourceSize, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS); 312 | THROW_IF_FAILED(d3D12Device->CreateCommittedResource( 313 | &x1, 314 | D3D12_HEAP_FLAG_NONE, 315 | &x2, 316 | D3D12_RESOURCE_STATE_COMMON, 317 | nullptr, 318 | IID_PPV_ARGS(&persistentBuffer))); 319 | 320 | RebindPersistent(); 321 | } 322 | 323 | } 324 | 325 | void RebindPersistent() 326 | { 327 | // The persistent resource should be bound as the output to the IDMLOperatorInitializer. 328 | if (persistentResourceSize != 0) 329 | { 330 | DML_BUFFER_BINDING bufferBinding{ persistentBuffer, 0, persistentResourceSize }; 331 | DML_BINDING_DESC bindingDesc{ DML_BINDING_TYPE_BUFFER, &bufferBinding }; 332 | dmlBindingTable->BindOutputs(1, &bindingDesc); 333 | } 334 | } 335 | 336 | void RebindTemporary() 337 | { 338 | if (temporaryResourceSize != 0) 339 | { 340 | DML_BUFFER_BINDING bufferBinding{ temporaryBuffer, 0, temporaryResourceSize }; 341 | DML_BINDING_DESC bindingDesc{ DML_BINDING_TYPE_BUFFER, &bufferBinding }; 342 | dmlBindingTable->BindTemporaryResource(&bindingDesc); 343 | } 344 | } 345 | 346 | 347 | CComPtr uploadBuffer; 348 | CComPtr inputBuffer; 349 | 350 | CComPtr outputBuffer; 351 | 352 | void CreateBuffers(size_t Total,void* data,std::vector> ranges,bool O) 353 | { 354 | auto x1 = O ? CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT) : CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD); 355 | auto x2 = CD3DX12_RESOURCE_DESC::Buffer(Total,O ? D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS : D3D12_RESOURCE_FLAG_NONE); 356 | THROW_IF_FAILED(d3D12Device->CreateCommittedResource( 357 | &x1, 358 | D3D12_HEAP_FLAG_NONE, 359 | &x2, 360 | O ? D3D12_RESOURCE_STATE_UNORDERED_ACCESS : D3D12_RESOURCE_STATE_GENERIC_READ, 361 | nullptr, 362 | IID_PPV_ARGS(O ? &outputBuffer : &uploadBuffer))); 363 | if (O == 0) 364 | { 365 | auto x3 = CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT); 366 | auto x4 = CD3DX12_RESOURCE_DESC::Buffer(Total, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS); 367 | THROW_IF_FAILED(d3D12Device->CreateCommittedResource( 368 | &x3, 369 | D3D12_HEAP_FLAG_NONE, 370 | &x4, 371 | D3D12_RESOURCE_STATE_COPY_DEST, 372 | nullptr, 373 | IID_PPV_ARGS(&inputBuffer))); 374 | } 375 | 376 | if (O == 1) 377 | { 378 | std::vector outputBufferBinding(ranges.size()); 379 | std::vector outputBindingDesc(ranges.size()); 380 | for (size_t i = 0; i < ranges.size(); i++) 381 | { 382 | auto& ob = outputBufferBinding[i]; 383 | ob.Buffer = outputBuffer; 384 | ob.Offset = std::get<0>(ranges[i]); 385 | ob.SizeInBytes = std::get<1>(ranges[i]); 386 | 387 | auto& od = outputBindingDesc[i]; 388 | od.Type = DML_BINDING_TYPE_BUFFER; 389 | od.Desc = &ob; 390 | }; 391 | dmlBindingTable->BindOutputs((UINT)ranges.size(), outputBindingDesc.data()); 392 | return; 393 | } 394 | 395 | D3D12_SUBRESOURCE_DATA tensorSubresourceData{}; 396 | tensorSubresourceData.pData = data; 397 | tensorSubresourceData.RowPitch = static_cast(Total); 398 | tensorSubresourceData.SlicePitch = tensorSubresourceData.RowPitch; 399 | 400 | // Upload the input tensor to the GPU. 401 | ::UpdateSubresources(commandList, inputBuffer, uploadBuffer, 0, 0, 1, &tensorSubresourceData); 402 | 403 | auto x9 = CD3DX12_RESOURCE_BARRIER::Transition(inputBuffer, D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); 404 | commandList->ResourceBarrier(1, &x9); 405 | 406 | std::vector inputBufferBinding; 407 | inputBufferBinding.resize(ranges.size()); 408 | std::vector inputBindingDesc(ranges.size()); 409 | for (size_t i = 0; i < ranges.size(); i++) 410 | { 411 | auto& ibb = inputBufferBinding[i]; 412 | ibb.Buffer = inputBuffer; 413 | ibb.Offset = std::get<0>(ranges[i]); 414 | ibb.SizeInBytes = std::get<1>(ranges[i]); 415 | 416 | inputBindingDesc[i].Type = DML_BINDING_TYPE_BUFFER; 417 | inputBindingDesc[i].Desc = &ibb; 418 | 419 | } 420 | dmlBindingTable->BindInputs((UINT)inputBindingDesc.size(), inputBindingDesc.data()); 421 | } 422 | 423 | void Record(int what) 424 | { 425 | if (what == 0) 426 | dmlCommandRecorder->RecordDispatch(commandList, dmlOperatorInitializer, dmlBindingTable); 427 | if (what == 1) 428 | dmlCommandRecorder->RecordDispatch(commandList, dmlCompiledOperator, dmlBindingTable); 429 | } 430 | }; 431 | 432 | 433 | auto LinearRegressionCPU(float* px,float* py,size_t n) 434 | { 435 | // Sx 436 | float Sx = 0, Sy = 0,Sxy = 0,Sx2 = 0; 437 | for (size_t i = 0; i < n; i++) 438 | { 439 | Sx += px[i]; 440 | Sx2 += px[i] * px[i]; 441 | Sy += py[i]; 442 | Sxy += px[i] * py[i]; 443 | } 444 | // B 445 | 446 | float B = (n * Sxy - Sx * Sy) / ((n * Sx2) - (Sx * Sx)); 447 | float A = (Sy - (B * Sx)) / n; 448 | 449 | printf("Linear Regression CPU:\r\nSx = %f\r\nSy = %f\r\nSxy = %f\r\nSx2 = %f\r\nA = %f\r\nB = %f\r\n\r\n", Sx,Sy,Sxy,Sx2,A,B); 450 | return std::tuple(A, B); 451 | } 452 | 453 | 454 | std::vector xs = { 10,15,20,25,30,35 }; 455 | std::vector ys = { 1003,1005,1010,1008,1014,1022 }; 456 | size_t N = xs.size(); 457 | 458 | 459 | #include 460 | 461 | void RandomData() 462 | { 463 | xs.clear(); 464 | ys.clear(); 465 | 466 | int how = 1024 * 1024 * 32; 467 | 468 | printf("Generating %i random floats...",how); 469 | xs.resize(how); 470 | ys.resize(how); 471 | 472 | N = xs.size(); 473 | std::random_device rd; 474 | std::mt19937 e2(rd()); 475 | 476 | std::uniform_real_distribution<> dist1(0.0f, 1.0f); 477 | std::uniform_real_distribution<> dist2(10.0f, 100.0f); 478 | 479 | for (size_t i = 0; i < N; i++) 480 | { 481 | xs[i] = (float)dist1(e2); 482 | ys[i] = (float)dist2(e2); 483 | } 484 | 485 | 486 | } 487 | 488 | int main() 489 | { 490 | // RandomData(); 491 | 492 | 493 | CoInitialize(0); 494 | ML ml; 495 | 496 | // Initialize DirectX 12 497 | THROW_IF_FAILED(ml.InitializeDirect3D12()); 498 | 499 | // Create the DirectML device. 500 | THROW_IF_FAILED(ml.CreateDML()); 501 | 502 | #define Method 3 503 | #ifndef Method 504 | #error Please define Method above to 1,2 or 3 505 | #endif 506 | 507 | if (Method == 3) 508 | LinearRegressionCPU(xs.data(), ys.data(), N); 509 | 510 | UINT64 tensorInputSize = 0; 511 | std::vector inputTensorElementArray; 512 | if (Method == 1) 513 | { 514 | // Compile the operators 515 | auto dmlc = ml.CreateCompiledOperatorAbs({ 2,2 }, &tensorInputSize); 516 | ml.dmlCompiledOperator.Attach(dmlc.Detach()); 517 | inputTensorElementArray.resize(tensorInputSize / 4); 518 | } 519 | if (Method == 2) 520 | { 521 | // Compile the operators 522 | auto dmlc = ml.CreateCompiledOperatorAdd({ 2,2 }, &tensorInputSize); 523 | ml.dmlCompiledOperator.Attach(dmlc.Detach()); 524 | inputTensorElementArray.resize(tensorInputSize /4); 525 | } 526 | if (Method == 3) // LR 527 | { 528 | auto dmlc = ml.CreateCompiledOperatorLinearRegression((UINT32)N, &tensorInputSize); 529 | ml.dmlCompiledOperator.Attach(dmlc.Detach()); 530 | inputTensorElementArray.resize(tensorInputSize / 4); 531 | } 532 | // Initialize with numbers 533 | std::wstring inputString; 534 | if (Method != 3) 535 | { 536 | for (size_t i = 0; i < inputTensorElementArray.size(); i++) 537 | { 538 | inputTensorElementArray[i] = -1.0f * (i + 1); 539 | inputString += std::to_wstring(inputTensorElementArray[i]) + L' '; 540 | } 541 | } 542 | if (Method == 3) 543 | { 544 | // Initialize the linear regression 545 | inputString = L""; 546 | auto sz2 = inputTensorElementArray.size() / 2; 547 | memcpy(inputTensorElementArray.data(), xs.data(), std::min(sz2, xs.size()) * sizeof(float)); 548 | memcpy(inputTensorElementArray.data() + sz2, ys.data(), std::min(sz2, ys.size()) * sizeof(float)); 549 | } 550 | if (N <= 5) 551 | std::wcout << L"Inputs\r\n-------------\r\n" << inputString << std::endl << std::endl; 552 | 553 | auto tensorOutputSize = tensorInputSize; 554 | 555 | UINT64 Method3TensorSizes[6] = {}; 556 | 557 | 558 | if (Method == 3) 559 | { 560 | // We need 6 tensors for intermediates and output 561 | 562 | // First output should be N*4 bytes, aligned 563 | UINT64 f1 = N * 4; 564 | while (f1 % DML_MINIMUM_BUFFER_TENSOR_ALIGNMENT) 565 | f1++; 566 | Method3TensorSizes[0] = f1; 567 | 568 | // Second output, same 569 | UINT64 f2 = N * 4; 570 | while (f2 % DML_MINIMUM_BUFFER_TENSOR_ALIGNMENT) 571 | f2++; 572 | Method3TensorSizes[1] = f2; 573 | 574 | // Third output, same 575 | UINT64 f3 = N * 4; 576 | while (f3 % DML_MINIMUM_BUFFER_TENSOR_ALIGNMENT) 577 | f3++; 578 | Method3TensorSizes[2] = f3; 579 | 580 | // Fourth output, same 581 | UINT64 f4 = N * 4; 582 | while (f4 % DML_MINIMUM_BUFFER_TENSOR_ALIGNMENT) 583 | f4++; 584 | Method3TensorSizes[3] = f4; 585 | 586 | // Fifth output, same 587 | UINT64 f5 = N * 4; 588 | while (f5 % DML_MINIMUM_BUFFER_TENSOR_ALIGNMENT) 589 | f5++; 590 | Method3TensorSizes[4] = f5; 591 | 592 | 593 | // Sixth output, same 594 | UINT64 f6 = N * 4; 595 | while (f6 % DML_MINIMUM_BUFFER_TENSOR_ALIGNMENT) 596 | f6++; 597 | Method3TensorSizes[5] = f6; 598 | 599 | tensorOutputSize = (f1 + f2 + f3 + f4 + f5 + f6); 600 | } 601 | 602 | // Initialize 603 | ml.CreateInitializer(); 604 | 605 | // https://learn.microsoft.com/en-us/windows/ai/directml/dml-binding 606 | // Query the operator for the required size (in descriptors) of its binding table. 607 | ml.CreateHeap(); 608 | 609 | // Create a binding table over the descriptor heap we just created. 610 | ml.CreateBindingTable(); 611 | 612 | // The temporary resource is scratch memory (used internally by DirectML), whose contents you don't need to define. 613 | ml.CreateTemporaryResources(); 614 | 615 | // The persistent resource is long-lived, and you need to initialize it using the IDMLOperatorInitializer. 616 | ml.CreatePersistentResources(); 617 | 618 | // The command recorder is a stateless object that records Dispatches into an existing Direct3D 12 command list. 619 | ml.CreateCommandRecorder(); 620 | 621 | // Record execution of the operator initializer. 622 | ml.Record(0); 623 | 624 | // Close the Direct3D 12 command list, and submit it for execution as you would any other command list. You could 625 | // in principle record the execution into the same command list as the initialization, but you need only to Initialize 626 | // once, and typically you want to Execute an operator more frequently than that. 627 | ml.CloseExecuteResetWait(); 628 | 629 | // Bind and execute the operator on the GPU. 630 | ml.SetDescriptorHeaps(); 631 | 632 | // Reset the binding table to bind for the operator we want to execute (it was previously used to bind for the initializer). 633 | ml.ResetToExecute(); 634 | 635 | // Rebind Temporary and Persistent stuff 636 | ml.RebindTemporary(); 637 | ml.RebindPersistent(); 638 | 639 | 640 | if (Method == 1) 641 | ml.CreateBuffers(tensorInputSize, inputTensorElementArray.data(), { {0,tensorInputSize} },0); 642 | 643 | if (Method == 2) 644 | ml.CreateBuffers(tensorInputSize, inputTensorElementArray.data(), { {0,tensorInputSize/2},{tensorInputSize/2,tensorInputSize/2} },0); 645 | 646 | if (Method == 3) 647 | ml.CreateBuffers(tensorInputSize, inputTensorElementArray.data(), { {0,tensorInputSize / 2},{tensorInputSize / 2,tensorInputSize / 2} },0); 648 | 649 | if (Method == 1) 650 | ml.CreateBuffers(tensorOutputSize, 0, { {0,tensorOutputSize} }, 1); 651 | 652 | if (Method == 2) 653 | ml.CreateBuffers(tensorOutputSize, 0, { {0,tensorOutputSize/2} }, 1); 654 | 655 | if (Method == 3) 656 | ml.CreateBuffers(tensorOutputSize, 0, { 657 | {0,Method3TensorSizes[0]}, 658 | {Method3TensorSizes[0],Method3TensorSizes[1]}, 659 | {Method3TensorSizes[0] + Method3TensorSizes[1],Method3TensorSizes[2]}, 660 | {Method3TensorSizes[0] + Method3TensorSizes[1] + Method3TensorSizes[2],Method3TensorSizes[3]}, 661 | {Method3TensorSizes[0] + Method3TensorSizes[1] + Method3TensorSizes[2] + Method3TensorSizes[3],Method3TensorSizes[4]}, 662 | {Method3TensorSizes[0] + Method3TensorSizes[1] + Method3TensorSizes[2] + Method3TensorSizes[3] + Method3TensorSizes[4],Method3TensorSizes[5]}, 663 | }, 1); 664 | 665 | // Run it 666 | ml.Record(1); 667 | ml.CloseExecuteResetWait(); 668 | 669 | // The output buffer now contains the result of the identity operator, 670 | // so read it back if you want the CPU to access it. 671 | CComPtr readbackBuffer; 672 | auto x7 = CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_READBACK); 673 | auto x8 = CD3DX12_RESOURCE_DESC::Buffer(tensorOutputSize); 674 | THROW_IF_FAILED(ml.d3D12Device->CreateCommittedResource( 675 | &x7, 676 | D3D12_HEAP_FLAG_NONE, 677 | &x8, 678 | D3D12_RESOURCE_STATE_COPY_DEST, 679 | nullptr, 680 | IID_PPV_ARGS(&readbackBuffer))); 681 | 682 | auto x10 = CD3DX12_RESOURCE_BARRIER::Transition(ml.outputBuffer,D3D12_RESOURCE_STATE_UNORDERED_ACCESS,D3D12_RESOURCE_STATE_COPY_SOURCE); 683 | ml.commandList->ResourceBarrier(1,&x10); 684 | 685 | ml.commandList->CopyResource(readbackBuffer, ml.outputBuffer); 686 | 687 | ml.CloseExecuteResetWait(); 688 | 689 | D3D12_RANGE tensorBufferRange{ 0, static_cast(tensorOutputSize) }; 690 | FLOAT* outputBufferData{}; 691 | THROW_IF_FAILED(readbackBuffer->Map(0, &tensorBufferRange, reinterpret_cast(&outputBufferData))); 692 | std::wstring outputString; 693 | 694 | float Sx = 0, Sy = 0, Sxy = 0, Sx2 = 0; 695 | if (Method == 1) 696 | { 697 | outputString += L"Output\r\n-----------------\r\n"; 698 | for (size_t tensorElementIndex = 0; tensorElementIndex < 4 ; ++tensorElementIndex, ++outputBufferData) 699 | outputString += std::to_wstring(*outputBufferData) + L' '; 700 | outputString += L"\r\n\r\n"; 701 | std::wcout << outputString; 702 | } 703 | if (Method == 2) 704 | { 705 | outputString += L"Output\r\n-----------------\r\n"; 706 | for (size_t tensorElementIndex = 0; tensorElementIndex < 8; ++tensorElementIndex, ++outputBufferData) 707 | outputString += std::to_wstring(*outputBufferData) + L' '; 708 | outputString += L"\r\n\r\n"; 709 | std::wcout << outputString; 710 | } 711 | if (Method == 3) 712 | { 713 | // Output 1, 714 | char* o = (char*)outputBufferData; 715 | Sx = outputBufferData[N - 1]; 716 | 717 | if (N <= 5) 718 | { 719 | outputString += L"Output 1 - Sx\r\n-----------------\r\n"; 720 | for (size_t tensorElementIndex = 0; tensorElementIndex < N; ++tensorElementIndex, ++outputBufferData) 721 | outputString += std::to_wstring(*outputBufferData) + L' '; 722 | outputString += L"\r\n\r\n"; 723 | } 724 | 725 | o += Method3TensorSizes[0]; 726 | outputBufferData = (float*)o; 727 | Sy = outputBufferData[N - 1]; 728 | if (N <= 5) 729 | { 730 | outputString += L"Output 2 - Sy\r\n-----------------\r\n"; 731 | for (size_t tensorElementIndex = 0; tensorElementIndex < N; ++tensorElementIndex, ++outputBufferData) 732 | outputString += std::to_wstring(*outputBufferData) + L' '; 733 | outputString += L"\r\n\r\n"; 734 | } 735 | 736 | o += Method3TensorSizes[1]; 737 | outputBufferData = (float*)o; 738 | if (N <= 5) 739 | { 740 | outputString += L"Output 3 - xy\r\n-----------------\r\n"; 741 | for (size_t tensorElementIndex = 0; tensorElementIndex < N; ++tensorElementIndex, ++outputBufferData) 742 | outputString += std::to_wstring(*outputBufferData) + L' '; 743 | outputString += L"\r\n\r\n"; 744 | } 745 | 746 | o += Method3TensorSizes[2]; 747 | outputBufferData = (float*)o; 748 | Sxy = outputBufferData[N - 1]; 749 | if (N <= 5) 750 | { 751 | outputString += L"Output 4 - Sxy\r\n-----------------\r\n"; 752 | for (size_t tensorElementIndex = 0; tensorElementIndex < N; ++tensorElementIndex, ++outputBufferData) 753 | outputString += std::to_wstring(*outputBufferData) + L' '; 754 | outputString += L"\r\n\r\n"; 755 | } 756 | 757 | o += Method3TensorSizes[3]; 758 | outputBufferData = (float*)o; 759 | if (N <= 5) 760 | { 761 | outputString += L"Output 5 - xx\r\n-----------------\r\n"; 762 | for (size_t tensorElementIndex = 0; tensorElementIndex < N; ++tensorElementIndex, ++outputBufferData) 763 | outputString += std::to_wstring(*outputBufferData) + L' '; 764 | outputString += L"\r\n\r\n"; 765 | } 766 | 767 | o += Method3TensorSizes[4]; 768 | outputBufferData = (float*)o; 769 | Sx2 = outputBufferData[N - 1]; 770 | if (N <= 5) 771 | { 772 | outputString += L"Output 6 - Sxx\r\n-----------------\r\n"; 773 | for (size_t tensorElementIndex = 0; tensorElementIndex < N; ++tensorElementIndex, ++outputBufferData) 774 | outputString += std::to_wstring(*outputBufferData) + L' '; 775 | outputString += L"\r\n\r\n"; 776 | } 777 | } 778 | else 779 | { 780 | for (size_t tensorElementIndex{ 0 }; tensorElementIndex < (tensorOutputSize / 4); ++tensorElementIndex, ++outputBufferData) 781 | { 782 | outputString += std::to_wstring(*outputBufferData) + L' '; 783 | } 784 | } 785 | if (N <= 5) 786 | std::wcout << L"Outputs\r\n-------------\r\n" << outputString << std::endl << std::endl; 787 | 788 | // B 789 | float B = (N * Sxy - Sx * Sy) / ((N * Sx2) - (Sx * Sx)); 790 | float A = (Sy - (B * Sx)) / N; 791 | 792 | 793 | if (Method == 3) 794 | printf("Linear Regression GPU:\r\nSx = %f\r\nSy = %f\r\nSxy = %f\r\nSx2 = %f\r\nA = %f\r\nB = %f\r\n\r\n", Sx, Sy, Sxy, Sx2, A, B); 795 | 796 | D3D12_RANGE emptyRange{ 0, 0 }; 797 | readbackBuffer->Unmap(0, &emptyRange); 798 | getchar(); 799 | } 800 | 801 | 802 | 803 | -------------------------------------------------------------------------------- /DirectMLTest.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.9.34728.123 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DirectMLTest", "DirectMLTest.vcxproj", "{3561A20A-AA08-4D3E-BD33-4A5794EA8249}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {3561A20A-AA08-4D3E-BD33-4A5794EA8249}.Debug|x64.ActiveCfg = Debug|x64 17 | {3561A20A-AA08-4D3E-BD33-4A5794EA8249}.Debug|x64.Build.0 = Debug|x64 18 | {3561A20A-AA08-4D3E-BD33-4A5794EA8249}.Debug|x86.ActiveCfg = Debug|Win32 19 | {3561A20A-AA08-4D3E-BD33-4A5794EA8249}.Debug|x86.Build.0 = Debug|Win32 20 | {3561A20A-AA08-4D3E-BD33-4A5794EA8249}.Release|x64.ActiveCfg = Release|x64 21 | {3561A20A-AA08-4D3E-BD33-4A5794EA8249}.Release|x64.Build.0 = Release|x64 22 | {3561A20A-AA08-4D3E-BD33-4A5794EA8249}.Release|x86.ActiveCfg = Release|Win32 23 | {3561A20A-AA08-4D3E-BD33-4A5794EA8249}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {E3CDE6EF-7698-4E8B-947A-036C6F4E3271} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /DirectMLTest.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 17.0 23 | Win32Proj 24 | {3561a20a-aa08-4d3e-bd33-4a5794ea8249} 25 | DirectMLTest 26 | 10.0 27 | 28 | 29 | 30 | Application 31 | true 32 | v143 33 | Unicode 34 | 35 | 36 | Application 37 | false 38 | v143 39 | true 40 | Unicode 41 | 42 | 43 | Application 44 | true 45 | v143 46 | Unicode 47 | 48 | 49 | Application 50 | false 51 | v143 52 | true 53 | Unicode 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | Level3 76 | true 77 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 78 | true 79 | stdcpp17 80 | 81 | 82 | Console 83 | true 84 | 85 | 86 | 87 | 88 | Level3 89 | true 90 | true 91 | true 92 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 93 | true 94 | stdcpp17 95 | 96 | 97 | Console 98 | true 99 | true 100 | true 101 | 102 | 103 | 104 | 105 | Level3 106 | true 107 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 108 | true 109 | stdcpp17 110 | 111 | 112 | Console 113 | true 114 | 115 | 116 | 117 | 118 | Level3 119 | true 120 | true 121 | true 122 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 123 | true 124 | stdcpp17 125 | 126 | 127 | Console 128 | true 129 | true 130 | true 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | -------------------------------------------------------------------------------- /DirectMLTest.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) [year] [fullname] 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the 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 THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DirectMLTest 2 | 3 | A sample that is based on [HelloDirectML](https://github.com/microsoft/DirectML/blob/master/Samples/HelloDirectML/) but extends it with real life operations: A Linear Regression of a configurable number of variables. 4 | 5 | [Article](https://www.codeproject.com/Articles/5380834/Machine-Learning-for-Cplusplus-developers-the-hard) in CodeProject. 6 | -------------------------------------------------------------------------------- /d3dx12.h: -------------------------------------------------------------------------------- 1 | //********************************************************* 2 | // 3 | // Copyright (c) Microsoft. All rights reserved. 4 | // This code is licensed under the MIT License (MIT). 5 | // THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF 6 | // ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY 7 | // IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR 8 | // PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. 9 | // 10 | //********************************************************* 11 | 12 | #ifndef __D3DX12_H__ 13 | #define __D3DX12_H__ 14 | 15 | #include "d3d12.h" 16 | 17 | #if defined( __cplusplus ) 18 | 19 | struct CD3DX12_DEFAULT {}; 20 | extern const DECLSPEC_SELECTANY CD3DX12_DEFAULT D3D12_DEFAULT; 21 | 22 | //------------------------------------------------------------------------------------------------ 23 | inline bool operator==( const D3D12_VIEWPORT& l, const D3D12_VIEWPORT& r ) 24 | { 25 | return l.TopLeftX == r.TopLeftX && l.TopLeftY == r.TopLeftY && l.Width == r.Width && 26 | l.Height == r.Height && l.MinDepth == r.MinDepth && l.MaxDepth == r.MaxDepth; 27 | } 28 | 29 | //------------------------------------------------------------------------------------------------ 30 | inline bool operator!=( const D3D12_VIEWPORT& l, const D3D12_VIEWPORT& r ) 31 | { return !( l == r ); } 32 | 33 | //------------------------------------------------------------------------------------------------ 34 | struct CD3DX12_RECT : public D3D12_RECT 35 | { 36 | CD3DX12_RECT() = default; 37 | explicit CD3DX12_RECT( const D3D12_RECT& o ) : 38 | D3D12_RECT( o ) 39 | {} 40 | explicit CD3DX12_RECT( 41 | LONG Left, 42 | LONG Top, 43 | LONG Right, 44 | LONG Bottom ) 45 | { 46 | left = Left; 47 | top = Top; 48 | right = Right; 49 | bottom = Bottom; 50 | } 51 | }; 52 | 53 | //------------------------------------------------------------------------------------------------ 54 | struct CD3DX12_VIEWPORT : public D3D12_VIEWPORT 55 | { 56 | CD3DX12_VIEWPORT() = default; 57 | explicit CD3DX12_VIEWPORT( const D3D12_VIEWPORT& o ) : 58 | D3D12_VIEWPORT( o ) 59 | {} 60 | explicit CD3DX12_VIEWPORT( 61 | FLOAT topLeftX, 62 | FLOAT topLeftY, 63 | FLOAT width, 64 | FLOAT height, 65 | FLOAT minDepth = D3D12_MIN_DEPTH, 66 | FLOAT maxDepth = D3D12_MAX_DEPTH ) 67 | { 68 | TopLeftX = topLeftX; 69 | TopLeftY = topLeftY; 70 | Width = width; 71 | Height = height; 72 | MinDepth = minDepth; 73 | MaxDepth = maxDepth; 74 | } 75 | explicit CD3DX12_VIEWPORT( 76 | _In_ ID3D12Resource* pResource, 77 | UINT mipSlice = 0, 78 | FLOAT topLeftX = 0.0f, 79 | FLOAT topLeftY = 0.0f, 80 | FLOAT minDepth = D3D12_MIN_DEPTH, 81 | FLOAT maxDepth = D3D12_MAX_DEPTH ) 82 | { 83 | auto Desc = pResource->GetDesc(); 84 | const UINT64 SubresourceWidth = Desc.Width >> mipSlice; 85 | const UINT64 SubresourceHeight = Desc.Height >> mipSlice; 86 | switch (Desc.Dimension) 87 | { 88 | case D3D12_RESOURCE_DIMENSION_BUFFER: 89 | TopLeftX = topLeftX; 90 | TopLeftY = 0.0f; 91 | Width = Desc.Width - topLeftX; 92 | Height = 1.0f; 93 | break; 94 | case D3D12_RESOURCE_DIMENSION_TEXTURE1D: 95 | TopLeftX = topLeftX; 96 | TopLeftY = 0.0f; 97 | Width = (SubresourceWidth ? SubresourceWidth : 1.0f) - topLeftX; 98 | Height = 1.0f; 99 | break; 100 | case D3D12_RESOURCE_DIMENSION_TEXTURE2D: 101 | case D3D12_RESOURCE_DIMENSION_TEXTURE3D: 102 | TopLeftX = topLeftX; 103 | TopLeftY = topLeftY; 104 | Width = (SubresourceWidth ? SubresourceWidth : 1.0f) - topLeftX; 105 | Height = (SubresourceHeight ? SubresourceHeight: 1.0f) - topLeftY; 106 | break; 107 | default: break; 108 | } 109 | 110 | MinDepth = minDepth; 111 | MaxDepth = maxDepth; 112 | } 113 | }; 114 | 115 | //------------------------------------------------------------------------------------------------ 116 | struct CD3DX12_BOX : public D3D12_BOX 117 | { 118 | CD3DX12_BOX() = default; 119 | explicit CD3DX12_BOX( const D3D12_BOX& o ) : 120 | D3D12_BOX( o ) 121 | {} 122 | explicit CD3DX12_BOX( 123 | LONG Left, 124 | LONG Right ) 125 | { 126 | left = Left; 127 | top = 0; 128 | front = 0; 129 | right = Right; 130 | bottom = 1; 131 | back = 1; 132 | } 133 | explicit CD3DX12_BOX( 134 | LONG Left, 135 | LONG Top, 136 | LONG Right, 137 | LONG Bottom ) 138 | { 139 | left = Left; 140 | top = Top; 141 | front = 0; 142 | right = Right; 143 | bottom = Bottom; 144 | back = 1; 145 | } 146 | explicit CD3DX12_BOX( 147 | LONG Left, 148 | LONG Top, 149 | LONG Front, 150 | LONG Right, 151 | LONG Bottom, 152 | LONG Back ) 153 | { 154 | left = Left; 155 | top = Top; 156 | front = Front; 157 | right = Right; 158 | bottom = Bottom; 159 | back = Back; 160 | } 161 | }; 162 | inline bool operator==( const D3D12_BOX& l, const D3D12_BOX& r ) 163 | { 164 | return l.left == r.left && l.top == r.top && l.front == r.front && 165 | l.right == r.right && l.bottom == r.bottom && l.back == r.back; 166 | } 167 | inline bool operator!=( const D3D12_BOX& l, const D3D12_BOX& r ) 168 | { return !( l == r ); } 169 | 170 | //------------------------------------------------------------------------------------------------ 171 | struct CD3DX12_DEPTH_STENCIL_DESC : public D3D12_DEPTH_STENCIL_DESC 172 | { 173 | CD3DX12_DEPTH_STENCIL_DESC() = default; 174 | explicit CD3DX12_DEPTH_STENCIL_DESC( const D3D12_DEPTH_STENCIL_DESC& o ) : 175 | D3D12_DEPTH_STENCIL_DESC( o ) 176 | {} 177 | explicit CD3DX12_DEPTH_STENCIL_DESC( CD3DX12_DEFAULT ) 178 | { 179 | DepthEnable = TRUE; 180 | DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL; 181 | DepthFunc = D3D12_COMPARISON_FUNC_LESS; 182 | StencilEnable = FALSE; 183 | StencilReadMask = D3D12_DEFAULT_STENCIL_READ_MASK; 184 | StencilWriteMask = D3D12_DEFAULT_STENCIL_WRITE_MASK; 185 | const D3D12_DEPTH_STENCILOP_DESC defaultStencilOp = 186 | { D3D12_STENCIL_OP_KEEP, D3D12_STENCIL_OP_KEEP, D3D12_STENCIL_OP_KEEP, D3D12_COMPARISON_FUNC_ALWAYS }; 187 | FrontFace = defaultStencilOp; 188 | BackFace = defaultStencilOp; 189 | } 190 | explicit CD3DX12_DEPTH_STENCIL_DESC( 191 | BOOL depthEnable, 192 | D3D12_DEPTH_WRITE_MASK depthWriteMask, 193 | D3D12_COMPARISON_FUNC depthFunc, 194 | BOOL stencilEnable, 195 | UINT8 stencilReadMask, 196 | UINT8 stencilWriteMask, 197 | D3D12_STENCIL_OP frontStencilFailOp, 198 | D3D12_STENCIL_OP frontStencilDepthFailOp, 199 | D3D12_STENCIL_OP frontStencilPassOp, 200 | D3D12_COMPARISON_FUNC frontStencilFunc, 201 | D3D12_STENCIL_OP backStencilFailOp, 202 | D3D12_STENCIL_OP backStencilDepthFailOp, 203 | D3D12_STENCIL_OP backStencilPassOp, 204 | D3D12_COMPARISON_FUNC backStencilFunc ) 205 | { 206 | DepthEnable = depthEnable; 207 | DepthWriteMask = depthWriteMask; 208 | DepthFunc = depthFunc; 209 | StencilEnable = stencilEnable; 210 | StencilReadMask = stencilReadMask; 211 | StencilWriteMask = stencilWriteMask; 212 | FrontFace.StencilFailOp = frontStencilFailOp; 213 | FrontFace.StencilDepthFailOp = frontStencilDepthFailOp; 214 | FrontFace.StencilPassOp = frontStencilPassOp; 215 | FrontFace.StencilFunc = frontStencilFunc; 216 | BackFace.StencilFailOp = backStencilFailOp; 217 | BackFace.StencilDepthFailOp = backStencilDepthFailOp; 218 | BackFace.StencilPassOp = backStencilPassOp; 219 | BackFace.StencilFunc = backStencilFunc; 220 | } 221 | }; 222 | 223 | //------------------------------------------------------------------------------------------------ 224 | struct CD3DX12_DEPTH_STENCIL_DESC1 : public D3D12_DEPTH_STENCIL_DESC1 225 | { 226 | CD3DX12_DEPTH_STENCIL_DESC1() = default; 227 | explicit CD3DX12_DEPTH_STENCIL_DESC1( const D3D12_DEPTH_STENCIL_DESC1& o ) : 228 | D3D12_DEPTH_STENCIL_DESC1( o ) 229 | {} 230 | explicit CD3DX12_DEPTH_STENCIL_DESC1( const D3D12_DEPTH_STENCIL_DESC& o ) 231 | { 232 | DepthEnable = o.DepthEnable; 233 | DepthWriteMask = o.DepthWriteMask; 234 | DepthFunc = o.DepthFunc; 235 | StencilEnable = o.StencilEnable; 236 | StencilReadMask = o.StencilReadMask; 237 | StencilWriteMask = o.StencilWriteMask; 238 | FrontFace.StencilFailOp = o.FrontFace.StencilFailOp; 239 | FrontFace.StencilDepthFailOp = o.FrontFace.StencilDepthFailOp; 240 | FrontFace.StencilPassOp = o.FrontFace.StencilPassOp; 241 | FrontFace.StencilFunc = o.FrontFace.StencilFunc; 242 | BackFace.StencilFailOp = o.BackFace.StencilFailOp; 243 | BackFace.StencilDepthFailOp = o.BackFace.StencilDepthFailOp; 244 | BackFace.StencilPassOp = o.BackFace.StencilPassOp; 245 | BackFace.StencilFunc = o.BackFace.StencilFunc; 246 | DepthBoundsTestEnable = FALSE; 247 | } 248 | explicit CD3DX12_DEPTH_STENCIL_DESC1( CD3DX12_DEFAULT ) 249 | { 250 | DepthEnable = TRUE; 251 | DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL; 252 | DepthFunc = D3D12_COMPARISON_FUNC_LESS; 253 | StencilEnable = FALSE; 254 | StencilReadMask = D3D12_DEFAULT_STENCIL_READ_MASK; 255 | StencilWriteMask = D3D12_DEFAULT_STENCIL_WRITE_MASK; 256 | const D3D12_DEPTH_STENCILOP_DESC defaultStencilOp = 257 | { D3D12_STENCIL_OP_KEEP, D3D12_STENCIL_OP_KEEP, D3D12_STENCIL_OP_KEEP, D3D12_COMPARISON_FUNC_ALWAYS }; 258 | FrontFace = defaultStencilOp; 259 | BackFace = defaultStencilOp; 260 | DepthBoundsTestEnable = FALSE; 261 | } 262 | explicit CD3DX12_DEPTH_STENCIL_DESC1( 263 | BOOL depthEnable, 264 | D3D12_DEPTH_WRITE_MASK depthWriteMask, 265 | D3D12_COMPARISON_FUNC depthFunc, 266 | BOOL stencilEnable, 267 | UINT8 stencilReadMask, 268 | UINT8 stencilWriteMask, 269 | D3D12_STENCIL_OP frontStencilFailOp, 270 | D3D12_STENCIL_OP frontStencilDepthFailOp, 271 | D3D12_STENCIL_OP frontStencilPassOp, 272 | D3D12_COMPARISON_FUNC frontStencilFunc, 273 | D3D12_STENCIL_OP backStencilFailOp, 274 | D3D12_STENCIL_OP backStencilDepthFailOp, 275 | D3D12_STENCIL_OP backStencilPassOp, 276 | D3D12_COMPARISON_FUNC backStencilFunc, 277 | BOOL depthBoundsTestEnable ) 278 | { 279 | DepthEnable = depthEnable; 280 | DepthWriteMask = depthWriteMask; 281 | DepthFunc = depthFunc; 282 | StencilEnable = stencilEnable; 283 | StencilReadMask = stencilReadMask; 284 | StencilWriteMask = stencilWriteMask; 285 | FrontFace.StencilFailOp = frontStencilFailOp; 286 | FrontFace.StencilDepthFailOp = frontStencilDepthFailOp; 287 | FrontFace.StencilPassOp = frontStencilPassOp; 288 | FrontFace.StencilFunc = frontStencilFunc; 289 | BackFace.StencilFailOp = backStencilFailOp; 290 | BackFace.StencilDepthFailOp = backStencilDepthFailOp; 291 | BackFace.StencilPassOp = backStencilPassOp; 292 | BackFace.StencilFunc = backStencilFunc; 293 | DepthBoundsTestEnable = depthBoundsTestEnable; 294 | } 295 | operator D3D12_DEPTH_STENCIL_DESC() const 296 | { 297 | D3D12_DEPTH_STENCIL_DESC D; 298 | D.DepthEnable = DepthEnable; 299 | D.DepthWriteMask = DepthWriteMask; 300 | D.DepthFunc = DepthFunc; 301 | D.StencilEnable = StencilEnable; 302 | D.StencilReadMask = StencilReadMask; 303 | D.StencilWriteMask = StencilWriteMask; 304 | D.FrontFace.StencilFailOp = FrontFace.StencilFailOp; 305 | D.FrontFace.StencilDepthFailOp = FrontFace.StencilDepthFailOp; 306 | D.FrontFace.StencilPassOp = FrontFace.StencilPassOp; 307 | D.FrontFace.StencilFunc = FrontFace.StencilFunc; 308 | D.BackFace.StencilFailOp = BackFace.StencilFailOp; 309 | D.BackFace.StencilDepthFailOp = BackFace.StencilDepthFailOp; 310 | D.BackFace.StencilPassOp = BackFace.StencilPassOp; 311 | D.BackFace.StencilFunc = BackFace.StencilFunc; 312 | return D; 313 | } 314 | }; 315 | 316 | //------------------------------------------------------------------------------------------------ 317 | struct CD3DX12_BLEND_DESC : public D3D12_BLEND_DESC 318 | { 319 | CD3DX12_BLEND_DESC() = default; 320 | explicit CD3DX12_BLEND_DESC( const D3D12_BLEND_DESC& o ) : 321 | D3D12_BLEND_DESC( o ) 322 | {} 323 | explicit CD3DX12_BLEND_DESC( CD3DX12_DEFAULT ) 324 | { 325 | AlphaToCoverageEnable = FALSE; 326 | IndependentBlendEnable = FALSE; 327 | const D3D12_RENDER_TARGET_BLEND_DESC defaultRenderTargetBlendDesc = 328 | { 329 | FALSE,FALSE, 330 | D3D12_BLEND_ONE, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD, 331 | D3D12_BLEND_ONE, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD, 332 | D3D12_LOGIC_OP_NOOP, 333 | D3D12_COLOR_WRITE_ENABLE_ALL, 334 | }; 335 | for (UINT i = 0; i < D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT; ++i) 336 | RenderTarget[ i ] = defaultRenderTargetBlendDesc; 337 | } 338 | }; 339 | 340 | //------------------------------------------------------------------------------------------------ 341 | struct CD3DX12_RASTERIZER_DESC : public D3D12_RASTERIZER_DESC 342 | { 343 | CD3DX12_RASTERIZER_DESC() = default; 344 | explicit CD3DX12_RASTERIZER_DESC( const D3D12_RASTERIZER_DESC& o ) : 345 | D3D12_RASTERIZER_DESC( o ) 346 | {} 347 | explicit CD3DX12_RASTERIZER_DESC( CD3DX12_DEFAULT ) 348 | { 349 | FillMode = D3D12_FILL_MODE_SOLID; 350 | CullMode = D3D12_CULL_MODE_BACK; 351 | FrontCounterClockwise = FALSE; 352 | DepthBias = D3D12_DEFAULT_DEPTH_BIAS; 353 | DepthBiasClamp = D3D12_DEFAULT_DEPTH_BIAS_CLAMP; 354 | SlopeScaledDepthBias = D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS; 355 | DepthClipEnable = TRUE; 356 | MultisampleEnable = FALSE; 357 | AntialiasedLineEnable = FALSE; 358 | ForcedSampleCount = 0; 359 | ConservativeRaster = D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF; 360 | } 361 | explicit CD3DX12_RASTERIZER_DESC( 362 | D3D12_FILL_MODE fillMode, 363 | D3D12_CULL_MODE cullMode, 364 | BOOL frontCounterClockwise, 365 | INT depthBias, 366 | FLOAT depthBiasClamp, 367 | FLOAT slopeScaledDepthBias, 368 | BOOL depthClipEnable, 369 | BOOL multisampleEnable, 370 | BOOL antialiasedLineEnable, 371 | UINT forcedSampleCount, 372 | D3D12_CONSERVATIVE_RASTERIZATION_MODE conservativeRaster) 373 | { 374 | FillMode = fillMode; 375 | CullMode = cullMode; 376 | FrontCounterClockwise = frontCounterClockwise; 377 | DepthBias = depthBias; 378 | DepthBiasClamp = depthBiasClamp; 379 | SlopeScaledDepthBias = slopeScaledDepthBias; 380 | DepthClipEnable = depthClipEnable; 381 | MultisampleEnable = multisampleEnable; 382 | AntialiasedLineEnable = antialiasedLineEnable; 383 | ForcedSampleCount = forcedSampleCount; 384 | ConservativeRaster = conservativeRaster; 385 | } 386 | }; 387 | 388 | //------------------------------------------------------------------------------------------------ 389 | struct CD3DX12_RESOURCE_ALLOCATION_INFO : public D3D12_RESOURCE_ALLOCATION_INFO 390 | { 391 | CD3DX12_RESOURCE_ALLOCATION_INFO() = default; 392 | explicit CD3DX12_RESOURCE_ALLOCATION_INFO( const D3D12_RESOURCE_ALLOCATION_INFO& o ) : 393 | D3D12_RESOURCE_ALLOCATION_INFO( o ) 394 | {} 395 | CD3DX12_RESOURCE_ALLOCATION_INFO( 396 | UINT64 size, 397 | UINT64 alignment ) 398 | { 399 | SizeInBytes = size; 400 | Alignment = alignment; 401 | } 402 | }; 403 | 404 | //------------------------------------------------------------------------------------------------ 405 | struct CD3DX12_HEAP_PROPERTIES : public D3D12_HEAP_PROPERTIES 406 | { 407 | CD3DX12_HEAP_PROPERTIES() = default; 408 | explicit CD3DX12_HEAP_PROPERTIES(const D3D12_HEAP_PROPERTIES &o) : 409 | D3D12_HEAP_PROPERTIES(o) 410 | {} 411 | CD3DX12_HEAP_PROPERTIES( 412 | D3D12_CPU_PAGE_PROPERTY cpuPageProperty, 413 | D3D12_MEMORY_POOL memoryPoolPreference, 414 | UINT creationNodeMask = 1, 415 | UINT nodeMask = 1 ) 416 | { 417 | Type = D3D12_HEAP_TYPE_CUSTOM; 418 | CPUPageProperty = cpuPageProperty; 419 | MemoryPoolPreference = memoryPoolPreference; 420 | CreationNodeMask = creationNodeMask; 421 | VisibleNodeMask = nodeMask; 422 | } 423 | explicit CD3DX12_HEAP_PROPERTIES( 424 | D3D12_HEAP_TYPE type, 425 | UINT creationNodeMask = 1, 426 | UINT nodeMask = 1 ) 427 | { 428 | Type = type; 429 | CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; 430 | MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; 431 | CreationNodeMask = creationNodeMask; 432 | VisibleNodeMask = nodeMask; 433 | } 434 | bool IsCPUAccessible() const 435 | { 436 | return Type == D3D12_HEAP_TYPE_UPLOAD || Type == D3D12_HEAP_TYPE_READBACK || (Type == D3D12_HEAP_TYPE_CUSTOM && 437 | (CPUPageProperty == D3D12_CPU_PAGE_PROPERTY_WRITE_COMBINE || CPUPageProperty == D3D12_CPU_PAGE_PROPERTY_WRITE_BACK)); 438 | } 439 | }; 440 | inline bool operator==( const D3D12_HEAP_PROPERTIES& l, const D3D12_HEAP_PROPERTIES& r ) 441 | { 442 | return l.Type == r.Type && l.CPUPageProperty == r.CPUPageProperty && 443 | l.MemoryPoolPreference == r.MemoryPoolPreference && 444 | l.CreationNodeMask == r.CreationNodeMask && 445 | l.VisibleNodeMask == r.VisibleNodeMask; 446 | } 447 | inline bool operator!=( const D3D12_HEAP_PROPERTIES& l, const D3D12_HEAP_PROPERTIES& r ) 448 | { return !( l == r ); } 449 | 450 | //------------------------------------------------------------------------------------------------ 451 | struct CD3DX12_HEAP_DESC : public D3D12_HEAP_DESC 452 | { 453 | CD3DX12_HEAP_DESC() = default; 454 | explicit CD3DX12_HEAP_DESC(const D3D12_HEAP_DESC &o) : 455 | D3D12_HEAP_DESC(o) 456 | {} 457 | CD3DX12_HEAP_DESC( 458 | UINT64 size, 459 | D3D12_HEAP_PROPERTIES properties, 460 | UINT64 alignment = 0, 461 | D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE ) 462 | { 463 | SizeInBytes = size; 464 | Properties = properties; 465 | Alignment = alignment; 466 | Flags = flags; 467 | } 468 | CD3DX12_HEAP_DESC( 469 | UINT64 size, 470 | D3D12_HEAP_TYPE type, 471 | UINT64 alignment = 0, 472 | D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE ) 473 | { 474 | SizeInBytes = size; 475 | Properties = CD3DX12_HEAP_PROPERTIES( type ); 476 | Alignment = alignment; 477 | Flags = flags; 478 | } 479 | CD3DX12_HEAP_DESC( 480 | UINT64 size, 481 | D3D12_CPU_PAGE_PROPERTY cpuPageProperty, 482 | D3D12_MEMORY_POOL memoryPoolPreference, 483 | UINT64 alignment = 0, 484 | D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE ) 485 | { 486 | SizeInBytes = size; 487 | Properties = CD3DX12_HEAP_PROPERTIES( cpuPageProperty, memoryPoolPreference ); 488 | Alignment = alignment; 489 | Flags = flags; 490 | } 491 | CD3DX12_HEAP_DESC( 492 | const D3D12_RESOURCE_ALLOCATION_INFO& resAllocInfo, 493 | D3D12_HEAP_PROPERTIES properties, 494 | D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE ) 495 | { 496 | SizeInBytes = resAllocInfo.SizeInBytes; 497 | Properties = properties; 498 | Alignment = resAllocInfo.Alignment; 499 | Flags = flags; 500 | } 501 | CD3DX12_HEAP_DESC( 502 | const D3D12_RESOURCE_ALLOCATION_INFO& resAllocInfo, 503 | D3D12_HEAP_TYPE type, 504 | D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE ) 505 | { 506 | SizeInBytes = resAllocInfo.SizeInBytes; 507 | Properties = CD3DX12_HEAP_PROPERTIES( type ); 508 | Alignment = resAllocInfo.Alignment; 509 | Flags = flags; 510 | } 511 | CD3DX12_HEAP_DESC( 512 | const D3D12_RESOURCE_ALLOCATION_INFO& resAllocInfo, 513 | D3D12_CPU_PAGE_PROPERTY cpuPageProperty, 514 | D3D12_MEMORY_POOL memoryPoolPreference, 515 | D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE ) 516 | { 517 | SizeInBytes = resAllocInfo.SizeInBytes; 518 | Properties = CD3DX12_HEAP_PROPERTIES( cpuPageProperty, memoryPoolPreference ); 519 | Alignment = resAllocInfo.Alignment; 520 | Flags = flags; 521 | } 522 | bool IsCPUAccessible() const 523 | { return static_cast< const CD3DX12_HEAP_PROPERTIES* >( &Properties )->IsCPUAccessible(); } 524 | }; 525 | inline bool operator==( const D3D12_HEAP_DESC& l, const D3D12_HEAP_DESC& r ) 526 | { 527 | return l.SizeInBytes == r.SizeInBytes && 528 | l.Properties == r.Properties && 529 | l.Alignment == r.Alignment && 530 | l.Flags == r.Flags; 531 | } 532 | inline bool operator!=( const D3D12_HEAP_DESC& l, const D3D12_HEAP_DESC& r ) 533 | { return !( l == r ); } 534 | 535 | //------------------------------------------------------------------------------------------------ 536 | struct CD3DX12_CLEAR_VALUE : public D3D12_CLEAR_VALUE 537 | { 538 | CD3DX12_CLEAR_VALUE() = default; 539 | explicit CD3DX12_CLEAR_VALUE(const D3D12_CLEAR_VALUE &o) : 540 | D3D12_CLEAR_VALUE(o) 541 | {} 542 | CD3DX12_CLEAR_VALUE( 543 | DXGI_FORMAT format, 544 | const FLOAT color[4] ) 545 | { 546 | Format = format; 547 | memcpy( Color, color, sizeof( Color ) ); 548 | } 549 | CD3DX12_CLEAR_VALUE( 550 | DXGI_FORMAT format, 551 | FLOAT depth, 552 | UINT8 stencil ) 553 | { 554 | Format = format; 555 | /* Use memcpy to preserve NAN values */ 556 | memcpy( &DepthStencil.Depth, &depth, sizeof( depth ) ); 557 | DepthStencil.Stencil = stencil; 558 | } 559 | }; 560 | 561 | //------------------------------------------------------------------------------------------------ 562 | struct CD3DX12_RANGE : public D3D12_RANGE 563 | { 564 | CD3DX12_RANGE() = default; 565 | explicit CD3DX12_RANGE(const D3D12_RANGE &o) : 566 | D3D12_RANGE(o) 567 | {} 568 | CD3DX12_RANGE( 569 | SIZE_T begin, 570 | SIZE_T end ) 571 | { 572 | Begin = begin; 573 | End = end; 574 | } 575 | }; 576 | 577 | //------------------------------------------------------------------------------------------------ 578 | struct CD3DX12_RANGE_UINT64 : public D3D12_RANGE_UINT64 579 | { 580 | CD3DX12_RANGE_UINT64() = default; 581 | explicit CD3DX12_RANGE_UINT64(const D3D12_RANGE_UINT64 &o) : 582 | D3D12_RANGE_UINT64(o) 583 | {} 584 | CD3DX12_RANGE_UINT64( 585 | UINT64 begin, 586 | UINT64 end ) 587 | { 588 | Begin = begin; 589 | End = end; 590 | } 591 | }; 592 | 593 | //------------------------------------------------------------------------------------------------ 594 | struct CD3DX12_SUBRESOURCE_RANGE_UINT64 : public D3D12_SUBRESOURCE_RANGE_UINT64 595 | { 596 | CD3DX12_SUBRESOURCE_RANGE_UINT64() = default; 597 | explicit CD3DX12_SUBRESOURCE_RANGE_UINT64(const D3D12_SUBRESOURCE_RANGE_UINT64 &o) : 598 | D3D12_SUBRESOURCE_RANGE_UINT64(o) 599 | {} 600 | CD3DX12_SUBRESOURCE_RANGE_UINT64( 601 | UINT subresource, 602 | const D3D12_RANGE_UINT64& range ) 603 | { 604 | Subresource = subresource; 605 | Range = range; 606 | } 607 | CD3DX12_SUBRESOURCE_RANGE_UINT64( 608 | UINT subresource, 609 | UINT64 begin, 610 | UINT64 end ) 611 | { 612 | Subresource = subresource; 613 | Range.Begin = begin; 614 | Range.End = end; 615 | } 616 | }; 617 | 618 | //------------------------------------------------------------------------------------------------ 619 | struct CD3DX12_SHADER_BYTECODE : public D3D12_SHADER_BYTECODE 620 | { 621 | CD3DX12_SHADER_BYTECODE() = default; 622 | explicit CD3DX12_SHADER_BYTECODE(const D3D12_SHADER_BYTECODE &o) : 623 | D3D12_SHADER_BYTECODE(o) 624 | {} 625 | CD3DX12_SHADER_BYTECODE( 626 | _In_ ID3DBlob* pShaderBlob ) 627 | { 628 | pShaderBytecode = pShaderBlob->GetBufferPointer(); 629 | BytecodeLength = pShaderBlob->GetBufferSize(); 630 | } 631 | CD3DX12_SHADER_BYTECODE( 632 | const void* _pShaderBytecode, 633 | SIZE_T bytecodeLength ) 634 | { 635 | pShaderBytecode = _pShaderBytecode; 636 | BytecodeLength = bytecodeLength; 637 | } 638 | }; 639 | 640 | //------------------------------------------------------------------------------------------------ 641 | struct CD3DX12_TILED_RESOURCE_COORDINATE : public D3D12_TILED_RESOURCE_COORDINATE 642 | { 643 | CD3DX12_TILED_RESOURCE_COORDINATE() = default; 644 | explicit CD3DX12_TILED_RESOURCE_COORDINATE(const D3D12_TILED_RESOURCE_COORDINATE &o) : 645 | D3D12_TILED_RESOURCE_COORDINATE(o) 646 | {} 647 | CD3DX12_TILED_RESOURCE_COORDINATE( 648 | UINT x, 649 | UINT y, 650 | UINT z, 651 | UINT subresource ) 652 | { 653 | X = x; 654 | Y = y; 655 | Z = z; 656 | Subresource = subresource; 657 | } 658 | }; 659 | 660 | //------------------------------------------------------------------------------------------------ 661 | struct CD3DX12_TILE_REGION_SIZE : public D3D12_TILE_REGION_SIZE 662 | { 663 | CD3DX12_TILE_REGION_SIZE() = default; 664 | explicit CD3DX12_TILE_REGION_SIZE(const D3D12_TILE_REGION_SIZE &o) : 665 | D3D12_TILE_REGION_SIZE(o) 666 | {} 667 | CD3DX12_TILE_REGION_SIZE( 668 | UINT numTiles, 669 | BOOL useBox, 670 | UINT width, 671 | UINT16 height, 672 | UINT16 depth ) 673 | { 674 | NumTiles = numTiles; 675 | UseBox = useBox; 676 | Width = width; 677 | Height = height; 678 | Depth = depth; 679 | } 680 | }; 681 | 682 | //------------------------------------------------------------------------------------------------ 683 | struct CD3DX12_SUBRESOURCE_TILING : public D3D12_SUBRESOURCE_TILING 684 | { 685 | CD3DX12_SUBRESOURCE_TILING() = default; 686 | explicit CD3DX12_SUBRESOURCE_TILING(const D3D12_SUBRESOURCE_TILING &o) : 687 | D3D12_SUBRESOURCE_TILING(o) 688 | {} 689 | CD3DX12_SUBRESOURCE_TILING( 690 | UINT widthInTiles, 691 | UINT16 heightInTiles, 692 | UINT16 depthInTiles, 693 | UINT startTileIndexInOverallResource ) 694 | { 695 | WidthInTiles = widthInTiles; 696 | HeightInTiles = heightInTiles; 697 | DepthInTiles = depthInTiles; 698 | StartTileIndexInOverallResource = startTileIndexInOverallResource; 699 | } 700 | }; 701 | 702 | //------------------------------------------------------------------------------------------------ 703 | struct CD3DX12_TILE_SHAPE : public D3D12_TILE_SHAPE 704 | { 705 | CD3DX12_TILE_SHAPE() = default; 706 | explicit CD3DX12_TILE_SHAPE(const D3D12_TILE_SHAPE &o) : 707 | D3D12_TILE_SHAPE(o) 708 | {} 709 | CD3DX12_TILE_SHAPE( 710 | UINT widthInTexels, 711 | UINT heightInTexels, 712 | UINT depthInTexels ) 713 | { 714 | WidthInTexels = widthInTexels; 715 | HeightInTexels = heightInTexels; 716 | DepthInTexels = depthInTexels; 717 | } 718 | }; 719 | 720 | //------------------------------------------------------------------------------------------------ 721 | struct CD3DX12_RESOURCE_BARRIER : public D3D12_RESOURCE_BARRIER 722 | { 723 | CD3DX12_RESOURCE_BARRIER() = default; 724 | explicit CD3DX12_RESOURCE_BARRIER(const D3D12_RESOURCE_BARRIER &o) : 725 | D3D12_RESOURCE_BARRIER(o) 726 | {} 727 | static inline CD3DX12_RESOURCE_BARRIER Transition( 728 | _In_ ID3D12Resource* pResource, 729 | D3D12_RESOURCE_STATES stateBefore, 730 | D3D12_RESOURCE_STATES stateAfter, 731 | UINT subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES, 732 | D3D12_RESOURCE_BARRIER_FLAGS flags = D3D12_RESOURCE_BARRIER_FLAG_NONE) 733 | { 734 | CD3DX12_RESOURCE_BARRIER result = {}; 735 | D3D12_RESOURCE_BARRIER &barrier = result; 736 | result.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; 737 | result.Flags = flags; 738 | barrier.Transition.pResource = pResource; 739 | barrier.Transition.StateBefore = stateBefore; 740 | barrier.Transition.StateAfter = stateAfter; 741 | barrier.Transition.Subresource = subresource; 742 | return result; 743 | } 744 | static inline CD3DX12_RESOURCE_BARRIER Aliasing( 745 | _In_ ID3D12Resource* pResourceBefore, 746 | _In_ ID3D12Resource* pResourceAfter) 747 | { 748 | CD3DX12_RESOURCE_BARRIER result = {}; 749 | D3D12_RESOURCE_BARRIER &barrier = result; 750 | result.Type = D3D12_RESOURCE_BARRIER_TYPE_ALIASING; 751 | barrier.Aliasing.pResourceBefore = pResourceBefore; 752 | barrier.Aliasing.pResourceAfter = pResourceAfter; 753 | return result; 754 | } 755 | static inline CD3DX12_RESOURCE_BARRIER UAV( 756 | _In_ ID3D12Resource* pResource) 757 | { 758 | CD3DX12_RESOURCE_BARRIER result = {}; 759 | D3D12_RESOURCE_BARRIER &barrier = result; 760 | result.Type = D3D12_RESOURCE_BARRIER_TYPE_UAV; 761 | barrier.UAV.pResource = pResource; 762 | return result; 763 | } 764 | }; 765 | 766 | //------------------------------------------------------------------------------------------------ 767 | struct CD3DX12_PACKED_MIP_INFO : public D3D12_PACKED_MIP_INFO 768 | { 769 | CD3DX12_PACKED_MIP_INFO() = default; 770 | explicit CD3DX12_PACKED_MIP_INFO(const D3D12_PACKED_MIP_INFO &o) : 771 | D3D12_PACKED_MIP_INFO(o) 772 | {} 773 | CD3DX12_PACKED_MIP_INFO( 774 | UINT8 numStandardMips, 775 | UINT8 numPackedMips, 776 | UINT numTilesForPackedMips, 777 | UINT startTileIndexInOverallResource ) 778 | { 779 | NumStandardMips = numStandardMips; 780 | NumPackedMips = numPackedMips; 781 | NumTilesForPackedMips = numTilesForPackedMips; 782 | StartTileIndexInOverallResource = startTileIndexInOverallResource; 783 | } 784 | }; 785 | 786 | //------------------------------------------------------------------------------------------------ 787 | struct CD3DX12_SUBRESOURCE_FOOTPRINT : public D3D12_SUBRESOURCE_FOOTPRINT 788 | { 789 | CD3DX12_SUBRESOURCE_FOOTPRINT() = default; 790 | explicit CD3DX12_SUBRESOURCE_FOOTPRINT(const D3D12_SUBRESOURCE_FOOTPRINT &o) : 791 | D3D12_SUBRESOURCE_FOOTPRINT(o) 792 | {} 793 | CD3DX12_SUBRESOURCE_FOOTPRINT( 794 | DXGI_FORMAT format, 795 | UINT width, 796 | UINT height, 797 | UINT depth, 798 | UINT rowPitch ) 799 | { 800 | Format = format; 801 | Width = width; 802 | Height = height; 803 | Depth = depth; 804 | RowPitch = rowPitch; 805 | } 806 | explicit CD3DX12_SUBRESOURCE_FOOTPRINT( 807 | const D3D12_RESOURCE_DESC& resDesc, 808 | UINT rowPitch ) 809 | { 810 | Format = resDesc.Format; 811 | Width = UINT( resDesc.Width ); 812 | Height = resDesc.Height; 813 | Depth = (resDesc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D ? resDesc.DepthOrArraySize : 1); 814 | RowPitch = rowPitch; 815 | } 816 | }; 817 | 818 | //------------------------------------------------------------------------------------------------ 819 | struct CD3DX12_TEXTURE_COPY_LOCATION : public D3D12_TEXTURE_COPY_LOCATION 820 | { 821 | CD3DX12_TEXTURE_COPY_LOCATION() = default; 822 | explicit CD3DX12_TEXTURE_COPY_LOCATION(const D3D12_TEXTURE_COPY_LOCATION &o) : 823 | D3D12_TEXTURE_COPY_LOCATION(o) 824 | {} 825 | CD3DX12_TEXTURE_COPY_LOCATION(_In_ ID3D12Resource* pRes) 826 | { 827 | pResource = pRes; 828 | Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; 829 | PlacedFootprint = {}; 830 | } 831 | CD3DX12_TEXTURE_COPY_LOCATION(_In_ ID3D12Resource* pRes, D3D12_PLACED_SUBRESOURCE_FOOTPRINT const& Footprint) 832 | { 833 | pResource = pRes; 834 | Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; 835 | PlacedFootprint = Footprint; 836 | } 837 | CD3DX12_TEXTURE_COPY_LOCATION(_In_ ID3D12Resource* pRes, UINT Sub) 838 | { 839 | pResource = pRes; 840 | Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; 841 | SubresourceIndex = Sub; 842 | } 843 | }; 844 | 845 | //------------------------------------------------------------------------------------------------ 846 | struct CD3DX12_DESCRIPTOR_RANGE : public D3D12_DESCRIPTOR_RANGE 847 | { 848 | CD3DX12_DESCRIPTOR_RANGE() = default; 849 | explicit CD3DX12_DESCRIPTOR_RANGE(const D3D12_DESCRIPTOR_RANGE &o) : 850 | D3D12_DESCRIPTOR_RANGE(o) 851 | {} 852 | CD3DX12_DESCRIPTOR_RANGE( 853 | D3D12_DESCRIPTOR_RANGE_TYPE rangeType, 854 | UINT numDescriptors, 855 | UINT baseShaderRegister, 856 | UINT registerSpace = 0, 857 | UINT offsetInDescriptorsFromTableStart = 858 | D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND) 859 | { 860 | Init(rangeType, numDescriptors, baseShaderRegister, registerSpace, offsetInDescriptorsFromTableStart); 861 | } 862 | 863 | inline void Init( 864 | D3D12_DESCRIPTOR_RANGE_TYPE rangeType, 865 | UINT numDescriptors, 866 | UINT baseShaderRegister, 867 | UINT registerSpace = 0, 868 | UINT offsetInDescriptorsFromTableStart = 869 | D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND) 870 | { 871 | Init(*this, rangeType, numDescriptors, baseShaderRegister, registerSpace, offsetInDescriptorsFromTableStart); 872 | } 873 | 874 | static inline void Init( 875 | _Out_ D3D12_DESCRIPTOR_RANGE &range, 876 | D3D12_DESCRIPTOR_RANGE_TYPE rangeType, 877 | UINT numDescriptors, 878 | UINT baseShaderRegister, 879 | UINT registerSpace = 0, 880 | UINT offsetInDescriptorsFromTableStart = 881 | D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND) 882 | { 883 | range.RangeType = rangeType; 884 | range.NumDescriptors = numDescriptors; 885 | range.BaseShaderRegister = baseShaderRegister; 886 | range.RegisterSpace = registerSpace; 887 | range.OffsetInDescriptorsFromTableStart = offsetInDescriptorsFromTableStart; 888 | } 889 | }; 890 | 891 | //------------------------------------------------------------------------------------------------ 892 | struct CD3DX12_ROOT_DESCRIPTOR_TABLE : public D3D12_ROOT_DESCRIPTOR_TABLE 893 | { 894 | CD3DX12_ROOT_DESCRIPTOR_TABLE() = default; 895 | explicit CD3DX12_ROOT_DESCRIPTOR_TABLE(const D3D12_ROOT_DESCRIPTOR_TABLE &o) : 896 | D3D12_ROOT_DESCRIPTOR_TABLE(o) 897 | {} 898 | CD3DX12_ROOT_DESCRIPTOR_TABLE( 899 | UINT numDescriptorRanges, 900 | _In_reads_opt_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE* _pDescriptorRanges) 901 | { 902 | Init(numDescriptorRanges, _pDescriptorRanges); 903 | } 904 | 905 | inline void Init( 906 | UINT numDescriptorRanges, 907 | _In_reads_opt_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE* _pDescriptorRanges) 908 | { 909 | Init(*this, numDescriptorRanges, _pDescriptorRanges); 910 | } 911 | 912 | static inline void Init( 913 | _Out_ D3D12_ROOT_DESCRIPTOR_TABLE &rootDescriptorTable, 914 | UINT numDescriptorRanges, 915 | _In_reads_opt_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE* _pDescriptorRanges) 916 | { 917 | rootDescriptorTable.NumDescriptorRanges = numDescriptorRanges; 918 | rootDescriptorTable.pDescriptorRanges = _pDescriptorRanges; 919 | } 920 | }; 921 | 922 | //------------------------------------------------------------------------------------------------ 923 | struct CD3DX12_ROOT_CONSTANTS : public D3D12_ROOT_CONSTANTS 924 | { 925 | CD3DX12_ROOT_CONSTANTS() = default; 926 | explicit CD3DX12_ROOT_CONSTANTS(const D3D12_ROOT_CONSTANTS &o) : 927 | D3D12_ROOT_CONSTANTS(o) 928 | {} 929 | CD3DX12_ROOT_CONSTANTS( 930 | UINT num32BitValues, 931 | UINT shaderRegister, 932 | UINT registerSpace = 0) 933 | { 934 | Init(num32BitValues, shaderRegister, registerSpace); 935 | } 936 | 937 | inline void Init( 938 | UINT num32BitValues, 939 | UINT shaderRegister, 940 | UINT registerSpace = 0) 941 | { 942 | Init(*this, num32BitValues, shaderRegister, registerSpace); 943 | } 944 | 945 | static inline void Init( 946 | _Out_ D3D12_ROOT_CONSTANTS &rootConstants, 947 | UINT num32BitValues, 948 | UINT shaderRegister, 949 | UINT registerSpace = 0) 950 | { 951 | rootConstants.Num32BitValues = num32BitValues; 952 | rootConstants.ShaderRegister = shaderRegister; 953 | rootConstants.RegisterSpace = registerSpace; 954 | } 955 | }; 956 | 957 | //------------------------------------------------------------------------------------------------ 958 | struct CD3DX12_ROOT_DESCRIPTOR : public D3D12_ROOT_DESCRIPTOR 959 | { 960 | CD3DX12_ROOT_DESCRIPTOR() = default; 961 | explicit CD3DX12_ROOT_DESCRIPTOR(const D3D12_ROOT_DESCRIPTOR &o) : 962 | D3D12_ROOT_DESCRIPTOR(o) 963 | {} 964 | CD3DX12_ROOT_DESCRIPTOR( 965 | UINT shaderRegister, 966 | UINT registerSpace = 0) 967 | { 968 | Init(shaderRegister, registerSpace); 969 | } 970 | 971 | inline void Init( 972 | UINT shaderRegister, 973 | UINT registerSpace = 0) 974 | { 975 | Init(*this, shaderRegister, registerSpace); 976 | } 977 | 978 | static inline void Init(_Out_ D3D12_ROOT_DESCRIPTOR &table, UINT shaderRegister, UINT registerSpace = 0) 979 | { 980 | table.ShaderRegister = shaderRegister; 981 | table.RegisterSpace = registerSpace; 982 | } 983 | }; 984 | 985 | //------------------------------------------------------------------------------------------------ 986 | struct CD3DX12_ROOT_PARAMETER : public D3D12_ROOT_PARAMETER 987 | { 988 | CD3DX12_ROOT_PARAMETER() = default; 989 | explicit CD3DX12_ROOT_PARAMETER(const D3D12_ROOT_PARAMETER &o) : 990 | D3D12_ROOT_PARAMETER(o) 991 | {} 992 | 993 | static inline void InitAsDescriptorTable( 994 | _Out_ D3D12_ROOT_PARAMETER &rootParam, 995 | UINT numDescriptorRanges, 996 | _In_reads_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE* pDescriptorRanges, 997 | D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) 998 | { 999 | rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; 1000 | rootParam.ShaderVisibility = visibility; 1001 | CD3DX12_ROOT_DESCRIPTOR_TABLE::Init(rootParam.DescriptorTable, numDescriptorRanges, pDescriptorRanges); 1002 | } 1003 | 1004 | static inline void InitAsConstants( 1005 | _Out_ D3D12_ROOT_PARAMETER &rootParam, 1006 | UINT num32BitValues, 1007 | UINT shaderRegister, 1008 | UINT registerSpace = 0, 1009 | D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) 1010 | { 1011 | rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS; 1012 | rootParam.ShaderVisibility = visibility; 1013 | CD3DX12_ROOT_CONSTANTS::Init(rootParam.Constants, num32BitValues, shaderRegister, registerSpace); 1014 | } 1015 | 1016 | static inline void InitAsConstantBufferView( 1017 | _Out_ D3D12_ROOT_PARAMETER &rootParam, 1018 | UINT shaderRegister, 1019 | UINT registerSpace = 0, 1020 | D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) 1021 | { 1022 | rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV; 1023 | rootParam.ShaderVisibility = visibility; 1024 | CD3DX12_ROOT_DESCRIPTOR::Init(rootParam.Descriptor, shaderRegister, registerSpace); 1025 | } 1026 | 1027 | static inline void InitAsShaderResourceView( 1028 | _Out_ D3D12_ROOT_PARAMETER &rootParam, 1029 | UINT shaderRegister, 1030 | UINT registerSpace = 0, 1031 | D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) 1032 | { 1033 | rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_SRV; 1034 | rootParam.ShaderVisibility = visibility; 1035 | CD3DX12_ROOT_DESCRIPTOR::Init(rootParam.Descriptor, shaderRegister, registerSpace); 1036 | } 1037 | 1038 | static inline void InitAsUnorderedAccessView( 1039 | _Out_ D3D12_ROOT_PARAMETER &rootParam, 1040 | UINT shaderRegister, 1041 | UINT registerSpace = 0, 1042 | D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) 1043 | { 1044 | rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_UAV; 1045 | rootParam.ShaderVisibility = visibility; 1046 | CD3DX12_ROOT_DESCRIPTOR::Init(rootParam.Descriptor, shaderRegister, registerSpace); 1047 | } 1048 | 1049 | inline void InitAsDescriptorTable( 1050 | UINT numDescriptorRanges, 1051 | _In_reads_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE* pDescriptorRanges, 1052 | D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) 1053 | { 1054 | InitAsDescriptorTable(*this, numDescriptorRanges, pDescriptorRanges, visibility); 1055 | } 1056 | 1057 | inline void InitAsConstants( 1058 | UINT num32BitValues, 1059 | UINT shaderRegister, 1060 | UINT registerSpace = 0, 1061 | D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) 1062 | { 1063 | InitAsConstants(*this, num32BitValues, shaderRegister, registerSpace, visibility); 1064 | } 1065 | 1066 | inline void InitAsConstantBufferView( 1067 | UINT shaderRegister, 1068 | UINT registerSpace = 0, 1069 | D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) 1070 | { 1071 | InitAsConstantBufferView(*this, shaderRegister, registerSpace, visibility); 1072 | } 1073 | 1074 | inline void InitAsShaderResourceView( 1075 | UINT shaderRegister, 1076 | UINT registerSpace = 0, 1077 | D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) 1078 | { 1079 | InitAsShaderResourceView(*this, shaderRegister, registerSpace, visibility); 1080 | } 1081 | 1082 | inline void InitAsUnorderedAccessView( 1083 | UINT shaderRegister, 1084 | UINT registerSpace = 0, 1085 | D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) 1086 | { 1087 | InitAsUnorderedAccessView(*this, shaderRegister, registerSpace, visibility); 1088 | } 1089 | }; 1090 | 1091 | //------------------------------------------------------------------------------------------------ 1092 | struct CD3DX12_STATIC_SAMPLER_DESC : public D3D12_STATIC_SAMPLER_DESC 1093 | { 1094 | CD3DX12_STATIC_SAMPLER_DESC() = default; 1095 | explicit CD3DX12_STATIC_SAMPLER_DESC(const D3D12_STATIC_SAMPLER_DESC &o) : 1096 | D3D12_STATIC_SAMPLER_DESC(o) 1097 | {} 1098 | CD3DX12_STATIC_SAMPLER_DESC( 1099 | UINT shaderRegister, 1100 | D3D12_FILTER filter = D3D12_FILTER_ANISOTROPIC, 1101 | D3D12_TEXTURE_ADDRESS_MODE addressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP, 1102 | D3D12_TEXTURE_ADDRESS_MODE addressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP, 1103 | D3D12_TEXTURE_ADDRESS_MODE addressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP, 1104 | FLOAT mipLODBias = 0, 1105 | UINT maxAnisotropy = 16, 1106 | D3D12_COMPARISON_FUNC comparisonFunc = D3D12_COMPARISON_FUNC_LESS_EQUAL, 1107 | D3D12_STATIC_BORDER_COLOR borderColor = D3D12_STATIC_BORDER_COLOR_OPAQUE_WHITE, 1108 | FLOAT minLOD = 0.f, 1109 | FLOAT maxLOD = D3D12_FLOAT32_MAX, 1110 | D3D12_SHADER_VISIBILITY shaderVisibility = D3D12_SHADER_VISIBILITY_ALL, 1111 | UINT registerSpace = 0) 1112 | { 1113 | Init( 1114 | shaderRegister, 1115 | filter, 1116 | addressU, 1117 | addressV, 1118 | addressW, 1119 | mipLODBias, 1120 | maxAnisotropy, 1121 | comparisonFunc, 1122 | borderColor, 1123 | minLOD, 1124 | maxLOD, 1125 | shaderVisibility, 1126 | registerSpace); 1127 | } 1128 | 1129 | static inline void Init( 1130 | _Out_ D3D12_STATIC_SAMPLER_DESC &samplerDesc, 1131 | UINT shaderRegister, 1132 | D3D12_FILTER filter = D3D12_FILTER_ANISOTROPIC, 1133 | D3D12_TEXTURE_ADDRESS_MODE addressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP, 1134 | D3D12_TEXTURE_ADDRESS_MODE addressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP, 1135 | D3D12_TEXTURE_ADDRESS_MODE addressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP, 1136 | FLOAT mipLODBias = 0, 1137 | UINT maxAnisotropy = 16, 1138 | D3D12_COMPARISON_FUNC comparisonFunc = D3D12_COMPARISON_FUNC_LESS_EQUAL, 1139 | D3D12_STATIC_BORDER_COLOR borderColor = D3D12_STATIC_BORDER_COLOR_OPAQUE_WHITE, 1140 | FLOAT minLOD = 0.f, 1141 | FLOAT maxLOD = D3D12_FLOAT32_MAX, 1142 | D3D12_SHADER_VISIBILITY shaderVisibility = D3D12_SHADER_VISIBILITY_ALL, 1143 | UINT registerSpace = 0) 1144 | { 1145 | samplerDesc.ShaderRegister = shaderRegister; 1146 | samplerDesc.Filter = filter; 1147 | samplerDesc.AddressU = addressU; 1148 | samplerDesc.AddressV = addressV; 1149 | samplerDesc.AddressW = addressW; 1150 | samplerDesc.MipLODBias = mipLODBias; 1151 | samplerDesc.MaxAnisotropy = maxAnisotropy; 1152 | samplerDesc.ComparisonFunc = comparisonFunc; 1153 | samplerDesc.BorderColor = borderColor; 1154 | samplerDesc.MinLOD = minLOD; 1155 | samplerDesc.MaxLOD = maxLOD; 1156 | samplerDesc.ShaderVisibility = shaderVisibility; 1157 | samplerDesc.RegisterSpace = registerSpace; 1158 | } 1159 | inline void Init( 1160 | UINT shaderRegister, 1161 | D3D12_FILTER filter = D3D12_FILTER_ANISOTROPIC, 1162 | D3D12_TEXTURE_ADDRESS_MODE addressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP, 1163 | D3D12_TEXTURE_ADDRESS_MODE addressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP, 1164 | D3D12_TEXTURE_ADDRESS_MODE addressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP, 1165 | FLOAT mipLODBias = 0, 1166 | UINT maxAnisotropy = 16, 1167 | D3D12_COMPARISON_FUNC comparisonFunc = D3D12_COMPARISON_FUNC_LESS_EQUAL, 1168 | D3D12_STATIC_BORDER_COLOR borderColor = D3D12_STATIC_BORDER_COLOR_OPAQUE_WHITE, 1169 | FLOAT minLOD = 0.f, 1170 | FLOAT maxLOD = D3D12_FLOAT32_MAX, 1171 | D3D12_SHADER_VISIBILITY shaderVisibility = D3D12_SHADER_VISIBILITY_ALL, 1172 | UINT registerSpace = 0) 1173 | { 1174 | Init( 1175 | *this, 1176 | shaderRegister, 1177 | filter, 1178 | addressU, 1179 | addressV, 1180 | addressW, 1181 | mipLODBias, 1182 | maxAnisotropy, 1183 | comparisonFunc, 1184 | borderColor, 1185 | minLOD, 1186 | maxLOD, 1187 | shaderVisibility, 1188 | registerSpace); 1189 | } 1190 | 1191 | }; 1192 | 1193 | //------------------------------------------------------------------------------------------------ 1194 | struct CD3DX12_ROOT_SIGNATURE_DESC : public D3D12_ROOT_SIGNATURE_DESC 1195 | { 1196 | CD3DX12_ROOT_SIGNATURE_DESC() = default; 1197 | explicit CD3DX12_ROOT_SIGNATURE_DESC(const D3D12_ROOT_SIGNATURE_DESC &o) : 1198 | D3D12_ROOT_SIGNATURE_DESC(o) 1199 | {} 1200 | CD3DX12_ROOT_SIGNATURE_DESC( 1201 | UINT numParameters, 1202 | _In_reads_opt_(numParameters) const D3D12_ROOT_PARAMETER* _pParameters, 1203 | UINT numStaticSamplers = 0, 1204 | _In_reads_opt_(numStaticSamplers) const D3D12_STATIC_SAMPLER_DESC* _pStaticSamplers = nullptr, 1205 | D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_FLAG_NONE) 1206 | { 1207 | Init(numParameters, _pParameters, numStaticSamplers, _pStaticSamplers, flags); 1208 | } 1209 | CD3DX12_ROOT_SIGNATURE_DESC(CD3DX12_DEFAULT) 1210 | { 1211 | Init(0, nullptr, 0, nullptr, D3D12_ROOT_SIGNATURE_FLAG_NONE); 1212 | } 1213 | 1214 | inline void Init( 1215 | UINT numParameters, 1216 | _In_reads_opt_(numParameters) const D3D12_ROOT_PARAMETER* _pParameters, 1217 | UINT numStaticSamplers = 0, 1218 | _In_reads_opt_(numStaticSamplers) const D3D12_STATIC_SAMPLER_DESC* _pStaticSamplers = nullptr, 1219 | D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_FLAG_NONE) 1220 | { 1221 | Init(*this, numParameters, _pParameters, numStaticSamplers, _pStaticSamplers, flags); 1222 | } 1223 | 1224 | static inline void Init( 1225 | _Out_ D3D12_ROOT_SIGNATURE_DESC &desc, 1226 | UINT numParameters, 1227 | _In_reads_opt_(numParameters) const D3D12_ROOT_PARAMETER* _pParameters, 1228 | UINT numStaticSamplers = 0, 1229 | _In_reads_opt_(numStaticSamplers) const D3D12_STATIC_SAMPLER_DESC* _pStaticSamplers = nullptr, 1230 | D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_FLAG_NONE) 1231 | { 1232 | desc.NumParameters = numParameters; 1233 | desc.pParameters = _pParameters; 1234 | desc.NumStaticSamplers = numStaticSamplers; 1235 | desc.pStaticSamplers = _pStaticSamplers; 1236 | desc.Flags = flags; 1237 | } 1238 | }; 1239 | 1240 | //------------------------------------------------------------------------------------------------ 1241 | struct CD3DX12_DESCRIPTOR_RANGE1 : public D3D12_DESCRIPTOR_RANGE1 1242 | { 1243 | CD3DX12_DESCRIPTOR_RANGE1() = default; 1244 | explicit CD3DX12_DESCRIPTOR_RANGE1(const D3D12_DESCRIPTOR_RANGE1 &o) : 1245 | D3D12_DESCRIPTOR_RANGE1(o) 1246 | {} 1247 | CD3DX12_DESCRIPTOR_RANGE1( 1248 | D3D12_DESCRIPTOR_RANGE_TYPE rangeType, 1249 | UINT numDescriptors, 1250 | UINT baseShaderRegister, 1251 | UINT registerSpace = 0, 1252 | D3D12_DESCRIPTOR_RANGE_FLAGS flags = D3D12_DESCRIPTOR_RANGE_FLAG_NONE, 1253 | UINT offsetInDescriptorsFromTableStart = 1254 | D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND) 1255 | { 1256 | Init(rangeType, numDescriptors, baseShaderRegister, registerSpace, flags, offsetInDescriptorsFromTableStart); 1257 | } 1258 | 1259 | inline void Init( 1260 | D3D12_DESCRIPTOR_RANGE_TYPE rangeType, 1261 | UINT numDescriptors, 1262 | UINT baseShaderRegister, 1263 | UINT registerSpace = 0, 1264 | D3D12_DESCRIPTOR_RANGE_FLAGS flags = D3D12_DESCRIPTOR_RANGE_FLAG_NONE, 1265 | UINT offsetInDescriptorsFromTableStart = 1266 | D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND) 1267 | { 1268 | Init(*this, rangeType, numDescriptors, baseShaderRegister, registerSpace, flags, offsetInDescriptorsFromTableStart); 1269 | } 1270 | 1271 | static inline void Init( 1272 | _Out_ D3D12_DESCRIPTOR_RANGE1 &range, 1273 | D3D12_DESCRIPTOR_RANGE_TYPE rangeType, 1274 | UINT numDescriptors, 1275 | UINT baseShaderRegister, 1276 | UINT registerSpace = 0, 1277 | D3D12_DESCRIPTOR_RANGE_FLAGS flags = D3D12_DESCRIPTOR_RANGE_FLAG_NONE, 1278 | UINT offsetInDescriptorsFromTableStart = 1279 | D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND) 1280 | { 1281 | range.RangeType = rangeType; 1282 | range.NumDescriptors = numDescriptors; 1283 | range.BaseShaderRegister = baseShaderRegister; 1284 | range.RegisterSpace = registerSpace; 1285 | range.Flags = flags; 1286 | range.OffsetInDescriptorsFromTableStart = offsetInDescriptorsFromTableStart; 1287 | } 1288 | }; 1289 | 1290 | //------------------------------------------------------------------------------------------------ 1291 | struct CD3DX12_ROOT_DESCRIPTOR_TABLE1 : public D3D12_ROOT_DESCRIPTOR_TABLE1 1292 | { 1293 | CD3DX12_ROOT_DESCRIPTOR_TABLE1() = default; 1294 | explicit CD3DX12_ROOT_DESCRIPTOR_TABLE1(const D3D12_ROOT_DESCRIPTOR_TABLE1 &o) : 1295 | D3D12_ROOT_DESCRIPTOR_TABLE1(o) 1296 | {} 1297 | CD3DX12_ROOT_DESCRIPTOR_TABLE1( 1298 | UINT numDescriptorRanges, 1299 | _In_reads_opt_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE1* _pDescriptorRanges) 1300 | { 1301 | Init(numDescriptorRanges, _pDescriptorRanges); 1302 | } 1303 | 1304 | inline void Init( 1305 | UINT numDescriptorRanges, 1306 | _In_reads_opt_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE1* _pDescriptorRanges) 1307 | { 1308 | Init(*this, numDescriptorRanges, _pDescriptorRanges); 1309 | } 1310 | 1311 | static inline void Init( 1312 | _Out_ D3D12_ROOT_DESCRIPTOR_TABLE1 &rootDescriptorTable, 1313 | UINT numDescriptorRanges, 1314 | _In_reads_opt_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE1* _pDescriptorRanges) 1315 | { 1316 | rootDescriptorTable.NumDescriptorRanges = numDescriptorRanges; 1317 | rootDescriptorTable.pDescriptorRanges = _pDescriptorRanges; 1318 | } 1319 | }; 1320 | 1321 | //------------------------------------------------------------------------------------------------ 1322 | struct CD3DX12_ROOT_DESCRIPTOR1 : public D3D12_ROOT_DESCRIPTOR1 1323 | { 1324 | CD3DX12_ROOT_DESCRIPTOR1() = default; 1325 | explicit CD3DX12_ROOT_DESCRIPTOR1(const D3D12_ROOT_DESCRIPTOR1 &o) : 1326 | D3D12_ROOT_DESCRIPTOR1(o) 1327 | {} 1328 | CD3DX12_ROOT_DESCRIPTOR1( 1329 | UINT shaderRegister, 1330 | UINT registerSpace = 0, 1331 | D3D12_ROOT_DESCRIPTOR_FLAGS flags = D3D12_ROOT_DESCRIPTOR_FLAG_NONE) 1332 | { 1333 | Init(shaderRegister, registerSpace, flags); 1334 | } 1335 | 1336 | inline void Init( 1337 | UINT shaderRegister, 1338 | UINT registerSpace = 0, 1339 | D3D12_ROOT_DESCRIPTOR_FLAGS flags = D3D12_ROOT_DESCRIPTOR_FLAG_NONE) 1340 | { 1341 | Init(*this, shaderRegister, registerSpace, flags); 1342 | } 1343 | 1344 | static inline void Init( 1345 | _Out_ D3D12_ROOT_DESCRIPTOR1 &table, 1346 | UINT shaderRegister, 1347 | UINT registerSpace = 0, 1348 | D3D12_ROOT_DESCRIPTOR_FLAGS flags = D3D12_ROOT_DESCRIPTOR_FLAG_NONE) 1349 | { 1350 | table.ShaderRegister = shaderRegister; 1351 | table.RegisterSpace = registerSpace; 1352 | table.Flags = flags; 1353 | } 1354 | }; 1355 | 1356 | //------------------------------------------------------------------------------------------------ 1357 | struct CD3DX12_ROOT_PARAMETER1 : public D3D12_ROOT_PARAMETER1 1358 | { 1359 | CD3DX12_ROOT_PARAMETER1() = default; 1360 | explicit CD3DX12_ROOT_PARAMETER1(const D3D12_ROOT_PARAMETER1 &o) : 1361 | D3D12_ROOT_PARAMETER1(o) 1362 | {} 1363 | 1364 | static inline void InitAsDescriptorTable( 1365 | _Out_ D3D12_ROOT_PARAMETER1 &rootParam, 1366 | UINT numDescriptorRanges, 1367 | _In_reads_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE1* pDescriptorRanges, 1368 | D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) 1369 | { 1370 | rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; 1371 | rootParam.ShaderVisibility = visibility; 1372 | CD3DX12_ROOT_DESCRIPTOR_TABLE1::Init(rootParam.DescriptorTable, numDescriptorRanges, pDescriptorRanges); 1373 | } 1374 | 1375 | static inline void InitAsConstants( 1376 | _Out_ D3D12_ROOT_PARAMETER1 &rootParam, 1377 | UINT num32BitValues, 1378 | UINT shaderRegister, 1379 | UINT registerSpace = 0, 1380 | D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) 1381 | { 1382 | rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS; 1383 | rootParam.ShaderVisibility = visibility; 1384 | CD3DX12_ROOT_CONSTANTS::Init(rootParam.Constants, num32BitValues, shaderRegister, registerSpace); 1385 | } 1386 | 1387 | static inline void InitAsConstantBufferView( 1388 | _Out_ D3D12_ROOT_PARAMETER1 &rootParam, 1389 | UINT shaderRegister, 1390 | UINT registerSpace = 0, 1391 | D3D12_ROOT_DESCRIPTOR_FLAGS flags = D3D12_ROOT_DESCRIPTOR_FLAG_NONE, 1392 | D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) 1393 | { 1394 | rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV; 1395 | rootParam.ShaderVisibility = visibility; 1396 | CD3DX12_ROOT_DESCRIPTOR1::Init(rootParam.Descriptor, shaderRegister, registerSpace, flags); 1397 | } 1398 | 1399 | static inline void InitAsShaderResourceView( 1400 | _Out_ D3D12_ROOT_PARAMETER1 &rootParam, 1401 | UINT shaderRegister, 1402 | UINT registerSpace = 0, 1403 | D3D12_ROOT_DESCRIPTOR_FLAGS flags = D3D12_ROOT_DESCRIPTOR_FLAG_NONE, 1404 | D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) 1405 | { 1406 | rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_SRV; 1407 | rootParam.ShaderVisibility = visibility; 1408 | CD3DX12_ROOT_DESCRIPTOR1::Init(rootParam.Descriptor, shaderRegister, registerSpace, flags); 1409 | } 1410 | 1411 | static inline void InitAsUnorderedAccessView( 1412 | _Out_ D3D12_ROOT_PARAMETER1 &rootParam, 1413 | UINT shaderRegister, 1414 | UINT registerSpace = 0, 1415 | D3D12_ROOT_DESCRIPTOR_FLAGS flags = D3D12_ROOT_DESCRIPTOR_FLAG_NONE, 1416 | D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) 1417 | { 1418 | rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_UAV; 1419 | rootParam.ShaderVisibility = visibility; 1420 | CD3DX12_ROOT_DESCRIPTOR1::Init(rootParam.Descriptor, shaderRegister, registerSpace, flags); 1421 | } 1422 | 1423 | inline void InitAsDescriptorTable( 1424 | UINT numDescriptorRanges, 1425 | _In_reads_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE1* pDescriptorRanges, 1426 | D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) 1427 | { 1428 | InitAsDescriptorTable(*this, numDescriptorRanges, pDescriptorRanges, visibility); 1429 | } 1430 | 1431 | inline void InitAsConstants( 1432 | UINT num32BitValues, 1433 | UINT shaderRegister, 1434 | UINT registerSpace = 0, 1435 | D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) 1436 | { 1437 | InitAsConstants(*this, num32BitValues, shaderRegister, registerSpace, visibility); 1438 | } 1439 | 1440 | inline void InitAsConstantBufferView( 1441 | UINT shaderRegister, 1442 | UINT registerSpace = 0, 1443 | D3D12_ROOT_DESCRIPTOR_FLAGS flags = D3D12_ROOT_DESCRIPTOR_FLAG_NONE, 1444 | D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) 1445 | { 1446 | InitAsConstantBufferView(*this, shaderRegister, registerSpace, flags, visibility); 1447 | } 1448 | 1449 | inline void InitAsShaderResourceView( 1450 | UINT shaderRegister, 1451 | UINT registerSpace = 0, 1452 | D3D12_ROOT_DESCRIPTOR_FLAGS flags = D3D12_ROOT_DESCRIPTOR_FLAG_NONE, 1453 | D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) 1454 | { 1455 | InitAsShaderResourceView(*this, shaderRegister, registerSpace, flags, visibility); 1456 | } 1457 | 1458 | inline void InitAsUnorderedAccessView( 1459 | UINT shaderRegister, 1460 | UINT registerSpace = 0, 1461 | D3D12_ROOT_DESCRIPTOR_FLAGS flags = D3D12_ROOT_DESCRIPTOR_FLAG_NONE, 1462 | D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) 1463 | { 1464 | InitAsUnorderedAccessView(*this, shaderRegister, registerSpace, flags, visibility); 1465 | } 1466 | }; 1467 | 1468 | //------------------------------------------------------------------------------------------------ 1469 | struct CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC : public D3D12_VERSIONED_ROOT_SIGNATURE_DESC 1470 | { 1471 | CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC() = default; 1472 | explicit CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC(const D3D12_VERSIONED_ROOT_SIGNATURE_DESC &o) : 1473 | D3D12_VERSIONED_ROOT_SIGNATURE_DESC(o) 1474 | {} 1475 | explicit CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC(const D3D12_ROOT_SIGNATURE_DESC &o) 1476 | { 1477 | Version = D3D_ROOT_SIGNATURE_VERSION_1_0; 1478 | Desc_1_0 = o; 1479 | } 1480 | explicit CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC(const D3D12_ROOT_SIGNATURE_DESC1 &o) 1481 | { 1482 | Version = D3D_ROOT_SIGNATURE_VERSION_1_1; 1483 | Desc_1_1 = o; 1484 | } 1485 | CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC( 1486 | UINT numParameters, 1487 | _In_reads_opt_(numParameters) const D3D12_ROOT_PARAMETER* _pParameters, 1488 | UINT numStaticSamplers = 0, 1489 | _In_reads_opt_(numStaticSamplers) const D3D12_STATIC_SAMPLER_DESC* _pStaticSamplers = nullptr, 1490 | D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_FLAG_NONE) 1491 | { 1492 | Init_1_0(numParameters, _pParameters, numStaticSamplers, _pStaticSamplers, flags); 1493 | } 1494 | CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC( 1495 | UINT numParameters, 1496 | _In_reads_opt_(numParameters) const D3D12_ROOT_PARAMETER1* _pParameters, 1497 | UINT numStaticSamplers = 0, 1498 | _In_reads_opt_(numStaticSamplers) const D3D12_STATIC_SAMPLER_DESC* _pStaticSamplers = nullptr, 1499 | D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_FLAG_NONE) 1500 | { 1501 | Init_1_1(numParameters, _pParameters, numStaticSamplers, _pStaticSamplers, flags); 1502 | } 1503 | CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC(CD3DX12_DEFAULT) 1504 | { 1505 | Init_1_1(0, nullptr, 0, nullptr, D3D12_ROOT_SIGNATURE_FLAG_NONE); 1506 | } 1507 | 1508 | inline void Init_1_0( 1509 | UINT numParameters, 1510 | _In_reads_opt_(numParameters) const D3D12_ROOT_PARAMETER* _pParameters, 1511 | UINT numStaticSamplers = 0, 1512 | _In_reads_opt_(numStaticSamplers) const D3D12_STATIC_SAMPLER_DESC* _pStaticSamplers = nullptr, 1513 | D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_FLAG_NONE) 1514 | { 1515 | Init_1_0(*this, numParameters, _pParameters, numStaticSamplers, _pStaticSamplers, flags); 1516 | } 1517 | 1518 | static inline void Init_1_0( 1519 | _Out_ D3D12_VERSIONED_ROOT_SIGNATURE_DESC &desc, 1520 | UINT numParameters, 1521 | _In_reads_opt_(numParameters) const D3D12_ROOT_PARAMETER* _pParameters, 1522 | UINT numStaticSamplers = 0, 1523 | _In_reads_opt_(numStaticSamplers) const D3D12_STATIC_SAMPLER_DESC* _pStaticSamplers = nullptr, 1524 | D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_FLAG_NONE) 1525 | { 1526 | desc.Version = D3D_ROOT_SIGNATURE_VERSION_1_0; 1527 | desc.Desc_1_0.NumParameters = numParameters; 1528 | desc.Desc_1_0.pParameters = _pParameters; 1529 | desc.Desc_1_0.NumStaticSamplers = numStaticSamplers; 1530 | desc.Desc_1_0.pStaticSamplers = _pStaticSamplers; 1531 | desc.Desc_1_0.Flags = flags; 1532 | } 1533 | 1534 | inline void Init_1_1( 1535 | UINT numParameters, 1536 | _In_reads_opt_(numParameters) const D3D12_ROOT_PARAMETER1* _pParameters, 1537 | UINT numStaticSamplers = 0, 1538 | _In_reads_opt_(numStaticSamplers) const D3D12_STATIC_SAMPLER_DESC* _pStaticSamplers = nullptr, 1539 | D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_FLAG_NONE) 1540 | { 1541 | Init_1_1(*this, numParameters, _pParameters, numStaticSamplers, _pStaticSamplers, flags); 1542 | } 1543 | 1544 | static inline void Init_1_1( 1545 | _Out_ D3D12_VERSIONED_ROOT_SIGNATURE_DESC &desc, 1546 | UINT numParameters, 1547 | _In_reads_opt_(numParameters) const D3D12_ROOT_PARAMETER1* _pParameters, 1548 | UINT numStaticSamplers = 0, 1549 | _In_reads_opt_(numStaticSamplers) const D3D12_STATIC_SAMPLER_DESC* _pStaticSamplers = nullptr, 1550 | D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_FLAG_NONE) 1551 | { 1552 | desc.Version = D3D_ROOT_SIGNATURE_VERSION_1_1; 1553 | desc.Desc_1_1.NumParameters = numParameters; 1554 | desc.Desc_1_1.pParameters = _pParameters; 1555 | desc.Desc_1_1.NumStaticSamplers = numStaticSamplers; 1556 | desc.Desc_1_1.pStaticSamplers = _pStaticSamplers; 1557 | desc.Desc_1_1.Flags = flags; 1558 | } 1559 | }; 1560 | 1561 | //------------------------------------------------------------------------------------------------ 1562 | struct CD3DX12_CPU_DESCRIPTOR_HANDLE : public D3D12_CPU_DESCRIPTOR_HANDLE 1563 | { 1564 | CD3DX12_CPU_DESCRIPTOR_HANDLE() = default; 1565 | explicit CD3DX12_CPU_DESCRIPTOR_HANDLE(const D3D12_CPU_DESCRIPTOR_HANDLE &o) : 1566 | D3D12_CPU_DESCRIPTOR_HANDLE(o) 1567 | {} 1568 | CD3DX12_CPU_DESCRIPTOR_HANDLE(CD3DX12_DEFAULT) { ptr = 0; } 1569 | CD3DX12_CPU_DESCRIPTOR_HANDLE(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE &other, INT offsetScaledByIncrementSize) 1570 | { 1571 | InitOffsetted(other, offsetScaledByIncrementSize); 1572 | } 1573 | CD3DX12_CPU_DESCRIPTOR_HANDLE(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE &other, INT offsetInDescriptors, UINT descriptorIncrementSize) 1574 | { 1575 | InitOffsetted(other, offsetInDescriptors, descriptorIncrementSize); 1576 | } 1577 | CD3DX12_CPU_DESCRIPTOR_HANDLE& Offset(INT offsetInDescriptors, UINT descriptorIncrementSize) 1578 | { 1579 | ptr += INT64(offsetInDescriptors) * UINT64(descriptorIncrementSize); 1580 | return *this; 1581 | } 1582 | CD3DX12_CPU_DESCRIPTOR_HANDLE& Offset(INT offsetScaledByIncrementSize) 1583 | { 1584 | ptr += offsetScaledByIncrementSize; 1585 | return *this; 1586 | } 1587 | bool operator==(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE& other) const 1588 | { 1589 | return (ptr == other.ptr); 1590 | } 1591 | bool operator!=(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE& other) const 1592 | { 1593 | return (ptr != other.ptr); 1594 | } 1595 | CD3DX12_CPU_DESCRIPTOR_HANDLE &operator=(const D3D12_CPU_DESCRIPTOR_HANDLE &other) 1596 | { 1597 | ptr = other.ptr; 1598 | return *this; 1599 | } 1600 | 1601 | inline void InitOffsetted(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE &base, INT offsetScaledByIncrementSize) 1602 | { 1603 | InitOffsetted(*this, base, offsetScaledByIncrementSize); 1604 | } 1605 | 1606 | inline void InitOffsetted(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE &base, INT offsetInDescriptors, UINT descriptorIncrementSize) 1607 | { 1608 | InitOffsetted(*this, base, offsetInDescriptors, descriptorIncrementSize); 1609 | } 1610 | 1611 | static inline void InitOffsetted(_Out_ D3D12_CPU_DESCRIPTOR_HANDLE &handle, _In_ const D3D12_CPU_DESCRIPTOR_HANDLE &base, INT offsetScaledByIncrementSize) 1612 | { 1613 | handle.ptr = base.ptr + offsetScaledByIncrementSize; 1614 | } 1615 | 1616 | static inline void InitOffsetted(_Out_ D3D12_CPU_DESCRIPTOR_HANDLE &handle, _In_ const D3D12_CPU_DESCRIPTOR_HANDLE &base, INT offsetInDescriptors, UINT descriptorIncrementSize) 1617 | { 1618 | handle.ptr = static_cast(base.ptr + INT64(offsetInDescriptors) * UINT64(descriptorIncrementSize)); 1619 | } 1620 | }; 1621 | 1622 | //------------------------------------------------------------------------------------------------ 1623 | struct CD3DX12_GPU_DESCRIPTOR_HANDLE : public D3D12_GPU_DESCRIPTOR_HANDLE 1624 | { 1625 | CD3DX12_GPU_DESCRIPTOR_HANDLE() = default; 1626 | explicit CD3DX12_GPU_DESCRIPTOR_HANDLE(const D3D12_GPU_DESCRIPTOR_HANDLE &o) : 1627 | D3D12_GPU_DESCRIPTOR_HANDLE(o) 1628 | {} 1629 | CD3DX12_GPU_DESCRIPTOR_HANDLE(CD3DX12_DEFAULT) { ptr = 0; } 1630 | CD3DX12_GPU_DESCRIPTOR_HANDLE(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE &other, INT offsetScaledByIncrementSize) 1631 | { 1632 | InitOffsetted(other, offsetScaledByIncrementSize); 1633 | } 1634 | CD3DX12_GPU_DESCRIPTOR_HANDLE(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE &other, INT offsetInDescriptors, UINT descriptorIncrementSize) 1635 | { 1636 | InitOffsetted(other, offsetInDescriptors, descriptorIncrementSize); 1637 | } 1638 | CD3DX12_GPU_DESCRIPTOR_HANDLE& Offset(INT offsetInDescriptors, UINT descriptorIncrementSize) 1639 | { 1640 | ptr += INT64(offsetInDescriptors) * UINT64(descriptorIncrementSize); 1641 | return *this; 1642 | } 1643 | CD3DX12_GPU_DESCRIPTOR_HANDLE& Offset(INT offsetScaledByIncrementSize) 1644 | { 1645 | ptr += offsetScaledByIncrementSize; 1646 | return *this; 1647 | } 1648 | inline bool operator==(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE& other) const 1649 | { 1650 | return (ptr == other.ptr); 1651 | } 1652 | inline bool operator!=(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE& other) const 1653 | { 1654 | return (ptr != other.ptr); 1655 | } 1656 | CD3DX12_GPU_DESCRIPTOR_HANDLE &operator=(const D3D12_GPU_DESCRIPTOR_HANDLE &other) 1657 | { 1658 | ptr = other.ptr; 1659 | return *this; 1660 | } 1661 | 1662 | inline void InitOffsetted(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE &base, INT offsetScaledByIncrementSize) 1663 | { 1664 | InitOffsetted(*this, base, offsetScaledByIncrementSize); 1665 | } 1666 | 1667 | inline void InitOffsetted(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE &base, INT offsetInDescriptors, UINT descriptorIncrementSize) 1668 | { 1669 | InitOffsetted(*this, base, offsetInDescriptors, descriptorIncrementSize); 1670 | } 1671 | 1672 | static inline void InitOffsetted(_Out_ D3D12_GPU_DESCRIPTOR_HANDLE &handle, _In_ const D3D12_GPU_DESCRIPTOR_HANDLE &base, INT offsetScaledByIncrementSize) 1673 | { 1674 | handle.ptr = base.ptr + offsetScaledByIncrementSize; 1675 | } 1676 | 1677 | static inline void InitOffsetted(_Out_ D3D12_GPU_DESCRIPTOR_HANDLE &handle, _In_ const D3D12_GPU_DESCRIPTOR_HANDLE &base, INT offsetInDescriptors, UINT descriptorIncrementSize) 1678 | { 1679 | handle.ptr = static_cast(base.ptr + INT64(offsetInDescriptors) * UINT64(descriptorIncrementSize)); 1680 | } 1681 | }; 1682 | 1683 | //------------------------------------------------------------------------------------------------ 1684 | inline UINT D3D12CalcSubresource( UINT MipSlice, UINT ArraySlice, UINT PlaneSlice, UINT MipLevels, UINT ArraySize ) 1685 | { 1686 | return MipSlice + ArraySlice * MipLevels + PlaneSlice * MipLevels * ArraySize; 1687 | } 1688 | 1689 | //------------------------------------------------------------------------------------------------ 1690 | template 1691 | inline void D3D12DecomposeSubresource( UINT Subresource, UINT MipLevels, UINT ArraySize, _Out_ T& MipSlice, _Out_ U& ArraySlice, _Out_ V& PlaneSlice ) 1692 | { 1693 | MipSlice = static_cast(Subresource % MipLevels); 1694 | ArraySlice = static_cast((Subresource / MipLevels) % ArraySize); 1695 | PlaneSlice = static_cast(Subresource / (MipLevels * ArraySize)); 1696 | } 1697 | 1698 | //------------------------------------------------------------------------------------------------ 1699 | inline UINT8 D3D12GetFormatPlaneCount( 1700 | _In_ ID3D12Device* pDevice, 1701 | DXGI_FORMAT Format 1702 | ) 1703 | { 1704 | D3D12_FEATURE_DATA_FORMAT_INFO formatInfo = { Format, 0 }; 1705 | if (FAILED(pDevice->CheckFeatureSupport(D3D12_FEATURE_FORMAT_INFO, &formatInfo, sizeof(formatInfo)))) 1706 | { 1707 | return 0; 1708 | } 1709 | return formatInfo.PlaneCount; 1710 | } 1711 | 1712 | //------------------------------------------------------------------------------------------------ 1713 | struct CD3DX12_RESOURCE_DESC : public D3D12_RESOURCE_DESC 1714 | { 1715 | CD3DX12_RESOURCE_DESC() = default; 1716 | explicit CD3DX12_RESOURCE_DESC( const D3D12_RESOURCE_DESC& o ) : 1717 | D3D12_RESOURCE_DESC( o ) 1718 | {} 1719 | CD3DX12_RESOURCE_DESC( 1720 | D3D12_RESOURCE_DIMENSION dimension, 1721 | UINT64 alignment, 1722 | UINT64 width, 1723 | UINT height, 1724 | UINT16 depthOrArraySize, 1725 | UINT16 mipLevels, 1726 | DXGI_FORMAT format, 1727 | UINT sampleCount, 1728 | UINT sampleQuality, 1729 | D3D12_TEXTURE_LAYOUT layout, 1730 | D3D12_RESOURCE_FLAGS flags ) 1731 | { 1732 | Dimension = dimension; 1733 | Alignment = alignment; 1734 | Width = width; 1735 | Height = height; 1736 | DepthOrArraySize = depthOrArraySize; 1737 | MipLevels = mipLevels; 1738 | Format = format; 1739 | SampleDesc.Count = sampleCount; 1740 | SampleDesc.Quality = sampleQuality; 1741 | Layout = layout; 1742 | Flags = flags; 1743 | } 1744 | static inline CD3DX12_RESOURCE_DESC Buffer( 1745 | const D3D12_RESOURCE_ALLOCATION_INFO& resAllocInfo, 1746 | D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE ) 1747 | { 1748 | return CD3DX12_RESOURCE_DESC( D3D12_RESOURCE_DIMENSION_BUFFER, resAllocInfo.Alignment, resAllocInfo.SizeInBytes, 1749 | 1, 1, 1, DXGI_FORMAT_UNKNOWN, 1, 0, D3D12_TEXTURE_LAYOUT_ROW_MAJOR, flags ); 1750 | } 1751 | static inline CD3DX12_RESOURCE_DESC Buffer( 1752 | UINT64 width, 1753 | D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE, 1754 | UINT64 alignment = 0 ) 1755 | { 1756 | return CD3DX12_RESOURCE_DESC( D3D12_RESOURCE_DIMENSION_BUFFER, alignment, width, 1, 1, 1, 1757 | DXGI_FORMAT_UNKNOWN, 1, 0, D3D12_TEXTURE_LAYOUT_ROW_MAJOR, flags ); 1758 | } 1759 | static inline CD3DX12_RESOURCE_DESC Tex1D( 1760 | DXGI_FORMAT format, 1761 | UINT64 width, 1762 | UINT16 arraySize = 1, 1763 | UINT16 mipLevels = 0, 1764 | D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE, 1765 | D3D12_TEXTURE_LAYOUT layout = D3D12_TEXTURE_LAYOUT_UNKNOWN, 1766 | UINT64 alignment = 0 ) 1767 | { 1768 | return CD3DX12_RESOURCE_DESC( D3D12_RESOURCE_DIMENSION_TEXTURE1D, alignment, width, 1, arraySize, 1769 | mipLevels, format, 1, 0, layout, flags ); 1770 | } 1771 | static inline CD3DX12_RESOURCE_DESC Tex2D( 1772 | DXGI_FORMAT format, 1773 | UINT64 width, 1774 | UINT height, 1775 | UINT16 arraySize = 1, 1776 | UINT16 mipLevels = 0, 1777 | UINT sampleCount = 1, 1778 | UINT sampleQuality = 0, 1779 | D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE, 1780 | D3D12_TEXTURE_LAYOUT layout = D3D12_TEXTURE_LAYOUT_UNKNOWN, 1781 | UINT64 alignment = 0 ) 1782 | { 1783 | return CD3DX12_RESOURCE_DESC( D3D12_RESOURCE_DIMENSION_TEXTURE2D, alignment, width, height, arraySize, 1784 | mipLevels, format, sampleCount, sampleQuality, layout, flags ); 1785 | } 1786 | static inline CD3DX12_RESOURCE_DESC Tex3D( 1787 | DXGI_FORMAT format, 1788 | UINT64 width, 1789 | UINT height, 1790 | UINT16 depth, 1791 | UINT16 mipLevels = 0, 1792 | D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE, 1793 | D3D12_TEXTURE_LAYOUT layout = D3D12_TEXTURE_LAYOUT_UNKNOWN, 1794 | UINT64 alignment = 0 ) 1795 | { 1796 | return CD3DX12_RESOURCE_DESC( D3D12_RESOURCE_DIMENSION_TEXTURE3D, alignment, width, height, depth, 1797 | mipLevels, format, 1, 0, layout, flags ); 1798 | } 1799 | inline UINT16 Depth() const 1800 | { return (Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D ? DepthOrArraySize : 1); } 1801 | inline UINT16 ArraySize() const 1802 | { return (Dimension != D3D12_RESOURCE_DIMENSION_TEXTURE3D ? DepthOrArraySize : 1); } 1803 | inline UINT8 PlaneCount(_In_ ID3D12Device* pDevice) const 1804 | { return D3D12GetFormatPlaneCount(pDevice, Format); } 1805 | inline UINT Subresources(_In_ ID3D12Device* pDevice) const 1806 | { return MipLevels * ArraySize() * PlaneCount(pDevice); } 1807 | inline UINT CalcSubresource(UINT MipSlice, UINT ArraySlice, UINT PlaneSlice) 1808 | { return D3D12CalcSubresource(MipSlice, ArraySlice, PlaneSlice, MipLevels, ArraySize()); } 1809 | }; 1810 | inline bool operator==( const D3D12_RESOURCE_DESC& l, const D3D12_RESOURCE_DESC& r ) 1811 | { 1812 | return l.Dimension == r.Dimension && 1813 | l.Alignment == r.Alignment && 1814 | l.Width == r.Width && 1815 | l.Height == r.Height && 1816 | l.DepthOrArraySize == r.DepthOrArraySize && 1817 | l.MipLevels == r.MipLevels && 1818 | l.Format == r.Format && 1819 | l.SampleDesc.Count == r.SampleDesc.Count && 1820 | l.SampleDesc.Quality == r.SampleDesc.Quality && 1821 | l.Layout == r.Layout && 1822 | l.Flags == r.Flags; 1823 | } 1824 | inline bool operator!=( const D3D12_RESOURCE_DESC& l, const D3D12_RESOURCE_DESC& r ) 1825 | { return !( l == r ); } 1826 | 1827 | //------------------------------------------------------------------------------------------------ 1828 | struct CD3DX12_VIEW_INSTANCING_DESC : public D3D12_VIEW_INSTANCING_DESC 1829 | { 1830 | CD3DX12_VIEW_INSTANCING_DESC() = default; 1831 | explicit CD3DX12_VIEW_INSTANCING_DESC( const D3D12_VIEW_INSTANCING_DESC& o ) : 1832 | D3D12_VIEW_INSTANCING_DESC( o ) 1833 | {} 1834 | explicit CD3DX12_VIEW_INSTANCING_DESC( CD3DX12_DEFAULT ) 1835 | { 1836 | ViewInstanceCount = 0; 1837 | pViewInstanceLocations = nullptr; 1838 | Flags = D3D12_VIEW_INSTANCING_FLAG_NONE; 1839 | } 1840 | explicit CD3DX12_VIEW_INSTANCING_DESC( 1841 | UINT InViewInstanceCount, 1842 | const D3D12_VIEW_INSTANCE_LOCATION* InViewInstanceLocations, 1843 | D3D12_VIEW_INSTANCING_FLAGS InFlags) 1844 | { 1845 | ViewInstanceCount = InViewInstanceCount; 1846 | pViewInstanceLocations = InViewInstanceLocations; 1847 | Flags = InFlags; 1848 | } 1849 | }; 1850 | 1851 | //------------------------------------------------------------------------------------------------ 1852 | // Row-by-row memcpy 1853 | inline void MemcpySubresource( 1854 | _In_ const D3D12_MEMCPY_DEST* pDest, 1855 | _In_ const D3D12_SUBRESOURCE_DATA* pSrc, 1856 | SIZE_T RowSizeInBytes, 1857 | UINT NumRows, 1858 | UINT NumSlices) 1859 | { 1860 | for (UINT z = 0; z < NumSlices; ++z) 1861 | { 1862 | BYTE* pDestSlice = reinterpret_cast(pDest->pData) + pDest->SlicePitch * z; 1863 | const BYTE* pSrcSlice = reinterpret_cast(pSrc->pData) + pSrc->SlicePitch * z; 1864 | for (UINT y = 0; y < NumRows; ++y) 1865 | { 1866 | memcpy(pDestSlice + pDest->RowPitch * y, 1867 | pSrcSlice + pSrc->RowPitch * y, 1868 | RowSizeInBytes); 1869 | } 1870 | } 1871 | } 1872 | 1873 | //------------------------------------------------------------------------------------------------ 1874 | // Returns required size of a buffer to be used for data upload 1875 | inline UINT64 GetRequiredIntermediateSize( 1876 | _In_ ID3D12Resource* pDestinationResource, 1877 | _In_range_(0,D3D12_REQ_SUBRESOURCES) UINT FirstSubresource, 1878 | _In_range_(0,D3D12_REQ_SUBRESOURCES-FirstSubresource) UINT NumSubresources) 1879 | { 1880 | auto Desc = pDestinationResource->GetDesc(); 1881 | UINT64 RequiredSize = 0; 1882 | 1883 | ID3D12Device* pDevice = nullptr; 1884 | pDestinationResource->GetDevice(__uuidof(*pDevice), reinterpret_cast(&pDevice)); 1885 | pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, 0, nullptr, nullptr, nullptr, &RequiredSize); 1886 | pDevice->Release(); 1887 | 1888 | return RequiredSize; 1889 | } 1890 | 1891 | //------------------------------------------------------------------------------------------------ 1892 | // All arrays must be populated (e.g. by calling GetCopyableFootprints) 1893 | inline UINT64 UpdateSubresources( 1894 | _In_ ID3D12GraphicsCommandList* pCmdList, 1895 | _In_ ID3D12Resource* pDestinationResource, 1896 | _In_ ID3D12Resource* pIntermediate, 1897 | _In_range_(0,D3D12_REQ_SUBRESOURCES) UINT FirstSubresource, 1898 | _In_range_(0,D3D12_REQ_SUBRESOURCES-FirstSubresource) UINT NumSubresources, 1899 | UINT64 RequiredSize, 1900 | _In_reads_(NumSubresources) const D3D12_PLACED_SUBRESOURCE_FOOTPRINT* pLayouts, 1901 | _In_reads_(NumSubresources) const UINT* pNumRows, 1902 | _In_reads_(NumSubresources) const UINT64* pRowSizesInBytes, 1903 | _In_reads_(NumSubresources) const D3D12_SUBRESOURCE_DATA* pSrcData) 1904 | { 1905 | // Minor validation 1906 | auto IntermediateDesc = pIntermediate->GetDesc(); 1907 | auto DestinationDesc = pDestinationResource->GetDesc(); 1908 | if (IntermediateDesc.Dimension != D3D12_RESOURCE_DIMENSION_BUFFER || 1909 | IntermediateDesc.Width < RequiredSize + pLayouts[0].Offset || 1910 | RequiredSize > SIZE_T(-1) || 1911 | (DestinationDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER && 1912 | (FirstSubresource != 0 || NumSubresources != 1))) 1913 | { 1914 | return 0; 1915 | } 1916 | 1917 | BYTE* pData; 1918 | HRESULT hr = pIntermediate->Map(0, nullptr, reinterpret_cast(&pData)); 1919 | if (FAILED(hr)) 1920 | { 1921 | return 0; 1922 | } 1923 | 1924 | for (UINT i = 0; i < NumSubresources; ++i) 1925 | { 1926 | if (pRowSizesInBytes[i] > SIZE_T(-1)) return 0; 1927 | D3D12_MEMCPY_DEST DestData = { pData + pLayouts[i].Offset, pLayouts[i].Footprint.RowPitch, SIZE_T(pLayouts[i].Footprint.RowPitch) * SIZE_T(pNumRows[i]) }; 1928 | MemcpySubresource(&DestData, &pSrcData[i], static_cast(pRowSizesInBytes[i]), pNumRows[i], pLayouts[i].Footprint.Depth); 1929 | } 1930 | pIntermediate->Unmap(0, nullptr); 1931 | 1932 | if (DestinationDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) 1933 | { 1934 | pCmdList->CopyBufferRegion( 1935 | pDestinationResource, 0, pIntermediate, pLayouts[0].Offset, pLayouts[0].Footprint.Width); 1936 | } 1937 | else 1938 | { 1939 | for (UINT i = 0; i < NumSubresources; ++i) 1940 | { 1941 | CD3DX12_TEXTURE_COPY_LOCATION Dst(pDestinationResource, i + FirstSubresource); 1942 | CD3DX12_TEXTURE_COPY_LOCATION Src(pIntermediate, pLayouts[i]); 1943 | pCmdList->CopyTextureRegion(&Dst, 0, 0, 0, &Src, nullptr); 1944 | } 1945 | } 1946 | return RequiredSize; 1947 | } 1948 | 1949 | //------------------------------------------------------------------------------------------------ 1950 | // Heap-allocating UpdateSubresources implementation 1951 | inline UINT64 UpdateSubresources( 1952 | _In_ ID3D12GraphicsCommandList* pCmdList, 1953 | _In_ ID3D12Resource* pDestinationResource, 1954 | _In_ ID3D12Resource* pIntermediate, 1955 | UINT64 IntermediateOffset, 1956 | _In_range_(0,D3D12_REQ_SUBRESOURCES) UINT FirstSubresource, 1957 | _In_range_(0,D3D12_REQ_SUBRESOURCES-FirstSubresource) UINT NumSubresources, 1958 | _In_reads_(NumSubresources) D3D12_SUBRESOURCE_DATA* pSrcData) 1959 | { 1960 | UINT64 RequiredSize = 0; 1961 | UINT64 MemToAlloc = static_cast(sizeof(D3D12_PLACED_SUBRESOURCE_FOOTPRINT) + sizeof(UINT) + sizeof(UINT64)) * NumSubresources; 1962 | if (MemToAlloc > SIZE_MAX) 1963 | { 1964 | return 0; 1965 | } 1966 | void* pMem = HeapAlloc(GetProcessHeap(), 0, static_cast(MemToAlloc)); 1967 | if (pMem == nullptr) 1968 | { 1969 | return 0; 1970 | } 1971 | auto pLayouts = reinterpret_cast(pMem); 1972 | UINT64* pRowSizesInBytes = reinterpret_cast(pLayouts + NumSubresources); 1973 | UINT* pNumRows = reinterpret_cast(pRowSizesInBytes + NumSubresources); 1974 | 1975 | auto Desc = pDestinationResource->GetDesc(); 1976 | ID3D12Device* pDevice = nullptr; 1977 | pDestinationResource->GetDevice(__uuidof(*pDevice), reinterpret_cast(&pDevice)); 1978 | pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, IntermediateOffset, pLayouts, pNumRows, pRowSizesInBytes, &RequiredSize); 1979 | pDevice->Release(); 1980 | 1981 | UINT64 Result = UpdateSubresources(pCmdList, pDestinationResource, pIntermediate, FirstSubresource, NumSubresources, RequiredSize, pLayouts, pNumRows, pRowSizesInBytes, pSrcData); 1982 | HeapFree(GetProcessHeap(), 0, pMem); 1983 | return Result; 1984 | } 1985 | 1986 | //------------------------------------------------------------------------------------------------ 1987 | // Stack-allocating UpdateSubresources implementation 1988 | template 1989 | inline UINT64 UpdateSubresources( 1990 | _In_ ID3D12GraphicsCommandList* pCmdList, 1991 | _In_ ID3D12Resource* pDestinationResource, 1992 | _In_ ID3D12Resource* pIntermediate, 1993 | UINT64 IntermediateOffset, 1994 | _In_range_(0, MaxSubresources) UINT FirstSubresource, 1995 | _In_range_(1, MaxSubresources - FirstSubresource) UINT NumSubresources, 1996 | _In_reads_(NumSubresources) D3D12_SUBRESOURCE_DATA* pSrcData) 1997 | { 1998 | UINT64 RequiredSize = 0; 1999 | D3D12_PLACED_SUBRESOURCE_FOOTPRINT Layouts[MaxSubresources]; 2000 | UINT NumRows[MaxSubresources]; 2001 | UINT64 RowSizesInBytes[MaxSubresources]; 2002 | 2003 | auto Desc = pDestinationResource->GetDesc(); 2004 | ID3D12Device* pDevice = nullptr; 2005 | pDestinationResource->GetDevice(__uuidof(*pDevice), reinterpret_cast(&pDevice)); 2006 | pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, IntermediateOffset, Layouts, NumRows, RowSizesInBytes, &RequiredSize); 2007 | pDevice->Release(); 2008 | 2009 | return UpdateSubresources(pCmdList, pDestinationResource, pIntermediate, FirstSubresource, NumSubresources, RequiredSize, Layouts, NumRows, RowSizesInBytes, pSrcData); 2010 | } 2011 | 2012 | //------------------------------------------------------------------------------------------------ 2013 | inline bool D3D12IsLayoutOpaque( D3D12_TEXTURE_LAYOUT Layout ) 2014 | { return Layout == D3D12_TEXTURE_LAYOUT_UNKNOWN || Layout == D3D12_TEXTURE_LAYOUT_64KB_UNDEFINED_SWIZZLE; } 2015 | 2016 | //------------------------------------------------------------------------------------------------ 2017 | template 2018 | inline ID3D12CommandList * const * CommandListCast(t_CommandListType * const * pp) 2019 | { 2020 | // This cast is useful for passing strongly typed command list pointers into 2021 | // ExecuteCommandLists. 2022 | // This cast is valid as long as the const-ness is respected. D3D12 APIs do 2023 | // respect the const-ness of their arguments. 2024 | return reinterpret_cast(pp); 2025 | } 2026 | 2027 | //------------------------------------------------------------------------------------------------ 2028 | // D3D12 exports a new method for serializing root signatures in the Windows 10 Anniversary Update. 2029 | // To help enable root signature 1.1 features when they are available and not require maintaining 2030 | // two code paths for building root signatures, this helper method reconstructs a 1.0 signature when 2031 | // 1.1 is not supported. 2032 | inline HRESULT D3DX12SerializeVersionedRootSignature( 2033 | _In_ const D3D12_VERSIONED_ROOT_SIGNATURE_DESC* pRootSignatureDesc, 2034 | D3D_ROOT_SIGNATURE_VERSION MaxVersion, 2035 | _Outptr_ ID3DBlob** ppBlob, 2036 | _Always_(_Outptr_opt_result_maybenull_) ID3DBlob** ppErrorBlob) 2037 | { 2038 | if (ppErrorBlob != nullptr) 2039 | { 2040 | *ppErrorBlob = nullptr; 2041 | } 2042 | 2043 | switch (MaxVersion) 2044 | { 2045 | case D3D_ROOT_SIGNATURE_VERSION_1_0: 2046 | switch (pRootSignatureDesc->Version) 2047 | { 2048 | case D3D_ROOT_SIGNATURE_VERSION_1_0: 2049 | return D3D12SerializeRootSignature(&pRootSignatureDesc->Desc_1_0, D3D_ROOT_SIGNATURE_VERSION_1, ppBlob, ppErrorBlob); 2050 | 2051 | case D3D_ROOT_SIGNATURE_VERSION_1_1: 2052 | { 2053 | HRESULT hr = S_OK; 2054 | const D3D12_ROOT_SIGNATURE_DESC1& desc_1_1 = pRootSignatureDesc->Desc_1_1; 2055 | 2056 | const SIZE_T ParametersSize = sizeof(D3D12_ROOT_PARAMETER) * desc_1_1.NumParameters; 2057 | void* pParameters = (ParametersSize > 0) ? HeapAlloc(GetProcessHeap(), 0, ParametersSize) : nullptr; 2058 | if (ParametersSize > 0 && pParameters == nullptr) 2059 | { 2060 | hr = E_OUTOFMEMORY; 2061 | } 2062 | auto pParameters_1_0 = reinterpret_cast(pParameters); 2063 | 2064 | if (SUCCEEDED(hr)) 2065 | { 2066 | for (UINT n = 0; n < desc_1_1.NumParameters; n++) 2067 | { 2068 | __analysis_assume(ParametersSize == sizeof(D3D12_ROOT_PARAMETER) * desc_1_1.NumParameters); 2069 | pParameters_1_0[n].ParameterType = desc_1_1.pParameters[n].ParameterType; 2070 | pParameters_1_0[n].ShaderVisibility = desc_1_1.pParameters[n].ShaderVisibility; 2071 | 2072 | switch (desc_1_1.pParameters[n].ParameterType) 2073 | { 2074 | case D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS: 2075 | pParameters_1_0[n].Constants.Num32BitValues = desc_1_1.pParameters[n].Constants.Num32BitValues; 2076 | pParameters_1_0[n].Constants.RegisterSpace = desc_1_1.pParameters[n].Constants.RegisterSpace; 2077 | pParameters_1_0[n].Constants.ShaderRegister = desc_1_1.pParameters[n].Constants.ShaderRegister; 2078 | break; 2079 | 2080 | case D3D12_ROOT_PARAMETER_TYPE_CBV: 2081 | case D3D12_ROOT_PARAMETER_TYPE_SRV: 2082 | case D3D12_ROOT_PARAMETER_TYPE_UAV: 2083 | pParameters_1_0[n].Descriptor.RegisterSpace = desc_1_1.pParameters[n].Descriptor.RegisterSpace; 2084 | pParameters_1_0[n].Descriptor.ShaderRegister = desc_1_1.pParameters[n].Descriptor.ShaderRegister; 2085 | break; 2086 | 2087 | case D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE: 2088 | const D3D12_ROOT_DESCRIPTOR_TABLE1& table_1_1 = desc_1_1.pParameters[n].DescriptorTable; 2089 | 2090 | const SIZE_T DescriptorRangesSize = sizeof(D3D12_DESCRIPTOR_RANGE) * table_1_1.NumDescriptorRanges; 2091 | void* pDescriptorRanges = (DescriptorRangesSize > 0 && SUCCEEDED(hr)) ? HeapAlloc(GetProcessHeap(), 0, DescriptorRangesSize) : nullptr; 2092 | if (DescriptorRangesSize > 0 && pDescriptorRanges == nullptr) 2093 | { 2094 | hr = E_OUTOFMEMORY; 2095 | } 2096 | auto pDescriptorRanges_1_0 = reinterpret_cast(pDescriptorRanges); 2097 | 2098 | if (SUCCEEDED(hr)) 2099 | { 2100 | for (UINT x = 0; x < table_1_1.NumDescriptorRanges; x++) 2101 | { 2102 | __analysis_assume(DescriptorRangesSize == sizeof(D3D12_DESCRIPTOR_RANGE) * table_1_1.NumDescriptorRanges); 2103 | pDescriptorRanges_1_0[x].BaseShaderRegister = table_1_1.pDescriptorRanges[x].BaseShaderRegister; 2104 | pDescriptorRanges_1_0[x].NumDescriptors = table_1_1.pDescriptorRanges[x].NumDescriptors; 2105 | pDescriptorRanges_1_0[x].OffsetInDescriptorsFromTableStart = table_1_1.pDescriptorRanges[x].OffsetInDescriptorsFromTableStart; 2106 | pDescriptorRanges_1_0[x].RangeType = table_1_1.pDescriptorRanges[x].RangeType; 2107 | pDescriptorRanges_1_0[x].RegisterSpace = table_1_1.pDescriptorRanges[x].RegisterSpace; 2108 | } 2109 | } 2110 | 2111 | D3D12_ROOT_DESCRIPTOR_TABLE& table_1_0 = pParameters_1_0[n].DescriptorTable; 2112 | table_1_0.NumDescriptorRanges = table_1_1.NumDescriptorRanges; 2113 | table_1_0.pDescriptorRanges = pDescriptorRanges_1_0; 2114 | } 2115 | } 2116 | } 2117 | 2118 | if (SUCCEEDED(hr)) 2119 | { 2120 | CD3DX12_ROOT_SIGNATURE_DESC desc_1_0(desc_1_1.NumParameters, pParameters_1_0, desc_1_1.NumStaticSamplers, desc_1_1.pStaticSamplers, desc_1_1.Flags); 2121 | hr = D3D12SerializeRootSignature(&desc_1_0, D3D_ROOT_SIGNATURE_VERSION_1, ppBlob, ppErrorBlob); 2122 | } 2123 | 2124 | if (pParameters) 2125 | { 2126 | for (UINT n = 0; n < desc_1_1.NumParameters; n++) 2127 | { 2128 | if (desc_1_1.pParameters[n].ParameterType == D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE) 2129 | { 2130 | HeapFree(GetProcessHeap(), 0, reinterpret_cast(const_cast(pParameters_1_0[n].DescriptorTable.pDescriptorRanges))); 2131 | } 2132 | } 2133 | HeapFree(GetProcessHeap(), 0, pParameters); 2134 | } 2135 | return hr; 2136 | } 2137 | } 2138 | break; 2139 | 2140 | case D3D_ROOT_SIGNATURE_VERSION_1_1: 2141 | return D3D12SerializeVersionedRootSignature(pRootSignatureDesc, ppBlob, ppErrorBlob); 2142 | } 2143 | 2144 | return E_INVALIDARG; 2145 | } 2146 | 2147 | //------------------------------------------------------------------------------------------------ 2148 | struct CD3DX12_RT_FORMAT_ARRAY : public D3D12_RT_FORMAT_ARRAY 2149 | { 2150 | CD3DX12_RT_FORMAT_ARRAY() = default; 2151 | explicit CD3DX12_RT_FORMAT_ARRAY(const D3D12_RT_FORMAT_ARRAY& o) 2152 | : D3D12_RT_FORMAT_ARRAY(o) 2153 | {} 2154 | explicit CD3DX12_RT_FORMAT_ARRAY(_In_reads_(NumFormats) const DXGI_FORMAT* pFormats, UINT NumFormats) 2155 | { 2156 | NumRenderTargets = NumFormats; 2157 | memcpy(RTFormats, pFormats, sizeof(RTFormats)); 2158 | // assumes ARRAY_SIZE(pFormats) == ARRAY_SIZE(RTFormats) 2159 | } 2160 | }; 2161 | 2162 | //------------------------------------------------------------------------------------------------ 2163 | // Pipeline State Stream Helpers 2164 | //------------------------------------------------------------------------------------------------ 2165 | 2166 | //------------------------------------------------------------------------------------------------ 2167 | // Stream Subobjects, i.e. elements of a stream 2168 | 2169 | struct DefaultSampleMask { operator UINT() { return UINT_MAX; } }; 2170 | struct DefaultSampleDesc { operator DXGI_SAMPLE_DESC() { return DXGI_SAMPLE_DESC{1, 0}; } }; 2171 | 2172 | #pragma warning(push) 2173 | #pragma warning(disable : 4324) 2174 | template 2175 | class alignas(void*) CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT 2176 | { 2177 | private: 2178 | D3D12_PIPELINE_STATE_SUBOBJECT_TYPE _Type; 2179 | InnerStructType _Inner; 2180 | public: 2181 | CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT() noexcept : _Type(Type), _Inner(DefaultArg()) {} 2182 | CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT(InnerStructType const& i) : _Type(Type), _Inner(i) {} 2183 | CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT& operator=(InnerStructType const& i) { _Inner = i; return *this; } 2184 | operator InnerStructType() const { return _Inner; } 2185 | operator InnerStructType&() { return _Inner; } 2186 | }; 2187 | #pragma warning(pop) 2188 | typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< D3D12_PIPELINE_STATE_FLAGS, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_FLAGS> CD3DX12_PIPELINE_STATE_STREAM_FLAGS; 2189 | typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< UINT, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_NODE_MASK> CD3DX12_PIPELINE_STATE_STREAM_NODE_MASK; 2190 | typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< ID3D12RootSignature*, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_ROOT_SIGNATURE> CD3DX12_PIPELINE_STATE_STREAM_ROOT_SIGNATURE; 2191 | typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< D3D12_INPUT_LAYOUT_DESC, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_INPUT_LAYOUT> CD3DX12_PIPELINE_STATE_STREAM_INPUT_LAYOUT; 2192 | typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< D3D12_INDEX_BUFFER_STRIP_CUT_VALUE, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_IB_STRIP_CUT_VALUE> CD3DX12_PIPELINE_STATE_STREAM_IB_STRIP_CUT_VALUE; 2193 | typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< D3D12_PRIMITIVE_TOPOLOGY_TYPE, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_PRIMITIVE_TOPOLOGY> CD3DX12_PIPELINE_STATE_STREAM_PRIMITIVE_TOPOLOGY; 2194 | typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< D3D12_SHADER_BYTECODE, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_VS> CD3DX12_PIPELINE_STATE_STREAM_VS; 2195 | typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< D3D12_SHADER_BYTECODE, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_GS> CD3DX12_PIPELINE_STATE_STREAM_GS; 2196 | typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< D3D12_STREAM_OUTPUT_DESC, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_STREAM_OUTPUT> CD3DX12_PIPELINE_STATE_STREAM_STREAM_OUTPUT; 2197 | typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< D3D12_SHADER_BYTECODE, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_HS> CD3DX12_PIPELINE_STATE_STREAM_HS; 2198 | typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< D3D12_SHADER_BYTECODE, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DS> CD3DX12_PIPELINE_STATE_STREAM_DS; 2199 | typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< D3D12_SHADER_BYTECODE, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_PS> CD3DX12_PIPELINE_STATE_STREAM_PS; 2200 | typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< D3D12_SHADER_BYTECODE, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_CS> CD3DX12_PIPELINE_STATE_STREAM_CS; 2201 | typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< CD3DX12_BLEND_DESC, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_BLEND, CD3DX12_DEFAULT> CD3DX12_PIPELINE_STATE_STREAM_BLEND_DESC; 2202 | typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< CD3DX12_DEPTH_STENCIL_DESC, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL, CD3DX12_DEFAULT> CD3DX12_PIPELINE_STATE_STREAM_DEPTH_STENCIL; 2203 | typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< CD3DX12_DEPTH_STENCIL_DESC1, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL1, CD3DX12_DEFAULT> CD3DX12_PIPELINE_STATE_STREAM_DEPTH_STENCIL1; 2204 | typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< DXGI_FORMAT, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL_FORMAT> CD3DX12_PIPELINE_STATE_STREAM_DEPTH_STENCIL_FORMAT; 2205 | typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< CD3DX12_RASTERIZER_DESC, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_RASTERIZER, CD3DX12_DEFAULT> CD3DX12_PIPELINE_STATE_STREAM_RASTERIZER; 2206 | typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< D3D12_RT_FORMAT_ARRAY, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_RENDER_TARGET_FORMATS> CD3DX12_PIPELINE_STATE_STREAM_RENDER_TARGET_FORMATS; 2207 | typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< DXGI_SAMPLE_DESC, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_SAMPLE_DESC, DefaultSampleDesc> CD3DX12_PIPELINE_STATE_STREAM_SAMPLE_DESC; 2208 | typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< UINT, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_SAMPLE_MASK, DefaultSampleMask> CD3DX12_PIPELINE_STATE_STREAM_SAMPLE_MASK; 2209 | typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< D3D12_CACHED_PIPELINE_STATE, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_CACHED_PSO> CD3DX12_PIPELINE_STATE_STREAM_CACHED_PSO; 2210 | typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< CD3DX12_VIEW_INSTANCING_DESC, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_VIEW_INSTANCING, CD3DX12_DEFAULT> CD3DX12_PIPELINE_STATE_STREAM_VIEW_INSTANCING; 2211 | 2212 | //------------------------------------------------------------------------------------------------ 2213 | // Stream Parser Helpers 2214 | 2215 | struct ID3DX12PipelineParserCallbacks 2216 | { 2217 | // Subobject Callbacks 2218 | virtual void FlagsCb(D3D12_PIPELINE_STATE_FLAGS) {} 2219 | virtual void NodeMaskCb(UINT) {} 2220 | virtual void RootSignatureCb(ID3D12RootSignature*) {} 2221 | virtual void InputLayoutCb(const D3D12_INPUT_LAYOUT_DESC&) {} 2222 | virtual void IBStripCutValueCb(D3D12_INDEX_BUFFER_STRIP_CUT_VALUE) {} 2223 | virtual void PrimitiveTopologyTypeCb(D3D12_PRIMITIVE_TOPOLOGY_TYPE) {} 2224 | virtual void VSCb(const D3D12_SHADER_BYTECODE&) {} 2225 | virtual void GSCb(const D3D12_SHADER_BYTECODE&) {} 2226 | virtual void StreamOutputCb(const D3D12_STREAM_OUTPUT_DESC&) {} 2227 | virtual void HSCb(const D3D12_SHADER_BYTECODE&) {} 2228 | virtual void DSCb(const D3D12_SHADER_BYTECODE&) {} 2229 | virtual void PSCb(const D3D12_SHADER_BYTECODE&) {} 2230 | virtual void CSCb(const D3D12_SHADER_BYTECODE&) {} 2231 | virtual void BlendStateCb(const D3D12_BLEND_DESC&) {} 2232 | virtual void DepthStencilStateCb(const D3D12_DEPTH_STENCIL_DESC&) {} 2233 | virtual void DepthStencilState1Cb(const D3D12_DEPTH_STENCIL_DESC1&) {} 2234 | virtual void DSVFormatCb(DXGI_FORMAT) {} 2235 | virtual void RasterizerStateCb(const D3D12_RASTERIZER_DESC&) {} 2236 | virtual void RTVFormatsCb(const D3D12_RT_FORMAT_ARRAY&) {} 2237 | virtual void SampleDescCb(const DXGI_SAMPLE_DESC&) {} 2238 | virtual void SampleMaskCb(UINT) {} 2239 | virtual void ViewInstancingCb(const D3D12_VIEW_INSTANCING_DESC&) {} 2240 | virtual void CachedPSOCb(const D3D12_CACHED_PIPELINE_STATE&) {} 2241 | 2242 | // Error Callbacks 2243 | virtual void ErrorBadInputParameter(UINT /*ParameterIndex*/) {} 2244 | virtual void ErrorDuplicateSubobject(D3D12_PIPELINE_STATE_SUBOBJECT_TYPE /*DuplicateType*/) {} 2245 | virtual void ErrorUnknownSubobject(UINT /*UnknownTypeValue*/) {} 2246 | 2247 | virtual ~ID3DX12PipelineParserCallbacks() = default; 2248 | }; 2249 | 2250 | // CD3DX12_PIPELINE_STATE_STREAM1 Works on RS3+ (where there is a new view instancing subobject). 2251 | // Use CD3DX12_PIPELINE_STATE_STREAM for RS2+ support. 2252 | struct CD3DX12_PIPELINE_STATE_STREAM1 2253 | { 2254 | CD3DX12_PIPELINE_STATE_STREAM1() = default; 2255 | CD3DX12_PIPELINE_STATE_STREAM1(const D3D12_GRAPHICS_PIPELINE_STATE_DESC& Desc) 2256 | : Flags(Desc.Flags) 2257 | , NodeMask(Desc.NodeMask) 2258 | , pRootSignature(Desc.pRootSignature) 2259 | , InputLayout(Desc.InputLayout) 2260 | , IBStripCutValue(Desc.IBStripCutValue) 2261 | , PrimitiveTopologyType(Desc.PrimitiveTopologyType) 2262 | , VS(Desc.VS) 2263 | , GS(Desc.GS) 2264 | , StreamOutput(Desc.StreamOutput) 2265 | , HS(Desc.HS) 2266 | , DS(Desc.DS) 2267 | , PS(Desc.PS) 2268 | , BlendState(CD3DX12_BLEND_DESC(Desc.BlendState)) 2269 | , DepthStencilState(CD3DX12_DEPTH_STENCIL_DESC1(Desc.DepthStencilState)) 2270 | , DSVFormat(Desc.DSVFormat) 2271 | , RasterizerState(CD3DX12_RASTERIZER_DESC(Desc.RasterizerState)) 2272 | , RTVFormats(CD3DX12_RT_FORMAT_ARRAY(Desc.RTVFormats, Desc.NumRenderTargets)) 2273 | , SampleDesc(Desc.SampleDesc) 2274 | , SampleMask(Desc.SampleMask) 2275 | , CachedPSO(Desc.CachedPSO) 2276 | , ViewInstancingDesc(CD3DX12_VIEW_INSTANCING_DESC(CD3DX12_DEFAULT())) 2277 | {} 2278 | CD3DX12_PIPELINE_STATE_STREAM1(const D3D12_COMPUTE_PIPELINE_STATE_DESC& Desc) 2279 | : Flags(Desc.Flags) 2280 | , NodeMask(Desc.NodeMask) 2281 | , pRootSignature(Desc.pRootSignature) 2282 | , CS(CD3DX12_SHADER_BYTECODE(Desc.CS)) 2283 | , CachedPSO(Desc.CachedPSO) 2284 | { 2285 | static_cast(DepthStencilState).DepthEnable = false; 2286 | } 2287 | CD3DX12_PIPELINE_STATE_STREAM_FLAGS Flags; 2288 | CD3DX12_PIPELINE_STATE_STREAM_NODE_MASK NodeMask; 2289 | CD3DX12_PIPELINE_STATE_STREAM_ROOT_SIGNATURE pRootSignature; 2290 | CD3DX12_PIPELINE_STATE_STREAM_INPUT_LAYOUT InputLayout; 2291 | CD3DX12_PIPELINE_STATE_STREAM_IB_STRIP_CUT_VALUE IBStripCutValue; 2292 | CD3DX12_PIPELINE_STATE_STREAM_PRIMITIVE_TOPOLOGY PrimitiveTopologyType; 2293 | CD3DX12_PIPELINE_STATE_STREAM_VS VS; 2294 | CD3DX12_PIPELINE_STATE_STREAM_GS GS; 2295 | CD3DX12_PIPELINE_STATE_STREAM_STREAM_OUTPUT StreamOutput; 2296 | CD3DX12_PIPELINE_STATE_STREAM_HS HS; 2297 | CD3DX12_PIPELINE_STATE_STREAM_DS DS; 2298 | CD3DX12_PIPELINE_STATE_STREAM_PS PS; 2299 | CD3DX12_PIPELINE_STATE_STREAM_CS CS; 2300 | CD3DX12_PIPELINE_STATE_STREAM_BLEND_DESC BlendState; 2301 | CD3DX12_PIPELINE_STATE_STREAM_DEPTH_STENCIL1 DepthStencilState; 2302 | CD3DX12_PIPELINE_STATE_STREAM_DEPTH_STENCIL_FORMAT DSVFormat; 2303 | CD3DX12_PIPELINE_STATE_STREAM_RASTERIZER RasterizerState; 2304 | CD3DX12_PIPELINE_STATE_STREAM_RENDER_TARGET_FORMATS RTVFormats; 2305 | CD3DX12_PIPELINE_STATE_STREAM_SAMPLE_DESC SampleDesc; 2306 | CD3DX12_PIPELINE_STATE_STREAM_SAMPLE_MASK SampleMask; 2307 | CD3DX12_PIPELINE_STATE_STREAM_CACHED_PSO CachedPSO; 2308 | CD3DX12_PIPELINE_STATE_STREAM_VIEW_INSTANCING ViewInstancingDesc; 2309 | D3D12_GRAPHICS_PIPELINE_STATE_DESC GraphicsDescV0() const 2310 | { 2311 | D3D12_GRAPHICS_PIPELINE_STATE_DESC D; 2312 | D.Flags = this->Flags; 2313 | D.NodeMask = this->NodeMask; 2314 | D.pRootSignature = this->pRootSignature; 2315 | D.InputLayout = this->InputLayout; 2316 | D.IBStripCutValue = this->IBStripCutValue; 2317 | D.PrimitiveTopologyType = this->PrimitiveTopologyType; 2318 | D.VS = this->VS; 2319 | D.GS = this->GS; 2320 | D.StreamOutput = this->StreamOutput; 2321 | D.HS = this->HS; 2322 | D.DS = this->DS; 2323 | D.PS = this->PS; 2324 | D.BlendState = this->BlendState; 2325 | D.DepthStencilState = CD3DX12_DEPTH_STENCIL_DESC1(D3D12_DEPTH_STENCIL_DESC1(this->DepthStencilState)); 2326 | D.DSVFormat = this->DSVFormat; 2327 | D.RasterizerState = this->RasterizerState; 2328 | D.NumRenderTargets = D3D12_RT_FORMAT_ARRAY(this->RTVFormats).NumRenderTargets; 2329 | memcpy(D.RTVFormats, D3D12_RT_FORMAT_ARRAY(this->RTVFormats).RTFormats, sizeof(D.RTVFormats)); 2330 | D.SampleDesc = this->SampleDesc; 2331 | D.SampleMask = this->SampleMask; 2332 | D.CachedPSO = this->CachedPSO; 2333 | return D; 2334 | } 2335 | D3D12_COMPUTE_PIPELINE_STATE_DESC ComputeDescV0() const 2336 | { 2337 | D3D12_COMPUTE_PIPELINE_STATE_DESC D; 2338 | D.Flags = this->Flags; 2339 | D.NodeMask = this->NodeMask; 2340 | D.pRootSignature = this->pRootSignature; 2341 | D.CS = this->CS; 2342 | D.CachedPSO = this->CachedPSO; 2343 | return D; 2344 | } 2345 | }; 2346 | 2347 | // CD3DX12_PIPELINE_STATE_STREAM works on RS2+ but does not support new subobject(s) added in RS3+. 2348 | // See CD3DX12_PIPELINE_STATE_STREAM1 for instance. 2349 | struct CD3DX12_PIPELINE_STATE_STREAM 2350 | { 2351 | CD3DX12_PIPELINE_STATE_STREAM() = default; 2352 | CD3DX12_PIPELINE_STATE_STREAM(const D3D12_GRAPHICS_PIPELINE_STATE_DESC& Desc) 2353 | : Flags(Desc.Flags) 2354 | , NodeMask(Desc.NodeMask) 2355 | , pRootSignature(Desc.pRootSignature) 2356 | , InputLayout(Desc.InputLayout) 2357 | , IBStripCutValue(Desc.IBStripCutValue) 2358 | , PrimitiveTopologyType(Desc.PrimitiveTopologyType) 2359 | , VS(Desc.VS) 2360 | , GS(Desc.GS) 2361 | , StreamOutput(Desc.StreamOutput) 2362 | , HS(Desc.HS) 2363 | , DS(Desc.DS) 2364 | , PS(Desc.PS) 2365 | , BlendState(CD3DX12_BLEND_DESC(Desc.BlendState)) 2366 | , DepthStencilState(CD3DX12_DEPTH_STENCIL_DESC1(Desc.DepthStencilState)) 2367 | , DSVFormat(Desc.DSVFormat) 2368 | , RasterizerState(CD3DX12_RASTERIZER_DESC(Desc.RasterizerState)) 2369 | , RTVFormats(CD3DX12_RT_FORMAT_ARRAY(Desc.RTVFormats, Desc.NumRenderTargets)) 2370 | , SampleDesc(Desc.SampleDesc) 2371 | , SampleMask(Desc.SampleMask) 2372 | , CachedPSO(Desc.CachedPSO) 2373 | {} 2374 | CD3DX12_PIPELINE_STATE_STREAM(const D3D12_COMPUTE_PIPELINE_STATE_DESC& Desc) 2375 | : Flags(Desc.Flags) 2376 | , NodeMask(Desc.NodeMask) 2377 | , pRootSignature(Desc.pRootSignature) 2378 | , CS(CD3DX12_SHADER_BYTECODE(Desc.CS)) 2379 | , CachedPSO(Desc.CachedPSO) 2380 | {} 2381 | CD3DX12_PIPELINE_STATE_STREAM_FLAGS Flags; 2382 | CD3DX12_PIPELINE_STATE_STREAM_NODE_MASK NodeMask; 2383 | CD3DX12_PIPELINE_STATE_STREAM_ROOT_SIGNATURE pRootSignature; 2384 | CD3DX12_PIPELINE_STATE_STREAM_INPUT_LAYOUT InputLayout; 2385 | CD3DX12_PIPELINE_STATE_STREAM_IB_STRIP_CUT_VALUE IBStripCutValue; 2386 | CD3DX12_PIPELINE_STATE_STREAM_PRIMITIVE_TOPOLOGY PrimitiveTopologyType; 2387 | CD3DX12_PIPELINE_STATE_STREAM_VS VS; 2388 | CD3DX12_PIPELINE_STATE_STREAM_GS GS; 2389 | CD3DX12_PIPELINE_STATE_STREAM_STREAM_OUTPUT StreamOutput; 2390 | CD3DX12_PIPELINE_STATE_STREAM_HS HS; 2391 | CD3DX12_PIPELINE_STATE_STREAM_DS DS; 2392 | CD3DX12_PIPELINE_STATE_STREAM_PS PS; 2393 | CD3DX12_PIPELINE_STATE_STREAM_CS CS; 2394 | CD3DX12_PIPELINE_STATE_STREAM_BLEND_DESC BlendState; 2395 | CD3DX12_PIPELINE_STATE_STREAM_DEPTH_STENCIL1 DepthStencilState; 2396 | CD3DX12_PIPELINE_STATE_STREAM_DEPTH_STENCIL_FORMAT DSVFormat; 2397 | CD3DX12_PIPELINE_STATE_STREAM_RASTERIZER RasterizerState; 2398 | CD3DX12_PIPELINE_STATE_STREAM_RENDER_TARGET_FORMATS RTVFormats; 2399 | CD3DX12_PIPELINE_STATE_STREAM_SAMPLE_DESC SampleDesc; 2400 | CD3DX12_PIPELINE_STATE_STREAM_SAMPLE_MASK SampleMask; 2401 | CD3DX12_PIPELINE_STATE_STREAM_CACHED_PSO CachedPSO; 2402 | D3D12_GRAPHICS_PIPELINE_STATE_DESC GraphicsDescV0() const 2403 | { 2404 | D3D12_GRAPHICS_PIPELINE_STATE_DESC D; 2405 | D.Flags = this->Flags; 2406 | D.NodeMask = this->NodeMask; 2407 | D.pRootSignature = this->pRootSignature; 2408 | D.InputLayout = this->InputLayout; 2409 | D.IBStripCutValue = this->IBStripCutValue; 2410 | D.PrimitiveTopologyType = this->PrimitiveTopologyType; 2411 | D.VS = this->VS; 2412 | D.GS = this->GS; 2413 | D.StreamOutput = this->StreamOutput; 2414 | D.HS = this->HS; 2415 | D.DS = this->DS; 2416 | D.PS = this->PS; 2417 | D.BlendState = this->BlendState; 2418 | D.DepthStencilState = CD3DX12_DEPTH_STENCIL_DESC1(D3D12_DEPTH_STENCIL_DESC1(this->DepthStencilState)); 2419 | D.DSVFormat = this->DSVFormat; 2420 | D.RasterizerState = this->RasterizerState; 2421 | D.NumRenderTargets = D3D12_RT_FORMAT_ARRAY(this->RTVFormats).NumRenderTargets; 2422 | memcpy(D.RTVFormats, D3D12_RT_FORMAT_ARRAY(this->RTVFormats).RTFormats, sizeof(D.RTVFormats)); 2423 | D.SampleDesc = this->SampleDesc; 2424 | D.SampleMask = this->SampleMask; 2425 | D.CachedPSO = this->CachedPSO; 2426 | return D; 2427 | } 2428 | D3D12_COMPUTE_PIPELINE_STATE_DESC ComputeDescV0() const 2429 | { 2430 | D3D12_COMPUTE_PIPELINE_STATE_DESC D; 2431 | D.Flags = this->Flags; 2432 | D.NodeMask = this->NodeMask; 2433 | D.pRootSignature = this->pRootSignature; 2434 | D.CS = this->CS; 2435 | D.CachedPSO = this->CachedPSO; 2436 | return D; 2437 | } 2438 | }; 2439 | 2440 | struct CD3DX12_PIPELINE_STATE_STREAM_PARSE_HELPER : public ID3DX12PipelineParserCallbacks 2441 | { 2442 | CD3DX12_PIPELINE_STATE_STREAM1 PipelineStream; 2443 | CD3DX12_PIPELINE_STATE_STREAM_PARSE_HELPER() noexcept 2444 | : SeenDSS(false) 2445 | { 2446 | // Adjust defaults to account for absent members. 2447 | PipelineStream.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; 2448 | 2449 | // Depth disabled if no DSV format specified. 2450 | static_cast(PipelineStream.DepthStencilState).DepthEnable = false; 2451 | } 2452 | 2453 | // ID3DX12PipelineParserCallbacks 2454 | void FlagsCb(D3D12_PIPELINE_STATE_FLAGS Flags) override {PipelineStream.Flags = Flags;} 2455 | void NodeMaskCb(UINT NodeMask) override {PipelineStream.NodeMask = NodeMask;} 2456 | void RootSignatureCb(ID3D12RootSignature* pRootSignature) override {PipelineStream.pRootSignature = pRootSignature;} 2457 | void InputLayoutCb(const D3D12_INPUT_LAYOUT_DESC& InputLayout) override {PipelineStream.InputLayout = InputLayout;} 2458 | void IBStripCutValueCb(D3D12_INDEX_BUFFER_STRIP_CUT_VALUE IBStripCutValue) override {PipelineStream.IBStripCutValue = IBStripCutValue;} 2459 | void PrimitiveTopologyTypeCb(D3D12_PRIMITIVE_TOPOLOGY_TYPE PrimitiveTopologyType) override {PipelineStream.PrimitiveTopologyType = PrimitiveTopologyType;} 2460 | void VSCb(const D3D12_SHADER_BYTECODE& VS) override {PipelineStream.VS = VS;} 2461 | void GSCb(const D3D12_SHADER_BYTECODE& GS) override {PipelineStream.GS = GS;} 2462 | void StreamOutputCb(const D3D12_STREAM_OUTPUT_DESC& StreamOutput) override {PipelineStream.StreamOutput = StreamOutput;} 2463 | void HSCb(const D3D12_SHADER_BYTECODE& HS) override {PipelineStream.HS = HS;} 2464 | void DSCb(const D3D12_SHADER_BYTECODE& DS) override {PipelineStream.DS = DS;} 2465 | void PSCb(const D3D12_SHADER_BYTECODE& PS) override {PipelineStream.PS = PS;} 2466 | void CSCb(const D3D12_SHADER_BYTECODE& CS) override {PipelineStream.CS = CS;} 2467 | void BlendStateCb(const D3D12_BLEND_DESC& BlendState) override {PipelineStream.BlendState = CD3DX12_BLEND_DESC(BlendState);} 2468 | void DepthStencilStateCb(const D3D12_DEPTH_STENCIL_DESC& DepthStencilState) override 2469 | { 2470 | PipelineStream.DepthStencilState = CD3DX12_DEPTH_STENCIL_DESC1(DepthStencilState); 2471 | SeenDSS = true; 2472 | } 2473 | void DepthStencilState1Cb(const D3D12_DEPTH_STENCIL_DESC1& DepthStencilState) override 2474 | { 2475 | PipelineStream.DepthStencilState = CD3DX12_DEPTH_STENCIL_DESC1(DepthStencilState); 2476 | SeenDSS = true; 2477 | } 2478 | void DSVFormatCb(DXGI_FORMAT DSVFormat) override 2479 | { 2480 | PipelineStream.DSVFormat = DSVFormat; 2481 | if (!SeenDSS && DSVFormat != DXGI_FORMAT_UNKNOWN) 2482 | { 2483 | // Re-enable depth for the default state. 2484 | static_cast(PipelineStream.DepthStencilState).DepthEnable = true; 2485 | } 2486 | } 2487 | void RasterizerStateCb(const D3D12_RASTERIZER_DESC& RasterizerState) override {PipelineStream.RasterizerState = CD3DX12_RASTERIZER_DESC(RasterizerState);} 2488 | void RTVFormatsCb(const D3D12_RT_FORMAT_ARRAY& RTVFormats) override {PipelineStream.RTVFormats = RTVFormats;} 2489 | void SampleDescCb(const DXGI_SAMPLE_DESC& SampleDesc) override {PipelineStream.SampleDesc = SampleDesc;} 2490 | void SampleMaskCb(UINT SampleMask) override {PipelineStream.SampleMask = SampleMask;} 2491 | void ViewInstancingCb(const D3D12_VIEW_INSTANCING_DESC& ViewInstancingDesc) override {PipelineStream.ViewInstancingDesc = CD3DX12_VIEW_INSTANCING_DESC(ViewInstancingDesc);} 2492 | void CachedPSOCb(const D3D12_CACHED_PIPELINE_STATE& CachedPSO) override {PipelineStream.CachedPSO = CachedPSO;} 2493 | 2494 | private: 2495 | bool SeenDSS; 2496 | }; 2497 | 2498 | inline D3D12_PIPELINE_STATE_SUBOBJECT_TYPE D3DX12GetBaseSubobjectType(D3D12_PIPELINE_STATE_SUBOBJECT_TYPE SubobjectType) 2499 | { 2500 | switch (SubobjectType) 2501 | { 2502 | case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL1: 2503 | return D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL; 2504 | default: 2505 | return SubobjectType; 2506 | } 2507 | } 2508 | 2509 | inline HRESULT D3DX12ParsePipelineStream(const D3D12_PIPELINE_STATE_STREAM_DESC& Desc, ID3DX12PipelineParserCallbacks* pCallbacks) 2510 | { 2511 | if (pCallbacks == nullptr) 2512 | { 2513 | return E_INVALIDARG; 2514 | } 2515 | 2516 | if (Desc.SizeInBytes == 0 || Desc.pPipelineStateSubobjectStream == nullptr) 2517 | { 2518 | pCallbacks->ErrorBadInputParameter(1); // first parameter issue 2519 | return E_INVALIDARG; 2520 | } 2521 | 2522 | bool SubobjectSeen[D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_MAX_VALID] = {}; 2523 | for (SIZE_T CurOffset = 0, SizeOfSubobject = 0; CurOffset < Desc.SizeInBytes; CurOffset += SizeOfSubobject) 2524 | { 2525 | BYTE* pStream = static_cast(Desc.pPipelineStateSubobjectStream)+CurOffset; 2526 | auto SubobjectType = *reinterpret_cast(pStream); 2527 | if (SubobjectType < 0 || SubobjectType >= D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_MAX_VALID) 2528 | { 2529 | pCallbacks->ErrorUnknownSubobject(SubobjectType); 2530 | return E_INVALIDARG; 2531 | } 2532 | if (SubobjectSeen[D3DX12GetBaseSubobjectType(SubobjectType)]) 2533 | { 2534 | pCallbacks->ErrorDuplicateSubobject(SubobjectType); 2535 | return E_INVALIDARG; // disallow subobject duplicates in a stream 2536 | } 2537 | SubobjectSeen[SubobjectType] = true; 2538 | switch (SubobjectType) 2539 | { 2540 | case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_ROOT_SIGNATURE: 2541 | pCallbacks->RootSignatureCb(*reinterpret_cast(pStream)); 2542 | SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM::pRootSignature); 2543 | break; 2544 | case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_VS: 2545 | pCallbacks->VSCb(*reinterpret_cast(pStream)); 2546 | SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM::VS); 2547 | break; 2548 | case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_PS: 2549 | pCallbacks->PSCb(*reinterpret_cast(pStream)); 2550 | SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM::PS); 2551 | break; 2552 | case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DS: 2553 | pCallbacks->DSCb(*reinterpret_cast(pStream)); 2554 | SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM::DS); 2555 | break; 2556 | case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_HS: 2557 | pCallbacks->HSCb(*reinterpret_cast(pStream)); 2558 | SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM::HS); 2559 | break; 2560 | case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_GS: 2561 | pCallbacks->GSCb(*reinterpret_cast(pStream)); 2562 | SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM::GS); 2563 | break; 2564 | case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_CS: 2565 | pCallbacks->CSCb(*reinterpret_cast(pStream)); 2566 | SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM::CS); 2567 | break; 2568 | case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_STREAM_OUTPUT: 2569 | pCallbacks->StreamOutputCb(*reinterpret_cast(pStream)); 2570 | SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM::StreamOutput); 2571 | break; 2572 | case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_BLEND: 2573 | pCallbacks->BlendStateCb(*reinterpret_cast(pStream)); 2574 | SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM::BlendState); 2575 | break; 2576 | case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_SAMPLE_MASK: 2577 | pCallbacks->SampleMaskCb(*reinterpret_cast(pStream)); 2578 | SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM::SampleMask); 2579 | break; 2580 | case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_RASTERIZER: 2581 | pCallbacks->RasterizerStateCb(*reinterpret_cast(pStream)); 2582 | SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM::RasterizerState); 2583 | break; 2584 | case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL: 2585 | pCallbacks->DepthStencilStateCb(*reinterpret_cast(pStream)); 2586 | SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM_DEPTH_STENCIL); 2587 | break; 2588 | case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL1: 2589 | pCallbacks->DepthStencilState1Cb(*reinterpret_cast(pStream)); 2590 | SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM::DepthStencilState); 2591 | break; 2592 | case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_INPUT_LAYOUT: 2593 | pCallbacks->InputLayoutCb(*reinterpret_cast(pStream)); 2594 | SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM::InputLayout); 2595 | break; 2596 | case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_IB_STRIP_CUT_VALUE: 2597 | pCallbacks->IBStripCutValueCb(*reinterpret_cast(pStream)); 2598 | SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM::IBStripCutValue); 2599 | break; 2600 | case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_PRIMITIVE_TOPOLOGY: 2601 | pCallbacks->PrimitiveTopologyTypeCb(*reinterpret_cast(pStream)); 2602 | SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM::PrimitiveTopologyType); 2603 | break; 2604 | case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_RENDER_TARGET_FORMATS: 2605 | pCallbacks->RTVFormatsCb(*reinterpret_cast(pStream)); 2606 | SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM::RTVFormats); 2607 | break; 2608 | case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL_FORMAT: 2609 | pCallbacks->DSVFormatCb(*reinterpret_cast(pStream)); 2610 | SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM::DSVFormat); 2611 | break; 2612 | case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_SAMPLE_DESC: 2613 | pCallbacks->SampleDescCb(*reinterpret_cast(pStream)); 2614 | SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM::SampleDesc); 2615 | break; 2616 | case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_NODE_MASK: 2617 | pCallbacks->NodeMaskCb(*reinterpret_cast(pStream)); 2618 | SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM::NodeMask); 2619 | break; 2620 | case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_CACHED_PSO: 2621 | pCallbacks->CachedPSOCb(*reinterpret_cast(pStream)); 2622 | SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM::CachedPSO); 2623 | break; 2624 | case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_FLAGS: 2625 | pCallbacks->FlagsCb(*reinterpret_cast(pStream)); 2626 | SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM::Flags); 2627 | break; 2628 | case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_VIEW_INSTANCING: 2629 | pCallbacks->ViewInstancingCb(*reinterpret_cast(pStream)); 2630 | SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM1::ViewInstancingDesc); 2631 | break; 2632 | default: 2633 | pCallbacks->ErrorUnknownSubobject(SubobjectType); 2634 | return E_INVALIDARG; 2635 | break; 2636 | } 2637 | } 2638 | 2639 | return S_OK; 2640 | } 2641 | 2642 | //------------------------------------------------------------------------------------------------ 2643 | inline bool operator==( const D3D12_CLEAR_VALUE &a, const D3D12_CLEAR_VALUE &b) 2644 | { 2645 | if (a.Format != b.Format) return false; 2646 | if (a.Format == DXGI_FORMAT_D24_UNORM_S8_UINT 2647 | || a.Format == DXGI_FORMAT_D16_UNORM 2648 | || a.Format == DXGI_FORMAT_D32_FLOAT 2649 | || a.Format == DXGI_FORMAT_D32_FLOAT_S8X24_UINT) 2650 | { 2651 | return (a.DepthStencil.Depth == b.DepthStencil.Depth) && 2652 | (a.DepthStencil.Stencil == b.DepthStencil.Stencil); 2653 | } else { 2654 | return (a.Color[0] == b.Color[0]) && 2655 | (a.Color[1] == b.Color[1]) && 2656 | (a.Color[2] == b.Color[2]) && 2657 | (a.Color[3] == b.Color[3]); 2658 | } 2659 | } 2660 | inline bool operator==( const D3D12_RENDER_PASS_BEGINNING_ACCESS_CLEAR_PARAMETERS &a, const D3D12_RENDER_PASS_BEGINNING_ACCESS_CLEAR_PARAMETERS &b) 2661 | { 2662 | return a.ClearValue == b.ClearValue; 2663 | } 2664 | inline bool operator==( const D3D12_RENDER_PASS_ENDING_ACCESS_RESOLVE_PARAMETERS &a, const D3D12_RENDER_PASS_ENDING_ACCESS_RESOLVE_PARAMETERS &b) 2665 | { 2666 | if (a.pSrcResource != b.pSrcResource) return false; 2667 | if (a.pDstResource != b.pDstResource) return false; 2668 | if (a.SubresourceCount != b.SubresourceCount) return false; 2669 | if (a.Format != b.Format) return false; 2670 | if (a.ResolveMode != b.ResolveMode) return false; 2671 | if (a.PreserveResolveSource != b.PreserveResolveSource) return false; 2672 | return true; 2673 | } 2674 | inline bool operator==( const D3D12_RENDER_PASS_BEGINNING_ACCESS &a, const D3D12_RENDER_PASS_BEGINNING_ACCESS &b) 2675 | { 2676 | if (a.Type != b.Type) return false; 2677 | if (a.Type == D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_CLEAR && !(a.Clear == b.Clear)) return false; 2678 | return true; 2679 | } 2680 | inline bool operator==( const D3D12_RENDER_PASS_ENDING_ACCESS &a, const D3D12_RENDER_PASS_ENDING_ACCESS &b) 2681 | { 2682 | if (a.Type != b.Type) return false; 2683 | if (a.Type == D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_RESOLVE && !(a.Resolve == b.Resolve)) return false; 2684 | return true; 2685 | } 2686 | inline bool operator==( const D3D12_RENDER_PASS_RENDER_TARGET_DESC &a, const D3D12_RENDER_PASS_RENDER_TARGET_DESC &b) 2687 | { 2688 | if (a.cpuDescriptor.ptr != b.cpuDescriptor.ptr) return false; 2689 | if (!(a.BeginningAccess == b.BeginningAccess)) return false; 2690 | if (!(a.EndingAccess == b.EndingAccess)) return false; 2691 | return true; 2692 | } 2693 | inline bool operator==( const D3D12_RENDER_PASS_DEPTH_STENCIL_DESC &a, const D3D12_RENDER_PASS_DEPTH_STENCIL_DESC &b) 2694 | { 2695 | if (a.cpuDescriptor.ptr != b.cpuDescriptor.ptr) return false; 2696 | if (!(a.DepthBeginningAccess == b.DepthBeginningAccess)) return false; 2697 | if (!(a.StencilBeginningAccess == b.StencilBeginningAccess)) return false; 2698 | if (!(a.DepthEndingAccess == b.DepthEndingAccess)) return false; 2699 | if (!(a.StencilEndingAccess == b.StencilEndingAccess)) return false; 2700 | return true; 2701 | } 2702 | 2703 | 2704 | #ifndef D3DX12_NO_STATE_OBJECT_HELPERS 2705 | 2706 | //================================================================================================ 2707 | // D3DX12 State Object Creation Helpers 2708 | // 2709 | // Helper classes for creating new style state objects out of an arbitrary set of subobjects. 2710 | // Uses STL 2711 | // 2712 | // Start by instantiating CD3DX12_STATE_OBJECT_DESC (see it's public methods). 2713 | // One of its methods is CreateSubobject(), which has a comment showing a couple of options for 2714 | // defining subobjects using the helper classes for each subobject (CD3DX12_DXIL_LIBRARY_SUBOBJECT 2715 | // etc.). The subobject helpers each have methods specific to the subobject for configuring it's 2716 | // contents. 2717 | // 2718 | //================================================================================================ 2719 | #include 2720 | #include 2721 | #include 2722 | #include 2723 | #include 2724 | 2725 | //------------------------------------------------------------------------------------------------ 2726 | class CD3DX12_STATE_OBJECT_DESC 2727 | { 2728 | public: 2729 | CD3DX12_STATE_OBJECT_DESC() 2730 | { 2731 | Init(D3D12_STATE_OBJECT_TYPE_COLLECTION); 2732 | } 2733 | CD3DX12_STATE_OBJECT_DESC(D3D12_STATE_OBJECT_TYPE Type) 2734 | { 2735 | Init(Type); 2736 | } 2737 | void SetStateObjectType(D3D12_STATE_OBJECT_TYPE Type) { m_Desc.Type = Type; } 2738 | operator const D3D12_STATE_OBJECT_DESC&() 2739 | { 2740 | // Do final preparation work 2741 | m_RepointedAssociations.clear(); 2742 | m_SubobjectArray.clear(); 2743 | m_SubobjectArray.reserve(m_Desc.NumSubobjects); 2744 | // Flatten subobjects into an array (each flattened subobject still has a 2745 | // member that's a pointer to it's desc that's not flattened) 2746 | for (auto Iter = m_SubobjectList.begin(); 2747 | Iter != m_SubobjectList.end(); Iter++) 2748 | { 2749 | m_SubobjectArray.push_back(*Iter); 2750 | // Store new location in array so we can redirect pointers contained in subobjects 2751 | Iter->pSubobjectArrayLocation = &m_SubobjectArray.back(); 2752 | } 2753 | // For subobjects with pointer fields, create a new copy of those subobject definitions 2754 | // with fixed pointers 2755 | for (UINT i = 0; i < m_Desc.NumSubobjects; i++) 2756 | { 2757 | if (m_SubobjectArray[i].Type == D3D12_STATE_SUBOBJECT_TYPE_SUBOBJECT_TO_EXPORTS_ASSOCIATION) 2758 | { 2759 | auto pOriginalSubobjectAssociation = 2760 | reinterpret_cast(m_SubobjectArray[i].pDesc); 2761 | D3D12_SUBOBJECT_TO_EXPORTS_ASSOCIATION Repointed = *pOriginalSubobjectAssociation; 2762 | auto pWrapper = 2763 | static_cast(pOriginalSubobjectAssociation->pSubobjectToAssociate); 2764 | Repointed.pSubobjectToAssociate = pWrapper->pSubobjectArrayLocation; 2765 | m_RepointedAssociations.push_back(Repointed); 2766 | m_SubobjectArray[i].pDesc = &m_RepointedAssociations.back(); 2767 | } 2768 | } 2769 | // Below: using ugly way to get pointer in case .data() is not defined 2770 | m_Desc.pSubobjects = m_Desc.NumSubobjects ? &m_SubobjectArray[0] : nullptr; 2771 | return m_Desc; 2772 | } 2773 | operator const D3D12_STATE_OBJECT_DESC*() 2774 | { 2775 | // Cast calls the above final preparation work 2776 | return &static_cast(*this); 2777 | } 2778 | 2779 | // CreateSubobject creates a sububject helper (e.g. CD3DX12_HIT_GROUP_SUBOBJECT) 2780 | // whose lifetime is owned by this class. 2781 | // e.g. 2782 | // 2783 | // CD3DX12_STATE_OBJECT_DESC Collection1(D3D12_STATE_OBJECT_TYPE_COLLECTION); 2784 | // auto Lib0 = Collection1.CreateSubobject(); 2785 | // Lib0->SetDXILLibrary(&pMyAppDxilLibs[0]); 2786 | // Lib0->DefineExport(L"rayGenShader0"); // in practice these export listings might be 2787 | // // data/engine driven 2788 | // etc. 2789 | // 2790 | // Alternatively, users can instantiate sububject helpers explicitly, such as via local 2791 | // variables instead, passing the state object desc that should point to it into the helper 2792 | // constructor (or call mySubobjectHelper.AddToStateObject(Collection1)). 2793 | // In this alternative scenario, the user must keep the subobject alive as long as the state 2794 | // object it is associated with is alive, else it's pointer references will be stale. 2795 | // e.g. 2796 | // 2797 | // CD3DX12_STATE_OBJECT_DESC RaytracingState2(D3D12_STATE_OBJECT_TYPE_RAYTRACING_PIPELINE); 2798 | // CD3DX12_DXIL_LIBRARY_SUBOBJECT LibA(RaytracingState2); 2799 | // LibA.SetDXILLibrary(&pMyAppDxilLibs[4]); // not manually specifying exports 2800 | // // - meaning all exports in the libraries 2801 | // // are exported 2802 | // etc. 2803 | 2804 | template 2805 | T* CreateSubobject() 2806 | { 2807 | T* pSubobject = new T(*this); 2808 | m_OwnedSubobjectHelpers.emplace_back(pSubobject); 2809 | return pSubobject; 2810 | } 2811 | 2812 | private: 2813 | D3D12_STATE_SUBOBJECT* TrackSubobject(D3D12_STATE_SUBOBJECT_TYPE Type, void* pDesc) 2814 | { 2815 | SUBOBJECT_WRAPPER Subobject; 2816 | Subobject.pSubobjectArrayLocation = nullptr; 2817 | Subobject.Type = Type; 2818 | Subobject.pDesc = pDesc; 2819 | m_SubobjectList.push_back(Subobject); 2820 | m_Desc.NumSubobjects++; 2821 | return &m_SubobjectList.back(); 2822 | } 2823 | void Init(D3D12_STATE_OBJECT_TYPE Type) 2824 | { 2825 | SetStateObjectType(Type); 2826 | m_Desc.pSubobjects = nullptr; 2827 | m_Desc.NumSubobjects = 0; 2828 | m_SubobjectList.clear(); 2829 | m_SubobjectArray.clear(); 2830 | m_RepointedAssociations.clear(); 2831 | } 2832 | typedef struct SUBOBJECT_WRAPPER : public D3D12_STATE_SUBOBJECT 2833 | { 2834 | D3D12_STATE_SUBOBJECT* pSubobjectArrayLocation; // new location when flattened into array 2835 | // for repointing pointers in subobjects 2836 | } SUBOBJECT_WRAPPER; 2837 | D3D12_STATE_OBJECT_DESC m_Desc; 2838 | std::list m_SubobjectList; // Pointers to list nodes handed out so 2839 | // these can be edited live 2840 | std::vector m_SubobjectArray; // Built at the end, copying list contents 2841 | 2842 | std::list 2843 | m_RepointedAssociations; // subobject type that contains pointers to other subobjects, 2844 | // repointed to flattened array 2845 | 2846 | class StringContainer 2847 | { 2848 | public: 2849 | LPCWSTR LocalCopy(LPCWSTR string, bool bSingleString = false) 2850 | { 2851 | if (string) 2852 | { 2853 | if (bSingleString) 2854 | { 2855 | m_Strings.clear(); 2856 | m_Strings.push_back(string); 2857 | } 2858 | else 2859 | { 2860 | m_Strings.push_back(string); 2861 | } 2862 | return m_Strings.back().c_str(); 2863 | } 2864 | else 2865 | { 2866 | return nullptr; 2867 | } 2868 | } 2869 | void clear() { m_Strings.clear(); } 2870 | private: 2871 | std::list m_Strings; 2872 | }; 2873 | 2874 | class SUBOBJECT_HELPER_BASE 2875 | { 2876 | public: 2877 | SUBOBJECT_HELPER_BASE() { Init(); }; 2878 | virtual ~SUBOBJECT_HELPER_BASE() {}; 2879 | virtual D3D12_STATE_SUBOBJECT_TYPE Type() const = 0; 2880 | void AddToStateObject(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) 2881 | { 2882 | m_pSubobject = ContainingStateObject.TrackSubobject(Type(), Data()); 2883 | } 2884 | protected: 2885 | virtual void* Data() = 0; 2886 | void Init() { m_pSubobject = nullptr; } 2887 | D3D12_STATE_SUBOBJECT* m_pSubobject; 2888 | }; 2889 | 2890 | #if(__cplusplus >= 201103L) 2891 | std::list> m_OwnedSubobjectHelpers; 2892 | #else 2893 | class OWNED_HELPER 2894 | { 2895 | public: 2896 | OWNED_HELPER(const SUBOBJECT_HELPER_BASE* pHelper) { m_pHelper = pHelper; } 2897 | ~OWNED_HELPER() { delete m_pHelper; } 2898 | const SUBOBJECT_HELPER_BASE* m_pHelper; 2899 | }; 2900 | 2901 | std::list m_OwnedSubobjectHelpers; 2902 | #endif 2903 | 2904 | friend class CD3DX12_DXIL_LIBRARY_SUBOBJECT; 2905 | friend class CD3DX12_EXISTING_COLLECTION_SUBOBJECT; 2906 | friend class CD3DX12_SUBOBJECT_TO_EXPORTS_ASSOCIATION_SUBOBJECT; 2907 | friend class CD3DX12_DXIL_SUBOBJECT_TO_EXPORTS_ASSOCIATION; 2908 | friend class CD3DX12_HIT_GROUP_SUBOBJECT; 2909 | friend class CD3DX12_RAYTRACING_SHADER_CONFIG_SUBOBJECT; 2910 | friend class CD3DX12_RAYTRACING_PIPELINE_CONFIG_SUBOBJECT; 2911 | friend class CD3DX12_GLOBAL_ROOT_SIGNATURE_SUBOBJECT; 2912 | friend class CD3DX12_LOCAL_ROOT_SIGNATURE_SUBOBJECT; 2913 | friend class CD3DX12_STATE_OBJECT_CONFIG_SUBOBJECT; 2914 | friend class CD3DX12_NODE_MASK_SUBOBJECT; 2915 | }; 2916 | 2917 | //------------------------------------------------------------------------------------------------ 2918 | class CD3DX12_DXIL_LIBRARY_SUBOBJECT 2919 | : public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE 2920 | { 2921 | public: 2922 | CD3DX12_DXIL_LIBRARY_SUBOBJECT() 2923 | { 2924 | Init(); 2925 | } 2926 | CD3DX12_DXIL_LIBRARY_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) 2927 | { 2928 | Init(); 2929 | AddToStateObject(ContainingStateObject); 2930 | } 2931 | void SetDXILLibrary(D3D12_SHADER_BYTECODE*pCode) 2932 | { 2933 | static const D3D12_SHADER_BYTECODE Default = {}; 2934 | m_Desc.DXILLibrary = pCode ? *pCode : Default; 2935 | } 2936 | void DefineExport( 2937 | LPCWSTR Name, 2938 | LPCWSTR ExportToRename = nullptr, 2939 | D3D12_EXPORT_FLAGS Flags = D3D12_EXPORT_FLAG_NONE) 2940 | { 2941 | D3D12_EXPORT_DESC Export; 2942 | Export.Name = m_Strings.LocalCopy(Name); 2943 | Export.ExportToRename = m_Strings.LocalCopy(ExportToRename); 2944 | Export.Flags = Flags; 2945 | m_Exports.push_back(Export); 2946 | m_Desc.pExports = &m_Exports[0]; // using ugly way to get pointer in case .data() is not defined 2947 | m_Desc.NumExports = static_cast(m_Exports.size()); 2948 | } 2949 | template 2950 | void DefineExports(LPCWSTR(&Exports)[N]) 2951 | { 2952 | for (UINT i = 0; i < N; i++) 2953 | { 2954 | DefineExport(Exports[i]); 2955 | } 2956 | } 2957 | void DefineExports(LPCWSTR* Exports, UINT N) 2958 | { 2959 | for (UINT i = 0; i < N; i++) 2960 | { 2961 | DefineExport(Exports[i]); 2962 | } 2963 | } 2964 | D3D12_STATE_SUBOBJECT_TYPE Type() const 2965 | { 2966 | return D3D12_STATE_SUBOBJECT_TYPE_DXIL_LIBRARY; 2967 | } 2968 | operator const D3D12_STATE_SUBOBJECT&() const { return *m_pSubobject; } 2969 | operator const D3D12_DXIL_LIBRARY_DESC&() const { return m_Desc; } 2970 | private: 2971 | void Init() 2972 | { 2973 | SUBOBJECT_HELPER_BASE::Init(); 2974 | m_Desc = {}; 2975 | m_Strings.clear(); 2976 | m_Exports.clear(); 2977 | } 2978 | void* Data() { return &m_Desc; } 2979 | D3D12_DXIL_LIBRARY_DESC m_Desc; 2980 | CD3DX12_STATE_OBJECT_DESC::StringContainer m_Strings; 2981 | std::vector m_Exports; 2982 | }; 2983 | 2984 | //------------------------------------------------------------------------------------------------ 2985 | class CD3DX12_EXISTING_COLLECTION_SUBOBJECT 2986 | : public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE 2987 | { 2988 | public: 2989 | CD3DX12_EXISTING_COLLECTION_SUBOBJECT() 2990 | { 2991 | Init(); 2992 | } 2993 | CD3DX12_EXISTING_COLLECTION_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) 2994 | { 2995 | Init(); 2996 | AddToStateObject(ContainingStateObject); 2997 | } 2998 | void SetExistingCollection(ID3D12StateObject*pExistingCollection) 2999 | { 3000 | m_Desc.pExistingCollection = pExistingCollection; 3001 | m_CollectionRef = pExistingCollection; 3002 | } 3003 | void DefineExport( 3004 | LPCWSTR Name, 3005 | LPCWSTR ExportToRename = nullptr, 3006 | D3D12_EXPORT_FLAGS Flags = D3D12_EXPORT_FLAG_NONE) 3007 | { 3008 | D3D12_EXPORT_DESC Export; 3009 | Export.Name = m_Strings.LocalCopy(Name); 3010 | Export.ExportToRename = m_Strings.LocalCopy(ExportToRename); 3011 | Export.Flags = Flags; 3012 | m_Exports.push_back(Export); 3013 | m_Desc.pExports = &m_Exports[0]; // using ugly way to get pointer in case .data() is not defined 3014 | m_Desc.NumExports = static_cast(m_Exports.size()); 3015 | } 3016 | template 3017 | void DefineExports(LPCWSTR(&Exports)[N]) 3018 | { 3019 | for (UINT i = 0; i < N; i++) 3020 | { 3021 | DefineExport(Exports[i]); 3022 | } 3023 | } 3024 | void DefineExports(LPCWSTR* Exports, UINT N) 3025 | { 3026 | for (UINT i = 0; i < N; i++) 3027 | { 3028 | DefineExport(Exports[i]); 3029 | } 3030 | } 3031 | D3D12_STATE_SUBOBJECT_TYPE Type() const 3032 | { 3033 | return D3D12_STATE_SUBOBJECT_TYPE_EXISTING_COLLECTION; 3034 | } 3035 | operator const D3D12_STATE_SUBOBJECT&() const { return *m_pSubobject; } 3036 | operator const D3D12_EXISTING_COLLECTION_DESC&() const { return m_Desc; } 3037 | private: 3038 | void Init() 3039 | { 3040 | SUBOBJECT_HELPER_BASE::Init(); 3041 | m_Desc = {}; 3042 | m_CollectionRef = nullptr; 3043 | m_Strings.clear(); 3044 | m_Exports.clear(); 3045 | } 3046 | void* Data() { return &m_Desc; } 3047 | D3D12_EXISTING_COLLECTION_DESC m_Desc; 3048 | Microsoft::WRL::ComPtr m_CollectionRef; 3049 | CD3DX12_STATE_OBJECT_DESC::StringContainer m_Strings; 3050 | std::vector m_Exports; 3051 | }; 3052 | 3053 | //------------------------------------------------------------------------------------------------ 3054 | class CD3DX12_SUBOBJECT_TO_EXPORTS_ASSOCIATION_SUBOBJECT 3055 | : public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE 3056 | { 3057 | public: 3058 | CD3DX12_SUBOBJECT_TO_EXPORTS_ASSOCIATION_SUBOBJECT() 3059 | { 3060 | Init(); 3061 | } 3062 | CD3DX12_SUBOBJECT_TO_EXPORTS_ASSOCIATION_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) 3063 | { 3064 | Init(); 3065 | AddToStateObject(ContainingStateObject); 3066 | } 3067 | void SetSubobjectToAssociate(const D3D12_STATE_SUBOBJECT& SubobjectToAssociate) 3068 | { 3069 | m_Desc.pSubobjectToAssociate = &SubobjectToAssociate; 3070 | } 3071 | void AddExport(LPCWSTR Export) 3072 | { 3073 | m_Desc.NumExports++; 3074 | m_Exports.push_back(m_Strings.LocalCopy(Export)); 3075 | m_Desc.pExports = &m_Exports[0]; // using ugly way to get pointer in case .data() is not defined 3076 | } 3077 | template 3078 | void AddExports(LPCWSTR (&Exports)[N]) 3079 | { 3080 | for (UINT i = 0; i < N; i++) 3081 | { 3082 | AddExport(Exports[i]); 3083 | } 3084 | } 3085 | void AddExports(LPCWSTR* Exports, UINT N) 3086 | { 3087 | for (UINT i = 0; i < N; i++) 3088 | { 3089 | AddExport(Exports[i]); 3090 | } 3091 | } 3092 | D3D12_STATE_SUBOBJECT_TYPE Type() const 3093 | { 3094 | return D3D12_STATE_SUBOBJECT_TYPE_SUBOBJECT_TO_EXPORTS_ASSOCIATION; 3095 | } 3096 | operator const D3D12_STATE_SUBOBJECT&() const { return *m_pSubobject; } 3097 | operator const D3D12_SUBOBJECT_TO_EXPORTS_ASSOCIATION&() const { return m_Desc; } 3098 | private: 3099 | void Init() 3100 | { 3101 | SUBOBJECT_HELPER_BASE::Init(); 3102 | m_Desc = {}; 3103 | m_Strings.clear(); 3104 | m_Exports.clear(); 3105 | } 3106 | void* Data() { return &m_Desc; } 3107 | D3D12_SUBOBJECT_TO_EXPORTS_ASSOCIATION m_Desc; 3108 | CD3DX12_STATE_OBJECT_DESC::StringContainer m_Strings; 3109 | std::vector m_Exports; 3110 | }; 3111 | 3112 | //------------------------------------------------------------------------------------------------ 3113 | class CD3DX12_DXIL_SUBOBJECT_TO_EXPORTS_ASSOCIATION 3114 | : public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE 3115 | { 3116 | public: 3117 | CD3DX12_DXIL_SUBOBJECT_TO_EXPORTS_ASSOCIATION() 3118 | { 3119 | Init(); 3120 | } 3121 | CD3DX12_DXIL_SUBOBJECT_TO_EXPORTS_ASSOCIATION(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) 3122 | { 3123 | Init(); 3124 | AddToStateObject(ContainingStateObject); 3125 | } 3126 | void SetSubobjectNameToAssociate(LPCWSTR SubobjectToAssociate) 3127 | { 3128 | m_Desc.SubobjectToAssociate = m_SubobjectName.LocalCopy(SubobjectToAssociate, true); 3129 | } 3130 | void AddExport(LPCWSTR Export) 3131 | { 3132 | m_Desc.NumExports++; 3133 | m_Exports.push_back(m_Strings.LocalCopy(Export)); 3134 | m_Desc.pExports = &m_Exports[0]; // using ugly way to get pointer in case .data() is not defined 3135 | } 3136 | template 3137 | void AddExports(LPCWSTR (&Exports)[N]) 3138 | { 3139 | for (UINT i = 0; i < N; i++) 3140 | { 3141 | AddExport(Exports[i]); 3142 | } 3143 | } 3144 | void AddExports(LPCWSTR* Exports, UINT N) 3145 | { 3146 | for (UINT i = 0; i < N; i++) 3147 | { 3148 | AddExport(Exports[i]); 3149 | } 3150 | } 3151 | D3D12_STATE_SUBOBJECT_TYPE Type() const 3152 | { 3153 | return D3D12_STATE_SUBOBJECT_TYPE_DXIL_SUBOBJECT_TO_EXPORTS_ASSOCIATION; 3154 | } 3155 | operator const D3D12_STATE_SUBOBJECT&() const { return *m_pSubobject; } 3156 | operator const D3D12_DXIL_SUBOBJECT_TO_EXPORTS_ASSOCIATION&() const { return m_Desc; } 3157 | private: 3158 | void Init() 3159 | { 3160 | SUBOBJECT_HELPER_BASE::Init(); 3161 | m_Desc = {}; 3162 | m_Strings.clear(); 3163 | m_SubobjectName.clear(); 3164 | m_Exports.clear(); 3165 | } 3166 | void* Data() { return &m_Desc; } 3167 | D3D12_DXIL_SUBOBJECT_TO_EXPORTS_ASSOCIATION m_Desc; 3168 | CD3DX12_STATE_OBJECT_DESC::StringContainer m_Strings; 3169 | CD3DX12_STATE_OBJECT_DESC::StringContainer m_SubobjectName; 3170 | std::vector m_Exports; 3171 | }; 3172 | 3173 | //------------------------------------------------------------------------------------------------ 3174 | class CD3DX12_HIT_GROUP_SUBOBJECT 3175 | : public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE 3176 | { 3177 | public: 3178 | CD3DX12_HIT_GROUP_SUBOBJECT() 3179 | { 3180 | Init(); 3181 | } 3182 | CD3DX12_HIT_GROUP_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) 3183 | { 3184 | Init(); 3185 | AddToStateObject(ContainingStateObject); 3186 | } 3187 | void SetHitGroupExport(LPCWSTR exportName) 3188 | { 3189 | m_Desc.HitGroupExport = m_Strings[0].LocalCopy(exportName, true); 3190 | } 3191 | void SetHitGroupType(D3D12_HIT_GROUP_TYPE Type) { m_Desc.Type = Type; } 3192 | void SetAnyHitShaderImport(LPCWSTR importName) 3193 | { 3194 | m_Desc.AnyHitShaderImport = m_Strings[1].LocalCopy(importName, true); 3195 | } 3196 | void SetClosestHitShaderImport(LPCWSTR importName) 3197 | { 3198 | m_Desc.ClosestHitShaderImport = m_Strings[2].LocalCopy(importName, true); 3199 | } 3200 | void SetIntersectionShaderImport(LPCWSTR importName) 3201 | { 3202 | m_Desc.IntersectionShaderImport = m_Strings[3].LocalCopy(importName, true); 3203 | } 3204 | D3D12_STATE_SUBOBJECT_TYPE Type() const 3205 | { 3206 | return D3D12_STATE_SUBOBJECT_TYPE_HIT_GROUP; 3207 | } 3208 | operator const D3D12_STATE_SUBOBJECT&() const { return *m_pSubobject; } 3209 | operator const D3D12_HIT_GROUP_DESC&() const { return m_Desc; } 3210 | private: 3211 | void Init() 3212 | { 3213 | SUBOBJECT_HELPER_BASE::Init(); 3214 | m_Desc = {}; 3215 | for (UINT i = 0; i < m_NumStrings; i++) 3216 | { 3217 | m_Strings[i].clear(); 3218 | } 3219 | } 3220 | void* Data() { return &m_Desc; } 3221 | D3D12_HIT_GROUP_DESC m_Desc; 3222 | static const UINT m_NumStrings = 4; 3223 | CD3DX12_STATE_OBJECT_DESC::StringContainer 3224 | m_Strings[m_NumStrings]; // one string for every entrypoint name 3225 | }; 3226 | 3227 | //------------------------------------------------------------------------------------------------ 3228 | class CD3DX12_RAYTRACING_SHADER_CONFIG_SUBOBJECT 3229 | : public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE 3230 | { 3231 | public: 3232 | CD3DX12_RAYTRACING_SHADER_CONFIG_SUBOBJECT() 3233 | { 3234 | Init(); 3235 | } 3236 | CD3DX12_RAYTRACING_SHADER_CONFIG_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) 3237 | { 3238 | Init(); 3239 | AddToStateObject(ContainingStateObject); 3240 | } 3241 | void Config(UINT MaxPayloadSizeInBytes, UINT MaxAttributeSizeInBytes) 3242 | { 3243 | m_Desc.MaxPayloadSizeInBytes = MaxPayloadSizeInBytes; 3244 | m_Desc.MaxAttributeSizeInBytes = MaxAttributeSizeInBytes; 3245 | } 3246 | D3D12_STATE_SUBOBJECT_TYPE Type() const 3247 | { 3248 | return D3D12_STATE_SUBOBJECT_TYPE_RAYTRACING_SHADER_CONFIG; 3249 | } 3250 | operator const D3D12_STATE_SUBOBJECT&() const { return *m_pSubobject; } 3251 | operator const D3D12_RAYTRACING_SHADER_CONFIG&() const { return m_Desc; } 3252 | private: 3253 | void Init() 3254 | { 3255 | SUBOBJECT_HELPER_BASE::Init(); 3256 | m_Desc = {}; 3257 | } 3258 | void* Data() { return &m_Desc; } 3259 | D3D12_RAYTRACING_SHADER_CONFIG m_Desc; 3260 | }; 3261 | 3262 | //------------------------------------------------------------------------------------------------ 3263 | class CD3DX12_RAYTRACING_PIPELINE_CONFIG_SUBOBJECT 3264 | : public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE 3265 | { 3266 | public: 3267 | CD3DX12_RAYTRACING_PIPELINE_CONFIG_SUBOBJECT() 3268 | { 3269 | Init(); 3270 | } 3271 | CD3DX12_RAYTRACING_PIPELINE_CONFIG_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) 3272 | { 3273 | Init(); 3274 | AddToStateObject(ContainingStateObject); 3275 | } 3276 | void Config(UINT MaxTraceRecursionDepth) 3277 | { 3278 | m_Desc.MaxTraceRecursionDepth = MaxTraceRecursionDepth; 3279 | } 3280 | D3D12_STATE_SUBOBJECT_TYPE Type() const 3281 | { 3282 | return D3D12_STATE_SUBOBJECT_TYPE_RAYTRACING_PIPELINE_CONFIG; 3283 | } 3284 | operator const D3D12_STATE_SUBOBJECT&() const { return *m_pSubobject; } 3285 | operator const D3D12_RAYTRACING_PIPELINE_CONFIG&() const { return m_Desc; } 3286 | private: 3287 | void Init() 3288 | { 3289 | SUBOBJECT_HELPER_BASE::Init(); 3290 | m_Desc = {}; 3291 | } 3292 | void* Data() { return &m_Desc; } 3293 | D3D12_RAYTRACING_PIPELINE_CONFIG m_Desc; 3294 | }; 3295 | 3296 | //------------------------------------------------------------------------------------------------ 3297 | class CD3DX12_GLOBAL_ROOT_SIGNATURE_SUBOBJECT 3298 | : public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE 3299 | { 3300 | public: 3301 | CD3DX12_GLOBAL_ROOT_SIGNATURE_SUBOBJECT() 3302 | { 3303 | Init(); 3304 | } 3305 | CD3DX12_GLOBAL_ROOT_SIGNATURE_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) 3306 | { 3307 | Init(); 3308 | AddToStateObject(ContainingStateObject); 3309 | } 3310 | void SetRootSignature(ID3D12RootSignature* pRootSig) 3311 | { 3312 | m_pRootSig = pRootSig; 3313 | } 3314 | D3D12_STATE_SUBOBJECT_TYPE Type() const 3315 | { 3316 | return D3D12_STATE_SUBOBJECT_TYPE_GLOBAL_ROOT_SIGNATURE; 3317 | } 3318 | operator const D3D12_STATE_SUBOBJECT&() const { return *m_pSubobject; } 3319 | operator ID3D12RootSignature*() const { return m_pRootSig.Get(); } 3320 | private: 3321 | void Init() 3322 | { 3323 | SUBOBJECT_HELPER_BASE::Init(); 3324 | m_pRootSig = nullptr; 3325 | } 3326 | void* Data() { return m_pRootSig.GetAddressOf(); } 3327 | Microsoft::WRL::ComPtr m_pRootSig; 3328 | }; 3329 | 3330 | //------------------------------------------------------------------------------------------------ 3331 | class CD3DX12_LOCAL_ROOT_SIGNATURE_SUBOBJECT 3332 | : public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE 3333 | { 3334 | public: 3335 | CD3DX12_LOCAL_ROOT_SIGNATURE_SUBOBJECT() 3336 | { 3337 | Init(); 3338 | } 3339 | CD3DX12_LOCAL_ROOT_SIGNATURE_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) 3340 | { 3341 | Init(); 3342 | AddToStateObject(ContainingStateObject); 3343 | } 3344 | void SetRootSignature(ID3D12RootSignature* pRootSig) 3345 | { 3346 | m_pRootSig = pRootSig; 3347 | } 3348 | D3D12_STATE_SUBOBJECT_TYPE Type() const 3349 | { 3350 | return D3D12_STATE_SUBOBJECT_TYPE_LOCAL_ROOT_SIGNATURE; 3351 | } 3352 | operator const D3D12_STATE_SUBOBJECT&() const { return *m_pSubobject; } 3353 | operator ID3D12RootSignature*() const { return m_pRootSig.Get(); } 3354 | private: 3355 | void Init() 3356 | { 3357 | SUBOBJECT_HELPER_BASE::Init(); 3358 | m_pRootSig = nullptr; 3359 | } 3360 | void* Data() { return m_pRootSig.GetAddressOf(); } 3361 | Microsoft::WRL::ComPtr m_pRootSig; 3362 | }; 3363 | 3364 | //------------------------------------------------------------------------------------------------ 3365 | class CD3DX12_STATE_OBJECT_CONFIG_SUBOBJECT 3366 | : public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE 3367 | { 3368 | public: 3369 | CD3DX12_STATE_OBJECT_CONFIG_SUBOBJECT() 3370 | { 3371 | Init(); 3372 | } 3373 | CD3DX12_STATE_OBJECT_CONFIG_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) 3374 | { 3375 | Init(); 3376 | AddToStateObject(ContainingStateObject); 3377 | } 3378 | void SetFlags(D3D12_STATE_OBJECT_FLAGS Flags) 3379 | { 3380 | m_Desc.Flags = Flags; 3381 | } 3382 | D3D12_STATE_SUBOBJECT_TYPE Type() const 3383 | { 3384 | return D3D12_STATE_SUBOBJECT_TYPE_STATE_OBJECT_CONFIG; 3385 | } 3386 | operator const D3D12_STATE_SUBOBJECT&() const { return *m_pSubobject; } 3387 | operator const D3D12_STATE_OBJECT_CONFIG&() const { return m_Desc; } 3388 | private: 3389 | void Init() 3390 | { 3391 | SUBOBJECT_HELPER_BASE::Init(); 3392 | m_Desc = {}; 3393 | } 3394 | void* Data() { return &m_Desc; } 3395 | D3D12_STATE_OBJECT_CONFIG m_Desc; 3396 | }; 3397 | 3398 | //------------------------------------------------------------------------------------------------ 3399 | class CD3DX12_NODE_MASK_SUBOBJECT 3400 | : public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE 3401 | { 3402 | public: 3403 | CD3DX12_NODE_MASK_SUBOBJECT() 3404 | { 3405 | Init(); 3406 | } 3407 | CD3DX12_NODE_MASK_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) 3408 | { 3409 | Init(); 3410 | AddToStateObject(ContainingStateObject); 3411 | } 3412 | void SetNodeMask(UINT NodeMask) 3413 | { 3414 | m_Desc.NodeMask = NodeMask; 3415 | } 3416 | D3D12_STATE_SUBOBJECT_TYPE Type() const 3417 | { 3418 | return D3D12_STATE_SUBOBJECT_TYPE_NODE_MASK; 3419 | } 3420 | operator const D3D12_STATE_SUBOBJECT&() const { return *m_pSubobject; } 3421 | operator const D3D12_NODE_MASK&() const { return m_Desc; } 3422 | private: 3423 | void Init() 3424 | { 3425 | SUBOBJECT_HELPER_BASE::Init(); 3426 | m_Desc = {}; 3427 | } 3428 | void* Data() { return &m_Desc; } 3429 | D3D12_NODE_MASK m_Desc; 3430 | }; 3431 | 3432 | #endif // #ifndef D3DX12_NO_STATE_OBJECT_HELPERS 3433 | 3434 | #endif // defined( __cplusplus ) 3435 | 3436 | #endif //__D3DX12_H__ 3437 | 3438 | 3439 | 3440 | --------------------------------------------------------------------------------