ShaderOpTest.cpp 93 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // //
  3. // ShaderOpTest.cpp //
  4. // Copyright (C) Microsoft Corporation. All rights reserved. //
  5. // This file is distributed under the University of Illinois Open Source //
  6. // License. See LICENSE.TXT for details. //
  7. // //
  8. // Provides the implementation to run tests based on descriptions. //
  9. // //
  10. ///////////////////////////////////////////////////////////////////////////////
  11. // We need to keep & fix these warnings to integrate smoothly with HLK
  12. #pragma warning(error: 4100 4146 4242 4244 4267 4701 4389)
  13. #include <windows.h>
  14. #include <d3d12.h>
  15. #include <dxgi1_4.h>
  16. #include "dxc/Support/d3dx12.h"
  17. #include <d3dcompiler.h>
  18. #include <atlbase.h>
  19. #include <atlenc.h>
  20. #include "ShaderOpTest.h"
  21. #include "dxc/dxcapi.h" // IDxcCompiler
  22. #include "dxc/Support/Global.h" // OutputDebugBytes
  23. #include "dxc/Support/Unicode.h" // IsStarMatchUTF16
  24. #include "dxc/Support/dxcapi.use.h" // DxcDllSupport
  25. #include "dxc/DXIL/DxilConstants.h" // ComponentType
  26. #include "WexTestClass.h" // TAEF
  27. #include "HLSLTestUtils.h" // LogCommentFmt
  28. #include <stdlib.h>
  29. #include <DirectXMath.h>
  30. #include <intsafe.h>
  31. #include <strsafe.h>
  32. #include <xmllite.h>
  33. #pragma comment(lib, "xmllite.lib")
  34. ///////////////////////////////////////////////////////////////////////////////
  35. // Useful helper functions.
  36. static st::OutputStringFn g_OutputStrFn;
  37. static void * g_OutputStrFnCtx;
  38. void st::SetOutputFn(void *pCtx, OutputStringFn F) {
  39. g_OutputStrFnCtx = pCtx;
  40. g_OutputStrFn = F;
  41. }
  42. static void ShaderOpLogFmt(_In_z_ _Printf_format_string_ const wchar_t *fmt, ...) {
  43. va_list args;
  44. va_start(args, fmt);
  45. std::wstring buf(hlsl_test::vFormatToWString(fmt, args));
  46. va_end(args);
  47. if (g_OutputStrFn == nullptr)
  48. WEX::Logging::Log::Comment(buf.data());
  49. else
  50. g_OutputStrFn(g_OutputStrFnCtx, buf.data());
  51. }
  52. // Rely on TAEF Verifier helpers.
  53. #define CHECK_HR(x) { \
  54. if (!g_OutputStrFn) VERIFY_SUCCEEDED(x); else { \
  55. HRESULT _check_hr = (x); \
  56. if (FAILED(_check_hr)) AtlThrow(x); } \
  57. }
  58. // Check the specified HRESULT and return the success value.
  59. static HRESULT CHECK_HR_RET(HRESULT hr) {
  60. CHECK_HR(hr);
  61. return hr;
  62. }
  63. HRESULT LogIfLost(HRESULT hr, ID3D12Device *pDevice) {
  64. if (hr == DXGI_ERROR_DEVICE_REMOVED) {
  65. HRESULT reason = pDevice->GetDeviceRemovedReason();
  66. LPCWSTR reasonText = L"?";
  67. if (reason == DXGI_ERROR_DEVICE_HUNG) reasonText = L"DXGI_ERROR_DEVICE_HUNG";
  68. if (reason == DXGI_ERROR_DEVICE_REMOVED) reasonText = L"DXGI_ERROR_DEVICE_REMOVED";
  69. if (reason == DXGI_ERROR_DEVICE_RESET) reasonText = L"DXGI_ERROR_DEVICE_RESET";
  70. if (reason == DXGI_ERROR_DRIVER_INTERNAL_ERROR) reasonText = L"DXGI_ERROR_DRIVER_INTERNAL_ERROR";
  71. if (reason == DXGI_ERROR_INVALID_CALL) reasonText = L"DXGI_ERROR_INVALID_CALL";
  72. ShaderOpLogFmt(L"Device lost: 0x%08x (%s)", reason, reasonText);
  73. }
  74. return hr;
  75. }
  76. HRESULT LogIfLost(HRESULT hr, ID3D12Resource *pResource) {
  77. if (hr == DXGI_ERROR_DEVICE_REMOVED) {
  78. CComPtr<ID3D12Device> pDevice;
  79. pResource->GetDevice(__uuidof(ID3D12Device), (void**)&pDevice);
  80. LogIfLost(hr, pDevice);
  81. }
  82. return hr;
  83. }
  84. bool UseHardwareDevice(const DXGI_ADAPTER_DESC1 &desc, LPCWSTR AdapterName) {
  85. if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) {
  86. // Don't select the Basic Render Driver adapter.
  87. return false;
  88. }
  89. if (!AdapterName)
  90. return true;
  91. return Unicode::IsStarMatchUTF16(AdapterName, wcslen(AdapterName),
  92. desc.Description, wcslen(desc.Description));
  93. }
  94. void GetHardwareAdapter(IDXGIFactory2 *pFactory, LPCWSTR AdapterName,
  95. IDXGIAdapter1 **ppAdapter) {
  96. CComPtr<IDXGIAdapter1> adapter;
  97. *ppAdapter = nullptr;
  98. for (UINT adapterIndex = 0;
  99. DXGI_ERROR_NOT_FOUND != pFactory->EnumAdapters1(adapterIndex, &adapter);
  100. ++adapterIndex) {
  101. DXGI_ADAPTER_DESC1 desc;
  102. adapter->GetDesc1(&desc);
  103. if (!UseHardwareDevice(desc, AdapterName)) {
  104. adapter.Release();
  105. continue;
  106. }
  107. // Check to see if the adapter supports Direct3D 12, but don't create the
  108. // actual device yet.
  109. if (SUCCEEDED(D3D12CreateDevice(adapter, D3D_FEATURE_LEVEL_11_0,
  110. _uuidof(ID3D12Device), nullptr))) {
  111. break;
  112. }
  113. adapter.Release();
  114. }
  115. *ppAdapter = adapter.Detach();
  116. }
  117. void RecordTransitionBarrier(ID3D12GraphicsCommandList *pCommandList,
  118. ID3D12Resource *pResource,
  119. D3D12_RESOURCE_STATES before,
  120. D3D12_RESOURCE_STATES after) {
  121. CD3DX12_RESOURCE_BARRIER barrier(
  122. CD3DX12_RESOURCE_BARRIER::Transition(pResource, before, after));
  123. pCommandList->ResourceBarrier(1, &barrier);
  124. }
  125. void ExecuteCommandList(ID3D12CommandQueue *pQueue, ID3D12CommandList *pList) {
  126. ID3D12CommandList *ppCommandLists[] = { pList };
  127. pQueue->ExecuteCommandLists(1, ppCommandLists);
  128. }
  129. HRESULT SetObjectName(ID3D12Object *pObject, LPCSTR pName) {
  130. if (pObject && pName) {
  131. CA2W WideName(pName);
  132. return pObject->SetName(WideName);
  133. }
  134. return S_FALSE;
  135. }
  136. void WaitForSignal(ID3D12CommandQueue *pCQ, ID3D12Fence *pFence,
  137. HANDLE hFence, UINT64 fenceValue) {
  138. // Signal and increment the fence value.
  139. const UINT64 fence = fenceValue;
  140. CHECK_HR(pCQ->Signal(pFence, fence));
  141. if (pFence->GetCompletedValue() < fenceValue) {
  142. CHECK_HR(pFence->SetEventOnCompletion(fenceValue, hFence));
  143. WaitForSingleObject(hFence, INFINITE);
  144. //CHECK_HR(pCQ->Wait(pFence, fenceValue));
  145. }
  146. }
  147. static void SetupComputeValuePattern(std::vector<uint32_t> &values, size_t count) {
  148. values.resize(count); // one element per dispatch group, in bytes
  149. for (size_t i = 0; i < count; ++i) {
  150. values[i] = (uint32_t)i;
  151. }
  152. }
  153. void MappedData::dump() const {
  154. OutputDebugBytes(m_pData, m_size);
  155. }
  156. void MappedData::reset() {
  157. if (m_pResource != nullptr) {
  158. m_pResource->Unmap(0, nullptr);
  159. m_pResource.Release();
  160. }
  161. m_pData = nullptr;
  162. }
  163. ///////////////////////////////////////////////////////////////////////////////
  164. // Helper class for mapped data.
  165. void MappedData::reset(ID3D12Resource *pResource, UINT32 sizeInBytes) {
  166. reset();
  167. D3D12_RANGE r;
  168. r.Begin = 0;
  169. r.End = sizeInBytes;
  170. CHECK_HR(LogIfLost(pResource->Map(0, &r, &m_pData), pResource));
  171. m_pResource = pResource;
  172. m_size = sizeInBytes;
  173. }
  174. ///////////////////////////////////////////////////////////////////////////////
  175. // ShaderOpTest library implementation.
  176. namespace st {
  177. LPCSTR string_table::insert(LPCSTR pValue) {
  178. std::unordered_set<LPCSTR, HashStr, PredStr>::iterator i = m_values.find(pValue);
  179. if (i == m_values.end()) {
  180. size_t bufSize = strlen(pValue) + 1;
  181. std::vector<char> s;
  182. s.resize(bufSize);
  183. strcpy_s(s.data(), bufSize, pValue);
  184. LPCSTR result = s.data();
  185. m_values.insert(result);
  186. m_strings.push_back(std::move(s));
  187. return result;
  188. }
  189. else {
  190. return *i;
  191. }
  192. }
  193. LPCSTR string_table::insert(LPCWSTR pValue) {
  194. CW2A pValueAnsi(pValue);
  195. return insert(pValueAnsi.m_psz);
  196. }
  197. void CommandListRefs::CreateForDevice(ID3D12Device *pDevice, bool compute) {
  198. D3D12_COMMAND_LIST_TYPE T = compute ? D3D12_COMMAND_LIST_TYPE_COMPUTE
  199. : D3D12_COMMAND_LIST_TYPE_DIRECT;
  200. D3D12_COMMAND_QUEUE_DESC queueDesc = {};
  201. queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
  202. queueDesc.Type = T;
  203. if (Queue == nullptr) {
  204. CHECK_HR(pDevice->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&Queue)));
  205. }
  206. CHECK_HR(pDevice->CreateCommandAllocator(T, IID_PPV_ARGS(&Allocator)));
  207. CHECK_HR(pDevice->CreateCommandList(0, T, Allocator, nullptr,
  208. IID_PPV_ARGS(&List)));
  209. }
  210. void ShaderOpTest::CopyBackResources() {
  211. CommandListRefs ResCommandList;
  212. ResCommandList.CreateForDevice(m_pDevice, m_pShaderOp->IsCompute());
  213. ID3D12GraphicsCommandList *pList = ResCommandList.List;
  214. pList->SetName(L"ShaderOpTest Resource ReadBack CommandList");
  215. for (ShaderOpResource &R : m_pShaderOp->Resources) {
  216. if (!R.ReadBack)
  217. continue;
  218. ShaderOpResourceData &D = m_ResourceData[R.Name];
  219. RecordTransitionBarrier(pList, D.Resource, D.ResourceState,
  220. D3D12_RESOURCE_STATE_COPY_SOURCE);
  221. D.ResourceState = D3D12_RESOURCE_STATE_COPY_SOURCE;
  222. D3D12_RESOURCE_DESC &Desc = D.ShaderOpRes->Desc;
  223. if (Desc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) {
  224. pList->CopyResource(D.ReadBack, D.Resource);
  225. }
  226. else {
  227. UINT64 rowPitch = Desc.Width * GetByteSizeForFormat(Desc.Format);
  228. if (rowPitch % D3D12_TEXTURE_DATA_PITCH_ALIGNMENT)
  229. rowPitch += D3D12_TEXTURE_DATA_PITCH_ALIGNMENT - (rowPitch % D3D12_TEXTURE_DATA_PITCH_ALIGNMENT);
  230. D3D12_PLACED_SUBRESOURCE_FOOTPRINT Footprint;
  231. Footprint.Offset = 0;
  232. Footprint.Footprint = CD3DX12_SUBRESOURCE_FOOTPRINT(Desc.Format, (UINT)Desc.Width, Desc.Height, 1, (UINT)rowPitch);
  233. CD3DX12_TEXTURE_COPY_LOCATION DstLoc(D.ReadBack, Footprint);
  234. CD3DX12_TEXTURE_COPY_LOCATION SrcLoc(D.Resource, 0);
  235. pList->CopyTextureRegion(&DstLoc, 0, 0, 0, &SrcLoc, nullptr);
  236. }
  237. }
  238. pList->Close();
  239. ExecuteCommandList(ResCommandList.Queue, pList);
  240. WaitForSignal(ResCommandList.Queue, m_pFence, m_hFence, m_FenceValue++);
  241. }
  242. void ShaderOpTest::CreateCommandList() {
  243. bool priorQueue = m_CommandList.Queue != nullptr;
  244. m_CommandList.CreateForDevice(m_pDevice, m_pShaderOp->IsCompute());
  245. m_CommandList.Allocator->SetName(L"ShaderOpTest Allocator");
  246. m_CommandList.List->SetName(L"ShaderOpTest CommandList");
  247. if (!priorQueue)
  248. m_CommandList.Queue->SetName(L"ShaderOpTest CommandList");
  249. }
  250. void ShaderOpTest::CreateDescriptorHeaps() {
  251. for (ShaderOpDescriptorHeap &H : m_pShaderOp->DescriptorHeaps) {
  252. CComPtr<ID3D12DescriptorHeap> pHeap;
  253. if (H.Desc.NumDescriptors == 0) {
  254. H.Desc.NumDescriptors = (UINT)H.Descriptors.size();
  255. }
  256. CHECK_HR(m_pDevice->CreateDescriptorHeap(&H.Desc, IID_PPV_ARGS(&pHeap)));
  257. m_DescriptorHeaps.push_back(pHeap);
  258. m_DescriptorHeapsByName[H.Name] = pHeap;
  259. SetObjectName(pHeap, H.Name);
  260. const UINT descriptorSize = m_pDevice->GetDescriptorHandleIncrementSize(H.Desc.Type);
  261. CD3DX12_CPU_DESCRIPTOR_HANDLE cpuHandle(pHeap->GetCPUDescriptorHandleForHeapStart());
  262. CD3DX12_GPU_DESCRIPTOR_HANDLE gpuHandle = {};
  263. if (H.Desc.Type != D3D12_DESCRIPTOR_HEAP_TYPE_RTV)
  264. gpuHandle = CD3DX12_GPU_DESCRIPTOR_HANDLE(pHeap->GetGPUDescriptorHandleForHeapStart());
  265. for (ShaderOpDescriptor &D : H.Descriptors) {
  266. ShaderOpResource *R = m_pShaderOp->GetResourceByName(D.ResName);
  267. if (R == nullptr) {
  268. LPCSTR DescName = D.Name ? D.Name : "[unnamed descriptor]";
  269. ShaderOpLogFmt(L"Descriptor '%S' references missing resource '%S'", DescName, D.ResName);
  270. CHECK_HR(E_INVALIDARG);
  271. }
  272. ShaderOpResourceData &Data = m_ResourceData[D.ResName];
  273. ShaderOpDescriptorData DData;
  274. DData.Descriptor = &D;
  275. DData.ResData = &Data;
  276. if (0 == _stricmp(D.Kind, "UAV")) {
  277. ID3D12Resource *pCounterResource = nullptr;
  278. if (D.CounterName && *D.CounterName) {
  279. ShaderOpResourceData &CounterData = m_ResourceData[D.CounterName];
  280. pCounterResource = CounterData.Resource;
  281. }
  282. m_pDevice->CreateUnorderedAccessView(Data.Resource, pCounterResource,
  283. &D.UavDesc, cpuHandle);
  284. }
  285. else if (0 == _stricmp(D.Kind, "SRV")) {
  286. D3D12_SHADER_RESOURCE_VIEW_DESC *pSrvDesc = nullptr;
  287. if (D.SrvDescPresent) {
  288. pSrvDesc = &D.SrvDesc;
  289. }
  290. m_pDevice->CreateShaderResourceView(Data.Resource, pSrvDesc, cpuHandle);
  291. }
  292. else if (0 == _stricmp(D.Kind, "RTV")) {
  293. m_pDevice->CreateRenderTargetView(Data.Resource, nullptr, cpuHandle);
  294. }
  295. else if (0 == _stricmp(D.Kind, "CBV")) {
  296. D3D12_CONSTANT_BUFFER_VIEW_DESC cbvDesc;
  297. cbvDesc.BufferLocation = Data.Resource->GetGPUVirtualAddress();
  298. cbvDesc.SizeInBytes = (UINT)Data.Resource->GetDesc().Width;
  299. m_pDevice->CreateConstantBufferView(&cbvDesc, cpuHandle);
  300. }
  301. DData.CPUHandle = cpuHandle;
  302. m_DescriptorData[R->Name] = DData;
  303. cpuHandle = cpuHandle.Offset(descriptorSize);
  304. if (H.Desc.Type != D3D12_DESCRIPTOR_HEAP_TYPE_RTV) {
  305. DData.GPUHandle = gpuHandle;
  306. gpuHandle = gpuHandle.Offset(descriptorSize);
  307. }
  308. }
  309. }
  310. // Create query descriptor heap.
  311. D3D12_QUERY_HEAP_DESC queryHeapDesc;
  312. ZeroMemory(&queryHeapDesc, sizeof(queryHeapDesc));
  313. queryHeapDesc.Count = 1;
  314. queryHeapDesc.Type = D3D12_QUERY_HEAP_TYPE_PIPELINE_STATISTICS;
  315. CHECK_HR(m_pDevice->CreateQueryHeap(&queryHeapDesc, IID_PPV_ARGS(&m_pQueryHeap)));
  316. }
  317. void ShaderOpTest::CreateDevice() {
  318. if (m_pDevice == nullptr) {
  319. const D3D_FEATURE_LEVEL FeatureLevelRequired = D3D_FEATURE_LEVEL_11_0;
  320. CComPtr<IDXGIFactory4> factory;
  321. CComPtr<ID3D12Device> pDevice;
  322. CHECK_HR(CreateDXGIFactory1(IID_PPV_ARGS(&factory)));
  323. if (m_pShaderOp->UseWarpDevice) {
  324. CComPtr<IDXGIAdapter> warpAdapter;
  325. CHECK_HR(factory->EnumWarpAdapter(IID_PPV_ARGS(&warpAdapter)));
  326. CHECK_HR(D3D12CreateDevice(warpAdapter, FeatureLevelRequired,
  327. IID_PPV_ARGS(&pDevice)));
  328. } else {
  329. CComPtr<IDXGIAdapter1> hardwareAdapter;
  330. GetHardwareAdapter(factory, m_pShaderOp->AdapterName, &hardwareAdapter);
  331. if (hardwareAdapter == nullptr) {
  332. CHECK_HR(HRESULT_FROM_WIN32(ERROR_NOT_FOUND));
  333. }
  334. CHECK_HR(D3D12CreateDevice(hardwareAdapter, FeatureLevelRequired,
  335. IID_PPV_ARGS(&pDevice)));
  336. }
  337. m_pDevice.Attach(pDevice.Detach());
  338. m_pDevice->SetName(L"ShaderOpTest Device");
  339. }
  340. m_FenceValue = 1;
  341. CHECK_HR(m_pDevice->CreateFence(0, D3D12_FENCE_FLAG_NONE,
  342. __uuidof(ID3D12Fence), (void **)&m_pFence));
  343. m_pFence->SetName(L"ShaderOpTest Fence");
  344. m_hFence = CreateEvent(nullptr, FALSE, FALSE, nullptr);
  345. if (m_hFence == nullptr) {
  346. AtlThrow(HRESULT_FROM_WIN32(GetLastError()));
  347. }
  348. }
  349. static void InitByteCode(D3D12_SHADER_BYTECODE *pBytecode, ID3D10Blob *pBlob) {
  350. if (pBlob == nullptr) {
  351. pBytecode->BytecodeLength = 0;
  352. pBytecode->pShaderBytecode = nullptr;
  353. }
  354. else {
  355. pBytecode->BytecodeLength = pBlob->GetBufferSize();
  356. pBytecode->pShaderBytecode = pBlob->GetBufferPointer();
  357. }
  358. }
  359. template <typename TKey, typename TValue>
  360. TValue map_get_or_null(const std::map<TKey, TValue> &amap, const TKey& key) {
  361. auto it = amap.find(key);
  362. if (it == amap.end()) return nullptr;
  363. return (*it).second;
  364. }
  365. void ShaderOpTest::CreatePipelineState() {
  366. CreateRootSignature();
  367. CreateShaders();
  368. if (m_pShaderOp->IsCompute()) {
  369. CComPtr<ID3D10Blob> pCS;
  370. pCS = m_Shaders[m_pShaderOp->CS];
  371. D3D12_COMPUTE_PIPELINE_STATE_DESC CDesc;
  372. ZeroMemory(&CDesc, sizeof(CDesc));
  373. CDesc.pRootSignature = m_pRootSignature.p;
  374. InitByteCode(&CDesc.CS, pCS);
  375. CHECK_HR(m_pDevice->CreateComputePipelineState(&CDesc, IID_PPV_ARGS(&m_pPSO)));
  376. }
  377. // Wakanda technology, needs vibranium to work
  378. #if defined(NTDDI_WIN10_VB) && WDK_NTDDI_VERSION >= NTDDI_WIN10_VB
  379. else if (m_pShaderOp->MS) {
  380. // A couple types from a future version of d3dx12.h
  381. typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< D3D12_SHADER_BYTECODE, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_MS> CD3DX12_PIPELINE_STATE_STREAM_MS;
  382. typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< D3D12_SHADER_BYTECODE, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_AS> CD3DX12_PIPELINE_STATE_STREAM_AS;
  383. struct D3DX12_MESH_SHADER_PIPELINE_STATE_DESC
  384. {
  385. CD3DX12_PIPELINE_STATE_STREAM_ROOT_SIGNATURE RootSignature;
  386. CD3DX12_PIPELINE_STATE_STREAM_AS AS;
  387. CD3DX12_PIPELINE_STATE_STREAM_MS MS;
  388. CD3DX12_PIPELINE_STATE_STREAM_PS PS;
  389. CD3DX12_PIPELINE_STATE_STREAM_PRIMITIVE_TOPOLOGY PrimitiveTopologyType;
  390. CD3DX12_PIPELINE_STATE_STREAM_SAMPLE_MASK SampleMask;
  391. CD3DX12_PIPELINE_STATE_STREAM_RENDER_TARGET_FORMATS RTVFormats;
  392. } MDesc = {};
  393. CComPtr<ID3D10Blob> pAS, pMS, pPS;
  394. pAS = map_get_or_null(m_Shaders, m_pShaderOp->AS);
  395. pMS = map_get_or_null(m_Shaders, m_pShaderOp->MS);
  396. pPS = map_get_or_null(m_Shaders, m_pShaderOp->PS);
  397. ZeroMemory(&MDesc, sizeof(MDesc));
  398. MDesc.RootSignature = CD3DX12_PIPELINE_STATE_STREAM_ROOT_SIGNATURE(m_pRootSignature.p);
  399. D3D12_SHADER_BYTECODE BC;
  400. InitByteCode(&BC, pAS);
  401. MDesc.AS = CD3DX12_PIPELINE_STATE_STREAM_AS(BC);
  402. InitByteCode(&BC, pMS);
  403. MDesc.MS = CD3DX12_PIPELINE_STATE_STREAM_MS(BC);
  404. InitByteCode(&BC, pPS);
  405. MDesc.PS = CD3DX12_PIPELINE_STATE_STREAM_PS(BC);
  406. MDesc.PrimitiveTopologyType = CD3DX12_PIPELINE_STATE_STREAM_PRIMITIVE_TOPOLOGY(m_pShaderOp->PrimitiveTopologyType);
  407. MDesc.SampleMask = CD3DX12_PIPELINE_STATE_STREAM_SAMPLE_MASK(m_pShaderOp->SampleMask);
  408. D3D12_RT_FORMAT_ARRAY RtArray;
  409. ZeroMemory(&RtArray, sizeof(RtArray));
  410. RtArray.NumRenderTargets = (UINT)m_pShaderOp->RenderTargets.size();
  411. for (size_t i = 0; i < RtArray.NumRenderTargets; ++i) {
  412. ShaderOpResource *R = m_pShaderOp->GetResourceByName(m_pShaderOp->RenderTargets[i].Name);
  413. RtArray.RTFormats[i] = R->Desc.Format;
  414. }
  415. MDesc.RTVFormats = CD3DX12_PIPELINE_STATE_STREAM_RENDER_TARGET_FORMATS(RtArray);
  416. D3D12_PIPELINE_STATE_STREAM_DESC PDesc = {};
  417. PDesc.SizeInBytes = sizeof(MDesc);
  418. PDesc.pPipelineStateSubobjectStream = &MDesc;
  419. CComPtr<ID3D12Device2> pDevice2;
  420. CHECK_HR(m_pDevice->QueryInterface(&pDevice2));
  421. CHECK_HR(pDevice2->CreatePipelineState(&PDesc, IID_PPV_ARGS(&m_pPSO)));
  422. }
  423. #endif
  424. else {
  425. CComPtr<ID3D10Blob> pVS, pDS, pHS, pGS, pPS;
  426. pPS = map_get_or_null(m_Shaders, m_pShaderOp->PS);
  427. pVS = map_get_or_null(m_Shaders, m_pShaderOp->VS);
  428. pGS = map_get_or_null(m_Shaders, m_pShaderOp->GS);
  429. pHS = map_get_or_null(m_Shaders, m_pShaderOp->HS);
  430. pDS = map_get_or_null(m_Shaders, m_pShaderOp->DS);
  431. D3D12_GRAPHICS_PIPELINE_STATE_DESC GDesc;
  432. ZeroMemory(&GDesc, sizeof(GDesc));
  433. InitByteCode(&GDesc.VS, pVS);
  434. InitByteCode(&GDesc.HS, pHS);
  435. InitByteCode(&GDesc.DS, pDS);
  436. InitByteCode(&GDesc.GS, pGS);
  437. InitByteCode(&GDesc.PS, pPS);
  438. GDesc.InputLayout.NumElements = (UINT)m_pShaderOp->InputElements.size();
  439. GDesc.InputLayout.pInputElementDescs = m_pShaderOp->InputElements.data();
  440. GDesc.PrimitiveTopologyType = m_pShaderOp->PrimitiveTopologyType;
  441. GDesc.NumRenderTargets = (UINT)m_pShaderOp->RenderTargets.size();
  442. GDesc.SampleMask = m_pShaderOp->SampleMask;
  443. for (size_t i = 0; i < m_pShaderOp->RenderTargets.size(); ++i) {
  444. ShaderOpResource *R = m_pShaderOp->GetResourceByName(m_pShaderOp->RenderTargets[i].Name);
  445. GDesc.RTVFormats[i] = R->Desc.Format;
  446. }
  447. GDesc.SampleDesc.Count = 1; // TODO: read from file, set from shader operation; also apply to count
  448. GDesc.RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT); // TODO: read from file, set from op
  449. GDesc.BlendState = CD3DX12_BLEND_DESC(D3D12_DEFAULT); // TODO: read from file, set from op
  450. // TODO: pending values to set
  451. #if 0
  452. D3D12_STREAM_OUTPUT_DESC StreamOutput;
  453. D3D12_DEPTH_STENCIL_DESC DepthStencilState;
  454. D3D12_INDEX_BUFFER_STRIP_CUT_VALUE IBStripCutValue;
  455. DXGI_FORMAT DSVFormat;
  456. UINT NodeMask;
  457. D3D12_PIPELINE_STATE_FLAGS Flags;
  458. #endif
  459. GDesc.pRootSignature = m_pRootSignature.p;
  460. CHECK_HR(m_pDevice->CreateGraphicsPipelineState(&GDesc, IID_PPV_ARGS(&m_pPSO)));
  461. }
  462. }
  463. void ShaderOpTest::CreateResources() {
  464. CommandListRefs ResCommandList;
  465. ResCommandList.CreateForDevice(m_pDevice, true);
  466. ResCommandList.Allocator->SetName(L"ShaderOpTest Resource Creation Allocation");
  467. ResCommandList.Queue->SetName(L"ShaderOpTest Resource Creation Queue");
  468. ResCommandList.List->SetName(L"ShaderOpTest Resource Creation CommandList");
  469. ID3D12GraphicsCommandList *pList = ResCommandList.List.p;
  470. std::vector<CComPtr<ID3D12Resource> > intermediates;
  471. for (ShaderOpResource &R : m_pShaderOp->Resources) {
  472. if (m_ResourceData.count(R.Name) > 0) continue;
  473. // Initialize the upload resource early, to allow a by-name initializer
  474. // to set the desired width.
  475. bool initByName = R.Init && 0 == _stricmp("byname", R.Init);
  476. bool initZero = R.Init && 0 == _stricmp("zero", R.Init);
  477. bool initFromBytes = R.Init && 0 == _stricmp("frombytes", R.Init);
  478. bool hasInit = initByName || initZero || initFromBytes;
  479. bool isBuffer = R.Desc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER;
  480. std::vector<BYTE> values;
  481. if (hasInit) {
  482. if (isBuffer) {
  483. values.resize((size_t)R.Desc.Width);
  484. }
  485. else {
  486. // Probably needs more information.
  487. values.resize((size_t)(R.Desc.Width * R.Desc.Height *
  488. GetByteSizeForFormat(R.Desc.Format)));
  489. }
  490. if (initZero) {
  491. memset(values.data(), 0, values.size());
  492. }
  493. else if (initByName) {
  494. m_InitCallbackFn(R.Name, values, m_pShaderOp);
  495. if (isBuffer) {
  496. R.Desc.Width = values.size();
  497. }
  498. }
  499. else if (initFromBytes) {
  500. values = R.InitBytes;
  501. if (R.Desc.Width == 0) {
  502. if (isBuffer) {
  503. R.Desc.Width = values.size();
  504. }
  505. else if (R.Desc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE1D) {
  506. R.Desc.Width = values.size() / GetByteSizeForFormat(R.Desc.Format);
  507. }
  508. }
  509. }
  510. }
  511. if (!R.Desc.MipLevels)
  512. R.Desc.MipLevels = 1;
  513. CComPtr<ID3D12Resource> pResource;
  514. CHECK_HR(m_pDevice->CreateCommittedResource(
  515. &R.HeapProperties, R.HeapFlags, &R.Desc, R.InitialResourceState,
  516. nullptr, IID_PPV_ARGS(&pResource)));
  517. ShaderOpResourceData &D = m_ResourceData[R.Name];
  518. D.ShaderOpRes = &R;
  519. D.Resource = pResource;
  520. D.ResourceState = R.InitialResourceState;
  521. SetObjectName(pResource, R.Name);
  522. if (hasInit) {
  523. CComPtr<ID3D12Resource> pIntermediate;
  524. CD3DX12_HEAP_PROPERTIES upload(D3D12_HEAP_TYPE_UPLOAD);
  525. D3D12_RESOURCE_DESC uploadDesc = R.Desc;
  526. // Calculate size required for intermediate buffer
  527. UINT64 totalBytes;
  528. m_pDevice->GetCopyableFootprints(&uploadDesc, 0, R.Desc.MipLevels, 0, nullptr, nullptr, nullptr, &totalBytes);
  529. if (!isBuffer) {
  530. // Assuming a simple linear layout here.
  531. uploadDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
  532. uploadDesc.Width = totalBytes;
  533. uploadDesc.Height = 1;
  534. uploadDesc.MipLevels = 1;
  535. uploadDesc.Format = DXGI_FORMAT_UNKNOWN;
  536. uploadDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
  537. }
  538. uploadDesc.Flags = D3D12_RESOURCE_FLAG_NONE;
  539. CHECK_HR(m_pDevice->CreateCommittedResource(
  540. &upload, D3D12_HEAP_FLAG_NONE, &uploadDesc,
  541. D3D12_RESOURCE_STATE_GENERIC_READ, nullptr,
  542. IID_PPV_ARGS(&pIntermediate)));
  543. intermediates.push_back(pIntermediate);
  544. char uploadObjectName[128];
  545. if (R.Name && SUCCEEDED(StringCchPrintfA(
  546. uploadObjectName, _countof(uploadObjectName),
  547. "Upload resource for %s", R.Name))) {
  548. SetObjectName(pIntermediate, uploadObjectName);
  549. }
  550. D3D12_SUBRESOURCE_DATA transferData[16];
  551. UINT width = (UINT)R.Desc.Width;
  552. UINT height = R.Desc.Height;
  553. UINT pixelSize = GetByteSizeForFormat(R.Desc.Format);
  554. BYTE *data = values.data();
  555. VERIFY_IS_TRUE(R.Desc.MipLevels <= 16);
  556. for (UINT i = 0; i < R.Desc.MipLevels; i++) {
  557. if(!height) height = 1;
  558. if(!width) width = 1;
  559. transferData[i].pData = data;
  560. transferData[i].RowPitch = width*pixelSize;
  561. transferData[i].SlicePitch = width*height*pixelSize;
  562. data += width*height*pixelSize;
  563. height >>= 1;
  564. width >>= 1;
  565. }
  566. UpdateSubresources<16>(pList, pResource.p, pIntermediate.p, 0, 0, R.Desc.MipLevels,
  567. transferData);
  568. }
  569. if (R.ReadBack) {
  570. CComPtr<ID3D12Resource> pReadbackResource;
  571. CD3DX12_HEAP_PROPERTIES readback(D3D12_HEAP_TYPE_READBACK);
  572. UINT64 width = R.Desc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER
  573. ? R.Desc.Width
  574. : (R.Desc.Height * R.Desc.Width *
  575. GetByteSizeForFormat(R.Desc.Format));
  576. CD3DX12_RESOURCE_DESC readbackDesc(CD3DX12_RESOURCE_DESC::Buffer(width));
  577. readbackDesc.Flags = D3D12_RESOURCE_FLAG_NONE;
  578. CHECK_HR(m_pDevice->CreateCommittedResource(
  579. &readback, D3D12_HEAP_FLAG_NONE, &readbackDesc,
  580. D3D12_RESOURCE_STATE_COPY_DEST, nullptr,
  581. IID_PPV_ARGS(&pReadbackResource)));
  582. D.ReadBack = pReadbackResource;
  583. char readbackObjectName[128];
  584. if (R.Name && SUCCEEDED(StringCchPrintfA(
  585. readbackObjectName, _countof(readbackObjectName),
  586. "Readback resource for %s", R.Name))) {
  587. SetObjectName(pReadbackResource, readbackObjectName);
  588. }
  589. }
  590. if (R.TransitionTo != D.ResourceState) {
  591. RecordTransitionBarrier(pList, D.Resource, D.ResourceState,
  592. R.TransitionTo);
  593. D.ResourceState = R.TransitionTo;
  594. }
  595. }
  596. // Create a buffer to receive query results.
  597. {
  598. CComPtr<ID3D12Resource> pReadbackResource;
  599. CD3DX12_HEAP_PROPERTIES readback(D3D12_HEAP_TYPE_READBACK);
  600. CD3DX12_RESOURCE_DESC readbackDesc(CD3DX12_RESOURCE_DESC::Buffer(sizeof(D3D12_QUERY_DATA_PIPELINE_STATISTICS)));
  601. CHECK_HR(m_pDevice->CreateCommittedResource(
  602. &readback, D3D12_HEAP_FLAG_NONE, &readbackDesc,
  603. D3D12_RESOURCE_STATE_COPY_DEST, nullptr,
  604. IID_PPV_ARGS(&m_pQueryBuffer)));
  605. SetObjectName(m_pQueryBuffer, "Query Pipeline Readback Buffer");
  606. }
  607. CHECK_HR(pList->Close());
  608. ExecuteCommandList(ResCommandList.Queue, pList);
  609. WaitForSignal(ResCommandList.Queue, m_pFence, m_hFence, m_FenceValue++);
  610. }
  611. void ShaderOpTest::CreateRootSignature() {
  612. if (m_pShaderOp->RootSignature == nullptr) {
  613. AtlThrow(E_INVALIDARG);
  614. }
  615. CComPtr<ID3DBlob> pCode;
  616. CComPtr<ID3DBlob> pRootSignatureBlob;
  617. CComPtr<ID3DBlob> pError;
  618. std::string sQuoted;
  619. sQuoted.reserve(2 + strlen(m_pShaderOp->RootSignature) + 1);
  620. sQuoted.append("\"");
  621. sQuoted.append(m_pShaderOp->RootSignature);
  622. sQuoted.append("\"");
  623. char *ch = (char *)sQuoted.data();
  624. while (*ch) {
  625. if (*ch == '\r' || *ch == '\n') *ch = ' ';
  626. ++ch;
  627. }
  628. D3D_SHADER_MACRO M[2] = {
  629. { "RootSigVal", sQuoted.c_str() },
  630. { nullptr, nullptr }
  631. };
  632. HRESULT hr = D3DCompile(nullptr, 0, "RootSigShader", M, nullptr, sQuoted.c_str(),
  633. "rootsig_1_0", 0, 0, &pCode, &pError);
  634. if (FAILED(hr) && pError != nullptr) {
  635. ShaderOpLogFmt(L"Failed to compile root signature:\r\n%*S",
  636. (int)pError->GetBufferSize(),
  637. (LPCSTR)pError->GetBufferPointer());
  638. }
  639. CHECK_HR(hr);
  640. CHECK_HR(D3DGetBlobPart(pCode->GetBufferPointer(), pCode->GetBufferSize(),
  641. D3D_BLOB_ROOT_SIGNATURE, 0, &pRootSignatureBlob));
  642. CHECK_HR(m_pDevice->CreateRootSignature(
  643. 0, pRootSignatureBlob->GetBufferPointer(),
  644. pRootSignatureBlob->GetBufferSize(), IID_PPV_ARGS(&m_pRootSignature)));
  645. }
  646. static bool TargetUsesDxil(LPCSTR pText) {
  647. return (strlen(pText) > 3) && pText[3] >= '6'; // xx_6xx
  648. }
  649. static void splitWStringIntoVectors(LPWSTR str, wchar_t delim, std::vector<LPWSTR> &list) {
  650. if (str) {
  651. LPWSTR cur = str;
  652. list.push_back(cur);
  653. while (*cur != L'\0') {
  654. if (*cur == delim) {
  655. list.push_back(cur+1);
  656. *(cur) = L'\0';
  657. }
  658. cur++;
  659. }
  660. }
  661. }
  662. void ShaderOpTest::CreateShaders() {
  663. for (ShaderOpShader &S : m_pShaderOp->Shaders) {
  664. CComPtr<ID3DBlob> pCode;
  665. HRESULT hr = S_OK;
  666. LPCSTR pText = m_pShaderOp->GetShaderText(&S);
  667. if (S.Compiled) {
  668. int textLen = (int)strlen(pText);
  669. int decodedLen = Base64DecodeGetRequiredLength(textLen);
  670. // Length is an approximation, so we can't creat the final blob yet.
  671. std::vector<BYTE> decoded;
  672. decoded.resize(decodedLen);
  673. if (!Base64Decode(pText, textLen, decoded.data(), &decodedLen)) {
  674. ShaderOpLogFmt(L"Failed to decode compiled shader: %S\r\n", S.Name);
  675. CHECK_HR(E_FAIL);
  676. }
  677. // decodedLen should have the correct size now.
  678. CHECK_HR(D3DCreateBlob(decodedLen, &pCode));
  679. memcpy(pCode->GetBufferPointer(), decoded.data(), decodedLen);
  680. }
  681. else if (TargetUsesDxil(S.Target)) {
  682. CComPtr<IDxcCompiler> pCompiler;
  683. CComPtr<IDxcLibrary> pLibrary;
  684. CComPtr<IDxcBlobEncoding> pTextBlob;
  685. CComPtr<IDxcOperationResult> pResult;
  686. CA2W nameW(S.Name, CP_UTF8);
  687. CA2W entryPointW(S.EntryPoint, CP_UTF8);
  688. CA2W targetW(S.Target, CP_UTF8);
  689. CA2W argumentsW(S.Arguments, CP_UTF8);
  690. std::vector<LPWSTR> argumentsWList;
  691. splitWStringIntoVectors(argumentsW, L' ', argumentsWList);
  692. HRESULT resultCode;
  693. CHECK_HR(m_pDxcSupport->CreateInstance(CLSID_DxcLibrary, &pLibrary));
  694. CHECK_HR(pLibrary->CreateBlobWithEncodingFromPinned(
  695. pText, (UINT32)strlen(pText), CP_UTF8, &pTextBlob));
  696. CHECK_HR(m_pDxcSupport->CreateInstance(CLSID_DxcCompiler, &pCompiler));
  697. CHECK_HR(pCompiler->Compile(pTextBlob, nameW, entryPointW, targetW,
  698. (LPCWSTR *)argumentsWList.data(), (UINT32)argumentsWList.size(),
  699. nullptr, 0,
  700. nullptr, &pResult));
  701. CHECK_HR(pResult->GetStatus(&resultCode));
  702. if (FAILED(resultCode)) {
  703. CComPtr<IDxcBlobEncoding> errors;
  704. CHECK_HR(pResult->GetErrorBuffer(&errors));
  705. ShaderOpLogFmt(L"Failed to compile shader: %*S\r\n",
  706. (int)errors->GetBufferSize(),
  707. errors->GetBufferPointer());
  708. }
  709. CHECK_HR(resultCode);
  710. CHECK_HR(pResult->GetResult((IDxcBlob **)&pCode));
  711. #if 0 // use the following code to test compiled shader
  712. CComPtr<IDxcBlob> pCode;
  713. CHECK_HR(pResult->GetResult(&pCode));
  714. CComPtr<IDxcBlobEncoding> pBlob;
  715. CHECK_HR(pCompiler->Disassemble((IDxcBlob *)pCode, (IDxcBlobEncoding **)&pBlob));
  716. CComPtr<IDxcBlobEncoding> pUtf16Blob;
  717. pLibrary->GetBlobAsUtf16(pBlob, &pUtf16Blob);
  718. hlsl_test::LogCommentFmt(L"%*s", (int)pUtf16Blob->GetBufferSize() / 2, (LPCWSTR)pUtf16Blob->GetBufferPointer());
  719. #endif
  720. } else {
  721. CComPtr<ID3DBlob> pError;
  722. hr = D3DCompile(pText, strlen(pText), S.Name, nullptr, nullptr,
  723. S.EntryPoint, S.Target, 0, 0, &pCode, &pError);
  724. if (FAILED(hr) && pError != nullptr) {
  725. ShaderOpLogFmt(L"%*S\r\n", (int)pError->GetBufferSize(),
  726. ((LPCSTR)pError->GetBufferPointer()));
  727. }
  728. }
  729. CHECK_HR(hr);
  730. m_Shaders[S.Name] = pCode;
  731. }
  732. }
  733. void ShaderOpTest::GetPipelineStats(D3D12_QUERY_DATA_PIPELINE_STATISTICS *pStats) {
  734. MappedData M;
  735. M.reset(m_pQueryBuffer, sizeof(*pStats));
  736. memcpy(pStats, M.data(), sizeof(*pStats));
  737. }
  738. void ShaderOpTest::GetReadBackData(LPCSTR pResourceName, MappedData *pData) {
  739. pResourceName = m_pShaderOp->Strings.insert(pResourceName); // Unique
  740. ShaderOpResourceData &D = m_ResourceData.at(pResourceName);
  741. D3D12_RESOURCE_DESC Desc = D.ReadBack->GetDesc();
  742. UINT32 sizeInBytes = (UINT32)Desc.Width;
  743. pData->reset(D.ReadBack, sizeInBytes);
  744. }
  745. static void SetDescriptorHeaps(ID3D12GraphicsCommandList *pList,
  746. std::vector<ID3D12DescriptorHeap *> &heaps) {
  747. if (heaps.empty())
  748. return;
  749. std::vector<ID3D12DescriptorHeap *> localHeaps;
  750. for (auto &H : heaps) {
  751. if (H->GetDesc().Flags & D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE) {
  752. localHeaps.push_back(H);
  753. }
  754. }
  755. if (!localHeaps.empty())
  756. pList->SetDescriptorHeaps((UINT)localHeaps.size(), localHeaps.data());
  757. }
  758. void ShaderOpTest::RunCommandList() {
  759. ID3D12GraphicsCommandList *pList = m_CommandList.List.p;
  760. if (m_pShaderOp->IsCompute()) {
  761. pList->SetPipelineState(m_pPSO);
  762. pList->SetComputeRootSignature(m_pRootSignature);
  763. SetDescriptorHeaps(pList, m_DescriptorHeaps);
  764. SetRootValues(pList, m_pShaderOp->IsCompute());
  765. pList->Dispatch(m_pShaderOp->DispatchX, m_pShaderOp->DispatchY,
  766. m_pShaderOp->DispatchZ);
  767. } else {
  768. pList->SetPipelineState(m_pPSO);
  769. pList->SetGraphicsRootSignature(m_pRootSignature);
  770. SetDescriptorHeaps(pList, m_DescriptorHeaps);
  771. SetRootValues(pList, m_pShaderOp->IsCompute());
  772. D3D12_VIEWPORT viewport;
  773. if (!m_pShaderOp->RenderTargets.empty()) {
  774. // Use the first render target to set up the viewport and scissors.
  775. ShaderOpRenderTarget& rt = m_pShaderOp->RenderTargets[0];
  776. ShaderOpResource *R = m_pShaderOp->GetResourceByName(rt.Name);
  777. if (rt.Viewport.Width != 0 && rt.Viewport.Height != 0 ) {
  778. memcpy(&viewport, &rt.Viewport, sizeof(rt.Viewport));
  779. }
  780. else {
  781. memset(&viewport, 0, sizeof(viewport));
  782. viewport.Height = (FLOAT)R->Desc.Height;
  783. viewport.Width = (FLOAT)R->Desc.Width;
  784. viewport.MaxDepth = 1.0f;
  785. }
  786. pList->RSSetViewports(1, &viewport);
  787. D3D12_RECT scissorRect;
  788. memset(&scissorRect, 0, sizeof(scissorRect));
  789. scissorRect.right = (LONG)viewport.Width;
  790. scissorRect.bottom = (LONG)viewport.Height;
  791. pList->RSSetScissorRects(1, &scissorRect);
  792. }
  793. // Indicate that the buffers will be used as render targets.
  794. D3D12_CPU_DESCRIPTOR_HANDLE rtvHandles[8];
  795. UINT rtvHandleCount = (UINT)m_pShaderOp->RenderTargets.size();
  796. for (size_t i = 0; i < rtvHandleCount; ++i) {
  797. auto &rt = m_pShaderOp->RenderTargets[i].Name;
  798. ShaderOpDescriptorData &DData = m_DescriptorData[rt];
  799. rtvHandles[i] = DData.CPUHandle;
  800. RecordTransitionBarrier(pList, DData.ResData->Resource,
  801. DData.ResData->ResourceState,
  802. D3D12_RESOURCE_STATE_RENDER_TARGET);
  803. DData.ResData->ResourceState = D3D12_RESOURCE_STATE_RENDER_TARGET;
  804. }
  805. pList->OMSetRenderTargets(rtvHandleCount, rtvHandles, FALSE, nullptr);
  806. const float ClearColor[4] = { 0.0f, 0.2f, 0.4f, 1.0f };
  807. pList->ClearRenderTargetView(rtvHandles[0], ClearColor, 0, nullptr);
  808. #if defined(NTDDI_WIN10_VB) && WDK_NTDDI_VERSION >= NTDDI_WIN10_VB
  809. if (m_pShaderOp->MS) {
  810. #ifndef NDEBUG
  811. D3D12_FEATURE_DATA_D3D12_OPTIONS7 O7;
  812. DXASSERT_LOCALVAR(O7, SUCCEEDED(m_pDevice->CheckFeatureSupport((D3D12_FEATURE)D3D12_FEATURE_D3D12_OPTIONS7, &O7, sizeof(O7))), "mesh shader test enabled on platform without mesh support");
  813. #endif
  814. CComPtr<ID3D12GraphicsCommandList6> pList6;
  815. CHECK_HR(m_CommandList.List.p->QueryInterface(&pList6));
  816. pList6->BeginQuery(m_pQueryHeap, D3D12_QUERY_TYPE_PIPELINE_STATISTICS, 0);
  817. pList6->DispatchMesh(1, 1, 1);
  818. pList6->EndQuery(m_pQueryHeap, D3D12_QUERY_TYPE_PIPELINE_STATISTICS, 0);
  819. pList6->ResolveQueryData(m_pQueryHeap, D3D12_QUERY_TYPE_PIPELINE_STATISTICS,
  820. 0, 1, m_pQueryBuffer, 0);
  821. } else
  822. #endif
  823. {
  824. // TODO: set all of this from m_pShaderOp.
  825. ShaderOpResourceData &VBufferData = this->m_ResourceData[m_pShaderOp->Strings.insert("VBuffer")];
  826. D3D_PRIMITIVE_TOPOLOGY topology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED;
  827. for (ShaderOpResource &resource : m_pShaderOp->Resources) {
  828. if (_strcmpi(resource.Name, "VBuffer") == 0) {
  829. topology = resource.PrimitiveTopology;
  830. break;
  831. }
  832. }
  833. pList->IASetPrimitiveTopology(topology);
  834. // Calculate the stride in bytes from the inputs, assuming linear & contiguous.
  835. UINT strideInBytes = 0;
  836. for (auto && IE : m_pShaderOp->InputElements) {
  837. strideInBytes += GetByteSizeForFormat(IE.Format);
  838. }
  839. D3D12_VERTEX_BUFFER_VIEW vertexBufferView;
  840. vertexBufferView.BufferLocation = VBufferData.Resource->GetGPUVirtualAddress();
  841. vertexBufferView.StrideInBytes = strideInBytes;
  842. vertexBufferView.SizeInBytes = (UINT)VBufferData.ShaderOpRes->Desc.Width;
  843. pList->IASetVertexBuffers(0, 1, &vertexBufferView);
  844. UINT vertexCount = vertexBufferView.SizeInBytes / vertexBufferView.StrideInBytes;
  845. UINT instanceCount = 1;
  846. UINT vertexCountPerInstance = vertexCount / instanceCount;
  847. pList->BeginQuery(m_pQueryHeap, D3D12_QUERY_TYPE_PIPELINE_STATISTICS, 0);
  848. pList->DrawInstanced(vertexCountPerInstance, instanceCount, 0, 0);
  849. pList->EndQuery(m_pQueryHeap, D3D12_QUERY_TYPE_PIPELINE_STATISTICS, 0);
  850. pList->ResolveQueryData(m_pQueryHeap, D3D12_QUERY_TYPE_PIPELINE_STATISTICS,
  851. 0, 1, m_pQueryBuffer, 0);
  852. }
  853. }
  854. CHECK_HR(pList->Close());
  855. ExecuteCommandList(m_CommandList.Queue, pList);
  856. WaitForSignal(m_CommandList.Queue, m_pFence, m_hFence, m_FenceValue++);
  857. }
  858. void ShaderOpTest::RunShaderOp(ShaderOp *pShaderOp) {
  859. m_pShaderOp = pShaderOp;
  860. CreateDevice();
  861. CreateResources();
  862. CreateDescriptorHeaps();
  863. CreatePipelineState();
  864. CreateCommandList();
  865. RunCommandList();
  866. CopyBackResources();
  867. }
  868. void ShaderOpTest::RunShaderOp(std::shared_ptr<ShaderOp> ShaderOp) {
  869. m_OrigShaderOp = ShaderOp;
  870. RunShaderOp(m_OrigShaderOp.get());
  871. }
  872. void ShaderOpTest::SetRootValues(ID3D12GraphicsCommandList *pList,
  873. bool isCompute) {
  874. for (size_t i = 0; i < m_pShaderOp->RootValues.size(); ++i) {
  875. ShaderOpRootValue &V = m_pShaderOp->RootValues[i];
  876. UINT idx = V.Index == 0 ? (UINT)i : V.Index;
  877. if (V.ResName) {
  878. auto r_it = m_ResourceData.find(V.ResName);
  879. if (r_it == m_ResourceData.end()) {
  880. ShaderOpLogFmt(L"Root value #%u refers to missing resource %S", (unsigned)i, V.ResName);
  881. CHECK_HR(E_INVALIDARG);
  882. }
  883. // Issue a warning for trying to bind textures (GPU address will return null)
  884. ShaderOpResourceData &D = r_it->second;
  885. ID3D12Resource *pRes = D.Resource;
  886. if (isCompute) {
  887. switch (D.ShaderOpRes->TransitionTo) {
  888. case D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER:
  889. pList->SetComputeRootConstantBufferView(idx,
  890. pRes->GetGPUVirtualAddress());
  891. break;
  892. case D3D12_RESOURCE_STATE_UNORDERED_ACCESS:
  893. pList->SetComputeRootUnorderedAccessView(idx,
  894. pRes->GetGPUVirtualAddress());
  895. break;
  896. case D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE:
  897. default:
  898. pList->SetComputeRootShaderResourceView(idx,
  899. pRes->GetGPUVirtualAddress());
  900. break;
  901. }
  902. }
  903. else {
  904. switch (D.ShaderOpRes->TransitionTo) {
  905. case D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER:
  906. pList->SetGraphicsRootConstantBufferView(idx,
  907. pRes->GetGPUVirtualAddress());
  908. break;
  909. case D3D12_RESOURCE_STATE_UNORDERED_ACCESS:
  910. pList->SetGraphicsRootUnorderedAccessView(idx,
  911. pRes->GetGPUVirtualAddress());
  912. break;
  913. case D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE:
  914. default:
  915. pList->SetGraphicsRootShaderResourceView(idx,
  916. pRes->GetGPUVirtualAddress());
  917. break;
  918. }
  919. }
  920. }
  921. else if (V.HeapName) {
  922. D3D12_GPU_DESCRIPTOR_HANDLE heapBase(m_DescriptorHeapsByName[V.HeapName]->GetGPUDescriptorHandleForHeapStart());
  923. if (isCompute) {
  924. pList->SetComputeRootDescriptorTable(idx, heapBase);
  925. }
  926. else {
  927. pList->SetGraphicsRootDescriptorTable(idx, heapBase);
  928. }
  929. }
  930. }
  931. }
  932. void ShaderOpTest::SetDevice(ID3D12Device *pDevice) {
  933. m_pDevice = pDevice;
  934. }
  935. void ShaderOpTest::SetDxcSupport(dxc::DxcDllSupport *pDxcSupport) {
  936. m_pDxcSupport = pDxcSupport;
  937. }
  938. void ShaderOpTest::SetInitCallback(TInitCallbackFn InitCallbackFn) {
  939. m_InitCallbackFn = InitCallbackFn;
  940. }
  941. void ShaderOpTest::SetupRenderTarget(ShaderOp *pShaderOp, ID3D12Device *pDevice,
  942. ID3D12CommandQueue *pCommandQueue,
  943. ID3D12Resource *pRenderTarget) {
  944. SetDevice(pDevice);
  945. m_CommandList.Queue = pCommandQueue;
  946. // Simplification - add the render target name if missing, set it up 'by hand' if not.
  947. if (pShaderOp->RenderTargets.empty()) {
  948. ShaderOpRenderTarget RT;
  949. RT.Name = pShaderOp->Strings.insert("RTarget");
  950. pShaderOp->RenderTargets.push_back(RT);
  951. ShaderOpResource R;
  952. ZeroMemory(&R, sizeof(R));
  953. R.Desc = pRenderTarget->GetDesc();
  954. R.Name = pShaderOp->Strings.insert("RTarget");
  955. R.HeapFlags = D3D12_HEAP_FLAG_NONE;
  956. R.Init = nullptr;
  957. R.InitialResourceState = D3D12_RESOURCE_STATE_PRESENT;
  958. R.ReadBack = FALSE;
  959. pShaderOp->Resources.push_back(R);
  960. ShaderOpResourceData &D = m_ResourceData[R.Name];
  961. D.ShaderOpRes = &pShaderOp->Resources.back();
  962. D.Resource = pRenderTarget;
  963. D.ResourceState = R.InitialResourceState;
  964. }
  965. // Create a render target heap to put this in.
  966. ShaderOpDescriptorHeap *pRtvHeap = pShaderOp->GetDescriptorHeapByName("RtvHeap");
  967. if (pRtvHeap == nullptr) {
  968. ShaderOpDescriptorHeap H;
  969. ZeroMemory(&H, sizeof(H));
  970. H.Name = pShaderOp->Strings.insert("RtvHeap");
  971. H.Desc.NumDescriptors = 1;
  972. H.Desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
  973. pShaderOp->DescriptorHeaps.push_back(H);
  974. pRtvHeap = &pShaderOp->DescriptorHeaps.back();
  975. }
  976. if (pRtvHeap->Descriptors.empty()) {
  977. ShaderOpDescriptor D;
  978. ZeroMemory(&D, sizeof(D));
  979. D.Name = pShaderOp->Strings.insert("RTarget");
  980. D.ResName = D.Name;
  981. D.Kind = pShaderOp->Strings.insert("RTV");
  982. pRtvHeap->Descriptors.push_back(D);
  983. }
  984. }
  985. void ShaderOpTest::PresentRenderTarget(ShaderOp *pShaderOp,
  986. ID3D12CommandQueue *pCommandQueue,
  987. ID3D12Resource *pRenderTarget) {
  988. UNREFERENCED_PARAMETER(pShaderOp);
  989. CommandListRefs ResCommandList;
  990. ResCommandList.Queue = pCommandQueue;
  991. ResCommandList.CreateForDevice(m_pDevice, m_pShaderOp->IsCompute());
  992. ID3D12GraphicsCommandList *pList = ResCommandList.List;
  993. pList->SetName(L"ShaderOpTest Resource Present CommandList");
  994. RecordTransitionBarrier(pList, pRenderTarget,
  995. D3D12_RESOURCE_STATE_RENDER_TARGET,
  996. D3D12_RESOURCE_STATE_PRESENT);
  997. pList->Close();
  998. ExecuteCommandList(ResCommandList.Queue, pList);
  999. WaitForSignal(ResCommandList.Queue, m_pFence, m_hFence, m_FenceValue++);
  1000. }
  1001. ShaderOp *ShaderOpSet::GetShaderOp(LPCSTR pName) {
  1002. for (auto &S : ShaderOps) {
  1003. if (S->Name && 0 == _stricmp(pName, S->Name)) {
  1004. return S.get();
  1005. }
  1006. }
  1007. return nullptr;
  1008. }
  1009. ///////////////////////////////////////////////////////////////////////////////
  1010. // ShaderOpTest library implementation for deserialization.
  1011. #pragma region Parsing support
  1012. // Use this class to initialize a ShaderOp object from an XML document.
  1013. class ShaderOpParser {
  1014. private:
  1015. string_table *m_pStrings;
  1016. bool ReadAtElementName(IXmlReader *pReader, LPCWSTR pName);
  1017. HRESULT ReadAttrStr(IXmlReader *pReader, LPCWSTR pAttrName, LPCSTR *ppValue);
  1018. HRESULT ReadAttrBOOL(IXmlReader *pReader, LPCWSTR pAttrName, BOOL *pValue, BOOL defaultValue = FALSE);
  1019. HRESULT ReadAttrUINT64(IXmlReader *pReader, LPCWSTR pAttrName, UINT64 *pValue, UINT64 defaultValue = 0);
  1020. HRESULT ReadAttrUINT16(IXmlReader *pReader, LPCWSTR pAttrName, UINT16 *pValue, UINT16 defaultValue = 0);
  1021. HRESULT ReadAttrUINT(IXmlReader *pReader, LPCWSTR pAttrName, UINT *pValue, UINT defaultValue = 0);
  1022. HRESULT ReadAttrFloat(IXmlReader* pReader, LPCWSTR pAttrName, float* pValue, float defaultValue = 0);
  1023. void ReadElementContentStr(IXmlReader *pReader, LPCSTR *ppValue);
  1024. void ParseDescriptor(IXmlReader *pReader, ShaderOpDescriptor *pDesc);
  1025. void ParseDescriptorHeap(IXmlReader *pReader, ShaderOpDescriptorHeap *pHeap);
  1026. void ParseInputElement(IXmlReader *pReader, D3D12_INPUT_ELEMENT_DESC *pInputElement);
  1027. void ParseInputElements(IXmlReader *pReader, std::vector<D3D12_INPUT_ELEMENT_DESC> *pInputElements);
  1028. void ParseRenderTargets(IXmlReader *pReader, std::vector<ShaderOpRenderTarget> *pRenderTargets);
  1029. void ParseRenderTarget(IXmlReader* pReader, ShaderOpRenderTarget *pRenderTarget);
  1030. void ParseViewport(IXmlReader* pReader, D3D12_VIEWPORT *pViewport);
  1031. void ParseRootValue(IXmlReader *pReader, ShaderOpRootValue *pRootValue);
  1032. void ParseRootValues(IXmlReader *pReader, std::vector<ShaderOpRootValue> *pRootValues);
  1033. void ParseResource(IXmlReader *pReader, ShaderOpResource *pResource);
  1034. void ParseShader(IXmlReader *pReader, ShaderOpShader *pShader);
  1035. public:
  1036. void ParseShaderOpSet(IStream *pStream, ShaderOpSet *pShaderOpSet);
  1037. void ParseShaderOpSet(IXmlReader *pReader, ShaderOpSet *pShaderOpSet);
  1038. void ParseShaderOp(IXmlReader *pReader, ShaderOp *pShaderOp);
  1039. };
  1040. void ParseShaderOpSetFromStream(IStream *pStream, st::ShaderOpSet *pShaderOpSet) {
  1041. ShaderOpParser parser;
  1042. parser.ParseShaderOpSet(pStream, pShaderOpSet);
  1043. }
  1044. void ParseShaderOpSetFromXml(IXmlReader *pReader, st::ShaderOpSet *pShaderOpSet) {
  1045. ShaderOpParser parser;
  1046. parser.ParseShaderOpSet(pReader, pShaderOpSet);
  1047. }
  1048. enum class ParserEnumKind {
  1049. INPUT_CLASSIFICATION,
  1050. DXGI_FORMAT,
  1051. HEAP_TYPE,
  1052. CPU_PAGE_PROPERTY,
  1053. MEMORY_POOL,
  1054. RESOURCE_DIMENSION,
  1055. TEXTURE_LAYOUT,
  1056. RESOURCE_FLAG,
  1057. HEAP_FLAG,
  1058. RESOURCE_STATE,
  1059. DESCRIPTOR_HEAP_TYPE,
  1060. DESCRIPTOR_HEAP_FLAG,
  1061. SRV_DIMENSION,
  1062. UAV_DIMENSION,
  1063. PRIMITIVE_TOPOLOGY,
  1064. PRIMITIVE_TOPOLOGY_TYPE
  1065. };
  1066. struct ParserEnumValue {
  1067. LPCWSTR Name;
  1068. UINT Value;
  1069. };
  1070. struct ParserEnumTable {
  1071. size_t ValueCount;
  1072. const ParserEnumValue *Values;
  1073. ParserEnumKind Kind;
  1074. };
  1075. static const ParserEnumValue INPUT_CLASSIFICATION_TABLE[] = {
  1076. { L"INSTANCE", D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA },
  1077. { L"VERTEX", D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA }
  1078. };
  1079. static const ParserEnumValue DXGI_FORMAT_TABLE[] = {
  1080. { L"UNKNOWN", DXGI_FORMAT_UNKNOWN },
  1081. { L"R32G32B32A32_TYPELESS", DXGI_FORMAT_R32G32B32A32_TYPELESS },
  1082. { L"R32G32B32A32_FLOAT", DXGI_FORMAT_R32G32B32A32_FLOAT },
  1083. { L"R32G32B32A32_UINT", DXGI_FORMAT_R32G32B32A32_UINT },
  1084. { L"R32G32B32A32_SINT", DXGI_FORMAT_R32G32B32A32_SINT },
  1085. { L"R32G32B32_TYPELESS", DXGI_FORMAT_R32G32B32_TYPELESS },
  1086. { L"R32G32B32_FLOAT", DXGI_FORMAT_R32G32B32_FLOAT },
  1087. { L"R32G32B32_UINT", DXGI_FORMAT_R32G32B32_UINT },
  1088. { L"R32G32B32_SINT", DXGI_FORMAT_R32G32B32_SINT },
  1089. { L"R16G16B16A16_TYPELESS", DXGI_FORMAT_R16G16B16A16_TYPELESS },
  1090. { L"R16G16B16A16_FLOAT", DXGI_FORMAT_R16G16B16A16_FLOAT },
  1091. { L"R16G16B16A16_UNORM", DXGI_FORMAT_R16G16B16A16_UNORM },
  1092. { L"R16G16B16A16_UINT", DXGI_FORMAT_R16G16B16A16_UINT },
  1093. { L"R16G16B16A16_SNORM", DXGI_FORMAT_R16G16B16A16_SNORM },
  1094. { L"R16G16B16A16_SINT", DXGI_FORMAT_R16G16B16A16_SINT },
  1095. { L"R32G32_TYPELESS", DXGI_FORMAT_R32G32_TYPELESS },
  1096. { L"R32G32_FLOAT", DXGI_FORMAT_R32G32_FLOAT },
  1097. { L"R32G32_UINT", DXGI_FORMAT_R32G32_UINT },
  1098. { L"R32G32_SINT", DXGI_FORMAT_R32G32_SINT },
  1099. { L"R32G8X24_TYPELESS", DXGI_FORMAT_R32G8X24_TYPELESS },
  1100. { L"D32_FLOAT_S8X24_UINT", DXGI_FORMAT_D32_FLOAT_S8X24_UINT },
  1101. { L"R32_FLOAT_X8X24_TYPELESS", DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS },
  1102. { L"X32_TYPELESS_G8X24_UINT", DXGI_FORMAT_X32_TYPELESS_G8X24_UINT },
  1103. { L"R10G10B10A2_TYPELESS", DXGI_FORMAT_R10G10B10A2_TYPELESS },
  1104. { L"R10G10B10A2_UNORM", DXGI_FORMAT_R10G10B10A2_UNORM },
  1105. { L"R10G10B10A2_UINT", DXGI_FORMAT_R10G10B10A2_UINT },
  1106. { L"R11G11B10_FLOAT", DXGI_FORMAT_R11G11B10_FLOAT },
  1107. { L"R8G8B8A8_TYPELESS", DXGI_FORMAT_R8G8B8A8_TYPELESS },
  1108. { L"R8G8B8A8_UNORM", DXGI_FORMAT_R8G8B8A8_UNORM },
  1109. { L"R8G8B8A8_UNORM_SRGB", DXGI_FORMAT_R8G8B8A8_UNORM_SRGB },
  1110. { L"R8G8B8A8_UINT", DXGI_FORMAT_R8G8B8A8_UINT },
  1111. { L"R8G8B8A8_SNORM", DXGI_FORMAT_R8G8B8A8_SNORM },
  1112. { L"R8G8B8A8_SINT", DXGI_FORMAT_R8G8B8A8_SINT },
  1113. { L"R16G16_TYPELESS", DXGI_FORMAT_R16G16_TYPELESS },
  1114. { L"R16G16_FLOAT", DXGI_FORMAT_R16G16_FLOAT },
  1115. { L"R16G16_UNORM", DXGI_FORMAT_R16G16_UNORM },
  1116. { L"R16G16_UINT", DXGI_FORMAT_R16G16_UINT },
  1117. { L"R16G16_SNORM", DXGI_FORMAT_R16G16_SNORM },
  1118. { L"R16G16_SINT", DXGI_FORMAT_R16G16_SINT },
  1119. { L"R32_TYPELESS", DXGI_FORMAT_R32_TYPELESS },
  1120. { L"D32_FLOAT", DXGI_FORMAT_D32_FLOAT },
  1121. { L"R32_FLOAT", DXGI_FORMAT_R32_FLOAT },
  1122. { L"R32_UINT", DXGI_FORMAT_R32_UINT },
  1123. { L"R32_SINT", DXGI_FORMAT_R32_SINT },
  1124. { L"R24G8_TYPELESS", DXGI_FORMAT_R24G8_TYPELESS },
  1125. { L"D24_UNORM_S8_UINT", DXGI_FORMAT_D24_UNORM_S8_UINT },
  1126. { L"R24_UNORM_X8_TYPELESS", DXGI_FORMAT_R24_UNORM_X8_TYPELESS },
  1127. { L"X24_TYPELESS_G8_UINT", DXGI_FORMAT_X24_TYPELESS_G8_UINT },
  1128. { L"R8G8_TYPELESS", DXGI_FORMAT_R8G8_TYPELESS },
  1129. { L"R8G8_UNORM", DXGI_FORMAT_R8G8_UNORM },
  1130. { L"R8G8_UINT", DXGI_FORMAT_R8G8_UINT },
  1131. { L"R8G8_SNORM", DXGI_FORMAT_R8G8_SNORM },
  1132. { L"R8G8_SINT", DXGI_FORMAT_R8G8_SINT },
  1133. { L"R16_TYPELESS", DXGI_FORMAT_R16_TYPELESS },
  1134. { L"R16_FLOAT", DXGI_FORMAT_R16_FLOAT },
  1135. { L"D16_UNORM", DXGI_FORMAT_D16_UNORM },
  1136. { L"R16_UNORM", DXGI_FORMAT_R16_UNORM },
  1137. { L"R16_UINT", DXGI_FORMAT_R16_UINT },
  1138. { L"R16_SNORM", DXGI_FORMAT_R16_SNORM },
  1139. { L"R16_SINT", DXGI_FORMAT_R16_SINT },
  1140. { L"R8_TYPELESS", DXGI_FORMAT_R8_TYPELESS },
  1141. { L"R8_UNORM", DXGI_FORMAT_R8_UNORM },
  1142. { L"R8_UINT", DXGI_FORMAT_R8_UINT },
  1143. { L"R8_SNORM", DXGI_FORMAT_R8_SNORM },
  1144. { L"R8_SINT", DXGI_FORMAT_R8_SINT },
  1145. { L"A8_UNORM", DXGI_FORMAT_A8_UNORM },
  1146. { L"R1_UNORM", DXGI_FORMAT_R1_UNORM },
  1147. { L"R9G9B9E5_SHAREDEXP", DXGI_FORMAT_R9G9B9E5_SHAREDEXP },
  1148. { L"R8G8_B8G8_UNORM", DXGI_FORMAT_R8G8_B8G8_UNORM },
  1149. { L"G8R8_G8B8_UNORM", DXGI_FORMAT_G8R8_G8B8_UNORM },
  1150. { L"BC1_TYPELESS", DXGI_FORMAT_BC1_TYPELESS },
  1151. { L"BC1_UNORM", DXGI_FORMAT_BC1_UNORM },
  1152. { L"BC1_UNORM_SRGB", DXGI_FORMAT_BC1_UNORM_SRGB },
  1153. { L"BC2_TYPELESS", DXGI_FORMAT_BC2_TYPELESS },
  1154. { L"BC2_UNORM", DXGI_FORMAT_BC2_UNORM },
  1155. { L"BC2_UNORM_SRGB", DXGI_FORMAT_BC2_UNORM_SRGB },
  1156. { L"BC3_TYPELESS", DXGI_FORMAT_BC3_TYPELESS },
  1157. { L"BC3_UNORM", DXGI_FORMAT_BC3_UNORM },
  1158. { L"BC3_UNORM_SRGB", DXGI_FORMAT_BC3_UNORM_SRGB },
  1159. { L"BC4_TYPELESS", DXGI_FORMAT_BC4_TYPELESS },
  1160. { L"BC4_UNORM", DXGI_FORMAT_BC4_UNORM },
  1161. { L"BC4_SNORM", DXGI_FORMAT_BC4_SNORM },
  1162. { L"BC5_TYPELESS", DXGI_FORMAT_BC5_TYPELESS },
  1163. { L"BC5_UNORM", DXGI_FORMAT_BC5_UNORM },
  1164. { L"BC5_SNORM", DXGI_FORMAT_BC5_SNORM },
  1165. { L"B5G6R5_UNORM", DXGI_FORMAT_B5G6R5_UNORM },
  1166. { L"B5G5R5A1_UNORM", DXGI_FORMAT_B5G5R5A1_UNORM },
  1167. { L"B8G8R8A8_UNORM", DXGI_FORMAT_B8G8R8A8_UNORM },
  1168. { L"B8G8R8X8_UNORM", DXGI_FORMAT_B8G8R8X8_UNORM },
  1169. { L"R10G10B10_XR_BIAS_A2_UNORM", DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM },
  1170. { L"B8G8R8A8_TYPELESS", DXGI_FORMAT_B8G8R8A8_TYPELESS },
  1171. { L"B8G8R8A8_UNORM_SRGB", DXGI_FORMAT_B8G8R8A8_UNORM_SRGB },
  1172. { L"B8G8R8X8_TYPELESS", DXGI_FORMAT_B8G8R8X8_TYPELESS },
  1173. { L"B8G8R8X8_UNORM_SRGB", DXGI_FORMAT_B8G8R8X8_UNORM_SRGB },
  1174. { L"BC6H_TYPELESS", DXGI_FORMAT_BC6H_TYPELESS },
  1175. { L"BC6H_UF16", DXGI_FORMAT_BC6H_UF16 },
  1176. { L"BC6H_SF16", DXGI_FORMAT_BC6H_SF16 },
  1177. { L"BC7_TYPELESS", DXGI_FORMAT_BC7_TYPELESS },
  1178. { L"BC7_UNORM", DXGI_FORMAT_BC7_UNORM },
  1179. { L"BC7_UNORM_SRGB", DXGI_FORMAT_BC7_UNORM_SRGB },
  1180. { L"AYUV", DXGI_FORMAT_AYUV },
  1181. { L"Y410", DXGI_FORMAT_Y410 },
  1182. { L"Y416", DXGI_FORMAT_Y416 },
  1183. { L"NV12", DXGI_FORMAT_NV12 },
  1184. { L"P010", DXGI_FORMAT_P010 },
  1185. { L"P016", DXGI_FORMAT_P016 },
  1186. { L"420_OPAQUE", DXGI_FORMAT_420_OPAQUE },
  1187. { L"YUY2", DXGI_FORMAT_YUY2 },
  1188. { L"Y210", DXGI_FORMAT_Y210 },
  1189. { L"Y216", DXGI_FORMAT_Y216 },
  1190. { L"NV11", DXGI_FORMAT_NV11 },
  1191. { L"AI44", DXGI_FORMAT_AI44 },
  1192. { L"IA44", DXGI_FORMAT_IA44 },
  1193. { L"P8", DXGI_FORMAT_P8 },
  1194. { L"A8P8", DXGI_FORMAT_A8P8 },
  1195. { L"B4G4R4A4_UNORM", DXGI_FORMAT_B4G4R4A4_UNORM },
  1196. { L"P208", DXGI_FORMAT_P208 },
  1197. { L"V208", DXGI_FORMAT_V208 },
  1198. { L"V408", DXGI_FORMAT_V408 }
  1199. };
  1200. static const ParserEnumValue HEAP_TYPE_TABLE[] = {
  1201. { L"DEFAULT", D3D12_HEAP_TYPE_DEFAULT },
  1202. { L"UPLOAD", D3D12_HEAP_TYPE_UPLOAD },
  1203. { L"READBACK", D3D12_HEAP_TYPE_READBACK },
  1204. { L"CUSTOM", D3D12_HEAP_TYPE_CUSTOM }
  1205. };
  1206. static const ParserEnumValue CPU_PAGE_PROPERTY_TABLE[] = {
  1207. { L"UNKNOWN", D3D12_CPU_PAGE_PROPERTY_UNKNOWN },
  1208. { L"NOT_AVAILABLE", D3D12_CPU_PAGE_PROPERTY_NOT_AVAILABLE },
  1209. { L"WRITE_COMBINE", D3D12_CPU_PAGE_PROPERTY_WRITE_COMBINE },
  1210. { L"WRITE_BACK", D3D12_CPU_PAGE_PROPERTY_WRITE_BACK }
  1211. };
  1212. static const ParserEnumValue MEMORY_POOL_TABLE[] = {
  1213. { L"UNKNOWN", D3D12_MEMORY_POOL_UNKNOWN },
  1214. { L"L0 ", D3D12_MEMORY_POOL_L0 },
  1215. { L"L1", D3D12_MEMORY_POOL_L1 }
  1216. };
  1217. static const ParserEnumValue RESOURCE_DIMENSION_TABLE[] = {
  1218. { L"UNKNOWN", D3D12_RESOURCE_DIMENSION_UNKNOWN },
  1219. { L"BUFFER", D3D12_RESOURCE_DIMENSION_BUFFER },
  1220. { L"TEXTURE1D", D3D12_RESOURCE_DIMENSION_TEXTURE1D },
  1221. { L"TEXTURE2D", D3D12_RESOURCE_DIMENSION_TEXTURE2D },
  1222. { L"TEXTURE3D", D3D12_RESOURCE_DIMENSION_TEXTURE3D }
  1223. };
  1224. static const ParserEnumValue TEXTURE_LAYOUT_TABLE[] = {
  1225. { L"UNKNOWN", D3D12_TEXTURE_LAYOUT_UNKNOWN },
  1226. { L"ROW_MAJOR", D3D12_TEXTURE_LAYOUT_ROW_MAJOR },
  1227. { L"UNDEFINED_SWIZZLE", D3D12_TEXTURE_LAYOUT_64KB_UNDEFINED_SWIZZLE },
  1228. { L"STANDARD_SWIZZLE", D3D12_TEXTURE_LAYOUT_64KB_STANDARD_SWIZZLE }
  1229. };
  1230. static const ParserEnumValue RESOURCE_FLAG_TABLE[] = {
  1231. { L"NONE", D3D12_RESOURCE_FLAG_NONE },
  1232. { L"ALLOW_RENDER_TARGET", D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET },
  1233. { L"ALLOW_DEPTH_STENCIL", D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL },
  1234. { L"ALLOW_UNORDERED_ACCESS", D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS },
  1235. { L"DENY_SHADER_RESOURCE", D3D12_RESOURCE_FLAG_DENY_SHADER_RESOURCE },
  1236. { L"ALLOW_CROSS_ADAPTER", D3D12_RESOURCE_FLAG_ALLOW_CROSS_ADAPTER },
  1237. { L"ALLOW_SIMULTANEOUS_ACCESS", D3D12_RESOURCE_FLAG_ALLOW_SIMULTANEOUS_ACCESS }
  1238. };
  1239. static const ParserEnumValue HEAP_FLAG_TABLE[] = {
  1240. { L"NONE", D3D12_HEAP_FLAG_NONE },
  1241. { L"SHARED", D3D12_HEAP_FLAG_SHARED },
  1242. { L"DENY_BUFFERS", D3D12_HEAP_FLAG_DENY_BUFFERS },
  1243. { L"ALLOW_DISPLAY", D3D12_HEAP_FLAG_ALLOW_DISPLAY },
  1244. { L"SHARED_CROSS_ADAPTER", D3D12_HEAP_FLAG_SHARED_CROSS_ADAPTER },
  1245. { L"DENY_RT_DS_TEXTURES", D3D12_HEAP_FLAG_DENY_RT_DS_TEXTURES },
  1246. { L"DENY_NON_RT_DS_TEXTURES", D3D12_HEAP_FLAG_DENY_NON_RT_DS_TEXTURES },
  1247. { L"ALLOW_ALL_BUFFERS_AND_TEXTURES",D3D12_HEAP_FLAG_ALLOW_ALL_BUFFERS_AND_TEXTURES },
  1248. { L"ALLOW_ONLY_BUFFERS", D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS },
  1249. { L"ALLOW_ONLY_NON_RT_DS_TEXTURES", D3D12_HEAP_FLAG_ALLOW_ONLY_NON_RT_DS_TEXTURES },
  1250. { L"ALLOW_ONLY_RT_DS_TEXTURES", D3D12_HEAP_FLAG_ALLOW_ONLY_RT_DS_TEXTURES }
  1251. };
  1252. static const ParserEnumValue RESOURCE_STATE_TABLE[] = {
  1253. { L"COMMON", D3D12_RESOURCE_STATE_COMMON },
  1254. { L"VERTEX_AND_CONSTANT_BUFFER", D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER },
  1255. { L"INDEX_BUFFER", D3D12_RESOURCE_STATE_INDEX_BUFFER },
  1256. { L"RENDER_TARGET", D3D12_RESOURCE_STATE_RENDER_TARGET },
  1257. { L"UNORDERED_ACCESS", D3D12_RESOURCE_STATE_UNORDERED_ACCESS },
  1258. { L"DEPTH_WRITE", D3D12_RESOURCE_STATE_DEPTH_WRITE },
  1259. { L"DEPTH_READ", D3D12_RESOURCE_STATE_DEPTH_READ },
  1260. { L"NON_PIXEL_SHADER_RESOURCE", D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE },
  1261. { L"PIXEL_SHADER_RESOURCE", D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE },
  1262. { L"STREAM_OUT", D3D12_RESOURCE_STATE_STREAM_OUT },
  1263. { L"INDIRECT_ARGUMENT", D3D12_RESOURCE_STATE_INDIRECT_ARGUMENT },
  1264. { L"COPY_DEST", D3D12_RESOURCE_STATE_COPY_DEST },
  1265. { L"COPY_SOURCE", D3D12_RESOURCE_STATE_COPY_SOURCE },
  1266. { L"RESOLVE_DEST", D3D12_RESOURCE_STATE_RESOLVE_DEST },
  1267. { L"RESOLVE_SOURCE", D3D12_RESOURCE_STATE_RESOLVE_SOURCE },
  1268. { L"GENERIC_READ", D3D12_RESOURCE_STATE_GENERIC_READ },
  1269. { L"PRESENT", D3D12_RESOURCE_STATE_PRESENT },
  1270. { L"PREDICATION", D3D12_RESOURCE_STATE_PREDICATION }
  1271. };
  1272. static const ParserEnumValue DESCRIPTOR_HEAP_TYPE_TABLE[] = {
  1273. { L"CBV_SRV_UAV", D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV },
  1274. { L"SAMPLER", D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER },
  1275. { L"RTV", D3D12_DESCRIPTOR_HEAP_TYPE_RTV },
  1276. { L"DSV", D3D12_DESCRIPTOR_HEAP_TYPE_DSV }
  1277. };
  1278. static const ParserEnumValue DESCRIPTOR_HEAP_FLAG_TABLE[] = {
  1279. { L"NONE", D3D12_DESCRIPTOR_HEAP_FLAG_NONE },
  1280. { L"SHADER_VISIBLE", D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE }
  1281. };
  1282. static const ParserEnumValue SRV_DIMENSION_TABLE[] = {
  1283. { L"UNKNOWN", D3D12_SRV_DIMENSION_UNKNOWN },
  1284. { L"BUFFER", D3D12_SRV_DIMENSION_BUFFER },
  1285. { L"TEXTURE1D", D3D12_SRV_DIMENSION_TEXTURE1D },
  1286. { L"TEXTURE1DARRAY", D3D12_SRV_DIMENSION_TEXTURE1DARRAY },
  1287. { L"TEXTURE2D", D3D12_SRV_DIMENSION_TEXTURE2D },
  1288. { L"TEXTURE2DARRAY", D3D12_SRV_DIMENSION_TEXTURE2DARRAY },
  1289. { L"TEXTURE2DMS", D3D12_SRV_DIMENSION_TEXTURE2DMS },
  1290. { L"TEXTURE2DMSARRAY", D3D12_SRV_DIMENSION_TEXTURE2DMSARRAY },
  1291. { L"TEXTURE3D", D3D12_SRV_DIMENSION_TEXTURE3D },
  1292. { L"TEXTURECUBE", D3D12_SRV_DIMENSION_TEXTURECUBE },
  1293. { L"TEXTURECUBEARRAY", D3D12_SRV_DIMENSION_TEXTURECUBEARRAY }
  1294. };
  1295. static const ParserEnumValue UAV_DIMENSION_TABLE[] = {
  1296. { L"UNKNOWN", D3D12_UAV_DIMENSION_UNKNOWN },
  1297. { L"BUFFER", D3D12_UAV_DIMENSION_BUFFER },
  1298. { L"TEXTURE1D", D3D12_UAV_DIMENSION_TEXTURE1D },
  1299. { L"TEXTURE1DARRAY", D3D12_UAV_DIMENSION_TEXTURE1DARRAY },
  1300. { L"TEXTURE2D", D3D12_UAV_DIMENSION_TEXTURE2D },
  1301. { L"TEXTURE2DARRAY", D3D12_UAV_DIMENSION_TEXTURE2DARRAY },
  1302. { L"TEXTURE3D", D3D12_UAV_DIMENSION_TEXTURE3D }
  1303. };
  1304. static const ParserEnumValue PRIMITIVE_TOPOLOGY_TABLE[] = {
  1305. { L"UNDEFINED",D3D_PRIMITIVE_TOPOLOGY_UNDEFINED },
  1306. { L"POINTLIST",D3D_PRIMITIVE_TOPOLOGY_POINTLIST },
  1307. { L"LINELIST",D3D_PRIMITIVE_TOPOLOGY_LINELIST },
  1308. { L"LINESTRIP",D3D_PRIMITIVE_TOPOLOGY_LINESTRIP },
  1309. { L"TRIANGLELIST",D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST },
  1310. { L"TRIANGLESTRIP",D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP },
  1311. { L"LINELIST_ADJ",D3D_PRIMITIVE_TOPOLOGY_LINELIST_ADJ },
  1312. { L"LINESTRIP_ADJ",D3D_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ },
  1313. { L"TRIANGLELIST_ADJ",D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ },
  1314. { L"TRIANGLESTRIP_ADJ",D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ },
  1315. { L"1_CONTROL_POINT_PATCHLIST",D3D_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST },
  1316. { L"2_CONTROL_POINT_PATCHLIST",D3D_PRIMITIVE_TOPOLOGY_2_CONTROL_POINT_PATCHLIST },
  1317. { L"3_CONTROL_POINT_PATCHLIST",D3D_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST },
  1318. { L"4_CONTROL_POINT_PATCHLIST",D3D_PRIMITIVE_TOPOLOGY_4_CONTROL_POINT_PATCHLIST },
  1319. { L"5_CONTROL_POINT_PATCHLIST",D3D_PRIMITIVE_TOPOLOGY_5_CONTROL_POINT_PATCHLIST },
  1320. { L"6_CONTROL_POINT_PATCHLIST",D3D_PRIMITIVE_TOPOLOGY_6_CONTROL_POINT_PATCHLIST },
  1321. { L"7_CONTROL_POINT_PATCHLIST",D3D_PRIMITIVE_TOPOLOGY_7_CONTROL_POINT_PATCHLIST },
  1322. { L"8_CONTROL_POINT_PATCHLIST",D3D_PRIMITIVE_TOPOLOGY_8_CONTROL_POINT_PATCHLIST },
  1323. { L"9_CONTROL_POINT_PATCHLIST",D3D_PRIMITIVE_TOPOLOGY_9_CONTROL_POINT_PATCHLIST },
  1324. { L"10_CONTROL_POINT_PATCHLIST",D3D_PRIMITIVE_TOPOLOGY_10_CONTROL_POINT_PATCHLIST },
  1325. { L"11_CONTROL_POINT_PATCHLIST",D3D_PRIMITIVE_TOPOLOGY_11_CONTROL_POINT_PATCHLIST },
  1326. { L"12_CONTROL_POINT_PATCHLIST",D3D_PRIMITIVE_TOPOLOGY_12_CONTROL_POINT_PATCHLIST },
  1327. { L"13_CONTROL_POINT_PATCHLIST",D3D_PRIMITIVE_TOPOLOGY_13_CONTROL_POINT_PATCHLIST },
  1328. { L"14_CONTROL_POINT_PATCHLIST",D3D_PRIMITIVE_TOPOLOGY_14_CONTROL_POINT_PATCHLIST },
  1329. { L"15_CONTROL_POINT_PATCHLIST",D3D_PRIMITIVE_TOPOLOGY_15_CONTROL_POINT_PATCHLIST },
  1330. { L"16_CONTROL_POINT_PATCHLIST",D3D_PRIMITIVE_TOPOLOGY_16_CONTROL_POINT_PATCHLIST },
  1331. { L"17_CONTROL_POINT_PATCHLIST",D3D_PRIMITIVE_TOPOLOGY_17_CONTROL_POINT_PATCHLIST },
  1332. { L"18_CONTROL_POINT_PATCHLIST",D3D_PRIMITIVE_TOPOLOGY_18_CONTROL_POINT_PATCHLIST },
  1333. { L"19_CONTROL_POINT_PATCHLIST",D3D_PRIMITIVE_TOPOLOGY_19_CONTROL_POINT_PATCHLIST },
  1334. { L"20_CONTROL_POINT_PATCHLIST",D3D_PRIMITIVE_TOPOLOGY_20_CONTROL_POINT_PATCHLIST },
  1335. { L"21_CONTROL_POINT_PATCHLIST",D3D_PRIMITIVE_TOPOLOGY_21_CONTROL_POINT_PATCHLIST },
  1336. { L"22_CONTROL_POINT_PATCHLIST",D3D_PRIMITIVE_TOPOLOGY_22_CONTROL_POINT_PATCHLIST },
  1337. { L"23_CONTROL_POINT_PATCHLIST",D3D_PRIMITIVE_TOPOLOGY_23_CONTROL_POINT_PATCHLIST },
  1338. { L"24_CONTROL_POINT_PATCHLIST",D3D_PRIMITIVE_TOPOLOGY_24_CONTROL_POINT_PATCHLIST },
  1339. { L"25_CONTROL_POINT_PATCHLIST",D3D_PRIMITIVE_TOPOLOGY_25_CONTROL_POINT_PATCHLIST },
  1340. { L"26_CONTROL_POINT_PATCHLIST",D3D_PRIMITIVE_TOPOLOGY_26_CONTROL_POINT_PATCHLIST },
  1341. { L"27_CONTROL_POINT_PATCHLIST",D3D_PRIMITIVE_TOPOLOGY_27_CONTROL_POINT_PATCHLIST },
  1342. { L"28_CONTROL_POINT_PATCHLIST",D3D_PRIMITIVE_TOPOLOGY_28_CONTROL_POINT_PATCHLIST },
  1343. { L"29_CONTROL_POINT_PATCHLIST",D3D_PRIMITIVE_TOPOLOGY_29_CONTROL_POINT_PATCHLIST },
  1344. { L"30_CONTROL_POINT_PATCHLIST",D3D_PRIMITIVE_TOPOLOGY_30_CONTROL_POINT_PATCHLIST },
  1345. { L"31_CONTROL_POINT_PATCHLIST",D3D_PRIMITIVE_TOPOLOGY_31_CONTROL_POINT_PATCHLIST },
  1346. { L"32_CONTROL_POINT_PATCHLIST",D3D_PRIMITIVE_TOPOLOGY_32_CONTROL_POINT_PATCHLIST }
  1347. };
  1348. static const ParserEnumValue PRIMITIVE_TOPOLOGY_TYPE_TABLE[] = {
  1349. { L"UNDEFINED", D3D12_PRIMITIVE_TOPOLOGY_TYPE_UNDEFINED },
  1350. { L"POINT", D3D12_PRIMITIVE_TOPOLOGY_TYPE_POINT },
  1351. { L"LINE", D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE },
  1352. { L"TRIANGLE", D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE },
  1353. { L"PATCH", D3D12_PRIMITIVE_TOPOLOGY_TYPE_PATCH }
  1354. };
  1355. static const ParserEnumTable g_ParserEnumTables[] = {
  1356. { _countof(INPUT_CLASSIFICATION_TABLE), INPUT_CLASSIFICATION_TABLE, ParserEnumKind::INPUT_CLASSIFICATION },
  1357. { _countof(DXGI_FORMAT_TABLE), DXGI_FORMAT_TABLE, ParserEnumKind::DXGI_FORMAT },
  1358. { _countof(HEAP_TYPE_TABLE), HEAP_TYPE_TABLE, ParserEnumKind::HEAP_TYPE },
  1359. { _countof(CPU_PAGE_PROPERTY_TABLE), CPU_PAGE_PROPERTY_TABLE, ParserEnumKind::CPU_PAGE_PROPERTY },
  1360. { _countof(MEMORY_POOL_TABLE), MEMORY_POOL_TABLE, ParserEnumKind::MEMORY_POOL },
  1361. { _countof(RESOURCE_DIMENSION_TABLE), RESOURCE_DIMENSION_TABLE, ParserEnumKind::RESOURCE_DIMENSION },
  1362. { _countof(TEXTURE_LAYOUT_TABLE), TEXTURE_LAYOUT_TABLE, ParserEnumKind::TEXTURE_LAYOUT },
  1363. { _countof(RESOURCE_FLAG_TABLE), RESOURCE_FLAG_TABLE, ParserEnumKind::RESOURCE_FLAG },
  1364. { _countof(HEAP_FLAG_TABLE), HEAP_FLAG_TABLE, ParserEnumKind::HEAP_FLAG },
  1365. { _countof(RESOURCE_STATE_TABLE), RESOURCE_STATE_TABLE, ParserEnumKind::RESOURCE_STATE },
  1366. { _countof(DESCRIPTOR_HEAP_TYPE_TABLE), DESCRIPTOR_HEAP_TYPE_TABLE, ParserEnumKind::DESCRIPTOR_HEAP_TYPE },
  1367. { _countof(DESCRIPTOR_HEAP_FLAG_TABLE), DESCRIPTOR_HEAP_FLAG_TABLE, ParserEnumKind::DESCRIPTOR_HEAP_FLAG },
  1368. { _countof(SRV_DIMENSION_TABLE), SRV_DIMENSION_TABLE, ParserEnumKind::SRV_DIMENSION },
  1369. { _countof(UAV_DIMENSION_TABLE), UAV_DIMENSION_TABLE, ParserEnumKind::UAV_DIMENSION },
  1370. { _countof(PRIMITIVE_TOPOLOGY_TABLE), PRIMITIVE_TOPOLOGY_TABLE, ParserEnumKind::PRIMITIVE_TOPOLOGY },
  1371. { _countof(PRIMITIVE_TOPOLOGY_TYPE_TABLE), PRIMITIVE_TOPOLOGY_TYPE_TABLE, ParserEnumKind::PRIMITIVE_TOPOLOGY_TYPE },
  1372. };
  1373. static HRESULT GetEnumValue(LPCWSTR name, ParserEnumKind K, UINT *pValue) {
  1374. for (size_t i = 0; i < _countof(g_ParserEnumTables); ++i) {
  1375. const ParserEnumTable &T = g_ParserEnumTables[i];
  1376. if (T.Kind != K) {
  1377. continue;
  1378. }
  1379. for (size_t j = 0; j < T.ValueCount; ++j) {
  1380. if (_wcsicmp(name, T.Values[j].Name) == 0) {
  1381. *pValue = T.Values[j].Value;
  1382. return S_OK;
  1383. }
  1384. }
  1385. }
  1386. return E_INVALIDARG;
  1387. }
  1388. template <typename T>
  1389. static HRESULT GetEnumValueT(LPCWSTR name, ParserEnumKind K, T *pValue) {
  1390. UINT u;
  1391. HRESULT hr = GetEnumValue(name, K, &u);
  1392. *pValue = (T)u;
  1393. return hr;
  1394. }
  1395. template <typename T>
  1396. static HRESULT ReadAttrEnumT(IXmlReader *pReader, LPCWSTR pAttrName, ParserEnumKind K, T *pValue, T defaultValue, LPCWSTR pStripPrefix = nullptr) {
  1397. if (S_FALSE == CHECK_HR_RET(pReader->MoveToAttributeByName(pAttrName, nullptr))) {
  1398. *pValue = defaultValue;
  1399. return S_FALSE;
  1400. }
  1401. LPCWSTR pText;
  1402. CHECK_HR(pReader->GetValue(&pText, nullptr));
  1403. if (pStripPrefix && *pStripPrefix && _wcsnicmp(pStripPrefix, pText, wcslen(pStripPrefix)) == 0)
  1404. pText += wcslen(pStripPrefix);
  1405. CHECK_HR(GetEnumValueT(pText, K, pValue));
  1406. CHECK_HR(pReader->MoveToElement());
  1407. return S_OK;
  1408. }
  1409. static HRESULT ReadAttrINPUT_CLASSIFICATION(IXmlReader *pReader, LPCWSTR pAttrName, D3D12_INPUT_CLASSIFICATION *pValue) {
  1410. return ReadAttrEnumT(pReader, pAttrName, ParserEnumKind::INPUT_CLASSIFICATION, pValue, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA);
  1411. }
  1412. static HRESULT ReadAttrDESCRIPTOR_HEAP_TYPE(IXmlReader *pReader, LPCWSTR pAttrName, D3D12_DESCRIPTOR_HEAP_TYPE *pValue) {
  1413. return ReadAttrEnumT(pReader, pAttrName, ParserEnumKind::DESCRIPTOR_HEAP_TYPE, pValue, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
  1414. }
  1415. static HRESULT ReadAttrDESCRIPTOR_HEAP_FLAGS(IXmlReader *pReader, LPCWSTR pAttrName, D3D12_DESCRIPTOR_HEAP_FLAGS *pValue) {
  1416. return ReadAttrEnumT(pReader, pAttrName, ParserEnumKind::DESCRIPTOR_HEAP_FLAG, pValue, D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE);
  1417. }
  1418. static HRESULT ReadAttrDXGI_FORMAT(IXmlReader *pReader, LPCWSTR pAttrName, DXGI_FORMAT *pValue) {
  1419. return ReadAttrEnumT(pReader, pAttrName, ParserEnumKind::DXGI_FORMAT, pValue, DXGI_FORMAT_UNKNOWN, L"DXGI_FORMAT_");
  1420. }
  1421. static HRESULT ReadAttrHEAP_TYPE(IXmlReader *pReader, LPCWSTR pAttrName, D3D12_HEAP_TYPE *pValue) {
  1422. return ReadAttrEnumT(pReader, pAttrName, ParserEnumKind::HEAP_TYPE, pValue, D3D12_HEAP_TYPE_DEFAULT);
  1423. }
  1424. static HRESULT ReadAttrCPU_PAGE_PROPERTY(IXmlReader *pReader, LPCWSTR pAttrName, D3D12_CPU_PAGE_PROPERTY *pValue) {
  1425. return ReadAttrEnumT(pReader, pAttrName, ParserEnumKind::CPU_PAGE_PROPERTY, pValue, D3D12_CPU_PAGE_PROPERTY_UNKNOWN);
  1426. }
  1427. static HRESULT ReadAttrMEMORY_POOL(IXmlReader *pReader, LPCWSTR pAttrName, D3D12_MEMORY_POOL *pValue) {
  1428. return ReadAttrEnumT(pReader, pAttrName, ParserEnumKind::MEMORY_POOL, pValue, D3D12_MEMORY_POOL_UNKNOWN);
  1429. }
  1430. static HRESULT ReadAttrRESOURCE_DIMENSION(IXmlReader *pReader, LPCWSTR pAttrName, D3D12_RESOURCE_DIMENSION *pValue) {
  1431. return ReadAttrEnumT(pReader, pAttrName, ParserEnumKind::RESOURCE_DIMENSION, pValue, D3D12_RESOURCE_DIMENSION_BUFFER);
  1432. }
  1433. static HRESULT ReadAttrTEXTURE_LAYOUT(IXmlReader *pReader, LPCWSTR pAttrName, D3D12_TEXTURE_LAYOUT *pValue) {
  1434. return ReadAttrEnumT(pReader, pAttrName, ParserEnumKind::TEXTURE_LAYOUT, pValue, D3D12_TEXTURE_LAYOUT_UNKNOWN);
  1435. }
  1436. static HRESULT ReadAttrRESOURCE_FLAGS(IXmlReader *pReader, LPCWSTR pAttrName, D3D12_RESOURCE_FLAGS *pValue) {
  1437. return ReadAttrEnumT(pReader, pAttrName, ParserEnumKind::RESOURCE_FLAG, pValue, D3D12_RESOURCE_FLAG_NONE);
  1438. }
  1439. static HRESULT ReadAttrHEAP_FLAGS(IXmlReader *pReader, LPCWSTR pAttrName, D3D12_HEAP_FLAGS *pValue) {
  1440. return ReadAttrEnumT(pReader, pAttrName, ParserEnumKind::HEAP_FLAG, pValue, D3D12_HEAP_FLAG_NONE);
  1441. }
  1442. static HRESULT ReadAttrRESOURCE_STATES(IXmlReader *pReader, LPCWSTR pAttrName, D3D12_RESOURCE_STATES *pValue) {
  1443. return ReadAttrEnumT(pReader, pAttrName, ParserEnumKind::RESOURCE_STATE, pValue, D3D12_RESOURCE_STATE_COMMON);
  1444. }
  1445. static HRESULT ReadAttrSRV_DIMENSION(IXmlReader *pReader, LPCWSTR pAttrName, D3D12_SRV_DIMENSION *pValue) {
  1446. return ReadAttrEnumT(pReader, pAttrName, ParserEnumKind::SRV_DIMENSION, pValue, D3D12_SRV_DIMENSION_BUFFER);
  1447. }
  1448. static HRESULT ReadAttrUAV_DIMENSION(IXmlReader *pReader, LPCWSTR pAttrName, D3D12_UAV_DIMENSION *pValue) {
  1449. return ReadAttrEnumT(pReader, pAttrName, ParserEnumKind::UAV_DIMENSION, pValue, D3D12_UAV_DIMENSION_BUFFER);
  1450. }
  1451. static HRESULT ReadAttrPRIMITIVE_TOPOLOGY(IXmlReader *pReader, LPCWSTR pAttrName, D3D_PRIMITIVE_TOPOLOGY *pValue) {
  1452. return ReadAttrEnumT(pReader, pAttrName, ParserEnumKind::PRIMITIVE_TOPOLOGY, pValue, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
  1453. }
  1454. static HRESULT ReadAttrPRIMITIVE_TOPOLOGY_TYPE(IXmlReader *pReader, LPCWSTR pAttrName, D3D12_PRIMITIVE_TOPOLOGY_TYPE *pValue) {
  1455. return ReadAttrEnumT(pReader, pAttrName, ParserEnumKind::PRIMITIVE_TOPOLOGY_TYPE, pValue, D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE);
  1456. }
  1457. HRESULT ShaderOpParser::ReadAttrStr(IXmlReader *pReader, LPCWSTR pAttrName, LPCSTR *ppValue) {
  1458. if (S_FALSE == CHECK_HR_RET(pReader->MoveToAttributeByName(pAttrName, nullptr))) {
  1459. *ppValue = nullptr;
  1460. return S_FALSE;
  1461. }
  1462. LPCWSTR pValue;
  1463. CHECK_HR(pReader->GetValue(&pValue, nullptr));
  1464. *ppValue = m_pStrings->insert(pValue);
  1465. CHECK_HR(pReader->MoveToElement());
  1466. return S_OK;
  1467. }
  1468. HRESULT ShaderOpParser::ReadAttrBOOL(IXmlReader *pReader, LPCWSTR pAttrName, BOOL *pValue, BOOL defaultValue) {
  1469. if (S_FALSE == CHECK_HR_RET(pReader->MoveToAttributeByName(pAttrName, nullptr))) {
  1470. *pValue = defaultValue;
  1471. return S_FALSE;
  1472. }
  1473. LPCWSTR pText;
  1474. CHECK_HR(pReader->GetValue(&pText, nullptr));
  1475. if (_wcsicmp(pText, L"true") == 0) {
  1476. *pValue = TRUE;
  1477. }
  1478. else {
  1479. *pValue = FALSE;
  1480. }
  1481. CHECK_HR(pReader->MoveToElement());
  1482. return S_OK;
  1483. }
  1484. HRESULT ShaderOpParser::ReadAttrUINT64(IXmlReader *pReader, LPCWSTR pAttrName, UINT64 *pValue, UINT64 defaultValue) {
  1485. if (S_FALSE == CHECK_HR_RET(pReader->MoveToAttributeByName(pAttrName, nullptr))) {
  1486. *pValue = defaultValue;
  1487. return S_FALSE;
  1488. }
  1489. LPCWSTR pText;
  1490. CHECK_HR(pReader->GetValue(&pText, nullptr));
  1491. long long ll = _wtol(pText);
  1492. if (errno == ERANGE) CHECK_HR(E_INVALIDARG);
  1493. *pValue = ll;
  1494. CHECK_HR(pReader->MoveToElement());
  1495. return S_OK;
  1496. }
  1497. HRESULT ShaderOpParser::ReadAttrUINT(IXmlReader *pReader, LPCWSTR pAttrName, UINT *pValue, UINT defaultValue) {
  1498. UINT64 u64;
  1499. HRESULT hrRead = CHECK_HR_RET(ReadAttrUINT64(pReader, pAttrName, &u64, defaultValue));
  1500. CHECK_HR(UInt64ToUInt(u64, pValue));
  1501. return hrRead;
  1502. }
  1503. HRESULT ShaderOpParser::ReadAttrUINT16(IXmlReader *pReader, LPCWSTR pAttrName, UINT16 *pValue, UINT16 defaultValue) {
  1504. UINT64 u64;
  1505. HRESULT hrRead = CHECK_HR_RET(ReadAttrUINT64(pReader, pAttrName, &u64, defaultValue));
  1506. CHECK_HR(UInt64ToUInt16(u64, pValue));
  1507. return hrRead;
  1508. }
  1509. HRESULT ShaderOpParser::ReadAttrFloat(IXmlReader* pReader, LPCWSTR pAttrName, float* pValue, float defaultValue) {
  1510. if (S_FALSE == CHECK_HR_RET(pReader->MoveToAttributeByName(pAttrName, nullptr))) {
  1511. *pValue = defaultValue;
  1512. return S_FALSE;
  1513. }
  1514. LPCWSTR pText;
  1515. CHECK_HR(pReader->GetValue(&pText, nullptr));
  1516. float d = (float)_wtof(pText);
  1517. if (errno == ERANGE) CHECK_HR(E_INVALIDARG);
  1518. *pValue = d;
  1519. CHECK_HR(pReader->MoveToElement());
  1520. return S_OK;
  1521. }
  1522. void ShaderOpParser::ReadElementContentStr(IXmlReader *pReader, LPCSTR *ppValue) {
  1523. *ppValue = nullptr;
  1524. if (pReader->IsEmptyElement())
  1525. return;
  1526. UINT startDepth;
  1527. XmlNodeType nt;
  1528. CHECK_HR(pReader->GetDepth(&startDepth));
  1529. std::wstring value;
  1530. for (;;) {
  1531. UINT depth;
  1532. CHECK_HR(pReader->Read(&nt));
  1533. CHECK_HR(pReader->GetDepth(&depth));
  1534. if (nt == XmlNodeType_EndElement && depth == startDepth + 1)
  1535. break;
  1536. if (nt == XmlNodeType_CDATA || nt == XmlNodeType_Text || nt == XmlNodeType_Whitespace) {
  1537. LPCWSTR pText;
  1538. CHECK_HR(pReader->GetValue(&pText, nullptr));
  1539. value += pText;
  1540. }
  1541. }
  1542. *ppValue = m_pStrings->insert(value.c_str());
  1543. }
  1544. void ShaderOpParser::ParseDescriptor(IXmlReader *pReader, ShaderOpDescriptor *pDesc) {
  1545. if (!ReadAtElementName(pReader, L"Descriptor"))
  1546. return;
  1547. CHECK_HR(ReadAttrStr(pReader, L"Name", &pDesc->Name));
  1548. CHECK_HR(ReadAttrStr(pReader, L"ResName", &pDesc->ResName));
  1549. CHECK_HR(ReadAttrStr(pReader, L"CounterName", &pDesc->CounterName));
  1550. CHECK_HR(ReadAttrStr(pReader, L"Kind", &pDesc->Kind));
  1551. bool isSRV = pDesc->Kind && 0 == _stricmp(pDesc->Kind, "SRV");
  1552. pDesc->SrvDescPresent = false;
  1553. DXGI_FORMAT *pFormat;
  1554. if (isSRV) {
  1555. // D3D12_SHADER_RESOURCE_VIEW_DESC
  1556. pFormat = &pDesc->SrvDesc.Format;
  1557. }
  1558. else {
  1559. // D3D12_UNORDERED_ACCESS_VIEW_DESC - default for parsing
  1560. pFormat = &pDesc->UavDesc.Format;
  1561. }
  1562. HRESULT hrFormat = ReadAttrDXGI_FORMAT(pReader, L"Format", pFormat);
  1563. CHECK_HR(hrFormat);
  1564. if (isSRV) {
  1565. pDesc->SrvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
  1566. pDesc->SrvDescPresent |= S_OK ==
  1567. CHECK_HR_RET(ReadAttrSRV_DIMENSION(pReader, L"Dimension", &pDesc->SrvDesc.ViewDimension));
  1568. switch (pDesc->SrvDesc.ViewDimension) {
  1569. case D3D12_SRV_DIMENSION_BUFFER:
  1570. pDesc->SrvDescPresent |= S_OK ==
  1571. CHECK_HR_RET(ReadAttrUINT64(pReader, L"FirstElement", &pDesc->SrvDesc.Buffer.FirstElement));
  1572. LPCSTR pFlags;
  1573. pDesc->SrvDescPresent |= S_OK ==
  1574. CHECK_HR_RET(ReadAttrStr(pReader, L"Flags", &pFlags));
  1575. if (pFlags && *pFlags && 0 == _stricmp(pFlags, "RAW")) {
  1576. pDesc->SrvDesc.Buffer.Flags = D3D12_BUFFER_SRV_FLAG_RAW;
  1577. }
  1578. else {
  1579. pDesc->SrvDesc.Buffer.Flags = D3D12_BUFFER_SRV_FLAG_NONE;
  1580. }
  1581. pDesc->SrvDescPresent |= S_OK ==
  1582. CHECK_HR_RET(ReadAttrUINT(pReader, L"NumElements", &pDesc->SrvDesc.Buffer.NumElements));
  1583. pDesc->SrvDescPresent |= S_OK ==
  1584. CHECK_HR_RET(ReadAttrUINT(pReader, L"StructureByteStride", &pDesc->SrvDesc.Buffer.StructureByteStride));
  1585. break;
  1586. default:
  1587. CHECK_HR(E_NOTIMPL);
  1588. }
  1589. }
  1590. else {
  1591. CHECK_HR(ReadAttrUAV_DIMENSION(pReader, L"Dimension", &pDesc->UavDesc.ViewDimension));
  1592. switch (pDesc->UavDesc.ViewDimension) {
  1593. case D3D12_UAV_DIMENSION_BUFFER:
  1594. CHECK_HR(ReadAttrUINT64(pReader, L"FirstElement", &pDesc->UavDesc.Buffer.FirstElement));
  1595. CHECK_HR(ReadAttrUINT(pReader, L"NumElements", &pDesc->UavDesc.Buffer.NumElements));
  1596. CHECK_HR(ReadAttrUINT(pReader, L"StructureByteStride", &pDesc->UavDesc.Buffer.StructureByteStride));
  1597. CHECK_HR(ReadAttrUINT64(pReader, L"CounterOffsetInBytes", &pDesc->UavDesc.Buffer.CounterOffsetInBytes));
  1598. LPCSTR pFlags;
  1599. CHECK_HR(ReadAttrStr(pReader, L"Flags", &pFlags));
  1600. if (pFlags && *pFlags && 0 == _stricmp(pFlags, "RAW")) {
  1601. pDesc->UavDesc.Buffer.Flags = D3D12_BUFFER_UAV_FLAG_RAW;
  1602. }
  1603. else {
  1604. pDesc->UavDesc.Buffer.Flags = D3D12_BUFFER_UAV_FLAG_NONE;
  1605. }
  1606. if (hrFormat == S_FALSE && pDesc->UavDesc.Buffer.Flags & D3D12_BUFFER_UAV_FLAG_RAW) {
  1607. pDesc->UavDesc.Format = DXGI_FORMAT_R32_TYPELESS;
  1608. }
  1609. break;
  1610. case D3D12_UAV_DIMENSION_TEXTURE1D:
  1611. CHECK_HR(ReadAttrUINT(pReader, L"MipSlice", &pDesc->UavDesc.Texture1D.MipSlice));
  1612. break;
  1613. case D3D12_UAV_DIMENSION_TEXTURE1DARRAY:
  1614. CHECK_HR(ReadAttrUINT(pReader, L"MipSlice", &pDesc->UavDesc.Texture1DArray.MipSlice));
  1615. CHECK_HR(ReadAttrUINT(pReader, L"FirstArraySlice", &pDesc->UavDesc.Texture1DArray.FirstArraySlice));
  1616. CHECK_HR(ReadAttrUINT(pReader, L"ArraySize", &pDesc->UavDesc.Texture1DArray.ArraySize));
  1617. break;
  1618. case D3D12_UAV_DIMENSION_TEXTURE2D:
  1619. CHECK_HR(ReadAttrUINT(pReader, L"MipSlice", &pDesc->UavDesc.Texture2D.MipSlice));
  1620. CHECK_HR(ReadAttrUINT(pReader, L"PlaneSlice", &pDesc->UavDesc.Texture2D.PlaneSlice));
  1621. break;
  1622. case D3D12_UAV_DIMENSION_TEXTURE2DARRAY:
  1623. CHECK_HR(ReadAttrUINT(pReader, L"MipSlice", &pDesc->UavDesc.Texture2DArray.MipSlice));
  1624. CHECK_HR(ReadAttrUINT(pReader, L"FirstArraySlice", &pDesc->UavDesc.Texture2DArray.FirstArraySlice));
  1625. CHECK_HR(ReadAttrUINT(pReader, L"ArraySize", &pDesc->UavDesc.Texture2DArray.ArraySize));
  1626. CHECK_HR(ReadAttrUINT(pReader, L"PlaneSlice", &pDesc->UavDesc.Texture2DArray.PlaneSlice));
  1627. break;
  1628. case D3D12_UAV_DIMENSION_TEXTURE3D:
  1629. CHECK_HR(ReadAttrUINT(pReader, L"MipSlice", &pDesc->UavDesc.Texture3D.MipSlice));
  1630. CHECK_HR(ReadAttrUINT(pReader, L"FirstWSlice", &pDesc->UavDesc.Texture3D.FirstWSlice));
  1631. CHECK_HR(ReadAttrUINT(pReader, L"WSize", &pDesc->UavDesc.Texture3D.WSize));
  1632. break;
  1633. }
  1634. }
  1635. // If either is missing, set one from the other.
  1636. if (pDesc->Name && !pDesc->ResName) pDesc->ResName = pDesc->Name;
  1637. if (pDesc->ResName && !pDesc->Name) pDesc->Name = pDesc->ResName;
  1638. LPCSTR K = pDesc->Kind;
  1639. if (K == nullptr) {
  1640. ShaderOpLogFmt(L"Descriptor '%S' is missing Kind attribute.", pDesc->Name);
  1641. CHECK_HR(E_INVALIDARG);
  1642. } else if (0 != _stricmp(K, "UAV") && 0 != _stricmp(K, "SRV") &&
  1643. 0 != _stricmp(K, "CBV") && 0 != _stricmp(K, "RTV")) {
  1644. ShaderOpLogFmt(L"Descriptor '%S' references unknown kind '%S'",
  1645. pDesc->Name, K);
  1646. CHECK_HR(E_INVALIDARG);
  1647. }
  1648. }
  1649. void ShaderOpParser::ParseDescriptorHeap(IXmlReader *pReader, ShaderOpDescriptorHeap *pHeap) {
  1650. if (!ReadAtElementName(pReader, L"DescriptorHeap"))
  1651. return;
  1652. CHECK_HR(ReadAttrStr(pReader, L"Name", &pHeap->Name));
  1653. HRESULT hrFlags = ReadAttrDESCRIPTOR_HEAP_FLAGS(pReader, L"Flags", &pHeap->Desc.Flags);
  1654. CHECK_HR(hrFlags);
  1655. CHECK_HR(ReadAttrUINT(pReader, L"NodeMask", &pHeap->Desc.NodeMask));
  1656. CHECK_HR(ReadAttrUINT(pReader, L"NumDescriptors", &pHeap->Desc.NumDescriptors));
  1657. CHECK_HR(ReadAttrDESCRIPTOR_HEAP_TYPE(pReader, L"Type", &pHeap->Desc.Type));
  1658. if (pHeap->Desc.Type == D3D12_DESCRIPTOR_HEAP_TYPE_RTV && hrFlags == S_FALSE)
  1659. pHeap->Desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
  1660. if (pReader->IsEmptyElement())
  1661. return;
  1662. UINT startDepth;
  1663. XmlNodeType nt;
  1664. CHECK_HR(pReader->GetDepth(&startDepth));
  1665. std::wstring value;
  1666. for (;;) {
  1667. UINT depth;
  1668. CHECK_HR(pReader->Read(&nt));
  1669. CHECK_HR(pReader->GetDepth(&depth));
  1670. if (nt == XmlNodeType_EndElement && depth == startDepth + 1)
  1671. break;
  1672. if (nt == XmlNodeType_Element) {
  1673. LPCWSTR pLocalName;
  1674. CHECK_HR(pReader->GetLocalName(&pLocalName, nullptr));
  1675. if (0 == wcscmp(pLocalName, L"Descriptor")) {
  1676. ShaderOpDescriptor D;
  1677. ParseDescriptor(pReader, &D);
  1678. pHeap->Descriptors.push_back(D);
  1679. }
  1680. }
  1681. }
  1682. }
  1683. void ShaderOpParser::ParseInputElement(IXmlReader *pReader, D3D12_INPUT_ELEMENT_DESC *pInputElement) {
  1684. if (!ReadAtElementName(pReader, L"InputElement"))
  1685. return;
  1686. CHECK_HR(ReadAttrStr(pReader, L"SemanticName", &pInputElement->SemanticName));
  1687. CHECK_HR(ReadAttrUINT(pReader, L"SemanticIndex", &pInputElement->SemanticIndex));
  1688. CHECK_HR(ReadAttrDXGI_FORMAT(pReader, L"Format", &pInputElement->Format));
  1689. CHECK_HR(ReadAttrUINT(pReader, L"InputSlot", &pInputElement->InputSlot));
  1690. CHECK_HR(ReadAttrUINT(pReader, L"AlignedByteOffset", &pInputElement->AlignedByteOffset, D3D12_APPEND_ALIGNED_ELEMENT));
  1691. CHECK_HR(ReadAttrINPUT_CLASSIFICATION(pReader, L"InputSlotClass", &pInputElement->InputSlotClass));
  1692. CHECK_HR(ReadAttrUINT(pReader, L"InstanceDataStepRate", &pInputElement->InstanceDataStepRate));
  1693. }
  1694. void ShaderOpParser::ParseInputElements(IXmlReader *pReader, std::vector<D3D12_INPUT_ELEMENT_DESC> *pInputElements) {
  1695. if (!ReadAtElementName(pReader, L"InputElements"))
  1696. return;
  1697. if (pReader->IsEmptyElement()) return;
  1698. UINT startDepth;
  1699. XmlNodeType nt;
  1700. CHECK_HR(pReader->GetDepth(&startDepth));
  1701. for (;;) {
  1702. UINT depth;
  1703. CHECK_HR(pReader->Read(&nt));
  1704. CHECK_HR(pReader->GetDepth(&depth));
  1705. if (nt == XmlNodeType_EndElement && depth == startDepth + 1)
  1706. return;
  1707. if (nt == XmlNodeType_Element) {
  1708. LPCWSTR pLocalName;
  1709. CHECK_HR(pReader->GetLocalName(&pLocalName, nullptr));
  1710. if (0 == wcscmp(pLocalName, L"InputElement")) {
  1711. D3D12_INPUT_ELEMENT_DESC desc;
  1712. ParseInputElement(pReader, &desc);
  1713. pInputElements->push_back(desc);
  1714. }
  1715. }
  1716. }
  1717. }
  1718. void ShaderOpParser::ParseRenderTargets(IXmlReader *pReader, std::vector<ShaderOpRenderTarget> *pRenderTargets) {
  1719. if (!ReadAtElementName(pReader, L"RenderTargets"))
  1720. return;
  1721. if (pReader->IsEmptyElement()) return;
  1722. UINT startDepth;
  1723. XmlNodeType nt;
  1724. CHECK_HR(pReader->GetDepth(&startDepth));
  1725. for (;;) {
  1726. UINT depth;
  1727. CHECK_HR(pReader->Read(&nt));
  1728. CHECK_HR(pReader->GetDepth(&depth));
  1729. if (nt == XmlNodeType_EndElement && depth == startDepth + 1)
  1730. return;
  1731. if (nt == XmlNodeType_Element) {
  1732. LPCWSTR pLocalName;
  1733. CHECK_HR(pReader->GetLocalName(&pLocalName, nullptr));
  1734. if (0 == wcscmp(pLocalName, L"RenderTarget")) {
  1735. ShaderOpRenderTarget RT;
  1736. ZeroMemory(&RT, sizeof(RT));
  1737. ParseRenderTarget(pReader, &RT);
  1738. pRenderTargets->push_back(RT);
  1739. }
  1740. }
  1741. }
  1742. }
  1743. void ShaderOpParser::ParseRenderTarget(IXmlReader* pReader, ShaderOpRenderTarget *pRenderTarget) {
  1744. if (!ReadAtElementName(pReader, L"RenderTarget"))
  1745. return;
  1746. CHECK_HR(ReadAttrStr(pReader, L"Name", &pRenderTarget->Name));
  1747. if (pReader->IsEmptyElement()) return;
  1748. UINT startDepth;
  1749. XmlNodeType nt;
  1750. CHECK_HR(pReader->GetDepth(&startDepth));
  1751. for (;;) {
  1752. UINT depth;
  1753. CHECK_HR(pReader->Read(&nt));
  1754. CHECK_HR(pReader->GetDepth(&depth));
  1755. if (nt == XmlNodeType_EndElement && depth == startDepth + 1)
  1756. return;
  1757. if (nt == XmlNodeType_Element) {
  1758. LPCWSTR pLocalName;
  1759. CHECK_HR(pReader->GetLocalName(&pLocalName, nullptr));
  1760. if (0 == wcscmp(pLocalName, L"Viewport")) {
  1761. ParseViewport(pReader, &pRenderTarget->Viewport);
  1762. }
  1763. }
  1764. }
  1765. }
  1766. void ShaderOpParser::ParseViewport(IXmlReader* pReader, D3D12_VIEWPORT *pViewport) {
  1767. if (!ReadAtElementName(pReader, L"Viewport"))
  1768. return;
  1769. CHECK_HR(ReadAttrFloat(pReader, L"TopLeftX", &pViewport->TopLeftX));
  1770. CHECK_HR(ReadAttrFloat(pReader, L"TopLeftY", &pViewport->TopLeftY));
  1771. CHECK_HR(ReadAttrFloat(pReader, L"Width", &pViewport->Width));
  1772. CHECK_HR(ReadAttrFloat(pReader, L"Height", &pViewport->Height));
  1773. CHECK_HR(ReadAttrFloat(pReader, L"MinDepth", &pViewport->MinDepth));
  1774. CHECK_HR(ReadAttrFloat(pReader, L"MaxDepth", &pViewport->MaxDepth));
  1775. if (pReader->IsEmptyElement()) return;
  1776. UINT startDepth;
  1777. XmlNodeType nt;
  1778. CHECK_HR(pReader->GetDepth(&startDepth));
  1779. for (;;) {
  1780. UINT depth;
  1781. CHECK_HR(pReader->Read(&nt));
  1782. CHECK_HR(pReader->GetDepth(&depth));
  1783. if (nt == XmlNodeType_EndElement && depth == startDepth + 1)
  1784. return;
  1785. }
  1786. }
  1787. void ShaderOpParser::ParseRootValue(IXmlReader *pReader, ShaderOpRootValue *pRootValue) {
  1788. if (!ReadAtElementName(pReader, L"RootValue"))
  1789. return;
  1790. CHECK_HR(ReadAttrStr(pReader, L"ResName", &pRootValue->ResName));
  1791. CHECK_HR(ReadAttrStr(pReader, L"HeapName", &pRootValue->HeapName));
  1792. CHECK_HR(ReadAttrUINT(pReader, L"Index", &pRootValue->Index));
  1793. }
  1794. void ShaderOpParser::ParseRootValues(IXmlReader *pReader, std::vector<ShaderOpRootValue> *pRootValues) {
  1795. if (!ReadAtElementName(pReader, L"RootValues"))
  1796. return;
  1797. if (pReader->IsEmptyElement()) return;
  1798. UINT startDepth;
  1799. XmlNodeType nt;
  1800. CHECK_HR(pReader->GetDepth(&startDepth));
  1801. for (;;) {
  1802. UINT depth;
  1803. CHECK_HR(pReader->Read(&nt));
  1804. CHECK_HR(pReader->GetDepth(&depth));
  1805. if (nt == XmlNodeType_EndElement && depth == startDepth + 1)
  1806. return;
  1807. if (nt == XmlNodeType_Element) {
  1808. LPCWSTR pLocalName;
  1809. CHECK_HR(pReader->GetLocalName(&pLocalName, nullptr));
  1810. if (0 == wcscmp(pLocalName, L"RootValue")) {
  1811. ShaderOpRootValue V;
  1812. ParseRootValue(pReader, &V);
  1813. pRootValues->push_back(V);
  1814. }
  1815. }
  1816. }
  1817. }
  1818. void ShaderOpParser::ParseShaderOpSet(IStream *pStream, ShaderOpSet *pShaderOpSet) {
  1819. CComPtr<IXmlReader> pReader;
  1820. CHECK_HR(CreateXmlReader(__uuidof(IXmlReader), (void **)&pReader, nullptr));
  1821. CHECK_HR(pReader->SetInput(pStream));
  1822. ParseShaderOpSet(pReader, pShaderOpSet);
  1823. }
  1824. void ShaderOpParser::ParseShaderOpSet(IXmlReader *pReader, ShaderOpSet *pShaderOpSet) {
  1825. if (!ReadAtElementName(pReader, L"ShaderOpSet"))
  1826. return;
  1827. UINT startDepth;
  1828. CHECK_HR(pReader->GetDepth(&startDepth));
  1829. XmlNodeType nt = XmlNodeType_Element;
  1830. for (;;) {
  1831. if (nt == XmlNodeType_Element) {
  1832. LPCWSTR pLocalName;
  1833. CHECK_HR(pReader->GetLocalName(&pLocalName, nullptr));
  1834. if (0 == wcscmp(pLocalName, L"ShaderOp")) {
  1835. pShaderOpSet->ShaderOps.emplace_back(std::make_unique<ShaderOp>());
  1836. ParseShaderOp(pReader, pShaderOpSet->ShaderOps.back().get());
  1837. }
  1838. }
  1839. else if (nt == XmlNodeType_EndElement) {
  1840. UINT depth;
  1841. CHECK_HR(pReader->GetDepth(&depth));
  1842. if (depth == startDepth + 1)
  1843. return;
  1844. }
  1845. CHECK_HR(pReader->Read(&nt));
  1846. }
  1847. }
  1848. void ShaderOpParser::ParseShaderOp(IXmlReader *pReader, ShaderOp *pShaderOp) {
  1849. m_pStrings = &pShaderOp->Strings;
  1850. // Look for a ShaderOp element.
  1851. if (!ReadAtElementName(pReader, L"ShaderOp"))
  1852. return;
  1853. CHECK_HR(ReadAttrStr(pReader, L"Name", &pShaderOp->Name));
  1854. CHECK_HR(ReadAttrStr(pReader, L"CS", &pShaderOp->CS));
  1855. CHECK_HR(ReadAttrStr(pReader, L"AS", &pShaderOp->AS));
  1856. CHECK_HR(ReadAttrStr(pReader, L"MS", &pShaderOp->MS));
  1857. CHECK_HR(ReadAttrStr(pReader, L"VS", &pShaderOp->VS));
  1858. CHECK_HR(ReadAttrStr(pReader, L"HS", &pShaderOp->HS));
  1859. CHECK_HR(ReadAttrStr(pReader, L"DS", &pShaderOp->DS));
  1860. CHECK_HR(ReadAttrStr(pReader, L"GS", &pShaderOp->GS));
  1861. CHECK_HR(ReadAttrStr(pReader, L"PS", &pShaderOp->PS));
  1862. CHECK_HR(ReadAttrUINT(pReader, L"DispatchX", &pShaderOp->DispatchX, 1));
  1863. CHECK_HR(ReadAttrUINT(pReader, L"DispatchY", &pShaderOp->DispatchY, 1));
  1864. CHECK_HR(ReadAttrUINT(pReader, L"DispatchZ", &pShaderOp->DispatchZ, 1));
  1865. CHECK_HR(ReadAttrPRIMITIVE_TOPOLOGY_TYPE(pReader, L"TopologyType", &pShaderOp->PrimitiveTopologyType));
  1866. UINT startDepth;
  1867. CHECK_HR(pReader->GetDepth(&startDepth));
  1868. XmlNodeType nt = XmlNodeType_Element;
  1869. for (;;) {
  1870. if (nt == XmlNodeType_Element) {
  1871. LPCWSTR pLocalName;
  1872. CHECK_HR(pReader->GetLocalName(&pLocalName, nullptr));
  1873. if (0 == wcscmp(pLocalName, L"InputElements")) {
  1874. ParseInputElements(pReader, &pShaderOp->InputElements);
  1875. }
  1876. else if (0 == wcscmp(pLocalName, L"Shader")) {
  1877. ShaderOpShader shader;
  1878. ParseShader(pReader, &shader);
  1879. pShaderOp->Shaders.push_back(shader);
  1880. }
  1881. else if (0 == wcscmp(pLocalName, L"RootSignature")) {
  1882. ReadElementContentStr(pReader, &pShaderOp->RootSignature);
  1883. }
  1884. else if (0 == wcscmp(pLocalName, L"RenderTargets")) {
  1885. ParseRenderTargets(pReader, &pShaderOp->RenderTargets);
  1886. }
  1887. else if (0 == wcscmp(pLocalName, L"Resource")) {
  1888. ShaderOpResource resource;
  1889. ParseResource(pReader, &resource);
  1890. pShaderOp->Resources.push_back(resource);
  1891. }
  1892. else if (0 == wcscmp(pLocalName, L"DescriptorHeap")) {
  1893. ShaderOpDescriptorHeap heap;
  1894. ParseDescriptorHeap(pReader, &heap);
  1895. pShaderOp->DescriptorHeaps.push_back(heap);
  1896. }
  1897. else if (0 == wcscmp(pLocalName, L"RootValues")) {
  1898. ParseRootValues(pReader, &pShaderOp->RootValues);
  1899. }
  1900. }
  1901. else if (nt == XmlNodeType_EndElement) {
  1902. UINT depth;
  1903. CHECK_HR(pReader->GetDepth(&depth));
  1904. if (depth == startDepth + 1)
  1905. return;
  1906. }
  1907. if (S_FALSE == CHECK_HR_RET(pReader->Read(&nt)))
  1908. return;
  1909. }
  1910. }
  1911. LPCWSTR SkipByteInitSeparators(LPCWSTR pText) {
  1912. while (*pText && (*pText == L' ' || *pText == L'\t' ||
  1913. *pText == L'\r' || *pText == L'\n' || *pText == L'{' ||
  1914. *pText == L'}' || *pText == L','))
  1915. ++pText;
  1916. return pText;
  1917. }
  1918. LPCWSTR FindByteInitSeparators(LPCWSTR pText) {
  1919. while (*pText &&
  1920. !(*pText == L' ' || *pText == L'\t' ||
  1921. *pText == L'\r' || *pText == L'\n' || *pText == L'{' ||
  1922. *pText == L'}' || *pText == L','))
  1923. ++pText;
  1924. return pText;
  1925. }
  1926. using namespace hlsl;
  1927. DXIL::ComponentType GetCompType(LPCWSTR pText, LPCWSTR pEnd) {
  1928. // if no prefix shown, use it as a default
  1929. if (pText == pEnd) return DXIL::ComponentType::F32;
  1930. // check if suffix starts with (half)
  1931. if (wcsncmp(pText, L"(half)", 6) == 0) {
  1932. return DXIL::ComponentType::F16;
  1933. }
  1934. switch (*(pEnd - 1)) {
  1935. case L'h':
  1936. case L'H':
  1937. return DXIL::ComponentType::F16;
  1938. case L'l':
  1939. case L'L':
  1940. return DXIL::ComponentType::F64;
  1941. case L'u':
  1942. case L'U':
  1943. return DXIL::ComponentType::U32;
  1944. case L'i':
  1945. case L'I':
  1946. return DXIL::ComponentType::I32;
  1947. case L'f':
  1948. case L'F':
  1949. default:
  1950. return DXIL::ComponentType::F32;
  1951. }
  1952. }
  1953. void ParseDataFromText(LPCWSTR pText, LPCWSTR pEnd, DXIL::ComponentType compType, std::vector<BYTE> &V) {
  1954. BYTE *pB;
  1955. if (compType == DXIL::ComponentType::F16 || compType == DXIL::ComponentType::F32) {
  1956. float fVal;
  1957. size_t wordSize = pEnd - pText;
  1958. if (wordSize >= 3 && 0 == _wcsnicmp(pEnd - 3, L"nan", 3)) {
  1959. fVal = NAN;
  1960. }
  1961. else if (wordSize >= 4 && 0 == _wcsnicmp(pEnd - 4, L"-inf", 4)) {
  1962. fVal = -(INFINITY);
  1963. }
  1964. else if ((wordSize >= 3 && 0 == _wcsnicmp(pEnd - 3, L"inf", 3)) ||
  1965. (wordSize >= 4 && 0 == _wcsnicmp(pEnd - 4, L"+inf", 4))) {
  1966. fVal = INFINITY;
  1967. }
  1968. else if (wordSize >= 7 && 0 == _wcsnicmp(pEnd - 7, L"-denorm", 7)) {
  1969. fVal = -(FLT_MIN / 2);
  1970. }
  1971. else if (wordSize >= 6 && 0 == _wcsnicmp(pEnd - 6, L"denorm", 6)) {
  1972. fVal = (FLT_MIN / 2);
  1973. }
  1974. else {
  1975. fVal = wcstof(pText, nullptr);
  1976. }
  1977. if (compType == DXIL::ComponentType::F16) {
  1978. uint16_t fp16Val = ConvertFloat32ToFloat16(fVal);
  1979. pB = (BYTE *)&fp16Val;
  1980. V.insert(V.end(), pB, pB + sizeof(uint16_t));
  1981. }
  1982. else {
  1983. pB = (BYTE *)&fVal;
  1984. V.insert(V.end(), pB, pB + sizeof(float));
  1985. }
  1986. }
  1987. else if (compType == DXIL::ComponentType::I32) {
  1988. int val = _wtoi(pText);
  1989. pB = (BYTE *)&val;
  1990. V.insert(V.end(), pB, pB + sizeof(int));
  1991. }
  1992. else {
  1993. DXASSERT_ARGS(false, "Unsupported stream component type : %u", compType);
  1994. }
  1995. }
  1996. void ShaderOpParser::ParseResource(IXmlReader *pReader, ShaderOpResource *pResource) {
  1997. if (!ReadAtElementName(pReader, L"Resource"))
  1998. return;
  1999. CHECK_HR(ReadAttrStr(pReader, L"Name", &pResource->Name));
  2000. CHECK_HR(ReadAttrStr(pReader, L"Init", &pResource->Init));
  2001. CHECK_HR(ReadAttrBOOL(pReader, L"ReadBack", &pResource->ReadBack));
  2002. CHECK_HR(ReadAttrHEAP_TYPE(pReader, L"HeapType", &pResource->HeapProperties.Type));
  2003. CHECK_HR(ReadAttrCPU_PAGE_PROPERTY(pReader, L"CPUPageProperty", &pResource->HeapProperties.CPUPageProperty));
  2004. CHECK_HR(ReadAttrMEMORY_POOL(pReader, L"MemoryPoolPreference", &pResource->HeapProperties.MemoryPoolPreference));
  2005. CHECK_HR(ReadAttrUINT(pReader, L"CreationNodeMask", &pResource->HeapProperties.CreationNodeMask));
  2006. CHECK_HR(ReadAttrUINT(pReader, L"VisibleNodeMask", &pResource->HeapProperties.VisibleNodeMask));
  2007. // D3D12_RESOURCE_DESC Desc;
  2008. CHECK_HR(ReadAttrRESOURCE_DIMENSION(pReader, L"Dimension", &pResource->Desc.Dimension));
  2009. CHECK_HR(ReadAttrUINT64(pReader, L"Alignment", &pResource->Desc.Alignment));
  2010. CHECK_HR(ReadAttrUINT64(pReader, L"Width", &pResource->Desc.Width));
  2011. CHECK_HR(ReadAttrUINT(pReader, L"Height", &pResource->Desc.Height));
  2012. CHECK_HR(ReadAttrUINT16(pReader, L"DepthOrArraySize", &pResource->Desc.DepthOrArraySize));
  2013. CHECK_HR(ReadAttrUINT16(pReader, L"MipLevels", &pResource->Desc.MipLevels));
  2014. CHECK_HR(ReadAttrDXGI_FORMAT(pReader, L"Format", &pResource->Desc.Format));
  2015. CHECK_HR(ReadAttrUINT(pReader, L"SampleCount", &pResource->Desc.SampleDesc.Count));
  2016. CHECK_HR(ReadAttrUINT(pReader, L"SampleQual", &pResource->Desc.SampleDesc.Quality));
  2017. CHECK_HR(ReadAttrTEXTURE_LAYOUT(pReader, L"Layout", &pResource->Desc.Layout));
  2018. CHECK_HR(ReadAttrRESOURCE_FLAGS(pReader, L"Flags", &pResource->Desc.Flags));
  2019. CHECK_HR(ReadAttrHEAP_FLAGS(pReader, L"HeapFlags", &pResource->HeapFlags));
  2020. CHECK_HR(ReadAttrRESOURCE_STATES(pReader, L"InitialResourceState", &pResource->InitialResourceState));
  2021. CHECK_HR(ReadAttrRESOURCE_STATES(pReader, L"TransitionTo", &pResource->TransitionTo));
  2022. CHECK_HR(ReadAttrPRIMITIVE_TOPOLOGY(pReader, L"Topology", &pResource->PrimitiveTopology));
  2023. // Set some fixed values.
  2024. if (pResource->Desc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) {
  2025. pResource->Desc.Height = 1;
  2026. pResource->Desc.DepthOrArraySize = 1;
  2027. pResource->Desc.MipLevels = 1;
  2028. pResource->Desc.Format = DXGI_FORMAT_UNKNOWN;
  2029. pResource->Desc.SampleDesc.Count = 1;
  2030. pResource->Desc.SampleDesc.Quality = 0;
  2031. pResource->Desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
  2032. }
  2033. if (pResource->Desc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE1D) {
  2034. if (pResource->Desc.Height == 0) pResource->Desc.Height = 1;
  2035. if (pResource->Desc.DepthOrArraySize == 0) pResource->Desc.DepthOrArraySize = 1;
  2036. if (pResource->Desc.SampleDesc.Count == 0) pResource->Desc.SampleDesc.Count = 1;
  2037. }
  2038. if (pResource->Desc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE2D) {
  2039. if (pResource->Desc.DepthOrArraySize == 0) pResource->Desc.DepthOrArraySize = 1;
  2040. if (pResource->Desc.SampleDesc.Count == 0 ) pResource->Desc.SampleDesc.Count = 1;
  2041. }
  2042. // If the resource has text, that goes into the bytes initialization area.
  2043. if (pReader->IsEmptyElement())
  2044. return;
  2045. std::vector<BYTE> &V = pResource->InitBytes;
  2046. XmlNodeType nt;
  2047. CHECK_HR(pReader->GetNodeType(&nt));
  2048. for (;;) {
  2049. if (nt == XmlNodeType_EndElement) {
  2050. return;
  2051. }
  2052. if (nt == XmlNodeType_Text) {
  2053. // Handle the byte payload. '{', '}', ',', whitespace - these are all
  2054. // separators and are ignored in terms of structure. We simply read
  2055. // literals, figure out their type based on suffix, and write the bytes
  2056. // into the target array.
  2057. LPCWSTR pText;
  2058. pReader->GetValue(&pText, nullptr);
  2059. while (*pText) {
  2060. pText = SkipByteInitSeparators(pText);
  2061. if (!*pText) continue;
  2062. LPCWSTR pEnd = FindByteInitSeparators(pText);
  2063. // Consider looking for prefixes/suffixes to handle bases and types.
  2064. DXIL::ComponentType compType = GetCompType(pText, pEnd);
  2065. ParseDataFromText(pText, pEnd, compType, V);
  2066. pText = pEnd;
  2067. }
  2068. }
  2069. if (S_FALSE == CHECK_HR_RET(pReader->Read(&nt)))
  2070. return;
  2071. }
  2072. }
  2073. void ShaderOpParser::ParseShader(IXmlReader *pReader, ShaderOpShader *pShader) {
  2074. if (!ReadAtElementName(pReader, L"Shader"))
  2075. return;
  2076. CHECK_HR(ReadAttrStr(pReader, L"Name", &pShader->Name));
  2077. CHECK_HR(ReadAttrStr(pReader, L"EntryPoint", &pShader->EntryPoint));
  2078. CHECK_HR(ReadAttrStr(pReader, L"Target", &pShader->Target));
  2079. CHECK_HR(ReadAttrStr(pReader, L"Arguments", &pShader->Arguments));
  2080. CHECK_HR(ReadAttrBOOL(pReader, L"Compiled", &pShader->Compiled))
  2081. ReadElementContentStr(pReader, &pShader->Text);
  2082. bool hasText = pShader->Text && *pShader->Text;
  2083. if (hasText) {
  2084. LPCSTR pCheck;
  2085. CHECK_HR(ReadAttrStr(pReader, L"Text", &pCheck));
  2086. if (pCheck && *pCheck) {
  2087. ShaderOpLogFmt(L"Shader %S has text content and a Text attribute; it "
  2088. L"should only have one",
  2089. pShader->Name);
  2090. CHECK_HR(E_INVALIDARG);
  2091. }
  2092. }
  2093. else {
  2094. CHECK_HR(ReadAttrStr(pReader, L"Text", &pShader->Text));
  2095. }
  2096. if (pShader->EntryPoint == nullptr)
  2097. pShader->EntryPoint = m_pStrings->insert("main");
  2098. }
  2099. bool ShaderOpParser::ReadAtElementName(IXmlReader *pReader, LPCWSTR pName) {
  2100. XmlNodeType nt;
  2101. CHECK_HR(pReader->GetNodeType(&nt));
  2102. for (;;) {
  2103. if (nt == XmlNodeType_Element) {
  2104. LPCWSTR pLocalName;
  2105. CHECK_HR(pReader->GetLocalName(&pLocalName, nullptr));
  2106. if (0 == wcscmp(pLocalName, pName)) {
  2107. return true;
  2108. }
  2109. }
  2110. if (S_FALSE == CHECK_HR_RET(pReader->Read(&nt)))
  2111. return false;
  2112. }
  2113. }
  2114. #pragma endregion Parsing support
  2115. } // namespace st