├── README.md
├── DirectMLTest.vcxproj.filters
├── LICENSE.txt
├── DirectMLTest.sln
├── .gitattributes
├── DirectMLTest.vcxproj
├── .gitignore
├── DirectMLTest.cpp
└── d3dx12.h
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/.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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/.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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------