12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388 |
- ///////////////////////////////////////////////////////////////////////////////
- // //
- // dxcdisassembler.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. //
- // //
- // Implements Disassembler. //
- // //
- ///////////////////////////////////////////////////////////////////////////////
- #include "dxc/Support/WinIncludes.h"
- #include "dxc/dxcapi.h"
- #include "dxc/Support/Global.h"
- #include "dxc/HLSL/DxilShaderModel.h"
- #include "dxc/HLSL/DxilModule.h"
- #include "dxc/HLSL/DxilResource.h"
- #include "dxc/HLSL/HLMatrixLowerHelper.h"
- #include "dxc/HLSL/DxilConstants.h"
- #include "dxc/HLSL/DxilOperations.h"
- #include "llvm/IR/DiagnosticInfo.h"
- #include "llvm/IR/DiagnosticPrinter.h"
- #include "llvm/IR/AssemblyAnnotationWriter.h"
- #include "llvm/Support/FormattedStream.h"
- #include "llvm/Support/Format.h"
- #include "dxc/HLSL/DxilPipelineStateValidation.h"
- #include "dxc/HLSL/DxilContainer.h"
- #include "dxc/HLSL/DxilUtil.h"
- #include "dxcutil.h"
- using namespace llvm;
- using namespace hlsl;
- namespace {
- // Disassemble helper functions.
- void PrintDiagnosticHandler(const DiagnosticInfo &DI, void *Context) {
- DiagnosticPrinter *printer = reinterpret_cast<DiagnosticPrinter *>(Context);
- DI.print(*printer);
- }
- template <typename T>
- const T *ByteOffset(LPCVOID p, uint32_t byteOffset) {
- return reinterpret_cast<const T *>((const uint8_t *)p + byteOffset);
- }
- bool SigElementHasStream(const DxilProgramSignatureElement &pSignature) {
- return pSignature.Stream != 0;
- }
- void PrintSignature(LPCSTR pName, const DxilProgramSignature *pSignature,
- bool bIsInput, raw_string_ostream &OS,
- StringRef comment) {
- OS << comment << "\n"
- << comment << " " << pName << " signature:\n"
- << comment << "\n"
- << comment
- << " Name Index Mask Register SysValue Format Used\n"
- << comment
- << " -------------------- ----- ------ -------- -------- ------- ------\n";
- if (pSignature->ParamCount == 0) {
- OS << comment << " no parameters\n";
- return;
- }
- const DxilProgramSignatureElement *pSigBegin =
- ByteOffset<DxilProgramSignatureElement>(pSignature,
- pSignature->ParamOffset);
- const DxilProgramSignatureElement *pSigEnd =
- pSigBegin + pSignature->ParamCount;
- bool bHasStreams = std::any_of(pSigBegin, pSigEnd, SigElementHasStream);
- for (const DxilProgramSignatureElement *pSig = pSigBegin; pSig != pSigEnd;
- ++pSig) {
- OS << comment << " ";
- const char *pSemanticName =
- ByteOffset<char>(pSignature, pSig->SemanticName);
- if (bHasStreams) {
- OS << "m" << pSig->Stream << ":";
- OS << left_justify(pSemanticName, 17);
- } else {
- OS << left_justify(pSemanticName, 20);
- }
- OS << ' ' << format("%5u", pSig->SemanticIndex);
- char Mask[4];
- memset(Mask, ' ', sizeof(Mask));
- if (pSig->Mask & DxilProgramSigMaskX)
- Mask[0] = 'x';
- if (pSig->Mask & DxilProgramSigMaskY)
- Mask[1] = 'y';
- if (pSig->Mask & DxilProgramSigMaskZ)
- Mask[2] = 'z';
- if (pSig->Mask & DxilProgramSigMaskW)
- Mask[3] = 'w';
- if (pSig->Register == -1) {
- OS << " N/A";
- if (!_stricmp(pSemanticName, "SV_Depth"))
- OS << " oDepth";
- else if (0 == _stricmp(pSemanticName, "SV_DepthGreaterEqual"))
- OS << " oDepthGE";
- else if (0 == _stricmp(pSemanticName, "SV_DepthLessEqual"))
- OS << " oDepthLE";
- else if (0 == _stricmp(pSemanticName, "SV_Coverage"))
- OS << " oMask";
- else if (0 == _stricmp(pSemanticName, "SV_StencilRef"))
- OS << " oStencilRef";
- else if (pSig->SystemValue == DxilProgramSigSemantic::PrimitiveID)
- OS << " primID";
- else
- OS << " special";
- } else {
- OS << " " << Mask[0] << Mask[1] << Mask[2] << Mask[3];
- OS << ' ' << format("%8u", pSig->Register);
- }
- LPCSTR pSysValue = "NONE";
- switch (pSig->SystemValue) {
- case DxilProgramSigSemantic::ClipDistance:
- pSysValue = "CLIPDST";
- break;
- case DxilProgramSigSemantic::CullDistance:
- pSysValue = "CULLDST";
- break;
- case DxilProgramSigSemantic::Position:
- pSysValue = "POS";
- break;
- case DxilProgramSigSemantic::RenderTargetArrayIndex:
- pSysValue = "RTINDEX";
- break;
- case DxilProgramSigSemantic::ViewPortArrayIndex:
- pSysValue = "VPINDEX";
- break;
- case DxilProgramSigSemantic::VertexID:
- pSysValue = "VERTID";
- break;
- case DxilProgramSigSemantic::PrimitiveID:
- pSysValue = "PRIMID";
- break;
- case DxilProgramSigSemantic::InstanceID:
- pSysValue = "INSTID";
- break;
- case DxilProgramSigSemantic::IsFrontFace:
- pSysValue = "FFACE";
- break;
- case DxilProgramSigSemantic::SampleIndex:
- pSysValue = "SAMPLE";
- break;
- case DxilProgramSigSemantic::Target:
- pSysValue = "TARGET";
- break;
- case DxilProgramSigSemantic::Depth:
- pSysValue = "DEPTH";
- break;
- case DxilProgramSigSemantic::DepthGE:
- pSysValue = "DEPTHGE";
- break;
- case DxilProgramSigSemantic::DepthLE:
- pSysValue = "DEPTHLE";
- break;
- case DxilProgramSigSemantic::Coverage:
- pSysValue = "COVERAGE";
- break;
- case DxilProgramSigSemantic::InnerCoverage:
- pSysValue = "INNERCOV";
- break;
- case DxilProgramSigSemantic::StencilRef:
- pSysValue = "STENCILREF";
- break;
- case DxilProgramSigSemantic::FinalQuadEdgeTessfactor:
- pSysValue = "QUADEDGE";
- break;
- case DxilProgramSigSemantic::FinalQuadInsideTessfactor:
- pSysValue = "QUADINT";
- break;
- case DxilProgramSigSemantic::FinalTriEdgeTessfactor:
- pSysValue = "TRIEDGE";
- break;
- case DxilProgramSigSemantic::FinalTriInsideTessfactor:
- pSysValue = "TRIINT";
- break;
- case DxilProgramSigSemantic::FinalLineDetailTessfactor:
- pSysValue = "LINEDET";
- break;
- case DxilProgramSigSemantic::FinalLineDensityTessfactor:
- pSysValue = "LINEDEN";
- break;
- case DxilProgramSigSemantic::Barycentrics:
- pSysValue = "BARYCEN";
- }
- OS << right_justify(pSysValue, 9);
- LPCSTR pFormat = "unknown";
- switch (pSig->CompType) {
- case DxilProgramSigCompType::Float32:
- pFormat = "float";
- break;
- case DxilProgramSigCompType::SInt32:
- pFormat = "int";
- break;
- case DxilProgramSigCompType::UInt32:
- pFormat = "uint";
- break;
- case DxilProgramSigCompType::UInt16:
- pFormat = "uint16";
- break;
- case DxilProgramSigCompType::SInt16:
- pFormat = "int16";
- break;
- case DxilProgramSigCompType::Float16:
- pFormat = "fp16";
- break;
- case DxilProgramSigCompType::UInt64:
- pFormat = "uint64";
- break;
- case DxilProgramSigCompType::SInt64:
- pFormat = "int64";
- break;
- case DxilProgramSigCompType::Float64:
- pFormat = "double";
- break;
- }
- OS << right_justify(pFormat, 8);
- memset(Mask, ' ', sizeof(Mask));
- BYTE rwMask = pSig->AlwaysReads_Mask;
- if (!bIsInput)
- rwMask = ~rwMask;
- if (rwMask & DxilProgramSigMaskX)
- Mask[0] = 'x';
- if (rwMask & DxilProgramSigMaskY)
- Mask[1] = 'y';
- if (rwMask & DxilProgramSigMaskZ)
- Mask[2] = 'z';
- if (rwMask & DxilProgramSigMaskW)
- Mask[3] = 'w';
- if (pSig->Register == -1)
- OS << (rwMask ? " YES" : " NO");
- else
- OS << " " << Mask[0] << Mask[1] << Mask[2] << Mask[3];
- OS << "\n";
- }
- OS << comment << "\n";
- }
- void PintCompMaskNameCompact(raw_string_ostream &OS, unsigned CompMask) {
- char Mask[5];
- memset(Mask, '\0', sizeof(Mask));
- unsigned idx = 0;
- if (CompMask & DxilProgramSigMaskX)
- Mask[idx++] = 'x';
- if (CompMask & DxilProgramSigMaskY)
- Mask[idx++] = 'y';
- if (CompMask & DxilProgramSigMaskZ)
- Mask[idx++] = 'z';
- if (CompMask & DxilProgramSigMaskW)
- Mask[idx++] = 'w';
- OS << right_justify(Mask, 4);
- }
- void PrintDxilSignature(LPCSTR pName, const DxilSignature &Signature,
- raw_string_ostream &OS, StringRef comment) {
- const std::vector<std::unique_ptr<DxilSignatureElement>> &sigElts =
- Signature.GetElements();
- if (sigElts.size() == 0)
- return;
- // TODO: Print all the data in DxilSignature.
- OS << comment << "\n"
- << comment << " " << pName << " signature:\n"
- << comment << "\n"
- << comment << " Name Index InterpMode DynIdx\n"
- << comment
- << " -------------------- ----- ---------------------- ------\n";
- for (auto &sigElt : sigElts) {
- OS << comment << " ";
- OS << left_justify(sigElt->GetName(), 20);
- auto &indexVec = sigElt->GetSemanticIndexVec();
- unsigned index = 0;
- if (!indexVec.empty()) {
- index = sigElt->GetSemanticIndexVec()[0];
- }
- OS << ' ' << format("%5u", index);
- sigElt->GetInterpolationMode()->GetName();
- OS << ' ' << right_justify(sigElt->GetInterpolationMode()->GetName(), 22);
- OS << " ";
- PintCompMaskNameCompact(OS, sigElt->GetDynIdxCompMask());
- OS << "\n";
- }
- }
- PCSTR g_pFeatureInfoNames[] = {
- "Double-precision floating point",
- "Raw and Structured buffers",
- "UAVs at every shader stage",
- "64 UAV slots",
- "Minimum-precision data types",
- "Double-precision extensions for 11.1",
- "Shader extensions for 11.1",
- "Comparison filtering for feature level 9",
- "Tiled resources",
- "PS Output Stencil Ref",
- "PS Inner Coverage",
- "Typed UAV Load Additional Formats",
- "Raster Ordered UAVs",
- "SV_RenderTargetArrayIndex or SV_ViewportArrayIndex from any shader "
- "feeding rasterizer",
- "Wave level operations",
- "64-Bit integer",
- "View Instancing",
- "Barycentrics",
- "Use native low precision"
- };
- static_assert(_countof(g_pFeatureInfoNames) == ShaderFeatureInfoCount, "g_pFeatureInfoNames needs to be updated");
- void PrintFeatureInfo(const DxilShaderFeatureInfo *pFeatureInfo,
- raw_string_ostream &OS, StringRef comment) {
- uint64_t featureFlags = pFeatureInfo->FeatureFlags;
- if (!featureFlags)
- return;
- OS << comment << "\n";
- OS << comment << " Note: shader requires additional functionality:\n";
- for (unsigned i = 0; i < ShaderFeatureInfoCount; i++) {
- if (featureFlags & (((uint64_t)1) << i))
- OS << comment << " " << g_pFeatureInfoNames[i] << "\n";
- }
- OS << comment << "\n";
- }
- void PrintResourceFormat(DxilResourceBase &res, unsigned alignment,
- raw_string_ostream &OS) {
- switch (res.GetClass()) {
- case DxilResourceBase::Class::CBuffer:
- case DxilResourceBase::Class::Sampler:
- OS << right_justify("NA", alignment);
- break;
- case DxilResourceBase::Class::UAV:
- case DxilResourceBase::Class::SRV:
- switch (res.GetKind()) {
- case DxilResource::Kind::RawBuffer:
- OS << right_justify("byte", alignment);
- break;
- case DxilResource::Kind::StructuredBuffer:
- OS << right_justify("struct", alignment);
- break;
- default:
- DxilResource *pRes = static_cast<DxilResource *>(&res);
- CompType &&compType = pRes->GetCompType();
- const char *compName = compType.GetName();
- // TODO: add vector size.
- OS << right_justify(compName, alignment);
- break;
- }
- }
- }
- void PrintResourceDim(DxilResourceBase &res, unsigned alignment,
- raw_string_ostream &OS) {
- switch (res.GetClass()) {
- case DxilResourceBase::Class::CBuffer:
- case DxilResourceBase::Class::Sampler:
- OS << right_justify("NA", alignment);
- break;
- case DxilResourceBase::Class::UAV:
- case DxilResourceBase::Class::SRV:
- switch (res.GetKind()) {
- case DxilResource::Kind::RawBuffer:
- case DxilResource::Kind::StructuredBuffer:
- if (res.GetClass() == DxilResourceBase::Class::SRV)
- OS << right_justify("r/o", alignment);
- else {
- DxilResource &dxilRes = static_cast<DxilResource &>(res);
- if (!dxilRes.HasCounter())
- OS << right_justify("r/w", alignment);
- else
- OS << right_justify("r/w+cnt", alignment);
- }
- break;
- case DxilResource::Kind::TypedBuffer:
- OS << right_justify("buf", alignment);
- break;
- case DxilResource::Kind::Texture2DMS:
- case DxilResource::Kind::Texture2DMSArray: {
- DxilResource *pRes = static_cast<DxilResource *>(&res);
- std::string dimName = res.GetResDimName();
- if (pRes->GetSampleCount())
- dimName += pRes->GetSampleCount();
- OS << right_justify(dimName, alignment);
- } break;
- default:
- OS << right_justify(res.GetResDimName(), alignment);
- break;
- }
- break;
- }
- }
- void PrintResourceBinding(DxilResourceBase &res, raw_string_ostream &OS,
- StringRef comment) {
- OS << comment << " " << left_justify(res.GetGlobalName(), 31);
- OS << right_justify(res.GetResClassName(), 10);
- PrintResourceFormat(res, 8, OS);
- PrintResourceDim(res, 12, OS);
- std::string ID = res.GetResIDPrefix();
- ID += std::to_string(res.GetID());
- OS << right_justify(ID, 8);
- std::string bind = res.GetResBindPrefix();
- bind += std::to_string(res.GetLowerBound());
- if (res.GetSpaceID())
- bind += ",space" + std::to_string(res.GetSpaceID());
- OS << right_justify(bind, 15);
- if (res.GetRangeSize() != UINT_MAX)
- OS << right_justify(std::to_string(res.GetRangeSize()), 6) << "\n";
- else
- OS << right_justify("unbounded", 6) << "\n";
- }
- void PrintResourceBindings(DxilModule &M, raw_string_ostream &OS,
- StringRef comment) {
- OS << comment << "\n"
- << comment << " Resource Bindings:\n"
- << comment << "\n"
- << comment
- << " Name Type Format Dim "
- "ID HLSL Bind Count\n"
- << comment
- << " ------------------------------ ---------- ------- ----------- "
- "------- -------------- ------\n";
- for (auto &res : M.GetCBuffers()) {
- PrintResourceBinding(*res.get(), OS, comment);
- }
- for (auto &res : M.GetSamplers()) {
- PrintResourceBinding(*res.get(), OS, comment);
- }
- for (auto &res : M.GetSRVs()) {
- PrintResourceBinding(*res.get(), OS, comment);
- }
- for (auto &res : M.GetUAVs()) {
- PrintResourceBinding(*res.get(), OS, comment);
- }
- OS << comment << "\n";
- }
- void PrintOutputsDependentOnViewId(
- llvm::raw_ostream &OS, llvm::StringRef comment, llvm::StringRef SetName,
- unsigned NumOutputs,
- const DxilViewIdState::OutputsDependentOnViewIdType
- &OutputsDependentOnViewId) {
- OS << comment << " " << SetName << " dependent on ViewId: { ";
- bool bFirst = true;
- for (unsigned i = 0; i < NumOutputs; i++) {
- if (OutputsDependentOnViewId[i]) {
- if (!bFirst)
- OS << ", ";
- OS << i;
- bFirst = false;
- }
- }
- OS << " }\n";
- }
- void PrintInputsContributingToOutputs(
- llvm::raw_ostream &OS, llvm::StringRef comment,
- llvm::StringRef InputSetName, llvm::StringRef OutputSetName,
- const DxilViewIdState::InputsContributingToOutputType
- &InputsContributingToOutputs) {
- OS << comment << " " << InputSetName << " contributing to computation of "
- << OutputSetName << ":\n";
- for (auto &it : InputsContributingToOutputs) {
- unsigned outIdx = it.first;
- auto &Inputs = it.second;
- OS << comment << " output " << outIdx << " depends on inputs: { ";
- bool bFirst = true;
- for (unsigned i : Inputs) {
- if (!bFirst)
- OS << ", ";
- OS << i;
- bFirst = false;
- }
- OS << " }\n";
- }
- }
- void PrintViewIdState(DxilModule &M, raw_string_ostream &OS,
- StringRef comment) {
- if (!M.GetModule()->getNamedMetadata("dx.viewIdState"))
- return;
- const ShaderModel *pSM = M.GetShaderModel();
- DxilViewIdState &VID = M.GetViewIdState();
- OS << comment << "\n";
- OS << comment << " ViewId state:\n";
- OS << comment << "\n";
- OS << comment << " Number of inputs: " << VID.getNumInputSigScalars();
- if (!pSM->IsGS()) {
- OS << ", outputs: " << VID.getNumOutputSigScalars(0);
- } else {
- OS << ", outputs per stream: { " << VID.getNumOutputSigScalars(0) << ", "
- << VID.getNumOutputSigScalars(1) << ", " << VID.getNumOutputSigScalars(2)
- << ", " << VID.getNumOutputSigScalars(3) << " }";
- }
- if (pSM->IsHS() || pSM->IsDS()) {
- OS << ", patchconst: " << VID.getNumPCSigScalars();
- }
- OS << "\n";
- if (!pSM->IsGS()) {
- PrintOutputsDependentOnViewId(OS, comment, "Outputs",
- VID.getNumOutputSigScalars(0),
- VID.getOutputsDependentOnViewId(0));
- } else {
- for (unsigned i = 0; i < 4; i++) {
- if (VID.getNumOutputSigScalars(i) > 0) {
- std::string OutputsName =
- std::string("Outputs for Stream ") + std::to_string(i);
- PrintOutputsDependentOnViewId(OS, comment, OutputsName,
- VID.getNumOutputSigScalars(i),
- VID.getOutputsDependentOnViewId(i));
- }
- }
- }
- if (pSM->IsHS()) {
- PrintOutputsDependentOnViewId(OS, comment, "PCOutputs",
- VID.getNumPCSigScalars(),
- VID.getPCOutputsDependentOnViewId());
- }
- if (!pSM->IsGS()) {
- PrintInputsContributingToOutputs(OS, comment, "Inputs", "Outputs",
- VID.getInputsContributingToOutputs(0));
- } else {
- for (unsigned i = 0; i < 4; i++) {
- if (VID.getNumOutputSigScalars(i) > 0) {
- std::string OutputsName =
- std::string("Outputs for Stream ") + std::to_string(i);
- PrintInputsContributingToOutputs(OS, comment, "Inputs", OutputsName,
- VID.getInputsContributingToOutputs(i));
- }
- }
- }
- if (pSM->IsHS()) {
- PrintInputsContributingToOutputs(OS, comment, "Inputs", "PCOutputs",
- VID.getInputsContributingToPCOutputs());
- } else if (pSM->IsDS()) {
- PrintInputsContributingToOutputs(OS, comment, "PCInputs", "Outputs",
- VID.getPCInputsContributingToOutputs());
- }
- OS << comment << "\n";
- }
- void PrintStructLayout(StructType *ST, DxilTypeSystem &typeSys,
- raw_string_ostream &OS, StringRef comment,
- StringRef varName, unsigned offset,
- unsigned indent, unsigned arraySize,
- unsigned sizeOfStruct = 0);
- void PrintTypeAndName(llvm::Type *Ty, DxilFieldAnnotation &annotation,
- std::string &StreamStr, unsigned arraySize, bool minPrecision) {
- raw_string_ostream Stream(StreamStr);
- while (Ty->isArrayTy())
- Ty = Ty->getArrayElementType();
- const char *compTyName = annotation.GetCompType().GetHLSLName(minPrecision);
- if (annotation.HasMatrixAnnotation()) {
- const DxilMatrixAnnotation &Matrix = annotation.GetMatrixAnnotation();
- switch (Matrix.Orientation) {
- case MatrixOrientation::RowMajor:
- Stream << "row_major ";
- break;
- case MatrixOrientation::ColumnMajor:
- Stream << "column_major ";
- break;
- }
- Stream << compTyName << Matrix.Rows << "x" << Matrix.Cols;
- } else if (Ty->isVectorTy())
- Stream << compTyName << Ty->getVectorNumElements();
- else
- Stream << compTyName;
- Stream << " " << annotation.GetFieldName();
- if (arraySize)
- Stream << "[" << arraySize << "]";
- Stream << ";";
- Stream.flush();
- }
- void PrintFieldLayout(llvm::Type *Ty, DxilFieldAnnotation &annotation,
- DxilTypeSystem &typeSys, raw_string_ostream &OS,
- StringRef comment, unsigned offset,
- unsigned indent, unsigned offsetIndent,
- unsigned sizeToPrint = 0) {
- offset += annotation.GetCBufferOffset();
- if (Ty->isStructTy() && !annotation.HasMatrixAnnotation()) {
- PrintStructLayout(cast<StructType>(Ty), typeSys, OS, comment,
- annotation.GetFieldName(), offset, indent, offsetIndent);
- } else {
- llvm::Type *EltTy = Ty;
- unsigned arraySize = 0;
- unsigned arrayLevel = 0;
- if (!HLMatrixLower::IsMatrixType(EltTy) && EltTy->isArrayTy()) {
- arraySize = 1;
- while (!HLMatrixLower::IsMatrixType(EltTy) && EltTy->isArrayTy()) {
- arraySize *= EltTy->getArrayNumElements();
- EltTy = EltTy->getArrayElementType();
- arrayLevel++;
- }
- }
- if (annotation.HasMatrixAnnotation()) {
- const DxilMatrixAnnotation &Matrix = annotation.GetMatrixAnnotation();
- switch (Matrix.Orientation) {
- case MatrixOrientation::RowMajor:
- arraySize /= Matrix.Rows;
- break;
- case MatrixOrientation::ColumnMajor:
- arraySize /= Matrix.Cols;
- break;
- }
- if (EltTy->isVectorTy()) {
- EltTy = EltTy->getVectorElementType();
- } else if (EltTy->isStructTy()) {
- unsigned col, row;
- EltTy = HLMatrixLower::GetMatrixInfo(EltTy, col, row);
- }
- if (arrayLevel == 1)
- arraySize = 0;
- }
- std::string StreamStr;
- if (!HLMatrixLower::IsMatrixType(EltTy) && EltTy->isStructTy()) {
- std::string NameTypeStr = annotation.GetFieldName();
- raw_string_ostream Stream(NameTypeStr);
- if (arraySize)
- Stream << "[" << std::to_string(arraySize) << "]";
- Stream << ";";
- Stream.flush();
- PrintStructLayout(cast<StructType>(EltTy), typeSys, OS, comment,
- NameTypeStr, offset, indent, offsetIndent);
- } else {
- (OS << comment).indent(indent);
- std::string NameTypeStr;
- PrintTypeAndName(Ty, annotation, NameTypeStr, arraySize, typeSys.UseMinPrecision());
- OS << left_justify(NameTypeStr, offsetIndent);
- // Offset
- OS << comment << " Offset:" << right_justify(std::to_string(offset), 5);
- if (sizeToPrint)
- OS << " Size: " << right_justify(std::to_string(sizeToPrint), 5);
- OS << "\n";
- }
- }
- }
- void PrintStructLayout(StructType *ST, DxilTypeSystem &typeSys,
- raw_string_ostream &OS, StringRef comment,
- StringRef varName, unsigned offset,
- unsigned indent, unsigned offsetIndent,
- unsigned sizeOfStruct) {
- DxilStructAnnotation *annotation = typeSys.GetStructAnnotation(ST);
- (OS << comment).indent(indent) << "struct " << ST->getName() << "\n";
- (OS << comment).indent(indent) << "{\n";
- OS << comment << "\n";
- unsigned fieldIndent = indent + 4;
- if (!annotation) {
- if (!sizeOfStruct) {
- (OS << comment).indent(indent) << "/* empty struct */\n";
- } else {
- (OS << comment).indent(indent) << "[" << sizeOfStruct << " x i8] (type annotation not present)\n";
- }
- } else {
- for (unsigned i = 0; i < ST->getNumElements(); i++) {
- PrintFieldLayout(ST->getElementType(i), annotation->GetFieldAnnotation(i),
- typeSys, OS, comment, offset, fieldIndent,
- offsetIndent - 4);
- }
- }
- (OS << comment).indent(indent) << "\n";
- // The 2 in offsetIndent-indent-2 is for "} ".
- (OS << comment).indent(indent)
- << "} " << left_justify(varName, offsetIndent - 2);
- OS << comment << " Offset:" << right_justify(std::to_string(offset), 5);
- if (sizeOfStruct)
- OS << " Size: " << right_justify(std::to_string(sizeOfStruct), 5);
- ;
- OS << "\n";
- OS << comment << "\n";
- }
- void PrintStructBufferDefinition(DxilResource *buf,
- DxilTypeSystem &typeSys,
- const DataLayout &DL,
- raw_string_ostream &OS,
- StringRef comment) {
- const unsigned offsetIndent = 50;
- OS << comment << " Resource bind info for " << buf->GetGlobalName() << "\n";
- OS << comment << " {\n";
- OS << comment << "\n";
- llvm::Type *RetTy = buf->GetRetType();
- // Skip none struct type.
- if (!RetTy->isStructTy() || HLMatrixLower::IsMatrixType(RetTy)) {
- Value *GV = buf->GetGlobalSymbol();
- llvm::Type *Ty = GV->getType()->getPointerElementType();
- // For resource array, use element type.
- if (Ty->isArrayTy())
- Ty = Ty->getArrayElementType();
- // Get the struct buffer type like this %class.StructuredBuffer = type {
- // %struct.mat }.
- StructType *ST = cast<StructType>(Ty);
- DxilStructAnnotation *annotation = typeSys.GetStructAnnotation(ST);
- if (nullptr == annotation) {
- OS << comment << " [" << DL.getTypeAllocSize(ST)
- << " x i8] (type annotation not present)\n";
- } else {
- DxilFieldAnnotation &fieldAnnotation = annotation->GetFieldAnnotation(0);
- fieldAnnotation.SetFieldName("$Element");
- PrintFieldLayout(RetTy, fieldAnnotation, typeSys, OS, comment,
- /*offset*/ 0, /*indent*/ 3, offsetIndent,
- DL.getTypeAllocSize(ST));
- }
- OS << comment << "\n";
- } else {
- StructType *ST = cast<StructType>(RetTy);
- // TODO: struct buffer has different layout.
- // Cannot use cbuffer layout here.
- DxilStructAnnotation *annotation = typeSys.GetStructAnnotation(ST);
- if (nullptr == annotation) {
- OS << comment << " [" << DL.getTypeAllocSize(ST)
- << " x i8] (type annotation not present)\n";
- } else {
- PrintStructLayout(ST, typeSys, OS, comment, "$Element;",
- /*offset*/ 0, /*indent*/ 3, offsetIndent,
- DL.getTypeAllocSize(ST));
- }
- }
- OS << comment << " }\n";
- OS << comment << "\n";
- }
- void PrintTBufferDefinition(DxilResource *buf, DxilTypeSystem &typeSys,
- raw_string_ostream &OS, StringRef comment) {
- const unsigned offsetIndent = 50;
- Value *GV = buf->GetGlobalSymbol();
- llvm::Type *Ty = GV->getType()->getPointerElementType();
- // For TextureBuffer<> buf[2], the array size is in Resource binding count
- // part.
- if (Ty->isArrayTy())
- Ty = Ty->getArrayElementType();
- DxilStructAnnotation *annotation =
- typeSys.GetStructAnnotation(cast<StructType>(Ty));
- OS << comment << " tbuffer " << buf->GetGlobalName() << "\n";
- OS << comment << " {\n";
- OS << comment << "\n";
- if (nullptr == annotation) {
- OS << comment << " (type annotation not present)\n";
- OS << comment << "\n";
- } else {
- PrintStructLayout(cast<StructType>(Ty), typeSys, OS, comment,
- buf->GetGlobalName(), /*offset*/ 0, /*indent*/ 3,
- offsetIndent, annotation->GetCBufferSize());
- }
- OS << comment << " }\n";
- OS << comment << "\n";
- }
- void PrintCBufferDefinition(DxilCBuffer *buf, DxilTypeSystem &typeSys,
- raw_string_ostream &OS, StringRef comment) {
- const unsigned offsetIndent = 50;
- Value *GV = buf->GetGlobalSymbol();
- llvm::Type *Ty = GV->getType()->getPointerElementType();
- // For ConstantBuffer<> buf[2], the array size is in Resource binding count
- // part.
- if (Ty->isArrayTy())
- Ty = Ty->getArrayElementType();
- DxilStructAnnotation *annotation =
- typeSys.GetStructAnnotation(cast<StructType>(Ty));
- OS << comment << " cbuffer " << buf->GetGlobalName() << "\n";
- OS << comment << " {\n";
- OS << comment << "\n";
- if (nullptr == annotation) {
- OS << comment << " [" << buf->GetSize()
- << " x i8] (type annotation not present)\n";
- OS << comment << "\n";
- } else {
- PrintStructLayout(cast<StructType>(Ty), typeSys, OS, comment,
- buf->GetGlobalName(), /*offset*/ 0, /*indent*/ 3,
- offsetIndent, buf->GetSize());
- }
- OS << comment << " }\n";
- OS << comment << "\n";
- }
- void PrintBufferDefinitions(DxilModule &M, raw_string_ostream &OS,
- StringRef comment) {
- OS << comment << "\n"
- << comment << " Buffer Definitions:\n"
- << comment << "\n";
- DxilTypeSystem &typeSys = M.GetTypeSystem();
- for (auto &CBuf : M.GetCBuffers())
- PrintCBufferDefinition(CBuf.get(), typeSys, OS, comment);
- const DataLayout &layout = M.GetModule()->getDataLayout();
- for (auto &res : M.GetSRVs()) {
- if (res->IsStructuredBuffer())
- PrintStructBufferDefinition(res.get(), typeSys, layout, OS, comment);
- else if (res->IsTBuffer())
- PrintTBufferDefinition(res.get(), typeSys, OS, comment);
- }
- for (auto &res : M.GetUAVs()) {
- if (res->IsStructuredBuffer())
- PrintStructBufferDefinition(res.get(), typeSys, layout, OS, comment);
- }
- }
- /* <py::lines('OPCODE-SIGS')>hctdb_instrhelp.get_opsigs()</py>*/
- // OPCODE-SIGS:BEGIN
- static const char *OpCodeSignatures[] = {
- "(index)", // TempRegLoad
- "(index,value)", // TempRegStore
- "(regIndex,index,component)", // MinPrecXRegLoad
- "(regIndex,index,component,value)", // MinPrecXRegStore
- "(inputSigId,rowIndex,colIndex,gsVertexAxis)", // LoadInput
- "(outputSigId,rowIndex,colIndex,value)", // StoreOutput
- "(value)", // FAbs
- "(value)", // Saturate
- "(value)", // IsNaN
- "(value)", // IsInf
- "(value)", // IsFinite
- "(value)", // IsNormal
- "(value)", // Cos
- "(value)", // Sin
- "(value)", // Tan
- "(value)", // Acos
- "(value)", // Asin
- "(value)", // Atan
- "(value)", // Hcos
- "(value)", // Hsin
- "(value)", // Htan
- "(value)", // Exp
- "(value)", // Frc
- "(value)", // Log
- "(value)", // Sqrt
- "(value)", // Rsqrt
- "(value)", // Round_ne
- "(value)", // Round_ni
- "(value)", // Round_pi
- "(value)", // Round_z
- "(value)", // Bfrev
- "(value)", // Countbits
- "(value)", // FirstbitLo
- "(value)", // FirstbitHi
- "(value)", // FirstbitSHi
- "(a,b)", // FMax
- "(a,b)", // FMin
- "(a,b)", // IMax
- "(a,b)", // IMin
- "(a,b)", // UMax
- "(a,b)", // UMin
- "(a,b)", // IMul
- "(a,b)", // UMul
- "(a,b)", // UDiv
- "(a,b)", // UAddc
- "(a,b)", // USubb
- "(a,b,c)", // FMad
- "(a,b,c)", // Fma
- "(a,b,c)", // IMad
- "(a,b,c)", // UMad
- "(a,b,c)", // Msad
- "(a,b,c)", // Ibfe
- "(a,b,c)", // Ubfe
- "(width,offset,value,replacedValue)", // Bfi
- "(ax,ay,bx,by)", // Dot2
- "(ax,ay,az,bx,by,bz)", // Dot3
- "(ax,ay,az,aw,bx,by,bz,bw)", // Dot4
- "(resourceClass,rangeId,index,nonUniformIndex)", // CreateHandle
- "(handle,byteOffset,alignment)", // CBufferLoad
- "(handle,regIndex)", // CBufferLoadLegacy
- "(srv,sampler,coord0,coord1,coord2,coord3,offset0,offset1,offset2,clamp)", // Sample
- "(srv,sampler,coord0,coord1,coord2,coord3,offset0,offset1,offset2,bias,clamp)", // SampleBias
- "(srv,sampler,coord0,coord1,coord2,coord3,offset0,offset1,offset2,LOD)", // SampleLevel
- "(srv,sampler,coord0,coord1,coord2,coord3,offset0,offset1,offset2,ddx0,ddx1,ddx2,ddy0,ddy1,ddy2,clamp)", // SampleGrad
- "(srv,sampler,coord0,coord1,coord2,coord3,offset0,offset1,offset2,compareValue,clamp)", // SampleCmp
- "(srv,sampler,coord0,coord1,coord2,coord3,offset0,offset1,offset2,compareValue)", // SampleCmpLevelZero
- "(srv,mipLevelOrSampleCount,coord0,coord1,coord2,offset0,offset1,offset2)", // TextureLoad
- "(srv,coord0,coord1,coord2,value0,value1,value2,value3,mask)", // TextureStore
- "(srv,index,wot)", // BufferLoad
- "(uav,coord0,coord1,value0,value1,value2,value3,mask)", // BufferStore
- "(uav,inc)", // BufferUpdateCounter
- "(status)", // CheckAccessFullyMapped
- "(handle,mipLevel)", // GetDimensions
- "(srv,sampler,coord0,coord1,coord2,coord3,offset0,offset1,channel)", // TextureGather
- "(srv,sampler,coord0,coord1,coord2,coord3,offset0,offset1,channel,compareVale)", // TextureGatherCmp
- "(srv,index)", // Texture2DMSGetSamplePosition
- "(index)", // RenderTargetGetSamplePosition
- "()", // RenderTargetGetSampleCount
- "(handle,atomicOp,offset0,offset1,offset2,newValue)", // AtomicBinOp
- "(handle,offset0,offset1,offset2,compareValue,newValue)", // AtomicCompareExchange
- "(barrierMode)", // Barrier
- "(handle,sampler,coord0,coord1,coord2,clamped)", // CalculateLOD
- "(condition)", // Discard
- "(value)", // DerivCoarseX
- "(value)", // DerivCoarseY
- "(value)", // DerivFineX
- "(value)", // DerivFineY
- "(inputSigId,inputRowIndex,inputColIndex,offsetX,offsetY)", // EvalSnapped
- "(inputSigId,inputRowIndex,inputColIndex,sampleIndex)", // EvalSampleIndex
- "(inputSigId,inputRowIndex,inputColIndex)", // EvalCentroid
- "()", // SampleIndex
- "()", // Coverage
- "()", // InnerCoverage
- "(component)", // ThreadId
- "(component)", // GroupId
- "(component)", // ThreadIdInGroup
- "()", // FlattenedThreadIdInGroup
- "(streamId)", // EmitStream
- "(streamId)", // CutStream
- "(streamId)", // EmitThenCutStream
- "()", // GSInstanceID
- "(lo,hi)", // MakeDouble
- "(value)", // SplitDouble
- "(inputSigId,row,col,index)", // LoadOutputControlPoint
- "(inputSigId,row,col)", // LoadPatchConstant
- "(component)", // DomainLocation
- "(outputSigID,row,col,value)", // StorePatchConstant
- "()", // OutputControlPointID
- "()", // PrimitiveID
- "()", // CycleCounterLegacy
- "()", // WaveIsFirstLane
- "()", // WaveGetLaneIndex
- "()", // WaveGetLaneCount
- "(cond)", // WaveAnyTrue
- "(cond)", // WaveAllTrue
- "(value)", // WaveActiveAllEqual
- "(cond)", // WaveActiveBallot
- "(value,lane)", // WaveReadLaneAt
- "(value)", // WaveReadLaneFirst
- "(value,op,sop)", // WaveActiveOp
- "(value,op)", // WaveActiveBit
- "(value,op,sop)", // WavePrefixOp
- "(value,quadLane)", // QuadReadLaneAt
- "(value,op)", // QuadOp
- "(value)", // BitcastI16toF16
- "(value)", // BitcastF16toI16
- "(value)", // BitcastI32toF32
- "(value)", // BitcastF32toI32
- "(value)", // BitcastI64toF64
- "(value)", // BitcastF64toI64
- "(value)", // LegacyF32ToF16
- "(value)", // LegacyF16ToF32
- "(value)", // LegacyDoubleToFloat
- "(value)", // LegacyDoubleToSInt32
- "(value)", // LegacyDoubleToUInt32
- "(value)", // WaveAllBitCount
- "(value)", // WavePrefixBitCount
- "(inputSigId,inputRowIndex,inputColIndex,VertexID)", // AttributeAtVertex
- "()", // ViewID
- "(srv,index,elementOffset,mask,alignment)", // RawBufferLoad
- "(uav,index,elementOffset,value0,value1,value2,value3,mask,alignment)", // RawBufferStore
- "()", // InstanceID
- "()", // InstanceIndex
- "()", // HitKind
- "()", // RayFlags
- "(col)", // DispatchRaysIndex
- "(col)", // DispatchRaysDimensions
- "(col)", // WorldRayOrigin
- "(col)", // WorldRayDirection
- "(col)", // ObjectRayOrigin
- "(col)", // ObjectRayDirection
- "(row,col)", // ObjectToWorld
- "(row,col)", // WorldToObject
- "()", // RayTMin
- "()", // RayTCurrent
- "()", // IgnoreHit
- "()", // AcceptHitAndEndSearch
- "(AccelerationStructure,RayFlags,InstanceInclusionMask,RayContributionToHitGroupIndex,MultiplierForGeometryContributionToShaderIndex,MissShaderIndex,Origin_X,Origin_Y,Origin_Z,TMin,Direction_X,Direction_Y,Direction_Z,TMax,payload)", // TraceRay
- "(THit,HitKind,Attributes)", // ReportHit
- "(ShaderIndex,Parameter)", // CallShader
- "(Resource)", // CreateHandleForLib
- "()" // PrimitiveIndex
- };
- // OPCODE-SIGS:END
- class DxcAssemblyAnnotationWriter : public llvm::AssemblyAnnotationWriter {
- public:
- ~DxcAssemblyAnnotationWriter() {}
- void printInfoComment(const Value &V, formatted_raw_ostream &OS) override {
- const CallInst *CI = dyn_cast<const CallInst>(&V);
- if (!CI) {
- return;
- }
- // TODO: annotate high-level operations where possible as well
- if (CI->getNumArgOperands() == 0 ||
- !CI->getCalledFunction()->getName().startswith("dx.op.")) {
- return;
- }
- const ConstantInt *CInt = dyn_cast<const ConstantInt>(CI->getArgOperand(0));
- if (!CInt) {
- // At this point, we know this is malformed; ignore.
- return;
- }
- unsigned opcodeVal = CInt->getZExtValue();
- if (opcodeVal >= (unsigned)DXIL::OpCode::NumOpCodes) {
- OS << " ; invalid DXIL opcode #" << opcodeVal;
- return;
- }
- // TODO: if an argument references a resource, look it up and write the
- // name/binding
- DXIL::OpCode opcode = (DXIL::OpCode)opcodeVal;
- OS << " ; " << hlsl::OP::GetOpCodeName(opcode)
- << OpCodeSignatures[opcodeVal];
- }
- };
- void PrintPipelineStateValidationRuntimeInfo(const char *pBuffer,
- DXIL::ShaderKind shaderKind,
- raw_string_ostream &OS,
- StringRef comment) {
- OS << comment << "\n"
- << comment << " Pipeline Runtime Information: \n"
- << comment << "\n";
- const unsigned offset = sizeof(unsigned);
- const PSVRuntimeInfo0 *pInfo = (PSVRuntimeInfo0 *)(pBuffer + offset);
- switch (shaderKind) {
- case DXIL::ShaderKind::Hull: {
- OS << comment << " Hull Shader\n";
- OS << comment
- << " InputControlPointCount=" << pInfo->HS.InputControlPointCount
- << "\n";
- OS << comment
- << " OutputControlPointCount=" << pInfo->HS.OutputControlPointCount
- << "\n";
- OS << comment << " Domain=";
- DXIL::TessellatorDomain domain =
- static_cast<DXIL::TessellatorDomain>(pInfo->HS.TessellatorDomain);
- switch (domain) {
- case DXIL::TessellatorDomain::IsoLine:
- OS << "isoline\n";
- break;
- case DXIL::TessellatorDomain::Tri:
- OS << "tri\n";
- break;
- case DXIL::TessellatorDomain::Quad:
- OS << "quad\n";
- break;
- default:
- OS << "invalid\n";
- break;
- }
- OS << comment << " OutputPrimitive=";
- DXIL::TessellatorOutputPrimitive primitive =
- static_cast<DXIL::TessellatorOutputPrimitive>(
- pInfo->HS.TessellatorOutputPrimitive);
- switch (primitive) {
- case DXIL::TessellatorOutputPrimitive::Point:
- OS << "point\n";
- break;
- case DXIL::TessellatorOutputPrimitive::Line:
- OS << "line\n";
- break;
- case DXIL::TessellatorOutputPrimitive::TriangleCW:
- OS << "triangle_cw\n";
- break;
- case DXIL::TessellatorOutputPrimitive::TriangleCCW:
- OS << "triangle_ccw\n";
- break;
- default:
- OS << "invalid\n";
- break;
- }
- } break;
- case DXIL::ShaderKind::Domain:
- OS << comment << " Domain Shader\n";
- OS << comment
- << " InputControlPointCount=" << pInfo->DS.InputControlPointCount
- << "\n";
- OS << comment
- << " OutputPositionPresent=" << (bool)pInfo->DS.OutputPositionPresent
- << "\n";
- break;
- case DXIL::ShaderKind::Geometry: {
- OS << comment << " Geometry Shader\n";
- OS << comment << " InputPrimitive=";
- DXIL::InputPrimitive primitive =
- static_cast<DXIL::InputPrimitive>(pInfo->GS.InputPrimitive);
- switch (primitive) {
- case DXIL::InputPrimitive::Point:
- OS << "point\n";
- break;
- case DXIL::InputPrimitive::Line:
- OS << "line\n";
- break;
- case DXIL::InputPrimitive::LineWithAdjacency:
- OS << "lineadj\n";
- break;
- case DXIL::InputPrimitive::Triangle:
- OS << "triangle\n";
- break;
- case DXIL::InputPrimitive::TriangleWithAdjacency:
- OS << "triangleadj\n";
- break;
- case DXIL::InputPrimitive::ControlPointPatch1:
- OS << "patch1\n";
- break;
- case DXIL::InputPrimitive::ControlPointPatch2:
- OS << "patch2\n";
- break;
- case DXIL::InputPrimitive::ControlPointPatch3:
- OS << "patch3\n";
- break;
- case DXIL::InputPrimitive::ControlPointPatch4:
- OS << "patch4\n";
- break;
- case DXIL::InputPrimitive::ControlPointPatch5:
- OS << "patch5\n";
- break;
- case DXIL::InputPrimitive::ControlPointPatch6:
- OS << "patch6\n";
- break;
- case DXIL::InputPrimitive::ControlPointPatch7:
- OS << "patch7\n";
- break;
- case DXIL::InputPrimitive::ControlPointPatch8:
- OS << "patch8\n";
- break;
- case DXIL::InputPrimitive::ControlPointPatch9:
- OS << "patch9\n";
- break;
- case DXIL::InputPrimitive::ControlPointPatch10:
- OS << "patch10\n";
- break;
- case DXIL::InputPrimitive::ControlPointPatch11:
- OS << "patch11\n";
- break;
- case DXIL::InputPrimitive::ControlPointPatch12:
- OS << "patch12\n";
- break;
- case DXIL::InputPrimitive::ControlPointPatch13:
- OS << "patch13\n";
- break;
- case DXIL::InputPrimitive::ControlPointPatch14:
- OS << "patch14\n";
- break;
- case DXIL::InputPrimitive::ControlPointPatch15:
- OS << "patch15\n";
- break;
- case DXIL::InputPrimitive::ControlPointPatch16:
- OS << "patch16\n";
- break;
- case DXIL::InputPrimitive::ControlPointPatch17:
- OS << "patch17\n";
- break;
- case DXIL::InputPrimitive::ControlPointPatch18:
- OS << "patch18\n";
- break;
- case DXIL::InputPrimitive::ControlPointPatch19:
- OS << "patch19\n";
- break;
- case DXIL::InputPrimitive::ControlPointPatch20:
- OS << "patch20\n";
- break;
- case DXIL::InputPrimitive::ControlPointPatch21:
- OS << "patch21\n";
- break;
- case DXIL::InputPrimitive::ControlPointPatch22:
- OS << "patch22\n";
- break;
- case DXIL::InputPrimitive::ControlPointPatch23:
- OS << "patch23\n";
- break;
- case DXIL::InputPrimitive::ControlPointPatch24:
- OS << "patch24\n";
- break;
- case DXIL::InputPrimitive::ControlPointPatch25:
- OS << "patch25\n";
- break;
- case DXIL::InputPrimitive::ControlPointPatch26:
- OS << "patch26\n";
- break;
- case DXIL::InputPrimitive::ControlPointPatch27:
- OS << "patch27\n";
- break;
- case DXIL::InputPrimitive::ControlPointPatch28:
- OS << "patch28\n";
- break;
- case DXIL::InputPrimitive::ControlPointPatch29:
- OS << "patch29\n";
- break;
- case DXIL::InputPrimitive::ControlPointPatch30:
- OS << "patch30\n";
- break;
- case DXIL::InputPrimitive::ControlPointPatch31:
- OS << "patch31\n";
- break;
- case DXIL::InputPrimitive::ControlPointPatch32:
- OS << "patch32\n";
- break;
- default:
- OS << "invalid\n";
- break;
- }
- OS << comment << " OutputTopology=";
- DXIL::PrimitiveTopology topology =
- static_cast<DXIL::PrimitiveTopology>(pInfo->GS.OutputTopology);
- switch (topology) {
- case DXIL::PrimitiveTopology::PointList:
- OS << "point\n";
- break;
- case DXIL::PrimitiveTopology::LineStrip:
- OS << "line\n";
- break;
- case DXIL::PrimitiveTopology::TriangleStrip:
- OS << "triangle\n";
- break;
- default:
- OS << "invalid\n";
- break;
- }
- OS << comment << " OutputStreamMask=" << pInfo->GS.OutputStreamMask << "\n";
- OS << comment
- << " OutputPositionPresent=" << (bool)pInfo->GS.OutputPositionPresent
- << "\n";
- } break;
- case DXIL::ShaderKind::Vertex:
- OS << comment << " Vertex Shader\n";
- OS << comment
- << " OutputPositionPresent=" << (bool)pInfo->VS.OutputPositionPresent
- << "\n";
- break;
- case DXIL::ShaderKind::Pixel:
- OS << comment << " Pixel Shader\n";
- OS << comment << " DepthOutput=" << (bool)pInfo->PS.DepthOutput << "\n";
- OS << comment << " SampleFrequency=" << (bool)pInfo->PS.SampleFrequency
- << "\n";
- break;
- }
- OS << comment << "\n";
- }
- }
- namespace dxcutil {
- HRESULT Disassemble(IDxcBlob *pProgram, raw_string_ostream &Stream) {
- const char *pIL = (const char *)pProgram->GetBufferPointer();
- uint32_t pILLength = pProgram->GetBufferSize();
- if (const DxilContainerHeader *pContainer =
- IsDxilContainerLike(pIL, pILLength)) {
- if (!IsValidDxilContainer(pContainer, pILLength)) {
- return DXC_E_CONTAINER_INVALID;
- }
- DxilPartIterator it = std::find_if(begin(pContainer), end(pContainer),
- DxilPartIsType(DFCC_FeatureInfo));
- if (it != end(pContainer)) {
- PrintFeatureInfo(
- reinterpret_cast<const DxilShaderFeatureInfo *>(GetDxilPartData(*it)),
- Stream, /*comment*/ ";");
- }
- it = std::find_if(begin(pContainer), end(pContainer),
- DxilPartIsType(DFCC_InputSignature));
- if (it != end(pContainer)) {
- PrintSignature(
- "Input",
- reinterpret_cast<const DxilProgramSignature *>(GetDxilPartData(*it)),
- true, Stream, /*comment*/ ";");
- }
- it = std::find_if(begin(pContainer), end(pContainer),
- DxilPartIsType(DFCC_OutputSignature));
- if (it != end(pContainer)) {
- PrintSignature(
- "Output",
- reinterpret_cast<const DxilProgramSignature *>(GetDxilPartData(*it)),
- false, Stream, /*comment*/ ";");
- }
- it = std::find_if(begin(pContainer), end(pContainer),
- DxilPartIsType(DFCC_PatchConstantSignature));
- if (it != end(pContainer)) {
- PrintSignature(
- "Patch Constant signature",
- reinterpret_cast<const DxilProgramSignature *>(GetDxilPartData(*it)),
- false, Stream, /*comment*/ ";");
- }
- it = std::find_if(begin(pContainer), end(pContainer),
- DxilPartIsType(DFCC_ShaderDebugName));
- if (it != end(pContainer)) {
- const char *pDebugName;
- if (!GetDxilShaderDebugName(*it, &pDebugName, nullptr)) {
- Stream << "; shader debug name present; corruption detected\n";
- } else if (pDebugName && *pDebugName) {
- Stream << "; shader debug name: " << pDebugName << "\n";
- }
- }
- it = std::find_if(begin(pContainer), end(pContainer),
- DxilPartIsType(DFCC_DXIL));
- if (it == end(pContainer)) {
- return DXC_E_CONTAINER_MISSING_DXIL;
- }
- DxilPartIterator dbgit =
- std::find_if(begin(pContainer), end(pContainer),
- DxilPartIsType(DFCC_ShaderDebugInfoDXIL));
- // Use dbg module if exist.
- if (dbgit != end(pContainer))
- it = dbgit;
- const DxilProgramHeader *pProgramHeader =
- reinterpret_cast<const DxilProgramHeader *>(GetDxilPartData(*it));
- if (!IsValidDxilProgramHeader(pProgramHeader, (*it)->PartSize)) {
- return DXC_E_CONTAINER_INVALID;
- }
- it = std::find_if(begin(pContainer), end(pContainer),
- DxilPartIsType(DFCC_PipelineStateValidation));
- if (it != end(pContainer)) {
- PrintPipelineStateValidationRuntimeInfo(
- GetDxilPartData(*it),
- GetVersionShaderType(pProgramHeader->ProgramVersion), Stream,
- /*comment*/ ";");
- }
- GetDxilProgramBitcode(pProgramHeader, &pIL, &pILLength);
- } else {
- const DxilProgramHeader *pProgramHeader =
- reinterpret_cast<const DxilProgramHeader *>(pIL);
- if (IsValidDxilProgramHeader(pProgramHeader, pILLength)) {
- GetDxilProgramBitcode(pProgramHeader, &pIL, &pILLength);
- }
- }
- std::string DiagStr;
- llvm::LLVMContext llvmContext;
- std::unique_ptr<llvm::Module> pModule(dxilutil::LoadModuleFromBitcode(
- llvm::StringRef(pIL, pILLength), llvmContext, DiagStr));
- if (pModule.get() == nullptr) {
- return DXC_E_IR_VERIFICATION_FAILED;
- }
- if (pModule->getNamedMetadata("dx.version")) {
- DxilModule &dxilModule = pModule->GetOrCreateDxilModule();
- if (!dxilModule.GetShaderModel()->IsLib()) {
- PrintDxilSignature("Input", dxilModule.GetInputSignature(), Stream,
- /*comment*/ ";");
- PrintDxilSignature("Output", dxilModule.GetOutputSignature(), Stream,
- /*comment*/ ";");
- PrintDxilSignature("Patch Constant signature",
- dxilModule.GetPatchConstantSignature(), Stream,
- /*comment*/ ";");
- }
- PrintBufferDefinitions(dxilModule, Stream, /*comment*/ ";");
- PrintResourceBindings(dxilModule, Stream, /*comment*/ ";");
- PrintViewIdState(dxilModule, Stream, /*comment*/ ";");
- }
- DxcAssemblyAnnotationWriter w;
- pModule->print(Stream, &w);
- Stream.flush();
- return S_OK;
- }
- }
|