12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081 |
- ///////////////////////////////////////////////////////////////////////////////
- // //
- // ShaderOpTest.cpp //
- // Copyright (C) Microsoft Corporation. All rights reserved. //
- // This file is distributed under the University of Illinois Open Source //
- // License. See LICENSE.TXT for details. //
- // //
- // Provides the implementation to run tests based on descriptions. //
- // //
- ///////////////////////////////////////////////////////////////////////////////
- #include <windows.h>
- #include <d3d12.h>
- #include <dxgi1_4.h>
- #include <D3dx12.h>
- #include <d3dcompiler.h>
- #include <atlbase.h>
- #include "ShaderOpTest.h"
- #include "dxc/dxcapi.h" // IDxcCompiler
- #include "dxc/Support/Global.h" // OutputDebugBytes
- #include "dxc/Support/Unicode.h" // IsStarMatchUTF16
- #include "dxc/Support/dxcapi.use.h" // DxcDllSupport
- #include "dxc/HLSL/DxilConstants.h" // ComponentType
- #include "WexTestClass.h" // TAEF
- #include "HLSLTestUtils.h" // LogCommentFmt
- #include <stdlib.h>
- #include <DirectXMath.h>
- #include <intsafe.h>
- #include <strsafe.h>
- #include <xmllite.h>
- #pragma comment(lib, "xmllite.lib")
- ///////////////////////////////////////////////////////////////////////////////
- // Useful helper functions.
- static st::OutputStringFn g_OutputStrFn;
- static void * g_OutputStrFnCtx;
- void st::SetOutputFn(void *pCtx, OutputStringFn F) {
- g_OutputStrFnCtx = pCtx;
- g_OutputStrFn = F;
- }
- static void ShaderOpLogFmt(_In_z_ _Printf_format_string_ const wchar_t *fmt, ...) {
- va_list args;
- va_start(args, fmt);
- std::wstring buf(hlsl_test::vFormatToWString(fmt, args));
- va_end(args);
- if (g_OutputStrFn == nullptr)
- WEX::Logging::Log::Comment(buf.data());
- else
- g_OutputStrFn(g_OutputStrFnCtx, buf.data());
- }
- // Rely on TAEF Verifier helpers.
- #define CHECK_HR(x) { \
- if (!g_OutputStrFn) VERIFY_SUCCEEDED(x); else { \
- HRESULT _check_hr = (x); \
- if (FAILED(_check_hr)) AtlThrow(x); } \
- }
- // Check the specified HRESULT and return the success value.
- static HRESULT CHECK_HR_RET(HRESULT hr) {
- CHECK_HR(hr);
- return hr;
- }
- HRESULT LogIfLost(HRESULT hr, ID3D12Device *pDevice) {
- if (hr == DXGI_ERROR_DEVICE_REMOVED) {
- HRESULT reason = pDevice->GetDeviceRemovedReason();
- LPCWSTR reasonText = L"?";
- if (reason == DXGI_ERROR_DEVICE_HUNG) reasonText = L"DXGI_ERROR_DEVICE_HUNG";
- if (reason == DXGI_ERROR_DEVICE_REMOVED) reasonText = L"DXGI_ERROR_DEVICE_REMOVED";
- if (reason == DXGI_ERROR_DEVICE_RESET) reasonText = L"DXGI_ERROR_DEVICE_RESET";
- if (reason == DXGI_ERROR_DRIVER_INTERNAL_ERROR) reasonText = L"DXGI_ERROR_DRIVER_INTERNAL_ERROR";
- if (reason == DXGI_ERROR_INVALID_CALL) reasonText = L"DXGI_ERROR_INVALID_CALL";
- ShaderOpLogFmt(L"Device lost: 0x%08x (%s)", reason, reasonText);
- }
- return hr;
- }
- HRESULT LogIfLost(HRESULT hr, ID3D12Resource *pResource) {
- if (hr == DXGI_ERROR_DEVICE_REMOVED) {
- CComPtr<ID3D12Device> pDevice;
- pResource->GetDevice(__uuidof(ID3D12Device), (void**)&pDevice);
- LogIfLost(hr, pDevice);
- }
- return hr;
- }
- bool UseHardwareDevice(const DXGI_ADAPTER_DESC1 &desc, LPCWSTR AdapterName) {
- if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) {
- // Don't select the Basic Render Driver adapter.
- return false;
- }
- if (!AdapterName)
- return true;
- return Unicode::IsStarMatchUTF16(AdapterName, wcslen(AdapterName),
- desc.Description, wcslen(desc.Description));
- }
- void GetHardwareAdapter(IDXGIFactory2 *pFactory, LPCWSTR AdapterName,
- IDXGIAdapter1 **ppAdapter) {
- CComPtr<IDXGIAdapter1> adapter;
- *ppAdapter = nullptr;
- for (UINT adapterIndex = 0;
- DXGI_ERROR_NOT_FOUND != pFactory->EnumAdapters1(adapterIndex, &adapter);
- ++adapterIndex) {
- DXGI_ADAPTER_DESC1 desc;
- adapter->GetDesc1(&desc);
- if (!UseHardwareDevice(desc, AdapterName)) {
- adapter.Release();
- continue;
- }
- // Check to see if the adapter supports Direct3D 12, but don't create the
- // actual device yet.
- if (SUCCEEDED(D3D12CreateDevice(adapter, D3D_FEATURE_LEVEL_11_0,
- _uuidof(ID3D12Device), nullptr))) {
- break;
- }
- adapter.Release();
- }
- *ppAdapter = adapter.Detach();
- }
- void RecordTransitionBarrier(ID3D12GraphicsCommandList *pCommandList,
- ID3D12Resource *pResource,
- D3D12_RESOURCE_STATES before,
- D3D12_RESOURCE_STATES after) {
- CD3DX12_RESOURCE_BARRIER barrier(
- CD3DX12_RESOURCE_BARRIER::Transition(pResource, before, after));
- pCommandList->ResourceBarrier(1, &barrier);
- }
- void ExecuteCommandList(ID3D12CommandQueue *pQueue, ID3D12CommandList *pList) {
- ID3D12CommandList *ppCommandLists[] = { pList };
- pQueue->ExecuteCommandLists(1, ppCommandLists);
- }
- HRESULT SetObjectName(ID3D12Object *pObject, LPCSTR pName) {
- if (pObject && pName) {
- CA2W WideName(pName);
- return pObject->SetName(WideName);
- }
- return S_FALSE;
- }
- void WaitForSignal(ID3D12CommandQueue *pCQ, ID3D12Fence *pFence,
- HANDLE hFence, UINT64 fenceValue) {
- // Signal and increment the fence value.
- const UINT64 fence = fenceValue;
- CHECK_HR(pCQ->Signal(pFence, fence));
- if (pFence->GetCompletedValue() < fenceValue) {
- CHECK_HR(pFence->SetEventOnCompletion(fenceValue, hFence));
- WaitForSingleObject(hFence, INFINITE);
- //CHECK_HR(pCQ->Wait(pFence, fenceValue));
- }
- }
- static void SetupComputeValuePattern(std::vector<uint32_t> &values, size_t count) {
- values.resize(count); // one element per dispatch group, in bytes
- for (size_t i = 0; i < count; ++i) {
- values[i] = (uint32_t)i;
- }
- }
- void MappedData::dump() const {
- OutputDebugBytes(m_pData, m_size);
- }
- void MappedData::reset() {
- if (m_pResource != nullptr) {
- m_pResource->Unmap(0, nullptr);
- m_pResource.Release();
- }
- m_pData = nullptr;
- }
- ///////////////////////////////////////////////////////////////////////////////
- // Helper class for mapped data.
- void MappedData::reset(ID3D12Resource *pResource, UINT32 sizeInBytes) {
- reset();
- D3D12_RANGE r;
- r.Begin = 0;
- r.End = sizeInBytes;
- CHECK_HR(LogIfLost(pResource->Map(0, &r, &m_pData), pResource));
- m_pResource = pResource;
- m_size = sizeInBytes;
- }
- ///////////////////////////////////////////////////////////////////////////////
- // ShaderOpTest library implementation.
- namespace st {
- LPCSTR string_table::insert(LPCSTR pValue) {
- std::unordered_set<LPCSTR, HashStr, PredStr>::iterator i = m_values.find(pValue);
- if (i == m_values.end()) {
- size_t bufSize = strlen(pValue) + 1;
- std::vector<char> s;
- s.resize(bufSize);
- strcpy_s(s.data(), bufSize, pValue);
- LPCSTR result = s.data();
- m_values.insert(result);
- m_strings.push_back(std::move(s));
- return result;
- }
- else {
- return *i;
- }
- }
- LPCSTR string_table::insert(LPCWSTR pValue) {
- CW2A pValueAnsi(pValue);
- return insert(pValueAnsi.m_psz);
- }
- void CommandListRefs::CreateForDevice(ID3D12Device *pDevice, bool compute) {
- D3D12_COMMAND_LIST_TYPE T = compute ? D3D12_COMMAND_LIST_TYPE_COMPUTE
- : D3D12_COMMAND_LIST_TYPE_DIRECT;
- D3D12_COMMAND_QUEUE_DESC queueDesc = {};
- queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
- queueDesc.Type = T;
- if (Queue == nullptr) {
- CHECK_HR(pDevice->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&Queue)));
- }
- CHECK_HR(pDevice->CreateCommandAllocator(T, IID_PPV_ARGS(&Allocator)));
- CHECK_HR(pDevice->CreateCommandList(0, T, Allocator, nullptr,
- IID_PPV_ARGS(&List)));
- }
- void ShaderOpTest::CopyBackResources() {
- CommandListRefs ResCommandList;
- ResCommandList.CreateForDevice(m_pDevice, m_pShaderOp->IsCompute());
- ID3D12GraphicsCommandList *pList = ResCommandList.List;
- pList->SetName(L"ShaderOpTest Resource ReadBack CommandList");
- for (ShaderOpResource &R : m_pShaderOp->Resources) {
- if (!R.ReadBack)
- continue;
- ShaderOpResourceData &D = m_ResourceData[R.Name];
- RecordTransitionBarrier(pList, D.Resource, D.ResourceState,
- D3D12_RESOURCE_STATE_COPY_SOURCE);
- D.ResourceState = D3D12_RESOURCE_STATE_COPY_SOURCE;
- D3D12_RESOURCE_DESC &Desc = D.ShaderOpRes->Desc;
- if (Desc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) {
- pList->CopyResource(D.ReadBack, D.Resource);
- }
- else {
- UINT rowPitch = Desc.Width * GetByteSizeForFormat(Desc.Format);
- if (rowPitch % D3D12_TEXTURE_DATA_PITCH_ALIGNMENT)
- rowPitch += D3D12_TEXTURE_DATA_PITCH_ALIGNMENT - (rowPitch % D3D12_TEXTURE_DATA_PITCH_ALIGNMENT);
- D3D12_PLACED_SUBRESOURCE_FOOTPRINT Footprint;
- Footprint.Offset = 0;
- Footprint.Footprint = CD3DX12_SUBRESOURCE_FOOTPRINT(Desc.Format, Desc.Width, Desc.Height, 1, rowPitch);
- CD3DX12_TEXTURE_COPY_LOCATION DstLoc(D.ReadBack, Footprint);
- CD3DX12_TEXTURE_COPY_LOCATION SrcLoc(D.Resource, 0);
- pList->CopyTextureRegion(&DstLoc, 0, 0, 0, &SrcLoc, nullptr);
- }
- }
- pList->Close();
- ExecuteCommandList(ResCommandList.Queue, pList);
- WaitForSignal(ResCommandList.Queue, m_pFence, m_hFence, m_FenceValue++);
- }
- void ShaderOpTest::CreateCommandList() {
- bool priorQueue = m_CommandList.Queue != nullptr;
- m_CommandList.CreateForDevice(m_pDevice, m_pShaderOp->IsCompute());
- m_CommandList.Allocator->SetName(L"ShaderOpTest Allocator");
- m_CommandList.List->SetName(L"ShaderOpTest CommandList");
- if (!priorQueue)
- m_CommandList.Queue->SetName(L"ShaderOpTest CommandList");
- }
- void ShaderOpTest::CreateDescriptorHeaps() {
- for (ShaderOpDescriptorHeap &H : m_pShaderOp->DescriptorHeaps) {
- CComPtr<ID3D12DescriptorHeap> pHeap;
- if (H.Desc.NumDescriptors == 0) {
- H.Desc.NumDescriptors = (UINT)H.Descriptors.size();
- }
- CHECK_HR(m_pDevice->CreateDescriptorHeap(&H.Desc, IID_PPV_ARGS(&pHeap)));
- m_DescriptorHeaps.push_back(pHeap);
- m_DescriptorHeapsByName[H.Name] = pHeap;
- SetObjectName(pHeap, H.Name);
- const UINT descriptorSize = m_pDevice->GetDescriptorHandleIncrementSize(H.Desc.Type);
- CD3DX12_CPU_DESCRIPTOR_HANDLE cpuHandle(pHeap->GetCPUDescriptorHandleForHeapStart());
- CD3DX12_GPU_DESCRIPTOR_HANDLE gpuHandle(pHeap->GetGPUDescriptorHandleForHeapStart());
- for (ShaderOpDescriptor &D : H.Descriptors) {
- ShaderOpResource *R = m_pShaderOp->GetResourceByName(D.ResName);
- if (R == nullptr) {
- LPCSTR DescName = D.Name ? D.Name : "[unnamed descriptor]";
- ShaderOpLogFmt(L"Descriptor '%S' references missing resource '%S'", DescName, D.ResName);
- CHECK_HR(E_INVALIDARG);
- }
- ShaderOpResourceData &Data = m_ResourceData[D.ResName];
- ShaderOpDescriptorData DData;
- DData.Descriptor = &D;
- DData.ResData = &Data;
- if (0 == _stricmp(D.Kind, "UAV")) {
- ID3D12Resource *pCounterResource = nullptr;
- if (D.CounterName && *D.CounterName) {
- ShaderOpResourceData &CounterData = m_ResourceData[D.CounterName];
- pCounterResource = CounterData.Resource;
- }
- m_pDevice->CreateUnorderedAccessView(Data.Resource, pCounterResource,
- &D.UavDesc, cpuHandle);
- }
- else if (0 == _stricmp(D.Kind, "SRV")) {
- D3D12_SHADER_RESOURCE_VIEW_DESC *pSrvDesc = nullptr;
- m_pDevice->CreateShaderResourceView(Data.Resource, pSrvDesc, cpuHandle);
- }
- else if (0 == _stricmp(D.Kind, "RTV")) {
- m_pDevice->CreateRenderTargetView(Data.Resource, nullptr, cpuHandle);
- }
- else if (0 == _stricmp(D.Kind, "CBV")) {
- D3D12_CONSTANT_BUFFER_VIEW_DESC cbvDesc;
- cbvDesc.BufferLocation = Data.Resource->GetGPUVirtualAddress();
- cbvDesc.SizeInBytes = Data.Resource->GetDesc().Width;
- m_pDevice->CreateConstantBufferView(&cbvDesc, cpuHandle);
- }
- DData.GPUHandle = gpuHandle;
- DData.CPUHandle = cpuHandle;
- m_DescriptorData[R->Name] = DData;
- cpuHandle = cpuHandle.Offset(descriptorSize);
- gpuHandle = gpuHandle.Offset(descriptorSize);
- }
- }
- // Create query descriptor heap.
- D3D12_QUERY_HEAP_DESC queryHeapDesc;
- ZeroMemory(&queryHeapDesc, sizeof(queryHeapDesc));
- queryHeapDesc.Count = 1;
- queryHeapDesc.Type = D3D12_QUERY_HEAP_TYPE_PIPELINE_STATISTICS;
- CHECK_HR(m_pDevice->CreateQueryHeap(&queryHeapDesc, IID_PPV_ARGS(&m_pQueryHeap)));
- }
- void ShaderOpTest::CreateDevice() {
- if (m_pDevice == nullptr) {
- const D3D_FEATURE_LEVEL FeatureLevelRequired = D3D_FEATURE_LEVEL_11_0;
- CComPtr<IDXGIFactory4> factory;
- CComPtr<ID3D12Device> pDevice;
- CHECK_HR(CreateDXGIFactory1(IID_PPV_ARGS(&factory)));
- if (m_pShaderOp->UseWarpDevice) {
- CComPtr<IDXGIAdapter> warpAdapter;
- CHECK_HR(factory->EnumWarpAdapter(IID_PPV_ARGS(&warpAdapter)));
- CHECK_HR(D3D12CreateDevice(warpAdapter, FeatureLevelRequired,
- IID_PPV_ARGS(&pDevice)));
- } else {
- CComPtr<IDXGIAdapter1> hardwareAdapter;
- GetHardwareAdapter(factory, m_pShaderOp->AdapterName, &hardwareAdapter);
- if (hardwareAdapter == nullptr) {
- CHECK_HR(HRESULT_FROM_WIN32(ERROR_NOT_FOUND));
- }
- CHECK_HR(D3D12CreateDevice(hardwareAdapter, FeatureLevelRequired,
- IID_PPV_ARGS(&pDevice)));
- }
- m_pDevice.Attach(pDevice.Detach());
- m_pDevice->SetName(L"ShaderOpTest Device");
- }
- m_FenceValue = 1;
- CHECK_HR(m_pDevice->CreateFence(0, D3D12_FENCE_FLAG_NONE,
- __uuidof(ID3D12Fence), (void **)&m_pFence));
- m_pFence->SetName(L"ShaderOpTest Fence");
- m_hFence = CreateEvent(nullptr, FALSE, FALSE, nullptr);
- if (m_hFence == nullptr) {
- AtlThrow(HRESULT_FROM_WIN32(GetLastError()));
- }
- }
- static void InitByteCode(D3D12_SHADER_BYTECODE *pBytecode, ID3D10Blob *pBlob) {
- if (pBlob == nullptr) {
- pBytecode->BytecodeLength = 0;
- pBytecode->pShaderBytecode = nullptr;
- }
- else {
- pBytecode->BytecodeLength = pBlob->GetBufferSize();
- pBytecode->pShaderBytecode = pBlob->GetBufferPointer();
- }
- }
- void ShaderOpTest::CreatePipelineState() {
- CreateRootSignature();
- CreateShaders();
- if (m_pShaderOp->IsCompute()) {
- CComPtr<ID3D10Blob> pCS;
- pCS = m_Shaders[m_pShaderOp->CS];
- D3D12_COMPUTE_PIPELINE_STATE_DESC CDesc;
- ZeroMemory(&CDesc, sizeof(CDesc));
- CDesc.pRootSignature = m_pRootSignature.p;
- InitByteCode(&CDesc.CS, pCS);
- CHECK_HR(m_pDevice->CreateComputePipelineState(&CDesc, IID_PPV_ARGS(&m_pPSO)));
- }
- else {
- CComPtr<ID3D10Blob> pPS;
- CComPtr<ID3D10Blob> pVS;
- pPS = m_Shaders[m_pShaderOp->PS];
- pVS = m_Shaders[m_pShaderOp->VS];
- D3D12_GRAPHICS_PIPELINE_STATE_DESC GDesc;
- ZeroMemory(&GDesc, sizeof(GDesc));
- InitByteCode(&GDesc.VS, pVS);
- InitByteCode(&GDesc.PS, pPS);
- GDesc.InputLayout.NumElements = m_pShaderOp->InputElements.size();
- GDesc.InputLayout.pInputElementDescs = m_pShaderOp->InputElements.data();
- GDesc.PrimitiveTopologyType = m_pShaderOp->PrimitiveTopologyType;
- GDesc.NumRenderTargets = m_pShaderOp->RenderTargets.size();
- GDesc.SampleMask = m_pShaderOp->SampleMask;
- for (size_t i = 0; i < m_pShaderOp->RenderTargets.size(); ++i) {
- ShaderOpResource *R = m_pShaderOp->GetResourceByName(m_pShaderOp->RenderTargets[i]);
- GDesc.RTVFormats[i] = R->Desc.Format;
- }
- GDesc.SampleDesc.Count = 1; // TODO: read from file, set from shader operation; also apply to count
- GDesc.RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT); // TODO: read from file, set from op
- GDesc.BlendState = CD3DX12_BLEND_DESC(D3D12_DEFAULT); // TODO: read from file, set from op
- // TODO: pending values to set
- #if 0
- D3D12_STREAM_OUTPUT_DESC StreamOutput;
- D3D12_DEPTH_STENCIL_DESC DepthStencilState;
- D3D12_INDEX_BUFFER_STRIP_CUT_VALUE IBStripCutValue;
- DXGI_FORMAT DSVFormat;
- UINT NodeMask;
- D3D12_PIPELINE_STATE_FLAGS Flags;
- #endif
- GDesc.pRootSignature = m_pRootSignature.p;
- CHECK_HR(m_pDevice->CreateGraphicsPipelineState(&GDesc, IID_PPV_ARGS(&m_pPSO)));
- }
- }
- void ShaderOpTest::CreateResources() {
- CommandListRefs ResCommandList;
- ResCommandList.CreateForDevice(m_pDevice, true);
- ResCommandList.Allocator->SetName(L"ShaderOpTest Resource Creation Allocation");
- ResCommandList.Queue->SetName(L"ShaderOpTest Resource Creation Queue");
- ResCommandList.List->SetName(L"ShaderOpTest Resource Creation CommandList");
-
- ID3D12GraphicsCommandList *pList = ResCommandList.List.p;
- std::vector<CComPtr<ID3D12Resource> > intermediates;
- for (ShaderOpResource &R : m_pShaderOp->Resources) {
- if (m_ResourceData.count(R.Name) > 0) continue;
- // Initialize the upload resource early, to allow a by-name initializer
- // to set the desired width.
- bool initByName = R.Init && 0 == _stricmp("byname", R.Init);
- bool initZero = R.Init && 0 == _stricmp("zero", R.Init);
- bool initFromBytes = R.Init && 0 == _stricmp("frombytes", R.Init);
- bool hasInit = initByName || initZero || initFromBytes;
- bool isBuffer = R.Desc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER;
- std::vector<BYTE> values;
- if (hasInit) {
- if (isBuffer) {
- values.resize((size_t)R.Desc.Width);
- }
- else {
- // Probably needs more information.
- values.resize((size_t)(R.Desc.Width * R.Desc.Height *
- GetByteSizeForFormat(R.Desc.Format)));
- }
- if (initZero) {
- memset(values.data(), 0, values.size());
- }
- else if (initByName) {
- m_InitCallbackFn(R.Name, values, m_pShaderOp);
- if (isBuffer) {
- R.Desc.Width = values.size();
- }
- }
- else if (initFromBytes) {
- values = R.InitBytes;
- if (R.Desc.Width == 0) {
- if (isBuffer) {
- R.Desc.Width = values.size();
- }
- else if (R.Desc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE1D) {
- R.Desc.Width = values.size() / GetByteSizeForFormat(R.Desc.Format);
- }
- }
- }
- }
- CComPtr<ID3D12Resource> pResource;
- CHECK_HR(m_pDevice->CreateCommittedResource(
- &R.HeapProperties, R.HeapFlags, &R.Desc, R.InitialResourceState,
- nullptr, IID_PPV_ARGS(&pResource)));
- ShaderOpResourceData &D = m_ResourceData[R.Name];
- D.ShaderOpRes = &R;
- D.Resource = pResource;
- D.ResourceState = R.InitialResourceState;
- SetObjectName(pResource, R.Name);
- if (hasInit) {
- CComPtr<ID3D12Resource> pIntermediate;
- CD3DX12_HEAP_PROPERTIES upload(D3D12_HEAP_TYPE_UPLOAD);
- D3D12_RESOURCE_DESC uploadDesc = R.Desc;
- // Calculate size required for intermediate buffer
- UINT64 totalBytes;
- m_pDevice->GetCopyableFootprints(&uploadDesc, 0, 1, 0, nullptr, nullptr, nullptr, &totalBytes);
- if (!isBuffer) {
- // Assuming a simple linear layout here.
- uploadDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
- uploadDesc.Width = totalBytes;
- uploadDesc.Height = 1;
- uploadDesc.MipLevels = 1;
- uploadDesc.Format = DXGI_FORMAT_UNKNOWN;
- uploadDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
- }
- uploadDesc.Flags = D3D12_RESOURCE_FLAG_NONE;
- CHECK_HR(m_pDevice->CreateCommittedResource(
- &upload, D3D12_HEAP_FLAG_NONE, &uploadDesc,
- D3D12_RESOURCE_STATE_GENERIC_READ, nullptr,
- IID_PPV_ARGS(&pIntermediate)));
- intermediates.push_back(pIntermediate);
- char uploadObjectName[128];
- if (R.Name && SUCCEEDED(StringCchPrintfA(
- uploadObjectName, _countof(uploadObjectName),
- "Upload resource for %s", R.Name))) {
- SetObjectName(pIntermediate, uploadObjectName);
- }
- D3D12_SUBRESOURCE_DATA transferData;
- transferData.pData = values.data();
- transferData.RowPitch = values.size() / R.Desc.Height;
- transferData.SlicePitch = values.size();
- UpdateSubresources<1>(pList, pResource.p, pIntermediate.p, 0, 0, 1,
- &transferData);
- }
- if (R.ReadBack) {
- CComPtr<ID3D12Resource> pReadbackResource;
- CD3DX12_HEAP_PROPERTIES readback(D3D12_HEAP_TYPE_READBACK);
- UINT64 width = R.Desc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER
- ? R.Desc.Width
- : (R.Desc.Height * R.Desc.Width *
- GetByteSizeForFormat(R.Desc.Format));
- CD3DX12_RESOURCE_DESC readbackDesc(CD3DX12_RESOURCE_DESC::Buffer(width));
- readbackDesc.Flags = D3D12_RESOURCE_FLAG_NONE;
- CHECK_HR(m_pDevice->CreateCommittedResource(
- &readback, D3D12_HEAP_FLAG_NONE, &readbackDesc,
- D3D12_RESOURCE_STATE_COPY_DEST, nullptr,
- IID_PPV_ARGS(&pReadbackResource)));
- D.ReadBack = pReadbackResource;
- char readbackObjectName[128];
- if (R.Name && SUCCEEDED(StringCchPrintfA(
- readbackObjectName, _countof(readbackObjectName),
- "Readback resource for %s", R.Name))) {
- SetObjectName(pReadbackResource, readbackObjectName);
- }
- }
- if (R.TransitionTo != D.ResourceState) {
- RecordTransitionBarrier(pList, D.Resource, D.ResourceState,
- R.TransitionTo);
- D.ResourceState = R.TransitionTo;
- }
- }
- // Create a buffer to receive query results.
- {
- CComPtr<ID3D12Resource> pReadbackResource;
- CD3DX12_HEAP_PROPERTIES readback(D3D12_HEAP_TYPE_READBACK);
- CD3DX12_RESOURCE_DESC readbackDesc(CD3DX12_RESOURCE_DESC::Buffer(sizeof(D3D12_QUERY_DATA_PIPELINE_STATISTICS)));
- CHECK_HR(m_pDevice->CreateCommittedResource(
- &readback, D3D12_HEAP_FLAG_NONE, &readbackDesc,
- D3D12_RESOURCE_STATE_COPY_DEST, nullptr,
- IID_PPV_ARGS(&m_pQueryBuffer)));
- SetObjectName(m_pQueryBuffer, "Query Pipeline Readback Buffer");
- }
- CHECK_HR(pList->Close());
- ExecuteCommandList(ResCommandList.Queue, pList);
- WaitForSignal(ResCommandList.Queue, m_pFence, m_hFence, m_FenceValue++);
- }
- void ShaderOpTest::CreateRootSignature() {
- if (m_pShaderOp->RootSignature == nullptr) {
- AtlThrow(E_INVALIDARG);
- }
- CComPtr<ID3DBlob> pCode;
- CComPtr<ID3DBlob> pRootSignatureBlob;
- CComPtr<ID3DBlob> pError;
- std::string sQuoted;
- sQuoted.reserve(2 + strlen(m_pShaderOp->RootSignature) + 1);
- sQuoted.append("\"");
- sQuoted.append(m_pShaderOp->RootSignature);
- sQuoted.append("\"");
- char *ch = (char *)sQuoted.data();
- while (*ch) {
- if (*ch == '\r' || *ch == '\n') *ch = ' ';
- ++ch;
- }
- D3D_SHADER_MACRO M[2] = {
- { "RootSigVal", sQuoted.c_str() },
- { nullptr, nullptr }
- };
- HRESULT hr = D3DCompile(nullptr, 0, "RootSigShader", M, nullptr, sQuoted.c_str(),
- "rootsig_1_0", 0, 0, &pCode, &pError);
- if (FAILED(hr) && pError != nullptr) {
- ShaderOpLogFmt(L"Failed to compile root signature:\r\n%*S",
- (int)pError->GetBufferSize(),
- (LPCSTR)pError->GetBufferPointer());
- }
- CHECK_HR(hr);
- CHECK_HR(D3DGetBlobPart(pCode->GetBufferPointer(), pCode->GetBufferSize(),
- D3D_BLOB_ROOT_SIGNATURE, 0, &pRootSignatureBlob));
- CHECK_HR(m_pDevice->CreateRootSignature(
- 0, pRootSignatureBlob->GetBufferPointer(),
- pRootSignatureBlob->GetBufferSize(), IID_PPV_ARGS(&m_pRootSignature)));
- }
- static bool TargetUsesDxil(LPCSTR pText) {
- return (strlen(pText) > 3) && pText[3] >= '6'; // xx_6xx
- }
- static void splitWStringIntoVectors(LPWSTR str, wchar_t delim, std::vector<LPWSTR> &list) {
- if (str) {
- LPWSTR cur = str;
- list.push_back(cur);
- while (*cur != L'\0') {
- if (*cur == delim) {
- list.push_back(cur+1);
- *(cur) = L'\0';
- }
- cur++;
- }
- }
- }
- void ShaderOpTest::CreateShaders() {
- for (ShaderOpShader &S : m_pShaderOp->Shaders) {
- CComPtr<ID3DBlob> pCode;
- HRESULT hr = S_OK;
- LPCSTR pText = m_pShaderOp->GetShaderText(&S);
- if (TargetUsesDxil(S.Target)) {
- CComPtr<IDxcCompiler> pCompiler;
- CComPtr<IDxcLibrary> pLibrary;
- CComPtr<IDxcBlobEncoding> pTextBlob;
- CComPtr<IDxcOperationResult> pResult;
- CA2W nameW(S.Name, CP_UTF8);
- CA2W entryPointW(S.EntryPoint, CP_UTF8);
- CA2W targetW(S.Target, CP_UTF8);
- CA2W argumentsW(S.Arguments, CP_UTF8);
- std::vector<LPWSTR> argumentsWList;
- splitWStringIntoVectors(argumentsW, L' ', argumentsWList);
- HRESULT resultCode;
- CHECK_HR(m_pDxcSupport->CreateInstance(CLSID_DxcLibrary, &pLibrary));
- CHECK_HR(pLibrary->CreateBlobWithEncodingFromPinned(
- (LPBYTE)pText, (UINT32)strlen(pText), CP_UTF8, &pTextBlob));
- CHECK_HR(m_pDxcSupport->CreateInstance(CLSID_DxcCompiler, &pCompiler));
- CHECK_HR(pCompiler->Compile(pTextBlob, nameW, entryPointW, targetW,
- (LPCWSTR *)argumentsWList.data(), argumentsWList.size(),
- nullptr, 0,
- nullptr, &pResult));
- CHECK_HR(pResult->GetStatus(&resultCode));
- if (FAILED(resultCode)) {
- CComPtr<IDxcBlobEncoding> errors;
- CHECK_HR(pResult->GetErrorBuffer(&errors));
- ShaderOpLogFmt(L"Failed to compile shader: %*S\r\n",
- (int)errors->GetBufferSize(),
- errors->GetBufferPointer());
- }
- CHECK_HR(resultCode);
- CHECK_HR(pResult->GetResult((IDxcBlob **)&pCode));
- } else {
- CComPtr<ID3DBlob> pError;
- hr = D3DCompile(pText, strlen(pText), S.Name, nullptr, nullptr,
- S.EntryPoint, S.Target, 0, 0, &pCode, &pError);
- if (FAILED(hr) && pError != nullptr) {
- ShaderOpLogFmt(L"%*S\r\n", (int)pError->GetBufferSize(),
- ((LPCSTR)pError->GetBufferPointer()));
- }
- }
- CHECK_HR(hr);
- m_Shaders[S.Name] = pCode;
- }
- }
- void ShaderOpTest::GetPipelineStats(D3D12_QUERY_DATA_PIPELINE_STATISTICS *pStats) {
- MappedData M;
- M.reset(m_pQueryBuffer, sizeof(*pStats));
- memcpy(pStats, M.data(), sizeof(*pStats));
- }
- void ShaderOpTest::GetReadBackData(LPCSTR pResourceName, MappedData *pData) {
- pResourceName = m_pShaderOp->Strings.insert(pResourceName); // Unique
- ShaderOpResourceData &D = m_ResourceData.at(pResourceName);
- D3D12_RESOURCE_DESC Desc = D.ReadBack->GetDesc();
- UINT32 sizeInBytes = (UINT32)Desc.Width;
- pData->reset(D.ReadBack, sizeInBytes);
- }
- static void SetDescriptorHeaps(ID3D12GraphicsCommandList *pList,
- std::vector<ID3D12DescriptorHeap *> &heaps) {
- if (heaps.empty())
- return;
- std::vector<ID3D12DescriptorHeap *> localHeaps;
- for (auto &H : heaps) {
- if (H->GetDesc().Flags & D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE) {
- localHeaps.push_back(H);
- }
- }
- if (!localHeaps.empty())
- pList->SetDescriptorHeaps((UINT)localHeaps.size(), localHeaps.data());
- }
- void ShaderOpTest::RunCommandList() {
- ID3D12GraphicsCommandList *pList = m_CommandList.List.p;
- if (m_pShaderOp->IsCompute()) {
- pList->SetPipelineState(m_pPSO);
- pList->SetComputeRootSignature(m_pRootSignature);
- SetDescriptorHeaps(pList, m_DescriptorHeaps);
- SetRootValues(pList, m_pShaderOp->IsCompute());
- pList->Dispatch(m_pShaderOp->DispatchX, m_pShaderOp->DispatchY,
- m_pShaderOp->DispatchZ);
- } else {
- pList->SetPipelineState(m_pPSO);
- pList->SetGraphicsRootSignature(m_pRootSignature);
- SetDescriptorHeaps(pList, m_DescriptorHeaps);
- SetRootValues(pList, m_pShaderOp->IsCompute());
- if (!m_pShaderOp->RenderTargets.empty()) {
- // Use the first render target to set up the viewport and scissors.
- ShaderOpResource *R = m_pShaderOp->GetResourceByName(m_pShaderOp->RenderTargets[0]);
- D3D12_VIEWPORT viewport;
- D3D12_RECT scissorRect;
- memset(&viewport, 0, sizeof(viewport));
- viewport.Height = R->Desc.Height;
- viewport.Width = R->Desc.Width;
- viewport.MaxDepth = 1.0f;
- memset(&scissorRect, 0, sizeof(scissorRect));
- scissorRect.right = viewport.Width;
- scissorRect.bottom = viewport.Height;
- pList->RSSetViewports(1, &viewport);
- pList->RSSetScissorRects(1, &scissorRect);
- }
- // Indicate that the buffers will be used as render targets.
- D3D12_CPU_DESCRIPTOR_HANDLE rtvHandles[8];
- UINT rtvHandleCount = m_pShaderOp->RenderTargets.size();
- for (size_t i = 0; i < rtvHandleCount; ++i) {
- auto &rt = m_pShaderOp->RenderTargets[i];
- ShaderOpDescriptorData &DData = m_DescriptorData[rt];
- rtvHandles[i] = DData.CPUHandle;
- RecordTransitionBarrier(pList, DData.ResData->Resource,
- DData.ResData->ResourceState,
- D3D12_RESOURCE_STATE_RENDER_TARGET);
- DData.ResData->ResourceState = D3D12_RESOURCE_STATE_RENDER_TARGET;
- }
- pList->OMSetRenderTargets(rtvHandleCount, rtvHandles, FALSE, nullptr);
- const float ClearColor[4] = { 0.0f, 0.2f, 0.4f, 1.0f };
- pList->ClearRenderTargetView(rtvHandles[0], ClearColor, 0, nullptr);
- // TODO: set all of this from m_pShaderOp.
- ShaderOpResourceData &VBufferData = this->m_ResourceData[m_pShaderOp->Strings.insert("VBuffer")];
- D3D_PRIMITIVE_TOPOLOGY topology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED;
- for (ShaderOpResource &resource : m_pShaderOp->Resources) {
- if (_strcmpi(resource.Name, "VBuffer") == 0) {
- topology = resource.PrimitiveTopology;
- break;
- }
- }
- pList->IASetPrimitiveTopology(topology);
- // Calculate the stride in bytes from the inputs, assuming linear & contiguous.
- UINT strideInBytes = 0;
- for (auto && IE : m_pShaderOp->InputElements) {
- strideInBytes += GetByteSizeForFormat(IE.Format);
- }
- D3D12_VERTEX_BUFFER_VIEW vertexBufferView;
- vertexBufferView.BufferLocation = VBufferData.Resource->GetGPUVirtualAddress();
- vertexBufferView.StrideInBytes = strideInBytes;
- vertexBufferView.SizeInBytes = VBufferData.ShaderOpRes->Desc.Width;
- pList->IASetVertexBuffers(0, 1, &vertexBufferView);
- UINT vertexCount = vertexBufferView.SizeInBytes / vertexBufferView.StrideInBytes;
- UINT instanceCount = 1;
- UINT vertexCountPerInstance = vertexCount / instanceCount;
- pList->BeginQuery(m_pQueryHeap, D3D12_QUERY_TYPE_PIPELINE_STATISTICS, 0);
- pList->DrawInstanced(vertexCountPerInstance, instanceCount, 0, 0);
- pList->EndQuery(m_pQueryHeap, D3D12_QUERY_TYPE_PIPELINE_STATISTICS, 0);
- pList->ResolveQueryData(m_pQueryHeap, D3D12_QUERY_TYPE_PIPELINE_STATISTICS,
- 0, 1, m_pQueryBuffer, 0);
- }
- CHECK_HR(pList->Close());
- ExecuteCommandList(m_CommandList.Queue, pList);
- WaitForSignal(m_CommandList.Queue, m_pFence, m_hFence, m_FenceValue++);
- }
- void ShaderOpTest::RunShaderOp(ShaderOp *pShaderOp) {
- m_pShaderOp = pShaderOp;
- CreateDevice();
- CreateResources();
- CreateDescriptorHeaps();
- CreatePipelineState();
- CreateCommandList();
- RunCommandList();
- CopyBackResources();
- }
- void ShaderOpTest::RunShaderOp(std::shared_ptr<ShaderOp> ShaderOp) {
- m_OrigShaderOp = ShaderOp;
- RunShaderOp(m_OrigShaderOp.get());
- }
- void ShaderOpTest::SetRootValues(ID3D12GraphicsCommandList *pList,
- bool isCompute) {
- for (size_t i = 0; i < m_pShaderOp->RootValues.size(); ++i) {
- ShaderOpRootValue &V = m_pShaderOp->RootValues[i];
- UINT idx = V.Index == 0 ? (UINT)i : V.Index;
- if (V.ResName) {
- auto r_it = m_ResourceData.find(V.ResName);
- if (r_it == m_ResourceData.end()) {
- ShaderOpLogFmt(L"Root value #%u refers to missing resource %S", (unsigned)i, V.ResName);
- CHECK_HR(E_INVALIDARG);
- }
- // Issue a warning for trying to bind textures (GPU address will return null)
- ShaderOpResourceData &D = r_it->second;
- ID3D12Resource *pRes = D.Resource;
- if (isCompute) {
- switch (D.ShaderOpRes->TransitionTo) {
- case D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER:
- pList->SetComputeRootConstantBufferView(idx,
- pRes->GetGPUVirtualAddress());
- break;
- case D3D12_RESOURCE_STATE_UNORDERED_ACCESS:
- pList->SetComputeRootUnorderedAccessView(idx,
- pRes->GetGPUVirtualAddress());
- break;
- case D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE:
- default:
- pList->SetComputeRootShaderResourceView(idx,
- pRes->GetGPUVirtualAddress());
- break;
- }
- }
- else {
- switch (D.ShaderOpRes->TransitionTo) {
- case D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER:
- pList->SetGraphicsRootConstantBufferView(idx,
- pRes->GetGPUVirtualAddress());
- break;
- case D3D12_RESOURCE_STATE_UNORDERED_ACCESS:
- pList->SetGraphicsRootUnorderedAccessView(idx,
- pRes->GetGPUVirtualAddress());
- break;
- case D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE:
- default:
- pList->SetGraphicsRootShaderResourceView(idx,
- pRes->GetGPUVirtualAddress());
- break;
- }
- }
- }
- else if (V.HeapName) {
- D3D12_GPU_DESCRIPTOR_HANDLE heapBase(m_DescriptorHeapsByName[V.HeapName]->GetGPUDescriptorHandleForHeapStart());
- if (isCompute) {
- pList->SetComputeRootDescriptorTable(idx, heapBase);
- }
- else {
- pList->SetGraphicsRootDescriptorTable(idx, heapBase);
- }
- }
- }
- }
- void ShaderOpTest::SetDevice(ID3D12Device *pDevice) {
- m_pDevice = pDevice;
- }
- void ShaderOpTest::SetDxcSupport(dxc::DxcDllSupport *pDxcSupport) {
- m_pDxcSupport = pDxcSupport;
- }
- void ShaderOpTest::SetInitCallback(TInitCallbackFn InitCallbackFn) {
- m_InitCallbackFn = InitCallbackFn;
- }
- void ShaderOpTest::SetupRenderTarget(ShaderOp *pShaderOp, ID3D12Device *pDevice,
- ID3D12CommandQueue *pCommandQueue,
- ID3D12Resource *pRenderTarget) {
- SetDevice(pDevice);
- m_CommandList.Queue = pCommandQueue;
- // Simplification - add the render target name if missing, set it up 'by hand' if not.
- if (pShaderOp->RenderTargets.empty()) {
- pShaderOp->RenderTargets.push_back(pShaderOp->Strings.insert("RTarget"));
- ShaderOpResource R;
- ZeroMemory(&R, sizeof(R));
- R.Desc = pRenderTarget->GetDesc();
- R.Name = pShaderOp->Strings.insert("RTarget");
- R.HeapFlags = D3D12_HEAP_FLAG_NONE;
- R.Init = nullptr;
- R.InitialResourceState = D3D12_RESOURCE_STATE_PRESENT;
- R.ReadBack = FALSE;
- pShaderOp->Resources.push_back(R);
- ShaderOpResourceData &D = m_ResourceData[R.Name];
- D.ShaderOpRes = &pShaderOp->Resources.back();
- D.Resource = pRenderTarget;
- D.ResourceState = R.InitialResourceState;
- }
- // Create a render target heap to put this in.
- ShaderOpDescriptorHeap *pRtvHeap = pShaderOp->GetDescriptorHeapByName("RtvHeap");
- if (pRtvHeap == nullptr) {
- ShaderOpDescriptorHeap H;
- ZeroMemory(&H, sizeof(H));
- H.Name = pShaderOp->Strings.insert("RtvHeap");
- H.Desc.NumDescriptors = 1;
- H.Desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
- pShaderOp->DescriptorHeaps.push_back(H);
- pRtvHeap = &pShaderOp->DescriptorHeaps.back();
- }
- if (pRtvHeap->Descriptors.empty()) {
- ShaderOpDescriptor D;
- ZeroMemory(&D, sizeof(D));
- D.Name = pShaderOp->Strings.insert("RTarget");
- D.ResName = D.Name;
- D.Kind = pShaderOp->Strings.insert("RTV");
- pRtvHeap->Descriptors.push_back(D);
- }
- }
- void ShaderOpTest::PresentRenderTarget(ShaderOp *pShaderOp,
- ID3D12CommandQueue *pCommandQueue,
- ID3D12Resource *pRenderTarget) {
- CommandListRefs ResCommandList;
- ResCommandList.Queue = pCommandQueue;
- ResCommandList.CreateForDevice(m_pDevice, m_pShaderOp->IsCompute());
- ID3D12GraphicsCommandList *pList = ResCommandList.List;
- pList->SetName(L"ShaderOpTest Resource Present CommandList");
- RecordTransitionBarrier(pList, pRenderTarget,
- D3D12_RESOURCE_STATE_RENDER_TARGET,
- D3D12_RESOURCE_STATE_PRESENT);
- pList->Close();
- ExecuteCommandList(ResCommandList.Queue, pList);
- WaitForSignal(ResCommandList.Queue, m_pFence, m_hFence, m_FenceValue++);
- }
- ShaderOp *ShaderOpSet::GetShaderOp(LPCSTR pName) {
- for (auto &S : ShaderOps) {
- if (S->Name && 0 == _stricmp(pName, S->Name)) {
- return S.get();
- }
- }
- return nullptr;
- }
- ///////////////////////////////////////////////////////////////////////////////
- // ShaderOpTest library implementation for deserialization.
- #pragma region Parsing support
- // Use this class to initialize a ShaderOp object from an XML document.
- class ShaderOpParser {
- private:
- string_table *m_pStrings;
- bool ReadAtElementName(IXmlReader *pReader, LPCWSTR pName);
- HRESULT ReadAttrStr(IXmlReader *pReader, LPCWSTR pAttrName, LPCSTR *ppValue);
- HRESULT ReadAttrBOOL(IXmlReader *pReader, LPCWSTR pAttrName, BOOL *pValue, BOOL defaultValue = FALSE);
- HRESULT ReadAttrUINT64(IXmlReader *pReader, LPCWSTR pAttrName, UINT64 *pValue, UINT64 defaultValue = 0);
- HRESULT ReadAttrUINT16(IXmlReader *pReader, LPCWSTR pAttrName, UINT16 *pValue, UINT16 defaultValue = 0);
- HRESULT ReadAttrUINT(IXmlReader *pReader, LPCWSTR pAttrName, UINT *pValue, UINT defaultValue = 0);
- void ReadElementContentStr(IXmlReader *pReader, LPCSTR *ppValue);
- void ParseDescriptor(IXmlReader *pReader, ShaderOpDescriptor *pDesc);
- void ParseDescriptorHeap(IXmlReader *pReader, ShaderOpDescriptorHeap *pHeap);
- void ParseInputElement(IXmlReader *pReader, D3D12_INPUT_ELEMENT_DESC *pInputElement);
- void ParseInputElements(IXmlReader *pReader, std::vector<D3D12_INPUT_ELEMENT_DESC> *pInputElements);
- void ParseRenderTargets(IXmlReader *pReader, std::vector<LPCSTR> *pRenderTargets);
- void ParseRootValue(IXmlReader *pReader, ShaderOpRootValue *pRootValue);
- void ParseRootValues(IXmlReader *pReader, std::vector<ShaderOpRootValue> *pRootValues);
- void ParseResource(IXmlReader *pReader, ShaderOpResource *pResource);
- void ParseShader(IXmlReader *pReader, ShaderOpShader *pShader);
- public:
- void ParseShaderOpSet(IStream *pStream, ShaderOpSet *pShaderOpSet);
- void ParseShaderOpSet(IXmlReader *pReader, ShaderOpSet *pShaderOpSet);
- void ParseShaderOp(IXmlReader *pReader, ShaderOp *pShaderOp);
- };
- void ParseShaderOpSetFromStream(IStream *pStream, st::ShaderOpSet *pShaderOpSet) {
- ShaderOpParser parser;
- parser.ParseShaderOpSet(pStream, pShaderOpSet);
- }
- void ParseShaderOpSetFromXml(IXmlReader *pReader, st::ShaderOpSet *pShaderOpSet) {
- ShaderOpParser parser;
- parser.ParseShaderOpSet(pReader, pShaderOpSet);
- }
- enum class ParserEnumKind {
- INPUT_CLASSIFICATION,
- DXGI_FORMAT,
- HEAP_TYPE,
- CPU_PAGE_PROPERTY,
- MEMORY_POOL,
- RESOURCE_DIMENSION,
- TEXTURE_LAYOUT,
- RESOURCE_FLAG,
- HEAP_FLAG,
- RESOURCE_STATE,
- DESCRIPTOR_HEAP_TYPE,
- DESCRIPTOR_HEAP_FLAG,
- UAV_DIMENSION,
- PRIMITIVE_TOPOLOGY,
- PRIMITIVE_TOPOLOGY_TYPE
- };
- struct ParserEnumValue {
- LPCWSTR Name;
- UINT Value;
- };
- struct ParserEnumTable {
- size_t ValueCount;
- const ParserEnumValue *Values;
- ParserEnumKind Kind;
- };
- static const ParserEnumValue INPUT_CLASSIFICATION_TABLE[] = {
- { L"INSTANCE", D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA },
- { L"VERTEX", D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA }
- };
- static const ParserEnumValue DXGI_FORMAT_TABLE[] = {
- { L"UNKNOWN", DXGI_FORMAT_UNKNOWN },
- { L"R32G32B32A32_TYPELESS", DXGI_FORMAT_R32G32B32A32_TYPELESS },
- { L"R32G32B32A32_FLOAT", DXGI_FORMAT_R32G32B32A32_FLOAT },
- { L"R32G32B32A32_UINT", DXGI_FORMAT_R32G32B32A32_UINT },
- { L"R32G32B32A32_SINT", DXGI_FORMAT_R32G32B32A32_SINT },
- { L"R32G32B32_TYPELESS", DXGI_FORMAT_R32G32B32_TYPELESS },
- { L"R32G32B32_FLOAT", DXGI_FORMAT_R32G32B32_FLOAT },
- { L"R32G32B32_UINT", DXGI_FORMAT_R32G32B32_UINT },
- { L"R32G32B32_SINT", DXGI_FORMAT_R32G32B32_SINT },
- { L"R16G16B16A16_TYPELESS", DXGI_FORMAT_R16G16B16A16_TYPELESS },
- { L"R16G16B16A16_FLOAT", DXGI_FORMAT_R16G16B16A16_FLOAT },
- { L"R16G16B16A16_UNORM", DXGI_FORMAT_R16G16B16A16_UNORM },
- { L"R16G16B16A16_UINT", DXGI_FORMAT_R16G16B16A16_UINT },
- { L"R16G16B16A16_SNORM", DXGI_FORMAT_R16G16B16A16_SNORM },
- { L"R16G16B16A16_SINT", DXGI_FORMAT_R16G16B16A16_SINT },
- { L"R32G32_TYPELESS", DXGI_FORMAT_R32G32_TYPELESS },
- { L"R32G32_FLOAT", DXGI_FORMAT_R32G32_FLOAT },
- { L"R32G32_UINT", DXGI_FORMAT_R32G32_UINT },
- { L"R32G32_SINT", DXGI_FORMAT_R32G32_SINT },
- { L"R32G8X24_TYPELESS", DXGI_FORMAT_R32G8X24_TYPELESS },
- { L"D32_FLOAT_S8X24_UINT", DXGI_FORMAT_D32_FLOAT_S8X24_UINT },
- { L"R32_FLOAT_X8X24_TYPELESS", DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS },
- { L"X32_TYPELESS_G8X24_UINT", DXGI_FORMAT_X32_TYPELESS_G8X24_UINT },
- { L"R10G10B10A2_TYPELESS", DXGI_FORMAT_R10G10B10A2_TYPELESS },
- { L"R10G10B10A2_UNORM", DXGI_FORMAT_R10G10B10A2_UNORM },
- { L"R10G10B10A2_UINT", DXGI_FORMAT_R10G10B10A2_UINT },
- { L"R11G11B10_FLOAT", DXGI_FORMAT_R11G11B10_FLOAT },
- { L"R8G8B8A8_TYPELESS", DXGI_FORMAT_R8G8B8A8_TYPELESS },
- { L"R8G8B8A8_UNORM", DXGI_FORMAT_R8G8B8A8_UNORM },
- { L"R8G8B8A8_UNORM_SRGB", DXGI_FORMAT_R8G8B8A8_UNORM_SRGB },
- { L"R8G8B8A8_UINT", DXGI_FORMAT_R8G8B8A8_UINT },
- { L"R8G8B8A8_SNORM", DXGI_FORMAT_R8G8B8A8_SNORM },
- { L"R8G8B8A8_SINT", DXGI_FORMAT_R8G8B8A8_SINT },
- { L"R16G16_TYPELESS", DXGI_FORMAT_R16G16_TYPELESS },
- { L"R16G16_FLOAT", DXGI_FORMAT_R16G16_FLOAT },
- { L"R16G16_UNORM", DXGI_FORMAT_R16G16_UNORM },
- { L"R16G16_UINT", DXGI_FORMAT_R16G16_UINT },
- { L"R16G16_SNORM", DXGI_FORMAT_R16G16_SNORM },
- { L"R16G16_SINT", DXGI_FORMAT_R16G16_SINT },
- { L"R32_TYPELESS", DXGI_FORMAT_R32_TYPELESS },
- { L"D32_FLOAT", DXGI_FORMAT_D32_FLOAT },
- { L"R32_FLOAT", DXGI_FORMAT_R32_FLOAT },
- { L"R32_UINT", DXGI_FORMAT_R32_UINT },
- { L"R32_SINT", DXGI_FORMAT_R32_SINT },
- { L"R24G8_TYPELESS", DXGI_FORMAT_R24G8_TYPELESS },
- { L"D24_UNORM_S8_UINT", DXGI_FORMAT_D24_UNORM_S8_UINT },
- { L"R24_UNORM_X8_TYPELESS", DXGI_FORMAT_R24_UNORM_X8_TYPELESS },
- { L"X24_TYPELESS_G8_UINT", DXGI_FORMAT_X24_TYPELESS_G8_UINT },
- { L"R8G8_TYPELESS", DXGI_FORMAT_R8G8_TYPELESS },
- { L"R8G8_UNORM", DXGI_FORMAT_R8G8_UNORM },
- { L"R8G8_UINT", DXGI_FORMAT_R8G8_UINT },
- { L"R8G8_SNORM", DXGI_FORMAT_R8G8_SNORM },
- { L"R8G8_SINT", DXGI_FORMAT_R8G8_SINT },
- { L"R16_TYPELESS", DXGI_FORMAT_R16_TYPELESS },
- { L"R16_FLOAT", DXGI_FORMAT_R16_FLOAT },
- { L"D16_UNORM", DXGI_FORMAT_D16_UNORM },
- { L"R16_UNORM", DXGI_FORMAT_R16_UNORM },
- { L"R16_UINT", DXGI_FORMAT_R16_UINT },
- { L"R16_SNORM", DXGI_FORMAT_R16_SNORM },
- { L"R16_SINT", DXGI_FORMAT_R16_SINT },
- { L"R8_TYPELESS", DXGI_FORMAT_R8_TYPELESS },
- { L"R8_UNORM", DXGI_FORMAT_R8_UNORM },
- { L"R8_UINT", DXGI_FORMAT_R8_UINT },
- { L"R8_SNORM", DXGI_FORMAT_R8_SNORM },
- { L"R8_SINT", DXGI_FORMAT_R8_SINT },
- { L"A8_UNORM", DXGI_FORMAT_A8_UNORM },
- { L"R1_UNORM", DXGI_FORMAT_R1_UNORM },
- { L"R9G9B9E5_SHAREDEXP", DXGI_FORMAT_R9G9B9E5_SHAREDEXP },
- { L"R8G8_B8G8_UNORM", DXGI_FORMAT_R8G8_B8G8_UNORM },
- { L"G8R8_G8B8_UNORM", DXGI_FORMAT_G8R8_G8B8_UNORM },
- { L"BC1_TYPELESS", DXGI_FORMAT_BC1_TYPELESS },
- { L"BC1_UNORM", DXGI_FORMAT_BC1_UNORM },
- { L"BC1_UNORM_SRGB", DXGI_FORMAT_BC1_UNORM_SRGB },
- { L"BC2_TYPELESS", DXGI_FORMAT_BC2_TYPELESS },
- { L"BC2_UNORM", DXGI_FORMAT_BC2_UNORM },
- { L"BC2_UNORM_SRGB", DXGI_FORMAT_BC2_UNORM_SRGB },
- { L"BC3_TYPELESS", DXGI_FORMAT_BC3_TYPELESS },
- { L"BC3_UNORM", DXGI_FORMAT_BC3_UNORM },
- { L"BC3_UNORM_SRGB", DXGI_FORMAT_BC3_UNORM_SRGB },
- { L"BC4_TYPELESS", DXGI_FORMAT_BC4_TYPELESS },
- { L"BC4_UNORM", DXGI_FORMAT_BC4_UNORM },
- { L"BC4_SNORM", DXGI_FORMAT_BC4_SNORM },
- { L"BC5_TYPELESS", DXGI_FORMAT_BC5_TYPELESS },
- { L"BC5_UNORM", DXGI_FORMAT_BC5_UNORM },
- { L"BC5_SNORM", DXGI_FORMAT_BC5_SNORM },
- { L"B5G6R5_UNORM", DXGI_FORMAT_B5G6R5_UNORM },
- { L"B5G5R5A1_UNORM", DXGI_FORMAT_B5G5R5A1_UNORM },
- { L"B8G8R8A8_UNORM", DXGI_FORMAT_B8G8R8A8_UNORM },
- { L"B8G8R8X8_UNORM", DXGI_FORMAT_B8G8R8X8_UNORM },
- { L"R10G10B10_XR_BIAS_A2_UNORM", DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM },
- { L"B8G8R8A8_TYPELESS", DXGI_FORMAT_B8G8R8A8_TYPELESS },
- { L"B8G8R8A8_UNORM_SRGB", DXGI_FORMAT_B8G8R8A8_UNORM_SRGB },
- { L"B8G8R8X8_TYPELESS", DXGI_FORMAT_B8G8R8X8_TYPELESS },
- { L"B8G8R8X8_UNORM_SRGB", DXGI_FORMAT_B8G8R8X8_UNORM_SRGB },
- { L"BC6H_TYPELESS", DXGI_FORMAT_BC6H_TYPELESS },
- { L"BC6H_UF16", DXGI_FORMAT_BC6H_UF16 },
- { L"BC6H_SF16", DXGI_FORMAT_BC6H_SF16 },
- { L"BC7_TYPELESS", DXGI_FORMAT_BC7_TYPELESS },
- { L"BC7_UNORM", DXGI_FORMAT_BC7_UNORM },
- { L"BC7_UNORM_SRGB", DXGI_FORMAT_BC7_UNORM_SRGB },
- { L"AYUV", DXGI_FORMAT_AYUV },
- { L"Y410", DXGI_FORMAT_Y410 },
- { L"Y416", DXGI_FORMAT_Y416 },
- { L"NV12", DXGI_FORMAT_NV12 },
- { L"P010", DXGI_FORMAT_P010 },
- { L"P016", DXGI_FORMAT_P016 },
- { L"420_OPAQUE", DXGI_FORMAT_420_OPAQUE },
- { L"YUY2", DXGI_FORMAT_YUY2 },
- { L"Y210", DXGI_FORMAT_Y210 },
- { L"Y216", DXGI_FORMAT_Y216 },
- { L"NV11", DXGI_FORMAT_NV11 },
- { L"AI44", DXGI_FORMAT_AI44 },
- { L"IA44", DXGI_FORMAT_IA44 },
- { L"P8", DXGI_FORMAT_P8 },
- { L"A8P8", DXGI_FORMAT_A8P8 },
- { L"B4G4R4A4_UNORM", DXGI_FORMAT_B4G4R4A4_UNORM },
- { L"P208", DXGI_FORMAT_P208 },
- { L"V208", DXGI_FORMAT_V208 },
- { L"V408", DXGI_FORMAT_V408 }
- };
- static const ParserEnumValue HEAP_TYPE_TABLE[] = {
- { L"DEFAULT", D3D12_HEAP_TYPE_DEFAULT },
- { L"UPLOAD", D3D12_HEAP_TYPE_UPLOAD },
- { L"READBACK", D3D12_HEAP_TYPE_READBACK },
- { L"CUSTOM", D3D12_HEAP_TYPE_CUSTOM }
- };
- static const ParserEnumValue CPU_PAGE_PROPERTY_TABLE[] = {
- { L"UNKNOWN", D3D12_CPU_PAGE_PROPERTY_UNKNOWN },
- { L"NOT_AVAILABLE", D3D12_CPU_PAGE_PROPERTY_NOT_AVAILABLE },
- { L"WRITE_COMBINE", D3D12_CPU_PAGE_PROPERTY_WRITE_COMBINE },
- { L"WRITE_BACK", D3D12_CPU_PAGE_PROPERTY_WRITE_BACK }
- };
- static const ParserEnumValue MEMORY_POOL_TABLE[] = {
- { L"UNKNOWN", D3D12_MEMORY_POOL_UNKNOWN },
- { L"L0 ", D3D12_MEMORY_POOL_L0 },
- { L"L1", D3D12_MEMORY_POOL_L1 }
- };
- static const ParserEnumValue RESOURCE_DIMENSION_TABLE[] = {
- { L"UNKNOWN", D3D12_RESOURCE_DIMENSION_UNKNOWN },
- { L"BUFFER", D3D12_RESOURCE_DIMENSION_BUFFER },
- { L"TEXTURE1D", D3D12_RESOURCE_DIMENSION_TEXTURE1D },
- { L"TEXTURE2D", D3D12_RESOURCE_DIMENSION_TEXTURE2D },
- { L"TEXTURE3D", D3D12_RESOURCE_DIMENSION_TEXTURE3D }
- };
- static const ParserEnumValue TEXTURE_LAYOUT_TABLE[] = {
- { L"UNKNOWN", D3D12_TEXTURE_LAYOUT_UNKNOWN },
- { L"ROW_MAJOR", D3D12_TEXTURE_LAYOUT_ROW_MAJOR },
- { L"UNDEFINED_SWIZZLE", D3D12_TEXTURE_LAYOUT_64KB_UNDEFINED_SWIZZLE },
- { L"STANDARD_SWIZZLE", D3D12_TEXTURE_LAYOUT_64KB_STANDARD_SWIZZLE }
- };
- static const ParserEnumValue RESOURCE_FLAG_TABLE[] = {
- { L"NONE", D3D12_RESOURCE_FLAG_NONE },
- { L"ALLOW_RENDER_TARGET", D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET },
- { L"ALLOW_DEPTH_STENCIL", D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL },
- { L"ALLOW_UNORDERED_ACCESS", D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS },
- { L"DENY_SHADER_RESOURCE", D3D12_RESOURCE_FLAG_DENY_SHADER_RESOURCE },
- { L"ALLOW_CROSS_ADAPTER", D3D12_RESOURCE_FLAG_ALLOW_CROSS_ADAPTER },
- { L"ALLOW_SIMULTANEOUS_ACCESS", D3D12_RESOURCE_FLAG_ALLOW_SIMULTANEOUS_ACCESS }
- };
- static const ParserEnumValue HEAP_FLAG_TABLE[] = {
- { L"NONE", D3D12_HEAP_FLAG_NONE },
- { L"SHARED", D3D12_HEAP_FLAG_SHARED },
- { L"DENY_BUFFERS", D3D12_HEAP_FLAG_DENY_BUFFERS },
- { L"ALLOW_DISPLAY", D3D12_HEAP_FLAG_ALLOW_DISPLAY },
- { L"SHARED_CROSS_ADAPTER", D3D12_HEAP_FLAG_SHARED_CROSS_ADAPTER },
- { L"DENY_RT_DS_TEXTURES", D3D12_HEAP_FLAG_DENY_RT_DS_TEXTURES },
- { L"DENY_NON_RT_DS_TEXTURES", D3D12_HEAP_FLAG_DENY_NON_RT_DS_TEXTURES },
- { L"ALLOW_ALL_BUFFERS_AND_TEXTURES",D3D12_HEAP_FLAG_ALLOW_ALL_BUFFERS_AND_TEXTURES },
- { L"ALLOW_ONLY_BUFFERS", D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS },
- { L"ALLOW_ONLY_NON_RT_DS_TEXTURES", D3D12_HEAP_FLAG_ALLOW_ONLY_NON_RT_DS_TEXTURES },
- { L"ALLOW_ONLY_RT_DS_TEXTURES", D3D12_HEAP_FLAG_ALLOW_ONLY_RT_DS_TEXTURES }
- };
- static const ParserEnumValue RESOURCE_STATE_TABLE[] = {
- { L"COMMON", D3D12_RESOURCE_STATE_COMMON },
- { L"VERTEX_AND_CONSTANT_BUFFER", D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER },
- { L"INDEX_BUFFER", D3D12_RESOURCE_STATE_INDEX_BUFFER },
- { L"RENDER_TARGET", D3D12_RESOURCE_STATE_RENDER_TARGET },
- { L"UNORDERED_ACCESS", D3D12_RESOURCE_STATE_UNORDERED_ACCESS },
- { L"DEPTH_WRITE", D3D12_RESOURCE_STATE_DEPTH_WRITE },
- { L"DEPTH_READ", D3D12_RESOURCE_STATE_DEPTH_READ },
- { L"NON_PIXEL_SHADER_RESOURCE", D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE },
- { L"PIXEL_SHADER_RESOURCE", D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE },
- { L"STREAM_OUT", D3D12_RESOURCE_STATE_STREAM_OUT },
- { L"INDIRECT_ARGUMENT", D3D12_RESOURCE_STATE_INDIRECT_ARGUMENT },
- { L"COPY_DEST", D3D12_RESOURCE_STATE_COPY_DEST },
- { L"COPY_SOURCE", D3D12_RESOURCE_STATE_COPY_SOURCE },
- { L"RESOLVE_DEST", D3D12_RESOURCE_STATE_RESOLVE_DEST },
- { L"RESOLVE_SOURCE", D3D12_RESOURCE_STATE_RESOLVE_SOURCE },
- { L"GENERIC_READ", D3D12_RESOURCE_STATE_GENERIC_READ },
- { L"PRESENT", D3D12_RESOURCE_STATE_PRESENT },
- { L"PREDICATION", D3D12_RESOURCE_STATE_PREDICATION }
- };
- static const ParserEnumValue DESCRIPTOR_HEAP_TYPE_TABLE[] = {
- { L"CBV_SRV_UAV", D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV },
- { L"SAMPLER", D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER },
- { L"RTV", D3D12_DESCRIPTOR_HEAP_TYPE_RTV },
- { L"DSV", D3D12_DESCRIPTOR_HEAP_TYPE_DSV }
- };
- static const ParserEnumValue DESCRIPTOR_HEAP_FLAG_TABLE[] = {
- { L"NONE", D3D12_DESCRIPTOR_HEAP_FLAG_NONE },
- { L"SHADER_VISIBLE", D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE }
- };
- static const ParserEnumValue UAV_DIMENSION_TABLE[] = {
- { L"UNKNOWN", D3D12_UAV_DIMENSION_UNKNOWN },
- { L"BUFFER", D3D12_UAV_DIMENSION_BUFFER },
- { L"TEXTURE1D", D3D12_UAV_DIMENSION_TEXTURE1D },
- { L"TEXTURE1DARRAY", D3D12_UAV_DIMENSION_TEXTURE1DARRAY },
- { L"TEXTURE2D", D3D12_UAV_DIMENSION_TEXTURE2D },
- { L"TEXTURE2DARRAY", D3D12_UAV_DIMENSION_TEXTURE2DARRAY },
- { L"TEXTURE3D", D3D12_UAV_DIMENSION_TEXTURE3D }
- };
- static const ParserEnumValue PRIMITIVE_TOPOLOGY_TABLE[] = {
- { L"UNDEFINED",D3D_PRIMITIVE_TOPOLOGY_UNDEFINED },
- { L"POINTLIST",D3D_PRIMITIVE_TOPOLOGY_POINTLIST },
- { L"LINELIST",D3D_PRIMITIVE_TOPOLOGY_LINELIST },
- { L"LINESTRIP",D3D_PRIMITIVE_TOPOLOGY_LINESTRIP },
- { L"TRIANGLELIST",D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST },
- { L"TRIANGLESTRIP",D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP },
- { L"LINELIST_ADJ",D3D_PRIMITIVE_TOPOLOGY_LINELIST_ADJ },
- { L"LINESTRIP_ADJ",D3D_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ },
- { L"TRIANGLELIST_ADJ",D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ },
- { L"TRIANGLESTRIP_ADJ",D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ },
- { L"1_CONTROL_POINT_PATCHLIST",D3D_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST },
- { L"2_CONTROL_POINT_PATCHLIST",D3D_PRIMITIVE_TOPOLOGY_2_CONTROL_POINT_PATCHLIST },
- { L"3_CONTROL_POINT_PATCHLIST",D3D_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST },
- { L"4_CONTROL_POINT_PATCHLIST",D3D_PRIMITIVE_TOPOLOGY_4_CONTROL_POINT_PATCHLIST },
- { L"5_CONTROL_POINT_PATCHLIST",D3D_PRIMITIVE_TOPOLOGY_5_CONTROL_POINT_PATCHLIST },
- { L"6_CONTROL_POINT_PATCHLIST",D3D_PRIMITIVE_TOPOLOGY_6_CONTROL_POINT_PATCHLIST },
- { L"7_CONTROL_POINT_PATCHLIST",D3D_PRIMITIVE_TOPOLOGY_7_CONTROL_POINT_PATCHLIST },
- { L"8_CONTROL_POINT_PATCHLIST",D3D_PRIMITIVE_TOPOLOGY_8_CONTROL_POINT_PATCHLIST },
- { L"9_CONTROL_POINT_PATCHLIST",D3D_PRIMITIVE_TOPOLOGY_9_CONTROL_POINT_PATCHLIST },
- { L"10_CONTROL_POINT_PATCHLIST",D3D_PRIMITIVE_TOPOLOGY_10_CONTROL_POINT_PATCHLIST },
- { L"11_CONTROL_POINT_PATCHLIST",D3D_PRIMITIVE_TOPOLOGY_11_CONTROL_POINT_PATCHLIST },
- { L"12_CONTROL_POINT_PATCHLIST",D3D_PRIMITIVE_TOPOLOGY_12_CONTROL_POINT_PATCHLIST },
- { L"13_CONTROL_POINT_PATCHLIST",D3D_PRIMITIVE_TOPOLOGY_13_CONTROL_POINT_PATCHLIST },
- { L"14_CONTROL_POINT_PATCHLIST",D3D_PRIMITIVE_TOPOLOGY_14_CONTROL_POINT_PATCHLIST },
- { L"15_CONTROL_POINT_PATCHLIST",D3D_PRIMITIVE_TOPOLOGY_15_CONTROL_POINT_PATCHLIST },
- { L"16_CONTROL_POINT_PATCHLIST",D3D_PRIMITIVE_TOPOLOGY_16_CONTROL_POINT_PATCHLIST },
- { L"17_CONTROL_POINT_PATCHLIST",D3D_PRIMITIVE_TOPOLOGY_17_CONTROL_POINT_PATCHLIST },
- { L"18_CONTROL_POINT_PATCHLIST",D3D_PRIMITIVE_TOPOLOGY_18_CONTROL_POINT_PATCHLIST },
- { L"19_CONTROL_POINT_PATCHLIST",D3D_PRIMITIVE_TOPOLOGY_19_CONTROL_POINT_PATCHLIST },
- { L"20_CONTROL_POINT_PATCHLIST",D3D_PRIMITIVE_TOPOLOGY_20_CONTROL_POINT_PATCHLIST },
- { L"21_CONTROL_POINT_PATCHLIST",D3D_PRIMITIVE_TOPOLOGY_21_CONTROL_POINT_PATCHLIST },
- { L"22_CONTROL_POINT_PATCHLIST",D3D_PRIMITIVE_TOPOLOGY_22_CONTROL_POINT_PATCHLIST },
- { L"23_CONTROL_POINT_PATCHLIST",D3D_PRIMITIVE_TOPOLOGY_23_CONTROL_POINT_PATCHLIST },
- { L"24_CONTROL_POINT_PATCHLIST",D3D_PRIMITIVE_TOPOLOGY_24_CONTROL_POINT_PATCHLIST },
- { L"25_CONTROL_POINT_PATCHLIST",D3D_PRIMITIVE_TOPOLOGY_25_CONTROL_POINT_PATCHLIST },
- { L"26_CONTROL_POINT_PATCHLIST",D3D_PRIMITIVE_TOPOLOGY_26_CONTROL_POINT_PATCHLIST },
- { L"27_CONTROL_POINT_PATCHLIST",D3D_PRIMITIVE_TOPOLOGY_27_CONTROL_POINT_PATCHLIST },
- { L"28_CONTROL_POINT_PATCHLIST",D3D_PRIMITIVE_TOPOLOGY_28_CONTROL_POINT_PATCHLIST },
- { L"29_CONTROL_POINT_PATCHLIST",D3D_PRIMITIVE_TOPOLOGY_29_CONTROL_POINT_PATCHLIST },
- { L"30_CONTROL_POINT_PATCHLIST",D3D_PRIMITIVE_TOPOLOGY_30_CONTROL_POINT_PATCHLIST },
- { L"31_CONTROL_POINT_PATCHLIST",D3D_PRIMITIVE_TOPOLOGY_31_CONTROL_POINT_PATCHLIST },
- { L"32_CONTROL_POINT_PATCHLIST",D3D_PRIMITIVE_TOPOLOGY_32_CONTROL_POINT_PATCHLIST }
- };
- static const ParserEnumValue PRIMITIVE_TOPOLOGY_TYPE_TABLE[] = {
- { L"UNDEFINED", D3D12_PRIMITIVE_TOPOLOGY_TYPE_UNDEFINED },
- { L"POINT", D3D12_PRIMITIVE_TOPOLOGY_TYPE_POINT },
- { L"LINE", D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE },
- { L"TRIANGLE", D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE },
- { L"PATCH", D3D12_PRIMITIVE_TOPOLOGY_TYPE_PATCH }
- };
- static const ParserEnumTable g_ParserEnumTables[] = {
- { _countof(INPUT_CLASSIFICATION_TABLE), INPUT_CLASSIFICATION_TABLE, ParserEnumKind::INPUT_CLASSIFICATION },
- { _countof(DXGI_FORMAT_TABLE), DXGI_FORMAT_TABLE, ParserEnumKind::DXGI_FORMAT },
- { _countof(HEAP_TYPE_TABLE), HEAP_TYPE_TABLE, ParserEnumKind::HEAP_TYPE },
- { _countof(CPU_PAGE_PROPERTY_TABLE), CPU_PAGE_PROPERTY_TABLE, ParserEnumKind::CPU_PAGE_PROPERTY },
- { _countof(MEMORY_POOL_TABLE), MEMORY_POOL_TABLE, ParserEnumKind::MEMORY_POOL },
- { _countof(RESOURCE_DIMENSION_TABLE), RESOURCE_DIMENSION_TABLE, ParserEnumKind::RESOURCE_DIMENSION },
- { _countof(TEXTURE_LAYOUT_TABLE), TEXTURE_LAYOUT_TABLE, ParserEnumKind::TEXTURE_LAYOUT },
- { _countof(RESOURCE_FLAG_TABLE), RESOURCE_FLAG_TABLE, ParserEnumKind::RESOURCE_FLAG },
- { _countof(HEAP_FLAG_TABLE), HEAP_FLAG_TABLE, ParserEnumKind::HEAP_FLAG },
- { _countof(RESOURCE_STATE_TABLE), RESOURCE_STATE_TABLE, ParserEnumKind::RESOURCE_STATE },
- { _countof(DESCRIPTOR_HEAP_TYPE_TABLE), DESCRIPTOR_HEAP_TYPE_TABLE, ParserEnumKind::DESCRIPTOR_HEAP_TYPE },
- { _countof(DESCRIPTOR_HEAP_FLAG_TABLE), DESCRIPTOR_HEAP_FLAG_TABLE, ParserEnumKind::DESCRIPTOR_HEAP_FLAG },
- { _countof(UAV_DIMENSION_TABLE), UAV_DIMENSION_TABLE, ParserEnumKind::UAV_DIMENSION },
- { _countof(PRIMITIVE_TOPOLOGY_TABLE), PRIMITIVE_TOPOLOGY_TABLE, ParserEnumKind::PRIMITIVE_TOPOLOGY },
- { _countof(PRIMITIVE_TOPOLOGY_TYPE_TABLE), PRIMITIVE_TOPOLOGY_TYPE_TABLE, ParserEnumKind::PRIMITIVE_TOPOLOGY_TYPE },
- };
- static HRESULT GetEnumValue(LPCWSTR name, ParserEnumKind K, UINT *pValue) {
- for (size_t i = 0; i < _countof(g_ParserEnumTables); ++i) {
- const ParserEnumTable &T = g_ParserEnumTables[i];
- if (T.Kind != K) {
- continue;
- }
- for (size_t j = 0; j < T.ValueCount; ++j) {
- if (_wcsicmp(name, T.Values[j].Name) == 0) {
- *pValue = T.Values[j].Value;
- return S_OK;
- }
- }
- }
- return E_INVALIDARG;
- }
- template <typename T>
- static HRESULT GetEnumValueT(LPCWSTR name, ParserEnumKind K, T *pValue) {
- UINT u;
- HRESULT hr = GetEnumValue(name, K, &u);
- *pValue = (T)u;
- return hr;
- }
- template <typename T>
- static HRESULT ReadAttrEnumT(IXmlReader *pReader, LPCWSTR pAttrName, ParserEnumKind K, T *pValue, T defaultValue, LPCWSTR pStripPrefix = nullptr) {
- if (S_FALSE == CHECK_HR_RET(pReader->MoveToAttributeByName(pAttrName, nullptr))) {
- *pValue = defaultValue;
- return S_FALSE;
- }
- LPCWSTR pText;
- CHECK_HR(pReader->GetValue(&pText, nullptr));
- if (pStripPrefix && *pStripPrefix && _wcsnicmp(pAttrName, pText, wcslen(pStripPrefix)) == 0)
- pText += wcslen(pStripPrefix);
- CHECK_HR(GetEnumValueT(pText, K, pValue));
- CHECK_HR(pReader->MoveToElement());
- return S_OK;
- }
- static HRESULT ReadAttrINPUT_CLASSIFICATION(IXmlReader *pReader, LPCWSTR pAttrName, D3D12_INPUT_CLASSIFICATION *pValue) {
- return ReadAttrEnumT(pReader, pAttrName, ParserEnumKind::INPUT_CLASSIFICATION, pValue, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA);
- }
- static HRESULT ReadAttrDESCRIPTOR_HEAP_TYPE(IXmlReader *pReader, LPCWSTR pAttrName, D3D12_DESCRIPTOR_HEAP_TYPE *pValue) {
- return ReadAttrEnumT(pReader, pAttrName, ParserEnumKind::DESCRIPTOR_HEAP_TYPE, pValue, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
- }
- static HRESULT ReadAttrDESCRIPTOR_HEAP_FLAGS(IXmlReader *pReader, LPCWSTR pAttrName, D3D12_DESCRIPTOR_HEAP_FLAGS *pValue) {
- return ReadAttrEnumT(pReader, pAttrName, ParserEnumKind::DESCRIPTOR_HEAP_FLAG, pValue, D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE);
- }
- static HRESULT ReadAttrDXGI_FORMAT(IXmlReader *pReader, LPCWSTR pAttrName, DXGI_FORMAT *pValue) {
- return ReadAttrEnumT(pReader, pAttrName, ParserEnumKind::DXGI_FORMAT, pValue, DXGI_FORMAT_UNKNOWN, L"DXGI_FORMAT_");
- }
- static HRESULT ReadAttrHEAP_TYPE(IXmlReader *pReader, LPCWSTR pAttrName, D3D12_HEAP_TYPE *pValue) {
- return ReadAttrEnumT(pReader, pAttrName, ParserEnumKind::HEAP_TYPE, pValue, D3D12_HEAP_TYPE_DEFAULT);
- }
- static HRESULT ReadAttrCPU_PAGE_PROPERTY(IXmlReader *pReader, LPCWSTR pAttrName, D3D12_CPU_PAGE_PROPERTY *pValue) {
- return ReadAttrEnumT(pReader, pAttrName, ParserEnumKind::CPU_PAGE_PROPERTY, pValue, D3D12_CPU_PAGE_PROPERTY_UNKNOWN);
- }
- static HRESULT ReadAttrMEMORY_POOL(IXmlReader *pReader, LPCWSTR pAttrName, D3D12_MEMORY_POOL *pValue) {
- return ReadAttrEnumT(pReader, pAttrName, ParserEnumKind::MEMORY_POOL, pValue, D3D12_MEMORY_POOL_UNKNOWN);
- }
- static HRESULT ReadAttrRESOURCE_DIMENSION(IXmlReader *pReader, LPCWSTR pAttrName, D3D12_RESOURCE_DIMENSION *pValue) {
- return ReadAttrEnumT(pReader, pAttrName, ParserEnumKind::RESOURCE_DIMENSION, pValue, D3D12_RESOURCE_DIMENSION_BUFFER);
- }
- static HRESULT ReadAttrTEXTURE_LAYOUT(IXmlReader *pReader, LPCWSTR pAttrName, D3D12_TEXTURE_LAYOUT *pValue) {
- return ReadAttrEnumT(pReader, pAttrName, ParserEnumKind::TEXTURE_LAYOUT, pValue, D3D12_TEXTURE_LAYOUT_UNKNOWN);
- }
- static HRESULT ReadAttrRESOURCE_FLAGS(IXmlReader *pReader, LPCWSTR pAttrName, D3D12_RESOURCE_FLAGS *pValue) {
- return ReadAttrEnumT(pReader, pAttrName, ParserEnumKind::RESOURCE_FLAG, pValue, D3D12_RESOURCE_FLAG_NONE);
- }
- static HRESULT ReadAttrHEAP_FLAGS(IXmlReader *pReader, LPCWSTR pAttrName, D3D12_HEAP_FLAGS *pValue) {
- return ReadAttrEnumT(pReader, pAttrName, ParserEnumKind::HEAP_FLAG, pValue, D3D12_HEAP_FLAG_NONE);
- }
- static HRESULT ReadAttrRESOURCE_STATES(IXmlReader *pReader, LPCWSTR pAttrName, D3D12_RESOURCE_STATES *pValue) {
- return ReadAttrEnumT(pReader, pAttrName, ParserEnumKind::RESOURCE_STATE, pValue, D3D12_RESOURCE_STATE_COMMON);
- }
- static HRESULT ReadAttrUAV_DIMENSION(IXmlReader *pReader, LPCWSTR pAttrName, D3D12_UAV_DIMENSION *pValue) {
- return ReadAttrEnumT(pReader, pAttrName, ParserEnumKind::UAV_DIMENSION, pValue, D3D12_UAV_DIMENSION_BUFFER);
- }
- static HRESULT ReadAttrPRIMITIVE_TOPOLOGY(IXmlReader *pReader, LPCWSTR pAttrName, D3D_PRIMITIVE_TOPOLOGY *pValue) {
- return ReadAttrEnumT(pReader, pAttrName, ParserEnumKind::PRIMITIVE_TOPOLOGY, pValue, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
- }
- static HRESULT ReadAttrPRIMITIVE_TOPOLOGY_TYPE(IXmlReader *pReader, LPCWSTR pAttrName, D3D12_PRIMITIVE_TOPOLOGY_TYPE *pValue) {
- return ReadAttrEnumT(pReader, pAttrName, ParserEnumKind::PRIMITIVE_TOPOLOGY_TYPE, pValue, D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE);
- }
- HRESULT ShaderOpParser::ReadAttrStr(IXmlReader *pReader, LPCWSTR pAttrName, LPCSTR *ppValue) {
- if (S_FALSE == CHECK_HR_RET(pReader->MoveToAttributeByName(pAttrName, nullptr))) {
- *ppValue = nullptr;
- return S_FALSE;
- }
- LPCWSTR pValue;
- CHECK_HR(pReader->GetValue(&pValue, nullptr));
- *ppValue = m_pStrings->insert(pValue);
- CHECK_HR(pReader->MoveToElement());
- return S_OK;
- }
- HRESULT ShaderOpParser::ReadAttrBOOL(IXmlReader *pReader, LPCWSTR pAttrName, BOOL *pValue, BOOL defaultValue) {
- if (S_FALSE == CHECK_HR_RET(pReader->MoveToAttributeByName(pAttrName, nullptr))) {
- *pValue = defaultValue;
- return S_FALSE;
- }
- LPCWSTR pText;
- CHECK_HR(pReader->GetValue(&pText, nullptr));
- if (_wcsicmp(pText, L"true") == 0) {
- *pValue = TRUE;
- }
- else {
- *pValue = FALSE;
- }
- CHECK_HR(pReader->MoveToElement());
- return S_OK;
- }
- HRESULT ShaderOpParser::ReadAttrUINT64(IXmlReader *pReader, LPCWSTR pAttrName, UINT64 *pValue, UINT64 defaultValue) {
- if (S_FALSE == CHECK_HR_RET(pReader->MoveToAttributeByName(pAttrName, nullptr))) {
- *pValue = defaultValue;
- return S_FALSE;
- }
- LPCWSTR pText;
- CHECK_HR(pReader->GetValue(&pText, nullptr));
- long long ll = _wtol(pText);
- if (errno == ERANGE) CHECK_HR(E_INVALIDARG);
- *pValue = ll;
- CHECK_HR(pReader->MoveToElement());
- return S_OK;
- }
- HRESULT ShaderOpParser::ReadAttrUINT(IXmlReader *pReader, LPCWSTR pAttrName, UINT *pValue, UINT defaultValue) {
- UINT64 u64;
- CHECK_HR(ReadAttrUINT64(pReader, pAttrName, &u64, defaultValue));
- CHECK_HR(UInt64ToUInt(u64, pValue));
- return S_OK;
- }
- HRESULT ShaderOpParser::ReadAttrUINT16(IXmlReader *pReader, LPCWSTR pAttrName, UINT16 *pValue, UINT16 defaultValue) {
- UINT64 u64;
- CHECK_HR(ReadAttrUINT64(pReader, pAttrName, &u64, defaultValue));
- CHECK_HR(UInt64ToUInt16(u64, pValue));
- return S_OK;
- }
- void ShaderOpParser::ReadElementContentStr(IXmlReader *pReader, LPCSTR *ppValue) {
- *ppValue = nullptr;
- if (pReader->IsEmptyElement())
- return;
- UINT startDepth;
- XmlNodeType nt;
- CHECK_HR(pReader->GetDepth(&startDepth));
- std::wstring value;
- for (;;) {
- UINT depth;
- CHECK_HR(pReader->Read(&nt));
- CHECK_HR(pReader->GetDepth(&depth));
- if (nt == XmlNodeType_EndElement && depth == startDepth + 1)
- break;
- if (nt == XmlNodeType_CDATA || nt == XmlNodeType_Text || nt == XmlNodeType_Whitespace) {
- LPCWSTR pText;
- CHECK_HR(pReader->GetValue(&pText, nullptr));
- value += pText;
- }
- }
- *ppValue = m_pStrings->insert(value.c_str());
- }
- void ShaderOpParser::ParseDescriptor(IXmlReader *pReader, ShaderOpDescriptor *pDesc) {
- if (!ReadAtElementName(pReader, L"Descriptor"))
- return;
- CHECK_HR(ReadAttrStr(pReader, L"Name", &pDesc->Name));
- CHECK_HR(ReadAttrStr(pReader, L"ResName", &pDesc->ResName));
- CHECK_HR(ReadAttrStr(pReader, L"CounterName", &pDesc->CounterName));
- CHECK_HR(ReadAttrStr(pReader, L"Kind", &pDesc->Kind));
- // D3D12_UNORDERED_ACCESS_VIEW_DESC
- HRESULT hrFormat = ReadAttrDXGI_FORMAT(pReader, L"Format", &pDesc->UavDesc.Format);
- CHECK_HR(hrFormat);
- CHECK_HR(ReadAttrUAV_DIMENSION(pReader, L"Dimension", &pDesc->UavDesc.ViewDimension));
- switch (pDesc->UavDesc.ViewDimension) {
- case D3D12_UAV_DIMENSION_BUFFER:
- CHECK_HR(ReadAttrUINT64(pReader, L"FirstElement", &pDesc->UavDesc.Buffer.FirstElement));
- CHECK_HR(ReadAttrUINT(pReader, L"NumElements", &pDesc->UavDesc.Buffer.NumElements));
- CHECK_HR(ReadAttrUINT(pReader, L"StructureByteStride", &pDesc->UavDesc.Buffer.StructureByteStride));
- CHECK_HR(ReadAttrUINT64(pReader, L"CounterOffsetInBytes", &pDesc->UavDesc.Buffer.CounterOffsetInBytes));
- LPCSTR pFlags;
- CHECK_HR(ReadAttrStr(pReader, L"Flags", &pFlags));
- if (pFlags && *pFlags && 0 == _stricmp(pFlags, "RAW")) {
- pDesc->UavDesc.Buffer.Flags = D3D12_BUFFER_UAV_FLAG_RAW;
- }
- else {
- pDesc->UavDesc.Buffer.Flags = D3D12_BUFFER_UAV_FLAG_NONE;
- }
- if (hrFormat == S_FALSE && pDesc->UavDesc.Buffer.Flags & D3D12_BUFFER_UAV_FLAG_RAW) {
- pDesc->UavDesc.Format = DXGI_FORMAT_R32_TYPELESS;
- }
- break;
- case D3D12_UAV_DIMENSION_TEXTURE1D:
- CHECK_HR(ReadAttrUINT(pReader, L"MipSlice", &pDesc->UavDesc.Texture1D.MipSlice));
- break;
- case D3D12_UAV_DIMENSION_TEXTURE1DARRAY:
- CHECK_HR(ReadAttrUINT(pReader, L"MipSlice", &pDesc->UavDesc.Texture1DArray.MipSlice));
- CHECK_HR(ReadAttrUINT(pReader, L"FirstArraySlice", &pDesc->UavDesc.Texture1DArray.FirstArraySlice));
- CHECK_HR(ReadAttrUINT(pReader, L"ArraySize", &pDesc->UavDesc.Texture1DArray.ArraySize));
- break;
- case D3D12_UAV_DIMENSION_TEXTURE2D:
- CHECK_HR(ReadAttrUINT(pReader, L"MipSlice", &pDesc->UavDesc.Texture2D.MipSlice));
- CHECK_HR(ReadAttrUINT(pReader, L"PlaneSlice", &pDesc->UavDesc.Texture2D.PlaneSlice));
- break;
- case D3D12_UAV_DIMENSION_TEXTURE2DARRAY:
- CHECK_HR(ReadAttrUINT(pReader, L"MipSlice", &pDesc->UavDesc.Texture2DArray.MipSlice));
- CHECK_HR(ReadAttrUINT(pReader, L"FirstArraySlice", &pDesc->UavDesc.Texture2DArray.FirstArraySlice));
- CHECK_HR(ReadAttrUINT(pReader, L"ArraySize", &pDesc->UavDesc.Texture2DArray.ArraySize));
- CHECK_HR(ReadAttrUINT(pReader, L"MipSlice", &pDesc->UavDesc.Texture2DArray.PlaneSlice));
- break;
- case D3D12_UAV_DIMENSION_TEXTURE3D:
- CHECK_HR(ReadAttrUINT(pReader, L"MipSlice", &pDesc->UavDesc.Texture3D.MipSlice));
- CHECK_HR(ReadAttrUINT(pReader, L"FirstWSlice", &pDesc->UavDesc.Texture3D.FirstWSlice));
- CHECK_HR(ReadAttrUINT(pReader, L"WSize", &pDesc->UavDesc.Texture3D.WSize));
- break;
- }
- // If either is missing, set one from the other.
- if (pDesc->Name && !pDesc->ResName) pDesc->ResName = pDesc->Name;
- if (pDesc->ResName && !pDesc->Name) pDesc->Name = pDesc->ResName;
- LPCSTR K = pDesc->Kind;
- if (K == nullptr) {
- ShaderOpLogFmt(L"Descriptor '%S' is missing Kind attribute.", pDesc->Name);
- CHECK_HR(E_INVALIDARG);
- } else if (0 != _stricmp(K, "UAV") && 0 != _stricmp(K, "SRV") &&
- 0 != _stricmp(K, "CBV") && 0 != _stricmp(K, "RTV")) {
- ShaderOpLogFmt(L"Descriptor '%S' references unknown kind '%S'",
- pDesc->Name, K);
- CHECK_HR(E_INVALIDARG);
- }
- }
- void ShaderOpParser::ParseDescriptorHeap(IXmlReader *pReader, ShaderOpDescriptorHeap *pHeap) {
- if (!ReadAtElementName(pReader, L"DescriptorHeap"))
- return;
- CHECK_HR(ReadAttrStr(pReader, L"Name", &pHeap->Name));
- HRESULT hrFlags = ReadAttrDESCRIPTOR_HEAP_FLAGS(pReader, L"Flags", &pHeap->Desc.Flags);
- CHECK_HR(hrFlags);
- CHECK_HR(ReadAttrUINT(pReader, L"NodeMask", &pHeap->Desc.NodeMask));
- CHECK_HR(ReadAttrUINT(pReader, L"NumDescriptors", &pHeap->Desc.NumDescriptors));
- CHECK_HR(ReadAttrDESCRIPTOR_HEAP_TYPE(pReader, L"Type", &pHeap->Desc.Type));
- if (pHeap->Desc.Type == D3D12_DESCRIPTOR_HEAP_TYPE_RTV && hrFlags == S_FALSE)
- pHeap->Desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
- if (pReader->IsEmptyElement())
- return;
- UINT startDepth;
- XmlNodeType nt;
- CHECK_HR(pReader->GetDepth(&startDepth));
- std::wstring value;
- for (;;) {
- UINT depth;
- CHECK_HR(pReader->Read(&nt));
- CHECK_HR(pReader->GetDepth(&depth));
- if (nt == XmlNodeType_EndElement && depth == startDepth + 1)
- break;
- if (nt == XmlNodeType_Element) {
- LPCWSTR pLocalName;
- CHECK_HR(pReader->GetLocalName(&pLocalName, nullptr));
- if (0 == wcscmp(pLocalName, L"Descriptor")) {
- ShaderOpDescriptor D;
- ParseDescriptor(pReader, &D);
- pHeap->Descriptors.push_back(D);
- }
- }
- }
- }
- void ShaderOpParser::ParseInputElement(IXmlReader *pReader, D3D12_INPUT_ELEMENT_DESC *pInputElement) {
- if (!ReadAtElementName(pReader, L"InputElement"))
- return;
- CHECK_HR(ReadAttrStr(pReader, L"SemanticName", &pInputElement->SemanticName));
- CHECK_HR(ReadAttrUINT(pReader, L"SemanticIndex", &pInputElement->SemanticIndex));
- CHECK_HR(ReadAttrDXGI_FORMAT(pReader, L"Format", &pInputElement->Format));
- CHECK_HR(ReadAttrUINT(pReader, L"InputSlot", &pInputElement->InputSlot));
- CHECK_HR(ReadAttrUINT(pReader, L"AlignedByteOffset", &pInputElement->AlignedByteOffset, D3D12_APPEND_ALIGNED_ELEMENT));
- CHECK_HR(ReadAttrINPUT_CLASSIFICATION(pReader, L"InputSlotClass", &pInputElement->InputSlotClass));
- CHECK_HR(ReadAttrUINT(pReader, L"InstanceDataStepRate", &pInputElement->InstanceDataStepRate));
- }
- void ShaderOpParser::ParseInputElements(IXmlReader *pReader, std::vector<D3D12_INPUT_ELEMENT_DESC> *pInputElements) {
- if (!ReadAtElementName(pReader, L"InputElements"))
- return;
- if (pReader->IsEmptyElement()) return;
- UINT startDepth;
- XmlNodeType nt;
- CHECK_HR(pReader->GetDepth(&startDepth));
- for (;;) {
- UINT depth;
- CHECK_HR(pReader->Read(&nt));
- CHECK_HR(pReader->GetDepth(&depth));
- if (nt == XmlNodeType_EndElement && depth == startDepth + 1)
- return;
- if (nt == XmlNodeType_Element) {
- LPCWSTR pLocalName;
- CHECK_HR(pReader->GetLocalName(&pLocalName, nullptr));
- if (0 == wcscmp(pLocalName, L"InputElement")) {
- D3D12_INPUT_ELEMENT_DESC desc;
- ParseInputElement(pReader, &desc);
- pInputElements->push_back(desc);
- }
- }
- }
- }
- void ShaderOpParser::ParseRenderTargets(IXmlReader *pReader, std::vector<LPCSTR> *pRenderTargets) {
- if (!ReadAtElementName(pReader, L"RenderTargets"))
- return;
- if (pReader->IsEmptyElement()) return;
- UINT startDepth;
- XmlNodeType nt;
- CHECK_HR(pReader->GetDepth(&startDepth));
- for (;;) {
- UINT depth;
- CHECK_HR(pReader->Read(&nt));
- CHECK_HR(pReader->GetDepth(&depth));
- if (nt == XmlNodeType_EndElement && depth == startDepth + 1)
- return;
- if (nt == XmlNodeType_Element) {
- LPCWSTR pLocalName;
- CHECK_HR(pReader->GetLocalName(&pLocalName, nullptr));
- if (0 == wcscmp(pLocalName, L"RenderTarget")) {
- LPCSTR pName;
- CHECK_HR(ReadAttrStr(pReader, L"Name", &pName));
- pRenderTargets->push_back(pName);
- }
- }
- }
- }
- void ShaderOpParser::ParseRootValue(IXmlReader *pReader, ShaderOpRootValue *pRootValue) {
- if (!ReadAtElementName(pReader, L"RootValue"))
- return;
- CHECK_HR(ReadAttrStr(pReader, L"ResName", &pRootValue->ResName));
- CHECK_HR(ReadAttrStr(pReader, L"HeapName", &pRootValue->HeapName));
- CHECK_HR(ReadAttrUINT(pReader, L"Index", &pRootValue->Index));
- }
- void ShaderOpParser::ParseRootValues(IXmlReader *pReader, std::vector<ShaderOpRootValue> *pRootValues) {
- if (!ReadAtElementName(pReader, L"RootValues"))
- return;
- if (pReader->IsEmptyElement()) return;
- UINT startDepth;
- XmlNodeType nt;
- CHECK_HR(pReader->GetDepth(&startDepth));
- for (;;) {
- UINT depth;
- CHECK_HR(pReader->Read(&nt));
- CHECK_HR(pReader->GetDepth(&depth));
- if (nt == XmlNodeType_EndElement && depth == startDepth + 1)
- return;
- if (nt == XmlNodeType_Element) {
- LPCWSTR pLocalName;
- CHECK_HR(pReader->GetLocalName(&pLocalName, nullptr));
- if (0 == wcscmp(pLocalName, L"RootValue")) {
- ShaderOpRootValue V;
- ParseRootValue(pReader, &V);
- pRootValues->push_back(V);
- }
- }
- }
- }
- void ShaderOpParser::ParseShaderOpSet(IStream *pStream, ShaderOpSet *pShaderOpSet) {
- CComPtr<IXmlReader> pReader;
- CHECK_HR(CreateXmlReader(__uuidof(IXmlReader), (void **)&pReader, nullptr));
- CHECK_HR(pReader->SetInput(pStream));
- ParseShaderOpSet(pReader, pShaderOpSet);
- }
- void ShaderOpParser::ParseShaderOpSet(IXmlReader *pReader, ShaderOpSet *pShaderOpSet) {
- if (!ReadAtElementName(pReader, L"ShaderOpSet"))
- return;
- UINT startDepth;
- CHECK_HR(pReader->GetDepth(&startDepth));
- XmlNodeType nt = XmlNodeType_Element;
- for (;;) {
- if (nt == XmlNodeType_Element) {
- LPCWSTR pLocalName;
- CHECK_HR(pReader->GetLocalName(&pLocalName, nullptr));
- if (0 == wcscmp(pLocalName, L"ShaderOp")) {
- pShaderOpSet->ShaderOps.emplace_back(std::make_unique<ShaderOp>());
- ParseShaderOp(pReader, pShaderOpSet->ShaderOps.back().get());
- }
- }
- else if (nt == XmlNodeType_EndElement) {
- UINT depth;
- CHECK_HR(pReader->GetDepth(&depth));
- if (depth == startDepth + 1)
- return;
- }
- CHECK_HR(pReader->Read(&nt));
- }
- }
- void ShaderOpParser::ParseShaderOp(IXmlReader *pReader, ShaderOp *pShaderOp) {
- m_pStrings = &pShaderOp->Strings;
- // Look for a ShaderOp element.
- if (!ReadAtElementName(pReader, L"ShaderOp"))
- return;
- CHECK_HR(ReadAttrStr(pReader, L"Name", &pShaderOp->Name));
- CHECK_HR(ReadAttrStr(pReader, L"CS", &pShaderOp->CS));
- CHECK_HR(ReadAttrStr(pReader, L"VS", &pShaderOp->VS));
- CHECK_HR(ReadAttrStr(pReader, L"PS", &pShaderOp->PS));
- CHECK_HR(ReadAttrUINT(pReader, L"DispatchX", &pShaderOp->DispatchX, 1));
- CHECK_HR(ReadAttrUINT(pReader, L"DispatchY", &pShaderOp->DispatchY, 1));
- CHECK_HR(ReadAttrUINT(pReader, L"DispatchZ", &pShaderOp->DispatchZ, 1));
- CHECK_HR(ReadAttrPRIMITIVE_TOPOLOGY_TYPE(pReader, L"TopologyType", &pShaderOp->PrimitiveTopologyType));
- UINT startDepth;
- CHECK_HR(pReader->GetDepth(&startDepth));
- XmlNodeType nt = XmlNodeType_Element;
- for (;;) {
- if (nt == XmlNodeType_Element) {
- LPCWSTR pLocalName;
- CHECK_HR(pReader->GetLocalName(&pLocalName, nullptr));
- if (0 == wcscmp(pLocalName, L"InputElements")) {
- ParseInputElements(pReader, &pShaderOp->InputElements);
- }
- else if (0 == wcscmp(pLocalName, L"Shader")) {
- ShaderOpShader shader;
- ParseShader(pReader, &shader);
- pShaderOp->Shaders.push_back(shader);
- }
- else if (0 == wcscmp(pLocalName, L"RootSignature")) {
- ReadElementContentStr(pReader, &pShaderOp->RootSignature);
- }
- else if (0 == wcscmp(pLocalName, L"RenderTargets")) {
- ParseRenderTargets(pReader, &pShaderOp->RenderTargets);
- }
- else if (0 == wcscmp(pLocalName, L"Resource")) {
- ShaderOpResource resource;
- ParseResource(pReader, &resource);
- pShaderOp->Resources.push_back(resource);
- }
- else if (0 == wcscmp(pLocalName, L"DescriptorHeap")) {
- ShaderOpDescriptorHeap heap;
- ParseDescriptorHeap(pReader, &heap);
- pShaderOp->DescriptorHeaps.push_back(heap);
- }
- else if (0 == wcscmp(pLocalName, L"RootValues")) {
- ParseRootValues(pReader, &pShaderOp->RootValues);
- }
- }
- else if (nt == XmlNodeType_EndElement) {
- UINT depth;
- CHECK_HR(pReader->GetDepth(&depth));
- if (depth == startDepth + 1)
- return;
- }
- if (S_FALSE == CHECK_HR_RET(pReader->Read(&nt)))
- return;
- }
- }
- LPCWSTR SkipByteInitSeparators(LPCWSTR pText) {
- while (*pText && (*pText == L' ' || *pText == L'\t' ||
- *pText == L'\r' || *pText == L'\n' || *pText == L'{' ||
- *pText == L'}' || *pText == L','))
- ++pText;
- return pText;
- }
- LPCWSTR FindByteInitSeparators(LPCWSTR pText) {
- while (*pText &&
- !(*pText == L' ' || *pText == L'\t' ||
- *pText == L'\r' || *pText == L'\n' || *pText == L'{' ||
- *pText == L'}' || *pText == L','))
- ++pText;
- return pText;
- }
- using namespace hlsl;
- DXIL::ComponentType GetCompType(LPCWSTR pText, LPCWSTR pEnd) {
- // if no prefix shown, use it as a default
- if (pText == pEnd) return DXIL::ComponentType::F32;
- // check if suffix starts with (half)
- if (wcsncmp(pText, L"(half)", 6) == 0) {
- return DXIL::ComponentType::F16;
- }
- switch (*(pEnd - 1)) {
- case L'h':
- case L'H':
- return DXIL::ComponentType::F16;
- case L'l':
- case L'L':
- return DXIL::ComponentType::F64;
- case L'u':
- case L'U':
- return DXIL::ComponentType::U32;
- case L'i':
- case L'I':
- return DXIL::ComponentType::I32;
- case L'f':
- case L'F':
- default:
- return DXIL::ComponentType::F32;
- }
- }
- bool GetSign(float x) {
- return std::signbit(x);
- }
- int GetMantissa(float x) {
- int bits = reinterpret_cast<int &>(x);
- return bits & 0x7fffff;
- }
- int GetExponent(float x) {
- int bits = reinterpret_cast<int &>(x);
- return (bits >> 23) & 0xff;
- }
- // Note: This is not a precise float32 to float16 conversion.
- // This function should be used to convert float values read from ShaderOp data that were intended to be used for halves.
- // So special values (nan, denorm, inf) for float32 will map to their corresponding bits in float16,
- // and it will not handle true conversions that spans float16 denorms and float32 non-denorms.
- uint16_t ConvertFloat32ToFloat16(float x) {
- bool isNeg = GetSign(x);
- int exp = GetExponent(x);
- int mantissa = GetMantissa(x);
- if (isnan(x)) return Float16NaN;
- if (isinf(x) || exp - 127 > 15) {
- return isNeg ? Float16NegInf : Float16PosInf;
- }
- if (isdenorm(x)) return isNeg ? Float16NegDenorm : Float16PosDenorm;
- if (exp == 0 && mantissa == 0) return isNeg ? Float16NegZero : Float16PosZero;
- else {
- DXASSERT(exp - 127 <= 15, "else invalid float conversion");
- uint16_t val = 0;
- val |= isNeg ? 0x8000 : 0;
- val |= (exp - 127 + 15) << 10; // subtract from float32 exponent bias and add float16 exponent bias
- val |= mantissa >> 13; // only first 10 significands taken
- return val;
- }
- }
- void ParseDataFromText(LPCWSTR pText, LPCWSTR pEnd, DXIL::ComponentType compType, std::vector<BYTE> &V) {
- BYTE *pB;
- if (compType == DXIL::ComponentType::F16 || compType == DXIL::ComponentType::F32) {
- float fVal;
- size_t wordSize = pEnd - pText;
- if (wordSize >= 3 && 0 == _wcsnicmp(pEnd - 3, L"nan", 3)) {
- fVal = NAN;
- }
- else if (wordSize >= 4 && 0 == _wcsnicmp(pEnd - 4, L"-inf", 4)) {
- fVal = -(INFINITY);
- }
- else if ((wordSize >= 3 && 0 == _wcsnicmp(pEnd - 3, L"inf", 3)) ||
- (wordSize >= 4 && 0 == _wcsnicmp(pEnd - 4, L"+inf", 4))) {
- fVal = INFINITY;
- }
- else if (wordSize >= 7 && 0 == _wcsnicmp(pEnd - 7, L"-denorm", 7)) {
- fVal = -(FLT_MIN / 2);
- }
- else if (wordSize >= 6 && 0 == _wcsnicmp(pEnd - 6, L"denorm", 6)) {
- fVal = (FLT_MIN / 2);
- }
- else {
- fVal = wcstof(pText, nullptr);
- }
- if (compType == DXIL::ComponentType::F16) {
- uint16_t fp16Val = ConvertFloat32ToFloat16(fVal);
- pB = (BYTE *)&fp16Val;
- V.insert(V.end(), pB, pB + sizeof(uint16_t));
- }
- else {
- pB = (BYTE *)&fVal;
- V.insert(V.end(), pB, pB + sizeof(float));
- }
- }
- else if (compType == DXIL::ComponentType::I32) {
- int val = _wtoi(pText);
- pB = (BYTE *)&val;
- V.insert(V.end(), pB, pB + sizeof(int));
- }
- else {
- DXASSERT(false, "Unsupported stream component type : %u", compType);
- }
- }
- void ShaderOpParser::ParseResource(IXmlReader *pReader, ShaderOpResource *pResource) {
- if (!ReadAtElementName(pReader, L"Resource"))
- return;
- CHECK_HR(ReadAttrStr(pReader, L"Name", &pResource->Name));
- CHECK_HR(ReadAttrStr(pReader, L"Init", &pResource->Init));
- CHECK_HR(ReadAttrBOOL(pReader, L"ReadBack", &pResource->ReadBack));
- CHECK_HR(ReadAttrHEAP_TYPE(pReader, L"HeapType", &pResource->HeapProperties.Type));
- CHECK_HR(ReadAttrCPU_PAGE_PROPERTY(pReader, L"CPUPageProperty", &pResource->HeapProperties.CPUPageProperty));
- CHECK_HR(ReadAttrMEMORY_POOL(pReader, L"MemoryPoolPreference", &pResource->HeapProperties.MemoryPoolPreference));
- CHECK_HR(ReadAttrUINT(pReader, L"CreationNodeMask", &pResource->HeapProperties.CreationNodeMask));
- CHECK_HR(ReadAttrUINT(pReader, L"VisibleNodeMask", &pResource->HeapProperties.VisibleNodeMask));
- // D3D12_RESOURCE_DESC Desc;
- CHECK_HR(ReadAttrRESOURCE_DIMENSION(pReader, L"Dimension", &pResource->Desc.Dimension));
- CHECK_HR(ReadAttrUINT64(pReader, L"Alignment", &pResource->Desc.Alignment));
- CHECK_HR(ReadAttrUINT64(pReader, L"Width", &pResource->Desc.Width));
- CHECK_HR(ReadAttrUINT(pReader, L"Height", &pResource->Desc.Height));
- CHECK_HR(ReadAttrUINT16(pReader, L"DepthOrArraySize", &pResource->Desc.DepthOrArraySize));
- CHECK_HR(ReadAttrUINT16(pReader, L"MipLevels", &pResource->Desc.MipLevels));
- CHECK_HR(ReadAttrDXGI_FORMAT(pReader, L"Format", &pResource->Desc.Format));
- CHECK_HR(ReadAttrUINT(pReader, L"SampleCount", &pResource->Desc.SampleDesc.Count));
- CHECK_HR(ReadAttrUINT(pReader, L"SampleQual", &pResource->Desc.SampleDesc.Quality));
- CHECK_HR(ReadAttrTEXTURE_LAYOUT(pReader, L"Layout", &pResource->Desc.Layout));
- CHECK_HR(ReadAttrRESOURCE_FLAGS(pReader, L"Flags", &pResource->Desc.Flags));
- CHECK_HR(ReadAttrHEAP_FLAGS(pReader, L"HeapFlags", &pResource->HeapFlags));
- CHECK_HR(ReadAttrRESOURCE_STATES(pReader, L"InitialResourceState", &pResource->InitialResourceState));
- CHECK_HR(ReadAttrRESOURCE_STATES(pReader, L"TransitionTo", &pResource->TransitionTo));
- CHECK_HR(ReadAttrPRIMITIVE_TOPOLOGY(pReader, L"Topology", &pResource->PrimitiveTopology));
- // Set some fixed values.
- if (pResource->Desc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) {
- pResource->Desc.Height = 1;
- pResource->Desc.DepthOrArraySize = 1;
- pResource->Desc.MipLevels = 1;
- pResource->Desc.Format = DXGI_FORMAT_UNKNOWN;
- pResource->Desc.SampleDesc.Count = 1;
- pResource->Desc.SampleDesc.Quality = 0;
- pResource->Desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
- }
- if (pResource->Desc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE1D) {
- if (pResource->Desc.Height == 0) pResource->Desc.Height = 1;
- if (pResource->Desc.DepthOrArraySize == 0) pResource->Desc.DepthOrArraySize = 1;
- if (pResource->Desc.SampleDesc.Count == 0) pResource->Desc.SampleDesc.Count = 1;
- }
- if (pResource->Desc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE2D) {
- if (pResource->Desc.DepthOrArraySize == 0) pResource->Desc.DepthOrArraySize = 1;
- if (pResource->Desc.SampleDesc.Count == 0 ) pResource->Desc.SampleDesc.Count = 1;
- }
- // If the resource has text, that goes into the bytes initialization area.
- if (pReader->IsEmptyElement())
- return;
- std::vector<BYTE> &V = pResource->InitBytes;
- XmlNodeType nt;
- CHECK_HR(pReader->GetNodeType(&nt));
- for (;;) {
- if (nt == XmlNodeType_EndElement) {
- return;
- }
- if (nt == XmlNodeType_Text) {
- // Handle the byte payload. '{', '}', ',', whitespace - these are all
- // separators and are ignored in terms of structure. We simply read
- // literals, figure out their type based on suffix, and write the bytes
- // into the target array.
- LPCWSTR pText;
- pReader->GetValue(&pText, nullptr);
- while (*pText) {
- pText = SkipByteInitSeparators(pText);
- if (!*pText) continue;
- LPCWSTR pEnd = FindByteInitSeparators(pText);
- // Consider looking for prefixes/suffixes to handle bases and types.
- DXIL::ComponentType compType = GetCompType(pText, pEnd);
- ParseDataFromText(pText, pEnd, compType, V);
- pText = pEnd;
- }
- }
- if (S_FALSE == CHECK_HR_RET(pReader->Read(&nt)))
- return;
- }
- }
- void ShaderOpParser::ParseShader(IXmlReader *pReader, ShaderOpShader *pShader) {
- if (!ReadAtElementName(pReader, L"Shader"))
- return;
- CHECK_HR(ReadAttrStr(pReader, L"Name", &pShader->Name));
- CHECK_HR(ReadAttrStr(pReader, L"EntryPoint", &pShader->EntryPoint));
- CHECK_HR(ReadAttrStr(pReader, L"Target", &pShader->Target));
- CHECK_HR(ReadAttrStr(pReader, L"Arguments", &pShader->Arguments))
- ReadElementContentStr(pReader, &pShader->Text);
- bool hasText = pShader->Text && *pShader->Text;
- if (hasText) {
- LPCSTR pCheck;
- CHECK_HR(ReadAttrStr(pReader, L"Text", &pCheck));
- if (pCheck && *pCheck) {
- ShaderOpLogFmt(L"Shader %S has text content and a Text attribute; it "
- L"should only have one",
- pShader->Name);
- CHECK_HR(E_INVALIDARG);
- }
- }
- else {
- CHECK_HR(ReadAttrStr(pReader, L"Text", &pShader->Text));
- }
- if (pShader->EntryPoint == nullptr)
- pShader->EntryPoint = m_pStrings->insert("main");
- }
- bool ShaderOpParser::ReadAtElementName(IXmlReader *pReader, LPCWSTR pName) {
- XmlNodeType nt;
- CHECK_HR(pReader->GetNodeType(&nt));
- for (;;) {
- if (nt == XmlNodeType_Element) {
- LPCWSTR pLocalName;
- CHECK_HR(pReader->GetLocalName(&pLocalName, nullptr));
- if (0 == wcscmp(pLocalName, pName)) {
- return true;
- }
- }
- if (S_FALSE == CHECK_HR_RET(pReader->Read(&nt)))
- return false;
- }
- }
- #pragma endregion Parsing support
- } // namespace st
|