Merged PR 80: Merge EntrySignature and FunctionProps together.

Merge EntrySignature and FunctionProps together.
This commit is contained in:
Xiang_Li (XBox) 2018-06-07 02:04:03 +00:00
Родитель c37d554d1e
Коммит 2adce9a983
18 изменённых файлов: 579 добавлений и 489 удалений

Просмотреть файл

@ -20,6 +20,9 @@ class Constant;
namespace hlsl { namespace hlsl {
struct DxilFunctionProps { struct DxilFunctionProps {
DxilFunctionProps() {
memset(this, 0, sizeof(DxilFunctionProps));
}
union { union {
// Compute shader. // Compute shader.
struct { struct {

Просмотреть файл

@ -87,10 +87,6 @@ public:
static const char kDxilSourceMainFileNameMDName[]; static const char kDxilSourceMainFileNameMDName[];
static const char kDxilSourceArgsMDName[]; static const char kDxilSourceArgsMDName[];
// Function props.
static const char kDxilFunctionPropertiesMDName[];
static const char kDxilEntrySignaturesMDName[];
static const unsigned kDxilEntryPointNumFields = 5; static const unsigned kDxilEntryPointNumFields = 5;
static const unsigned kDxilEntryPointFunction = 0; // Entry point function symbol. static const unsigned kDxilEntryPointFunction = 0; // Entry point function symbol.
static const unsigned kDxilEntryPointName = 1; // Entry point unmangled name. static const unsigned kDxilEntryPointName = 1; // Entry point unmangled name.
@ -125,7 +121,6 @@ public:
// Resources. // Resources.
static const char kDxilResourcesMDName[]; static const char kDxilResourcesMDName[];
static const char kDxilResourcesLinkInfoMDName[];
static const unsigned kDxilNumResourceFields = 4; static const unsigned kDxilNumResourceFields = 4;
static const unsigned kDxilResourceSRVs = 0; static const unsigned kDxilResourceSRVs = 0;
static const unsigned kDxilResourceUAVs = 1; static const unsigned kDxilResourceUAVs = 1;
@ -213,6 +208,9 @@ public:
static const unsigned kDxilHSStateTag = 3; static const unsigned kDxilHSStateTag = 3;
static const unsigned kDxilNumThreadsTag = 4; static const unsigned kDxilNumThreadsTag = 4;
static const unsigned kDxilAutoBindingSpaceTag = 5; static const unsigned kDxilAutoBindingSpaceTag = 5;
static const unsigned kDxilRayPayloadSizeTag = 6;
static const unsigned kDxilRayAttribSizeTag = 7;
static const unsigned kDxilShaderKindTag = 8;
// GSState. // GSState.
static const unsigned kDxilGSStateNumFields = 5; static const unsigned kDxilGSStateNumFields = 5;
@ -311,13 +309,6 @@ public:
void UpdateDxilResources(llvm::MDTuple *pDxilResourceTuple); void UpdateDxilResources(llvm::MDTuple *pDxilResourceTuple);
void GetDxilResources(const llvm::MDOperand &MDO, const llvm::MDTuple *&pSRVs, const llvm::MDTuple *&pUAVs, void GetDxilResources(const llvm::MDOperand &MDO, const llvm::MDTuple *&pSRVs, const llvm::MDTuple *&pUAVs,
const llvm::MDTuple *&pCBuffers, const llvm::MDTuple *&pSamplers); const llvm::MDTuple *&pCBuffers, const llvm::MDTuple *&pSamplers);
void EmitDxilResourceLinkInfoTuple(llvm::MDTuple *pSRVs, llvm::MDTuple *pUAVs,
llvm::MDTuple *pCBuffers,
llvm::MDTuple *pSamplers);
void LoadDxilResourceLinkInfoTuple(const llvm::MDTuple *&pSRVs,
const llvm::MDTuple *&pUAVs,
const llvm::MDTuple *&pCBuffers,
const llvm::MDTuple *&pSamplers);
void EmitDxilResourceBase(const DxilResourceBase &R, llvm::Metadata *ppMDVals[]); void EmitDxilResourceBase(const DxilResourceBase &R, llvm::Metadata *ppMDVals[]);
void LoadDxilResourceBase(const llvm::MDOperand &MDO, DxilResourceBase &R); void LoadDxilResourceBase(const llvm::MDOperand &MDO, DxilResourceBase &R);
llvm::MDTuple *EmitDxilSRV(const DxilResource &SRV); llvm::MDTuple *EmitDxilSRV(const DxilResource &SRV);
@ -351,18 +342,25 @@ public:
// Function props. // Function props.
llvm::MDTuple *EmitDxilFunctionProps(const hlsl::DxilFunctionProps *props, llvm::MDTuple *EmitDxilFunctionProps(const hlsl::DxilFunctionProps *props,
const llvm::Function *F); const llvm::Function *F);
llvm::Function *LoadDxilFunctionProps(llvm::MDTuple *pProps, const llvm::Function *LoadDxilFunctionProps(const llvm::MDTuple *pProps,
hlsl::DxilFunctionProps *props); hlsl::DxilFunctionProps *props);
llvm::MDTuple *EmitDxilEntryProperties(uint64_t rawShaderFlag,
const hlsl::DxilFunctionProps &props,
uint32_t autoBindingSpace);
void LoadDxilEntryProperties(const llvm::MDOperand &MDO,
uint64_t &rawShaderFlag,
hlsl::DxilFunctionProps &props,
uint32_t &autoBindingSpace);
// ViewId state. // ViewId state.
void EmitDxilViewIdState(DxilViewIdState &ViewIdState); void EmitDxilViewIdState(DxilViewIdState &ViewIdState);
void LoadDxilViewIdState(DxilViewIdState &ViewIdState); void LoadDxilViewIdState(DxilViewIdState &ViewIdState);
// Control flow hints. // Control flow hints.
static llvm::MDNode *EmitControlFlowHints(llvm::LLVMContext &Ctx, std::vector<DXIL::ControlFlowHint> &hints); static llvm::MDNode *EmitControlFlowHints(llvm::LLVMContext &Ctx, std::vector<DXIL::ControlFlowHint> &hints);
// Shader specific. // Shader specific.
private:
llvm::MDTuple *EmitDxilGSState(DXIL::InputPrimitive Primitive, unsigned MaxVertexCount, llvm::MDTuple *EmitDxilGSState(DXIL::InputPrimitive Primitive, unsigned MaxVertexCount,
unsigned ActiveStreamMask, DXIL::PrimitiveTopology StreamPrimitiveTopology, unsigned ActiveStreamMask, DXIL::PrimitiveTopology StreamPrimitiveTopology,
unsigned GSInstanceCount); unsigned GSInstanceCount);
@ -388,7 +386,7 @@ public:
DXIL::TessellatorPartitioning &TessPartitioning, DXIL::TessellatorPartitioning &TessPartitioning,
DXIL::TessellatorOutputPrimitive &TessOutputPrimitive, DXIL::TessellatorOutputPrimitive &TessOutputPrimitive,
float &MaxTessFactor); float &MaxTessFactor);
public:
// Utility functions. // Utility functions.
static bool IsKnownNamedMetaData(const llvm::NamedMDNode &Node); static bool IsKnownNamedMetaData(const llvm::NamedMDNode &Node);
static void combineDxilMetadata(llvm::Instruction *K, const llvm::Instruction *J); static void combineDxilMetadata(llvm::Instruction *K, const llvm::Instruction *J);

Просмотреть файл

@ -44,8 +44,11 @@ class OP;
class RootSignatureHandle; class RootSignatureHandle;
struct DxilFunctionProps; struct DxilFunctionProps;
typedef std::unordered_map<const llvm::Function *, std::unique_ptr<DxilFunctionProps>> DxilFunctionPropsMap; class DxilEntryProps;
typedef std::unordered_map<const llvm::Function *, std::unique_ptr<DxilEntrySignature>> DxilEntrySignatureMap;
using DxilEntryPropsMap =
std::unordered_map<const llvm::Function *, std::unique_ptr<DxilEntryProps>>;
/// Use this class to manipulate DXIL of a shader. /// Use this class to manipulate DXIL of a shader.
class DxilModule { class DxilModule {
public: public:
@ -124,19 +127,22 @@ public:
DxilSignature &GetPatchConstantSignature(); DxilSignature &GetPatchConstantSignature();
const DxilSignature &GetPatchConstantSignature() const; const DxilSignature &GetPatchConstantSignature() const;
const RootSignatureHandle &GetRootSignature() const; const RootSignatureHandle &GetRootSignature() const;
bool HasDxilEntrySignature(const llvm::Function *F) const; bool HasDxilEntrySignature(const llvm::Function *F) const;
DxilEntrySignature &GetDxilEntrySignature(const llvm::Function *F); DxilEntrySignature &GetDxilEntrySignature(const llvm::Function *F);
// Move DxilEntrySignature of F to NewF. // Move DxilEntryProps of F to NewF.
void ReplaceDxilEntrySignature(llvm::Function *F, llvm::Function *NewF); void ReplaceDxilEntryProps(llvm::Function *F, llvm::Function *NewF);
// Clone DxilEntryProps of F to NewF.
void CloneDxilEntryProps(llvm::Function *F, llvm::Function *NewF);
bool HasDxilEntryProps(const llvm::Function *F) const;
DxilEntryProps &GetDxilEntryProps(const llvm::Function *F);
// DxilFunctionProps. // DxilFunctionProps.
bool HasDxilFunctionProps(const llvm::Function *F) const; bool HasDxilFunctionProps(const llvm::Function *F) const;
DxilFunctionProps &GetDxilFunctionProps(const llvm::Function *F); DxilFunctionProps &GetDxilFunctionProps(const llvm::Function *F);
const DxilFunctionProps &GetDxilFunctionProps(const llvm::Function *F) const; const DxilFunctionProps &GetDxilFunctionProps(const llvm::Function *F) const;
void AddDxilFunctionProps(const llvm::Function *F, std::unique_ptr<DxilFunctionProps> &info);
// Move DxilFunctionProps of F to NewF. // Move DxilFunctionProps of F to NewF.
void ReplaceDxilFunctionProps(llvm::Function *F, llvm::Function *NewF);
void SetPatchConstantFunctionForHS(llvm::Function *hullShaderFunc, llvm::Function *patchConstantFunc); void SetPatchConstantFunctionForHS(llvm::Function *hullShaderFunc, llvm::Function *patchConstantFunc);
bool IsGraphicsShader(const llvm::Function *F) const; // vs,hs,ds,gs,ps bool IsGraphicsShader(const llvm::Function *F) const; // vs,hs,ds,gs,ps
bool IsPatchConstantShader(const llvm::Function *F) const; bool IsPatchConstantShader(const llvm::Function *F) const;
@ -180,8 +186,7 @@ public:
void ResetRootSignature(RootSignatureHandle *pValue); void ResetRootSignature(RootSignatureHandle *pValue);
void ResetTypeSystem(DxilTypeSystem *pValue); void ResetTypeSystem(DxilTypeSystem *pValue);
void ResetOP(hlsl::OP *hlslOP); void ResetOP(hlsl::OP *hlslOP);
void ResetFunctionPropsMap(DxilFunctionPropsMap &&propsMap); void ResetEntryPropsMap(DxilEntryPropsMap &&PropMap);
void ResetEntrySignatureMap(DxilEntrySignatureMap &&SigMap);
void StripDebugRelatedCode(); void StripDebugRelatedCode();
llvm::DebugInfoFinder &GetOrCreateDebugInfoFinder(); llvm::DebugInfoFinder &GetOrCreateDebugInfoFinder();
@ -270,7 +275,6 @@ public:
private: private:
// Signatures. // Signatures.
std::unique_ptr<DxilEntrySignature> m_EntrySignature;
std::unique_ptr<RootSignatureHandle> m_RootSignature; std::unique_ptr<RootSignatureHandle> m_RootSignature;
// Shader resources. // Shader resources.
@ -319,10 +323,8 @@ private:
// Type annotations. // Type annotations.
std::unique_ptr<DxilTypeSystem> m_pTypeSystem; std::unique_ptr<DxilTypeSystem> m_pTypeSystem;
// Function properties for shader functions. // EntryProps for shader functions.
DxilFunctionPropsMap m_DxilFunctionPropsMap; DxilEntryPropsMap m_DxilEntryPropsMap;
// EntrySig for shader functions.
DxilEntrySignatureMap m_DxilEntrySignatureMap;
// Keeps track of patch constant functions used by hull shaders // Keeps track of patch constant functions used by hull shaders
std::unordered_set<const llvm::Function *> m_PatchConstantFunctions; std::unordered_set<const llvm::Function *> m_PatchConstantFunctions;
@ -333,8 +335,6 @@ private:
// DXIL metadata serialization/deserialization. // DXIL metadata serialization/deserialization.
llvm::MDTuple *EmitDxilResources(); llvm::MDTuple *EmitDxilResources();
void LoadDxilResources(const llvm::MDOperand &MDO); void LoadDxilResources(const llvm::MDOperand &MDO);
llvm::MDTuple *EmitDxilShaderProperties();
void LoadDxilShaderProperties(const llvm::MDOperand &MDO);
// Helpers. // Helpers.
template<typename T> unsigned AddResource(std::vector<std::unique_ptr<T> > &Vec, std::unique_ptr<T> pRes); template<typename T> unsigned AddResource(std::vector<std::unique_ptr<T> > &Vec, std::unique_ptr<T> pRes);

Просмотреть файл

@ -1274,14 +1274,6 @@ void hlsl::SerializeDxilContainerForModule(DxilModule *pModule,
if (ValMajor == 1 && ValMinor == 0) if (ValMajor == 1 && ValMinor == 0)
Flags &= ~SerializeDxilFlags::IncludeDebugNamePart; Flags &= ~SerializeDxilFlags::IncludeDebugNamePart;
DxilProgramSignatureWriter inputSigWriter(
pModule->GetInputSignature(), pModule->GetTessellatorDomain(),
/*IsInput*/ true,
/*UseMinPrecision*/ pModule->GetUseMinPrecision());
DxilProgramSignatureWriter outputSigWriter(
pModule->GetOutputSignature(), pModule->GetTessellatorDomain(),
/*IsInput*/ false,
/*UseMinPrecision*/ pModule->GetUseMinPrecision());
DxilContainerWriter_impl writer; DxilContainerWriter_impl writer;
// Write the feature part. // Write the feature part.
@ -1290,39 +1282,55 @@ void hlsl::SerializeDxilContainerForModule(DxilModule *pModule,
featureInfoWriter.write(pStream); featureInfoWriter.write(pStream);
}); });
// Write the input and output signature parts. std::unique_ptr<DxilProgramSignatureWriter> pInputSigWriter = nullptr;
writer.AddPart(DFCC_InputSignature, inputSigWriter.size(), [&](AbstractMemoryStream *pStream) { std::unique_ptr<DxilProgramSignatureWriter> pOutputSigWriter = nullptr;
inputSigWriter.write(pStream); std::unique_ptr<DxilProgramSignatureWriter> pPatchConstantSigWriter = nullptr;
}); if (!pModule->GetShaderModel()->IsLib()) {
writer.AddPart(DFCC_OutputSignature, outputSigWriter.size(), [&](AbstractMemoryStream *pStream) { pInputSigWriter = llvm::make_unique<DxilProgramSignatureWriter>(
outputSigWriter.write(pStream); pModule->GetInputSignature(), pModule->GetTessellatorDomain(),
}); /*IsInput*/ true,
/*UseMinPrecision*/ pModule->GetUseMinPrecision());
DxilProgramSignatureWriter patchConstantSigWriter( pOutputSigWriter = llvm::make_unique<DxilProgramSignatureWriter>(
pModule->GetPatchConstantSignature(), pModule->GetTessellatorDomain(), pModule->GetOutputSignature(), pModule->GetTessellatorDomain(),
/*IsInput*/ pModule->GetShaderModel()->IsDS(), /*IsInput*/ false,
/*UseMinPrecision*/ pModule->GetUseMinPrecision()); /*UseMinPrecision*/ pModule->GetUseMinPrecision());
if (pModule->GetPatchConstantSignature().GetElements().size()) { // Write the input and output signature parts.
writer.AddPart(DFCC_PatchConstantSignature, patchConstantSigWriter.size(), writer.AddPart(DFCC_InputSignature, pInputSigWriter->size(),
[&](AbstractMemoryStream *pStream) { [&](AbstractMemoryStream *pStream) {
patchConstantSigWriter.write(pStream); pInputSigWriter->write(pStream);
});
writer.AddPart(DFCC_OutputSignature, pOutputSigWriter->size(),
[&](AbstractMemoryStream *pStream) {
pOutputSigWriter->write(pStream);
}); });
}
pPatchConstantSigWriter = llvm::make_unique<DxilProgramSignatureWriter>(
pModule->GetPatchConstantSignature(), pModule->GetTessellatorDomain(),
/*IsInput*/ pModule->GetShaderModel()->IsDS(),
/*UseMinPrecision*/ pModule->GetUseMinPrecision());
if (pModule->GetPatchConstantSignature().GetElements().size()) {
writer.AddPart(DFCC_PatchConstantSignature,
pPatchConstantSigWriter->size(),
[&](AbstractMemoryStream *pStream) {
pPatchConstantSigWriter->write(pStream);
});
}
}
// Write the DxilPipelineStateValidation (PSV0) part. // Write the DxilPipelineStateValidation (PSV0) part.
DxilRDATWriter RDATWriter(*pModule); std::unique_ptr<DxilRDATWriter> pRDATWriter = nullptr;
DxilPSVWriter PSVWriter(*pModule); std::unique_ptr<DxilPSVWriter> pPSVWriter = nullptr;
unsigned int major, minor; unsigned int major, minor;
pModule->GetDxilVersion(major, minor); pModule->GetDxilVersion(major, minor);
if (pModule->GetShaderModel()->IsLib() && (major >= 1 || minor == 1 && minor >= 3)) { if (pModule->GetShaderModel()->IsLib()) {
writer.AddPart(DFCC_RuntimeData, RDATWriter.size(), [&](AbstractMemoryStream *pStream) { pRDATWriter = llvm::make_unique<DxilRDATWriter>(*pModule);
RDATWriter.write(pStream); writer.AddPart(
}); DFCC_RuntimeData, pRDATWriter->size(),
} [&](AbstractMemoryStream *pStream) { pRDATWriter->write(pStream); });
else { } else if (!pModule->GetShaderModel()->IsLib()) {
writer.AddPart(DFCC_PipelineStateValidation, PSVWriter.size(), [&](AbstractMemoryStream *pStream) { pPSVWriter = llvm::make_unique<DxilPSVWriter>(*pModule);
PSVWriter.write(pStream); writer.AddPart(
}); DFCC_PipelineStateValidation, pPSVWriter->size(),
[&](AbstractMemoryStream *pStream) { pPSVWriter->write(pStream); });
} }
// Write the root signature (RTS0) part. // Write the root signature (RTS0) part.
DxilProgramRootSignatureWriter rootSigWriter(pModule->GetRootSignature()); DxilProgramRootSignatureWriter rootSigWriter(pModule->GetRootSignature());

27
lib/HLSL/DxilEntryProps.h Normal file
Просмотреть файл

@ -0,0 +1,27 @@
///////////////////////////////////////////////////////////////////////////////
// //
// DxilEntryProps.h //
// Copyright (C) Microsoft Corporation. All rights reserved. //
// This file is distributed under the University of Illinois Open Source //
// License. See LICENSE.TXT for details. //
// //
// Put entry signature and function props together. //
// //
///////////////////////////////////////////////////////////////////////////////
#pragma once
#include "dxc/HLSL/DxilSignature.h"
#include "dxc/HLSL/DxilFunctionProps.h"
namespace hlsl {
class DxilEntryProps {
public:
DxilEntrySignature sig;
DxilFunctionProps props;
DxilEntryProps(DxilFunctionProps &p, bool bUseMinPrecision)
: sig(p.shaderKind, bUseMinPrecision), props(p) {}
DxilEntryProps(DxilEntryProps &p)
: sig(p.sig), props(p.props) {}
};
}

Просмотреть файл

@ -22,6 +22,7 @@
#include "HLSignatureLower.h" #include "HLSignatureLower.h"
#include "dxc/HLSL/DxilUtil.h" #include "dxc/HLSL/DxilUtil.h"
#include "dxc/Support/exception.h" #include "dxc/Support/exception.h"
#include "DxilEntryProps.h"
#include "llvm/IR/GetElementPtrTypeIterator.h" #include "llvm/IR/GetElementPtrTypeIterator.h"
#include "llvm/IR/IRBuilder.h" #include "llvm/IR/IRBuilder.h"
@ -134,8 +135,7 @@ void InitResource(const DxilResource *pSource, DxilResource *pDest) {
InitResourceBase(pSource, pDest); InitResourceBase(pSource, pDest);
} }
void InitDxilModuleFromHLModule(HLModule &H, DxilModule &M, DxilEntrySignature *pSig, bool HasDebugInfo) { void InitDxilModuleFromHLModule(HLModule &H, DxilModule &M, bool HasDebugInfo) {
std::unique_ptr<DxilEntrySignature> pSigPtr(pSig);
// Subsystems. // Subsystems.
unsigned ValMajor, ValMinor; unsigned ValMajor, ValMinor;
@ -145,7 +145,6 @@ void InitDxilModuleFromHLModule(HLModule &H, DxilModule &M, DxilEntrySignature *
// Entry function. // Entry function.
Function *EntryFn = H.GetEntryFunction(); Function *EntryFn = H.GetEntryFunction();
DxilFunctionProps *FnProps = H.HasDxilFunctionProps(EntryFn) ? &H.GetDxilFunctionProps(EntryFn) : nullptr;
M.SetEntryFunction(EntryFn); M.SetEntryFunction(EntryFn);
M.SetEntryFunctionName(H.GetEntryFunctionName()); M.SetEntryFunctionName(H.GetEntryFunctionName());
@ -180,7 +179,6 @@ void InitDxilModuleFromHLModule(HLModule &H, DxilModule &M, DxilEntrySignature *
} }
// Signatures. // Signatures.
M.ResetEntrySignature(pSigPtr.release());
M.ResetRootSignature(H.ReleaseRootSignature()); M.ResetRootSignature(H.ReleaseRootSignature());
// Shader properties. // Shader properties.
@ -198,13 +196,6 @@ void InitDxilModuleFromHLModule(HLModule &H, DxilModule &M, DxilEntrySignature *
M.SetUseMinPrecision(H.GetHLOptions().bUseMinPrecision); M.SetUseMinPrecision(H.GetHLOptions().bUseMinPrecision);
if (FnProps)
M.SetShaderProperties(FnProps);
// Move function props.
if (M.GetShaderModel()->IsLib())
M.ResetFunctionPropsMap(H.ReleaseFunctionPropsMap());
// DXIL type system. // DXIL type system.
M.ResetTypeSystem(H.ReleaseTypeSystem()); M.ResetTypeSystem(H.ReleaseTypeSystem());
// Dxil OP. // Dxil OP.
@ -244,27 +235,40 @@ public:
// used to load them. // used to load them.
m_HasDbgInfo = getDebugMetadataVersionFromModule(M) != 0; m_HasDbgInfo = getDebugMetadataVersionFromModule(M) != 0;
std::unique_ptr<DxilEntrySignature> pSig =
llvm::make_unique<DxilEntrySignature>(SM->GetKind(), M.GetHLModule().GetHLOptions().bUseMinPrecision);
// EntrySig for shader functions. // EntrySig for shader functions.
DxilEntrySignatureMap DxilEntrySignatureMap; DxilEntryPropsMap EntryPropsMap;
if (!SM->IsLib()) { if (!SM->IsLib()) {
Function *EntryFn = m_pHLModule->GetEntryFunction();
if (!m_pHLModule->HasDxilFunctionProps(EntryFn)) {
M.getContext().emitError("Entry function don't have property.");
return false;
}
DxilFunctionProps &props = m_pHLModule->GetDxilFunctionProps(EntryFn);
std::unique_ptr<DxilEntryProps> pProps =
llvm::make_unique<DxilEntryProps>(
props, m_pHLModule->GetHLOptions().bUseMinPrecision);
HLSignatureLower sigLower(m_pHLModule->GetEntryFunction(), *m_pHLModule, HLSignatureLower sigLower(m_pHLModule->GetEntryFunction(), *m_pHLModule,
*pSig); pProps->sig);
sigLower.Run(); sigLower.Run();
EntryPropsMap[EntryFn] = std::move(pProps);
} else { } else {
for (auto It = M.begin(); It != M.end();) { for (auto It = M.begin(); It != M.end();) {
Function &F = *(It++); Function &F = *(It++);
// Lower signature for each graphics or compute entry function. // Lower signature for each graphics or compute entry function.
if (m_pHLModule->IsGraphicsShader(&F) || m_pHLModule->IsComputeShader(&F)) { if (m_pHLModule->HasDxilFunctionProps(&F)) {
DxilFunctionProps &props = m_pHLModule->GetDxilFunctionProps(&F); DxilFunctionProps &props = m_pHLModule->GetDxilFunctionProps(&F);
std::unique_ptr<DxilEntrySignature> pSig = std::unique_ptr<DxilEntryProps> pProps =
llvm::make_unique<DxilEntrySignature>(props.shaderKind, m_pHLModule->GetHLOptions().bUseMinPrecision); llvm::make_unique<DxilEntryProps>(
HLSignatureLower sigLower(&F, *m_pHLModule, *pSig); props, m_pHLModule->GetHLOptions().bUseMinPrecision);
// TODO: BUG: This will lower patch constant function sigs twice if used by two hull shaders! if (m_pHLModule->IsGraphicsShader(&F) ||
sigLower.Run(); m_pHLModule->IsComputeShader(&F)) {
DxilEntrySignatureMap[&F] = std::move(pSig); HLSignatureLower sigLower(&F, *m_pHLModule, pProps->sig);
// TODO: BUG: This will lower patch constant function sigs twice if
// used by two hull shaders!
sigLower.Run();
}
EntryPropsMap[&F] = std::move(pProps);
} }
} }
} }
@ -305,10 +309,12 @@ public:
// High-level metadata should now be turned into low-level metadata. // High-level metadata should now be turned into low-level metadata.
const bool SkipInit = true; const bool SkipInit = true;
hlsl::DxilModule &DxilMod = M.GetOrCreateDxilModule(SkipInit); hlsl::DxilModule &DxilMod = M.GetOrCreateDxilModule(SkipInit);
InitDxilModuleFromHLModule(*m_pHLModule, DxilMod, pSig.release(), if (!SM->IsLib()) {
m_HasDbgInfo); DxilMod.SetShaderProperties(&EntryPropsMap.begin()->second->props);
if (SM->IsLib()) }
DxilMod.ResetEntrySignatureMap(std::move(DxilEntrySignatureMap)); InitDxilModuleFromHLModule(*m_pHLModule, DxilMod, m_HasDbgInfo);
DxilMod.ResetEntryPropsMap(std::move(EntryPropsMap));
HLModule::ClearHLMetadata(M); HLModule::ClearHLMetadata(M);
M.ResetHLModule(); M.ResetHLModule();

Просмотреть файл

@ -10,6 +10,7 @@
#include "dxc/HLSL/DxilLinker.h" #include "dxc/HLSL/DxilLinker.h"
#include "dxc/HLSL/DxilCBuffer.h" #include "dxc/HLSL/DxilCBuffer.h"
#include "dxc/HLSL/DxilFunctionProps.h" #include "dxc/HLSL/DxilFunctionProps.h"
#include "DxilEntryProps.h"
#include "dxc/HLSL/DxilModule.h" #include "dxc/HLSL/DxilModule.h"
#include "dxc/HLSL/DxilOperations.h" #include "dxc/HLSL/DxilOperations.h"
#include "dxc/HLSL/DxilResource.h" #include "dxc/HLSL/DxilResource.h"
@ -734,13 +735,13 @@ DxilLinkJob::Link(std::pair<DxilFunctionLinkInfo *, DxilLib *> &entryLinkPair,
Function *NewEntryFunc = m_newFunctions[entryFunc->getName()]; Function *NewEntryFunc = m_newFunctions[entryFunc->getName()];
DM.SetEntryFunction(NewEntryFunc); DM.SetEntryFunction(NewEntryFunc);
DM.SetEntryFunctionName(entryFunc->getName()); DM.SetEntryFunctionName(entryFunc->getName());
if (entryDM.HasDxilEntrySignature(entryFunc)) {
// Add signature. DxilEntryPropsMap EntryPropMap;
DxilEntrySignature &entrySig = entryDM.GetDxilEntrySignature(entryFunc); std::unique_ptr<DxilEntryProps> pProps =
std::unique_ptr<DxilEntrySignature> newSig = std::make_unique<DxilEntryProps>(entryDM.GetDxilEntryProps(entryFunc));
llvm::make_unique<DxilEntrySignature>(entrySig); EntryPropMap[NewEntryFunc] = std::move(pProps);
DM.ResetEntrySignature(newSig.release()); DM.ResetEntryPropsMap(std::move(EntryPropMap));
}
if (NewEntryFunc->hasFnAttribute(llvm::Attribute::AlwaysInline)) if (NewEntryFunc->hasFnAttribute(llvm::Attribute::AlwaysInline))
NewEntryFunc->removeFnAttr(llvm::Attribute::AlwaysInline); NewEntryFunc->removeFnAttr(llvm::Attribute::AlwaysInline);
@ -823,30 +824,22 @@ DxilLinkJob::LinkToLib(const ShaderModel *pSM) {
AddFunctions(DM, vmap, initFuncSet); AddFunctions(DM, vmap, initFuncSet);
// Set DxilFunctionProps. // Set DxilFunctionProps.
DxilEntrySignatureMap DxilEntrySignatureMap; DxilEntryPropsMap EntryPropMap;
for (auto &it : m_functionDefs) { for (auto &it : m_functionDefs) {
DxilFunctionLinkInfo *linkInfo = it.first; DxilFunctionLinkInfo *linkInfo = it.first;
DxilLib *pLib = it.second; DxilLib *pLib = it.second;
DxilModule &tmpDM = pLib->GetDxilModule(); DxilModule &tmpDM = pLib->GetDxilModule();
Function *F = linkInfo->func; Function *F = linkInfo->func;
if (tmpDM.HasDxilFunctionProps(F)) { if (tmpDM.HasDxilEntryProps(F)) {
Function *NewF = m_newFunctions[F->getName()]; Function *NewF = m_newFunctions[F->getName()];
DxilFunctionProps props = tmpDM.GetDxilFunctionProps(F); DxilEntryProps &props = tmpDM.GetDxilEntryProps(F);
std::unique_ptr<DxilFunctionProps> pProps = std::unique_ptr<DxilEntryProps> pProps =
std::make_unique<DxilFunctionProps>(); std::make_unique<DxilEntryProps>(props);
*pProps = props; EntryPropMap[NewF] = std::move(pProps);
DM.AddDxilFunctionProps(NewF, pProps);
}
if (tmpDM.HasDxilEntrySignature(F)) {
Function *NewF = m_newFunctions[F->getName()];
std::unique_ptr<DxilEntrySignature> pSig =
llvm::make_unique<DxilEntrySignature>(tmpDM.GetDxilEntrySignature(F));
DxilEntrySignatureMap[NewF] = std::move(pSig);
} }
} }
DM.ResetEntrySignatureMap(std::move(DxilEntrySignatureMap)); DM.ResetEntryPropsMap(std::move(EntryPropMap));
// Add global // Add global
bool bSuccess = AddGlobals(DM, vmap); bool bSuccess = AddGlobals(DM, vmap);
@ -922,9 +915,7 @@ DxilLinkJob::LinkToLib(const ShaderModel *pSM) {
CloneFunction(F, NewF, vmap, &DM.GetTypeSystem()); CloneFunction(F, NewF, vmap, &DM.GetTypeSystem());
// add DxilFunctionProps if entry // add DxilFunctionProps if entry
if (DM.HasDxilFunctionProps(F)) { if (DM.HasDxilFunctionProps(F)) {
DxilFunctionProps &props = DM.GetDxilFunctionProps(F); DM.CloneDxilEntryProps(F, NewF);
auto newProps = llvm::make_unique<DxilFunctionProps>(props);
DM.AddDxilFunctionProps(NewF, newProps);
} }
} }
itName++; itName++;

Просмотреть файл

@ -19,6 +19,7 @@
#include "dxc/HLSL/DxilRootSignature.h" #include "dxc/HLSL/DxilRootSignature.h"
#include "dxc/HLSL/ComputeViewIdState.h" #include "dxc/HLSL/ComputeViewIdState.h"
#include "dxc/HLSL/DxilFunctionProps.h" #include "dxc/HLSL/DxilFunctionProps.h"
#include "dxc/HLSL/DxilShaderFlags.h"
#include "llvm/IR/Constants.h" #include "llvm/IR/Constants.h"
#include "llvm/IR/Function.h" #include "llvm/IR/Function.h"
@ -43,7 +44,6 @@ const char DxilMDHelper::kDxilVersionMDName[] = "dx.vers
const char DxilMDHelper::kDxilShaderModelMDName[] = "dx.shaderModel"; const char DxilMDHelper::kDxilShaderModelMDName[] = "dx.shaderModel";
const char DxilMDHelper::kDxilEntryPointsMDName[] = "dx.entryPoints"; const char DxilMDHelper::kDxilEntryPointsMDName[] = "dx.entryPoints";
const char DxilMDHelper::kDxilResourcesMDName[] = "dx.resources"; const char DxilMDHelper::kDxilResourcesMDName[] = "dx.resources";
const char DxilMDHelper::kDxilResourcesLinkInfoMDName[] = "dx.resources.link.info";
const char DxilMDHelper::kDxilTypeSystemMDName[] = "dx.typeAnnotations"; const char DxilMDHelper::kDxilTypeSystemMDName[] = "dx.typeAnnotations";
const char DxilMDHelper::kDxilTypeSystemHelperVariablePrefix[] = "dx.typevar."; const char DxilMDHelper::kDxilTypeSystemHelperVariablePrefix[] = "dx.typevar.";
const char DxilMDHelper::kDxilControlFlowHintMDName[] = "dx.controlflow.hints"; const char DxilMDHelper::kDxilControlFlowHintMDName[] = "dx.controlflow.hints";
@ -55,8 +55,6 @@ const char DxilMDHelper::kDxilValidatorVersionMDName[] = "dx.valv
// This named metadata is not valid in final module (should be moved to DxilContainer) // This named metadata is not valid in final module (should be moved to DxilContainer)
const char DxilMDHelper::kDxilRootSignatureMDName[] = "dx.rootSignature"; const char DxilMDHelper::kDxilRootSignatureMDName[] = "dx.rootSignature";
const char DxilMDHelper::kDxilViewIdStateMDName[] = "dx.viewIdState"; const char DxilMDHelper::kDxilViewIdStateMDName[] = "dx.viewIdState";
const char DxilMDHelper::kDxilFunctionPropertiesMDName[] = "dx.func.props";
const char DxilMDHelper::kDxilEntrySignaturesMDName[] = "dx.func.signatures";
const char DxilMDHelper::kDxilSourceContentsMDName[] = "dx.source.contents"; const char DxilMDHelper::kDxilSourceContentsMDName[] = "dx.source.contents";
const char DxilMDHelper::kDxilSourceDefinesMDName[] = "dx.source.defines"; const char DxilMDHelper::kDxilSourceDefinesMDName[] = "dx.source.defines";
@ -200,7 +198,8 @@ void DxilMDHelper::LoadDxilShaderModel(const ShaderModel *&pSM) {
// Entry points. // Entry points.
// //
void DxilMDHelper::EmitDxilEntryPoints(vector<MDNode *> &MDEntries) { void DxilMDHelper::EmitDxilEntryPoints(vector<MDNode *> &MDEntries) {
DXASSERT(MDEntries.size() == 1, "only one entry point is supported for now"); DXASSERT(MDEntries.size() == 1 || GetShaderModel()->IsLib(),
"only one entry point is supported for now");
NamedMDNode *pEntryPointsNamedMD = m_pModule->getNamedMetadata(kDxilEntryPointsMDName); NamedMDNode *pEntryPointsNamedMD = m_pModule->getNamedMetadata(kDxilEntryPointsMDName);
IFTBOOL(pEntryPointsNamedMD == nullptr, DXC_E_INCORRECT_DXIL_METADATA); IFTBOOL(pEntryPointsNamedMD == nullptr, DXC_E_INCORRECT_DXIL_METADATA);
pEntryPointsNamedMD = m_pModule->getOrInsertNamedMetadata(kDxilEntryPointsMDName); pEntryPointsNamedMD = m_pModule->getOrInsertNamedMetadata(kDxilEntryPointsMDName);
@ -486,52 +485,6 @@ void DxilMDHelper::UpdateDxilResources(llvm::MDTuple *pDxilResourceTuple) {
} }
} }
void DxilMDHelper::EmitDxilResourceLinkInfoTuple(MDTuple *pSRVs, MDTuple *pUAVs,
MDTuple *pCBuffers,
MDTuple *pSamplers) {
DXASSERT(pSRVs != nullptr || pUAVs != nullptr || pCBuffers != nullptr ||
pSamplers != nullptr,
"resource tuple should not be emitted if there are no resources");
Metadata *MDVals[kDxilNumResourceFields];
MDVals[kDxilResourceSRVs] = pSRVs;
MDVals[kDxilResourceUAVs] = pUAVs;
MDVals[kDxilResourceCBuffers] = pCBuffers;
MDVals[kDxilResourceSamplers] = pSamplers;
MDTuple *pTupleMD = MDNode::get(m_Ctx, MDVals);
NamedMDNode *pResourcesNamedMD =
m_pModule->getNamedMetadata(kDxilResourcesLinkInfoMDName);
IFTBOOL(pResourcesNamedMD == nullptr, DXC_E_INCORRECT_DXIL_METADATA);
pResourcesNamedMD =
m_pModule->getOrInsertNamedMetadata(kDxilResourcesLinkInfoMDName);
pResourcesNamedMD->addOperand(pTupleMD);
}
void DxilMDHelper::LoadDxilResourceLinkInfoTuple(const llvm::MDTuple *&pSRVs,
const llvm::MDTuple *&pUAVs,
const llvm::MDTuple *&pCBuffers,
const llvm::MDTuple *&pSamplers) {
NamedMDNode *pResourcesNamedMD =
m_pModule->getNamedMetadata(kDxilResourcesLinkInfoMDName);
if (!pResourcesNamedMD) {
pSRVs = pUAVs = pCBuffers = pSamplers = nullptr;
return;
}
IFTBOOL(pResourcesNamedMD->getNumOperands() == 1,
DXC_E_INCORRECT_DXIL_METADATA);
const MDTuple *pTupleMD = dyn_cast<MDTuple>(pResourcesNamedMD->getOperand(0));
IFTBOOL(pTupleMD != nullptr, DXC_E_INCORRECT_DXIL_METADATA);
IFTBOOL(pTupleMD->getNumOperands() == kDxilNumResourceFields,
DXC_E_INCORRECT_DXIL_METADATA);
pSRVs = CastToTupleOrNull(pTupleMD->getOperand(kDxilResourceSRVs));
pUAVs = CastToTupleOrNull(pTupleMD->getOperand(kDxilResourceUAVs));
pCBuffers = CastToTupleOrNull(pTupleMD->getOperand(kDxilResourceCBuffers));
pSamplers = CastToTupleOrNull(pTupleMD->getOperand(kDxilResourceSamplers));
}
void DxilMDHelper::GetDxilResources(const MDOperand &MDO, const MDTuple *&pSRVs, void DxilMDHelper::GetDxilResources(const MDOperand &MDO, const MDTuple *&pSRVs,
const MDTuple *&pUAVs, const MDTuple *&pCBuffers, const MDTuple *&pUAVs, const MDTuple *&pCBuffers,
const MDTuple *&pSamplers) { const MDTuple *&pSamplers) {
@ -954,10 +907,10 @@ void DxilMDHelper::LoadDxilFieldAnnotation(const MDOperand &MDO, DxilFieldAnnota
} }
} }
Function *DxilMDHelper::LoadDxilFunctionProps(MDTuple *pProps, const Function *DxilMDHelper::LoadDxilFunctionProps(const MDTuple *pProps,
hlsl::DxilFunctionProps *props) { hlsl::DxilFunctionProps *props) {
unsigned idx = 0; unsigned idx = 0;
Function *F = dyn_cast<Function>( const Function *F = dyn_cast<Function>(
dyn_cast<ValueAsMetadata>(pProps->getOperand(idx++))->getValue()); dyn_cast<ValueAsMetadata>(pProps->getOperand(idx++))->getValue());
DXIL::ShaderKind shaderKind = DXIL::ShaderKind shaderKind =
static_cast<DXIL::ShaderKind>(ConstMDToUint32(pProps->getOperand(idx++))); static_cast<DXIL::ShaderKind>(ConstMDToUint32(pProps->getOperand(idx++)));
@ -1031,6 +984,227 @@ Function *DxilMDHelper::LoadDxilFunctionProps(MDTuple *pProps,
return F; return F;
} }
MDTuple *DxilMDHelper::EmitDxilEntryProperties(uint64_t rawShaderFlag,
const DxilFunctionProps &props,
unsigned autoBindingSpace) {
vector<Metadata *> MDVals;
// DXIL shader flags.
if (props.IsPS()) {
if (props.ShaderProps.PS.EarlyDepthStencil) {
ShaderFlags flags;
flags.SetShaderFlagsRaw(rawShaderFlag);
flags.SetForceEarlyDepthStencil(true);
rawShaderFlag = flags.GetShaderFlagsRaw();
}
}
if (rawShaderFlag != 0) {
MDVals.emplace_back(Uint32ToConstMD(kDxilShaderFlagsTag));
MDVals.emplace_back(Uint64ToConstMD(rawShaderFlag));
}
// Add shader kind for lib entrys.
if (m_pSM->IsLib() && props.shaderKind != DXIL::ShaderKind::Library) {
MDVals.emplace_back(Uint32ToConstMD(kDxilShaderKindTag));
MDVals.emplace_back(
Uint32ToConstMD(static_cast<unsigned>(props.shaderKind)));
}
switch (props.shaderKind) {
// Compute shader.
case DXIL::ShaderKind::Compute: {
auto &CS = props.ShaderProps.CS;
MDVals.emplace_back(Uint32ToConstMD(DxilMDHelper::kDxilNumThreadsTag));
vector<Metadata *> NumThreadVals;
NumThreadVals.emplace_back(Uint32ToConstMD(CS.numThreads[0]));
NumThreadVals.emplace_back(Uint32ToConstMD(CS.numThreads[1]));
NumThreadVals.emplace_back(Uint32ToConstMD(CS.numThreads[2]));
MDVals.emplace_back(MDNode::get(m_Ctx, NumThreadVals));
} break;
// Geometry shader.
case DXIL::ShaderKind::Geometry: {
MDVals.emplace_back(Uint32ToConstMD(DxilMDHelper::kDxilGSStateTag));
DXIL::PrimitiveTopology topo = DXIL::PrimitiveTopology::Undefined;
unsigned activeStreamMask = 0;
for (size_t i = 0;
i < _countof(props.ShaderProps.GS.streamPrimitiveTopologies); ++i) {
if (props.ShaderProps.GS.streamPrimitiveTopologies[i] !=
DXIL::PrimitiveTopology::Undefined) {
activeStreamMask |= 1 << i;
DXASSERT_NOMSG(topo == DXIL::PrimitiveTopology::Undefined ||
topo ==
props.ShaderProps.GS.streamPrimitiveTopologies[i]);
topo = props.ShaderProps.GS.streamPrimitiveTopologies[i];
}
}
MDTuple *pMDTuple =
EmitDxilGSState(props.ShaderProps.GS.inputPrimitive,
props.ShaderProps.GS.maxVertexCount, activeStreamMask,
topo, props.ShaderProps.GS.instanceCount);
MDVals.emplace_back(pMDTuple);
} break;
// Domain shader.
case DXIL::ShaderKind::Domain: {
auto &DS = props.ShaderProps.DS;
MDVals.emplace_back(Uint32ToConstMD(DxilMDHelper::kDxilDSStateTag));
MDTuple *pMDTuple = EmitDxilDSState(DS.domain, DS.inputControlPoints);
MDVals.emplace_back(pMDTuple);
} break;
// Hull shader.
case DXIL::ShaderKind::Hull: {
auto &HS = props.ShaderProps.HS;
MDVals.emplace_back(Uint32ToConstMD(DxilMDHelper::kDxilHSStateTag));
MDTuple *pMDTuple = EmitDxilHSState(
HS.patchConstantFunc, HS.inputControlPoints, HS.outputControlPoints,
HS.domain, HS.partition, HS.outputPrimitive, HS.maxTessFactor);
MDVals.emplace_back(pMDTuple);
} break;
// Raytracing.
case DXIL::ShaderKind::AnyHit:
case DXIL::ShaderKind::ClosestHit: {
MDVals.emplace_back(Uint32ToConstMD(kDxilRayPayloadSizeTag));
MDVals.emplace_back(
Uint32ToConstMD(props.ShaderProps.Ray.payloadSizeInBytes));
MDVals.emplace_back(Uint32ToConstMD(kDxilRayAttribSizeTag));
MDVals.emplace_back(
Uint32ToConstMD(props.ShaderProps.Ray.attributeSizeInBytes));
} break;
case DXIL::ShaderKind::Miss:
case DXIL::ShaderKind::Callable: {
MDVals.emplace_back(Uint32ToConstMD(kDxilRayPayloadSizeTag));
MDVals.emplace_back(
Uint32ToConstMD(props.ShaderProps.Ray.payloadSizeInBytes));
} break;
default:
break;
}
if (autoBindingSpace != UINT_MAX && m_pSM->IsSMAtLeast(6, 3)) {
MDVals.emplace_back(Uint32ToConstMD(kDxilAutoBindingSpaceTag));
MDVals.emplace_back(
MDNode::get(m_Ctx, {Uint32ToConstMD(autoBindingSpace)}));
}
if (!MDVals.empty())
return MDNode::get(m_Ctx, MDVals);
else
return nullptr;
}
void DxilMDHelper::LoadDxilEntryProperties(const MDOperand &MDO,
uint64_t &rawShaderFlag,
DxilFunctionProps &props,
uint32_t &autoBindingSpace) {
if (MDO.get() == nullptr)
return;
const MDTuple *pTupleMD = dyn_cast<MDTuple>(MDO.get());
IFTBOOL(pTupleMD != nullptr, DXC_E_INCORRECT_DXIL_METADATA);
IFTBOOL((pTupleMD->getNumOperands() & 0x1) == 0,
DXC_E_INCORRECT_DXIL_METADATA);
bool bEarlyDepth = false;
if (!m_pSM->IsLib()) {
props.shaderKind = m_pSM->GetKind();
} else {
props.shaderKind = DXIL::ShaderKind::Library;
}
for (unsigned iNode = 0; iNode < pTupleMD->getNumOperands(); iNode += 2) {
unsigned Tag = DxilMDHelper::ConstMDToUint32(pTupleMD->getOperand(iNode));
const MDOperand &MDO = pTupleMD->getOperand(iNode + 1);
IFTBOOL(MDO.get() != nullptr, DXC_E_INCORRECT_DXIL_METADATA);
switch (Tag) {
case DxilMDHelper::kDxilShaderFlagsTag: {
rawShaderFlag = ConstMDToUint64(MDO);
ShaderFlags flags;
flags.SetShaderFlagsRaw(rawShaderFlag);
bEarlyDepth = flags.GetForceEarlyDepthStencil();
} break;
case DxilMDHelper::kDxilNumThreadsTag: {
DXASSERT(props.IsCS(), "else invalid shader kind");
auto &CS = props.ShaderProps.CS;
MDNode *pNode = cast<MDNode>(MDO.get());
CS.numThreads[0] = ConstMDToUint32(pNode->getOperand(0));
CS.numThreads[1] = ConstMDToUint32(pNode->getOperand(1));
CS.numThreads[2] = ConstMDToUint32(pNode->getOperand(2));
} break;
case DxilMDHelper::kDxilGSStateTag: {
DXASSERT(props.IsGS(), "else invalid shader kind");
auto &GS = props.ShaderProps.GS;
DXIL::PrimitiveTopology topo = DXIL::PrimitiveTopology::Undefined;
unsigned activeStreamMask;
LoadDxilGSState(MDO, GS.inputPrimitive, GS.maxVertexCount,
activeStreamMask, topo, GS.instanceCount);
if (topo != DXIL::PrimitiveTopology::Undefined) {
for (size_t i = 0; i < _countof(GS.streamPrimitiveTopologies); ++i) {
unsigned mask = 1 << i;
if (activeStreamMask & mask) {
GS.streamPrimitiveTopologies[i] = topo;
} else {
GS.streamPrimitiveTopologies[i] =
DXIL::PrimitiveTopology::Undefined;
}
}
}
} break;
case DxilMDHelper::kDxilDSStateTag: {
DXASSERT(props.IsDS(), "else invalid shader kind");
auto &DS = props.ShaderProps.DS;
LoadDxilDSState(MDO, DS.domain, DS.inputControlPoints);
} break;
case DxilMDHelper::kDxilHSStateTag: {
DXASSERT(props.IsHS(), "else invalid shader kind");
auto &HS = props.ShaderProps.HS;
LoadDxilHSState(MDO, HS.patchConstantFunc, HS.inputControlPoints,
HS.outputControlPoints, HS.domain, HS.partition,
HS.outputPrimitive, HS.maxTessFactor);
} break;
case DxilMDHelper::kDxilAutoBindingSpaceTag: {
MDNode *pNode = cast<MDNode>(MDO.get());
autoBindingSpace = ConstMDToUint32(pNode->getOperand(0));
break;
}
case DxilMDHelper::kDxilRayPayloadSizeTag: {
DXASSERT(props.IsAnyHit() || props.IsClosestHit() || props.IsMiss() ||
props.IsCallable(),
"else invalid shader kind");
props.ShaderProps.Ray.payloadSizeInBytes =
ConstMDToUint32(MDO);
} break;
case DxilMDHelper::kDxilRayAttribSizeTag: {
DXASSERT(props.IsAnyHit() || props.IsClosestHit(),
"else invalid shader kind");
props.ShaderProps.Ray.attributeSizeInBytes =
ConstMDToUint32(MDO);
} break;
case DxilMDHelper::kDxilShaderKindTag: {
DXIL::ShaderKind kind =
static_cast<DXIL::ShaderKind>(ConstMDToUint32(MDO));
DXASSERT(props.shaderKind == DXIL::ShaderKind::Library,
"else invalid shader kind");
props.shaderKind = kind;
} break;
default:
DXASSERT(false, "Unknown extended shader properties tag");
break;
}
}
if (bEarlyDepth) {
DXASSERT(props.IsPS(), "else invalid shader kind");
props.ShaderProps.PS.EarlyDepthStencil = true;
}
}
MDTuple * MDTuple *
DxilMDHelper::EmitDxilFunctionProps(const hlsl::DxilFunctionProps *props, DxilMDHelper::EmitDxilFunctionProps(const hlsl::DxilFunctionProps *props,
const Function *F) { const Function *F) {

Просмотреть файл

@ -15,6 +15,7 @@
#include "dxc/HLSL/DxilContainer.h" #include "dxc/HLSL/DxilContainer.h"
#include "dxc/HLSL/DxilRootSignature.h" #include "dxc/HLSL/DxilRootSignature.h"
#include "dxc/HLSL/DxilFunctionProps.h" #include "dxc/HLSL/DxilFunctionProps.h"
#include "DxilEntryProps.h"
#include "llvm/IR/Constants.h" #include "llvm/IR/Constants.h"
#include "llvm/IR/Function.h" #include "llvm/IR/Function.h"
@ -136,8 +137,6 @@ void DxilModule::SetShaderModel(const ShaderModel *pSM) {
m_pSM = pSM; m_pSM = pSM;
m_pSM->GetDxilVersion(m_DxilMajor, m_DxilMinor); m_pSM->GetDxilVersion(m_DxilMajor, m_DxilMinor);
m_pMDHelper->SetShaderModel(m_pSM); m_pMDHelper->SetShaderModel(m_pSM);
DXIL::ShaderKind shaderKind = pSM->GetKind();
m_EntrySignature = llvm::make_unique<DxilEntrySignature>(shaderKind, GetUseMinPrecision());
m_RootSignature.reset(new RootSignatureHandle()); m_RootSignature.reset(new RootSignatureHandle());
} }
@ -674,8 +673,7 @@ static void ConvertUsedResource(std::unordered_set<unsigned> &immResID,
void DxilModule::RemoveFunction(llvm::Function *F) { void DxilModule::RemoveFunction(llvm::Function *F) {
DXASSERT_NOMSG(F != nullptr); DXASSERT_NOMSG(F != nullptr);
m_DxilFunctionPropsMap.erase(F); m_DxilEntryPropsMap.erase(F);
m_DxilEntrySignatureMap.erase(F);
if (m_pTypeSystem.get()->GetFunctionAnnotation(F)) if (m_pTypeSystem.get()->GetFunctionAnnotation(F))
m_pTypeSystem.get()->EraseFunctionAnnotation(F); m_pTypeSystem.get()->EraseFunctionAnnotation(F);
m_pOP->RemoveFunction(F); m_pOP->RemoveFunction(F);
@ -775,51 +773,77 @@ void DxilModule::RemoveUnusedResourceSymbols() {
} }
DxilSignature &DxilModule::GetInputSignature() { DxilSignature &DxilModule::GetInputSignature() {
return m_EntrySignature->InputSignature; DXASSERT(m_DxilEntryPropsMap.size() == 1 && !m_pSM->IsLib(),
"only works for none lib profile");
return m_DxilEntryPropsMap.begin()->second->sig.InputSignature;
} }
const DxilSignature &DxilModule::GetInputSignature() const { const DxilSignature &DxilModule::GetInputSignature() const {
return m_EntrySignature->InputSignature; DXASSERT(m_DxilEntryPropsMap.size() == 1 && !m_pSM->IsLib(),
"only works for none lib profile");
return m_DxilEntryPropsMap.begin()->second->sig.InputSignature;
} }
DxilSignature &DxilModule::GetOutputSignature() { DxilSignature &DxilModule::GetOutputSignature() {
return m_EntrySignature->OutputSignature; DXASSERT(m_DxilEntryPropsMap.size() == 1 && !m_pSM->IsLib(),
"only works for none lib profile");
return m_DxilEntryPropsMap.begin()->second->sig.OutputSignature;
} }
const DxilSignature &DxilModule::GetOutputSignature() const { const DxilSignature &DxilModule::GetOutputSignature() const {
return m_EntrySignature->OutputSignature; DXASSERT(m_DxilEntryPropsMap.size() == 1 && !m_pSM->IsLib(),
"only works for none lib profile");
return m_DxilEntryPropsMap.begin()->second->sig.OutputSignature;
} }
DxilSignature &DxilModule::GetPatchConstantSignature() { DxilSignature &DxilModule::GetPatchConstantSignature() {
return m_EntrySignature->PatchConstantSignature; DXASSERT(m_DxilEntryPropsMap.size() == 1 && !m_pSM->IsLib(),
"only works for none lib profile");
return m_DxilEntryPropsMap.begin()->second->sig.PatchConstantSignature;
} }
const DxilSignature &DxilModule::GetPatchConstantSignature() const { const DxilSignature &DxilModule::GetPatchConstantSignature() const {
return m_EntrySignature->PatchConstantSignature; DXASSERT(m_DxilEntryPropsMap.size() == 1 && !m_pSM->IsLib(),
"only works for none lib profile");
return m_DxilEntryPropsMap.begin()->second->sig.PatchConstantSignature;
} }
const RootSignatureHandle &DxilModule::GetRootSignature() const { const RootSignatureHandle &DxilModule::GetRootSignature() const {
return *m_RootSignature; return *m_RootSignature;
} }
// Entry props.
bool DxilModule::HasDxilEntrySignature(const llvm::Function *F) const { bool DxilModule::HasDxilEntrySignature(const llvm::Function *F) const {
return m_DxilEntrySignatureMap.find(F) != m_DxilEntrySignatureMap.end(); return m_DxilEntryPropsMap.find(F) != m_DxilEntryPropsMap.end();
} }
DxilEntrySignature &DxilModule::GetDxilEntrySignature(const llvm::Function *F) { DxilEntrySignature &DxilModule::GetDxilEntrySignature(const llvm::Function *F) {
DXASSERT(m_DxilEntrySignatureMap.count(F) != 0, "cannot find F in map"); DXASSERT(m_DxilEntryPropsMap.count(F) != 0, "cannot find F in map");
return *m_DxilEntrySignatureMap[F]; return m_DxilEntryPropsMap[F].get()->sig;
} }
void DxilModule::ReplaceDxilEntrySignature(llvm::Function *F, void DxilModule::ReplaceDxilEntryProps(llvm::Function *F,
llvm::Function *NewF) { llvm::Function *NewF) {
DXASSERT(m_DxilEntrySignatureMap.count(F) != 0, "cannot find F in map"); DXASSERT(m_DxilEntryPropsMap.count(F) != 0, "cannot find F in map");
std::unique_ptr<DxilEntrySignature> Sig = std::unique_ptr<DxilEntryProps> Props = std::move(m_DxilEntryPropsMap[F]);
std::move(m_DxilEntrySignatureMap[F]); m_DxilEntryPropsMap.erase(F);
m_DxilEntrySignatureMap.erase(F); m_DxilEntryPropsMap[NewF] = std::move(Props);
m_DxilEntrySignatureMap[NewF] = std::move(Sig); }
void DxilModule::CloneDxilEntryProps(llvm::Function *F, llvm::Function *NewF) {
DXASSERT(m_DxilEntryPropsMap.count(F) != 0, "cannot find F in map");
std::unique_ptr<DxilEntryProps> Props =
llvm::make_unique<DxilEntryProps>(*m_DxilEntryPropsMap[F]);
m_DxilEntryPropsMap[NewF] = std::move(Props);
}
bool DxilModule::HasDxilEntryProps(const llvm::Function *F) const {
return m_DxilEntryPropsMap.find(F) != m_DxilEntryPropsMap.end();
}
DxilEntryProps &DxilModule::GetDxilEntryProps(const llvm::Function *F) {
DXASSERT(m_DxilEntryPropsMap.count(F) != 0, "cannot find F in map");
return *m_DxilEntryPropsMap.find(F)->second.get();
} }
bool DxilModule::HasDxilFunctionProps(const llvm::Function *F) const { bool DxilModule::HasDxilFunctionProps(const llvm::Function *F) const {
return m_DxilFunctionPropsMap.find(F) != m_DxilFunctionPropsMap.end(); return m_DxilEntryPropsMap.find(F) != m_DxilEntryPropsMap.end();
} }
DxilFunctionProps &DxilModule::GetDxilFunctionProps(const llvm::Function *F) { DxilFunctionProps &DxilModule::GetDxilFunctionProps(const llvm::Function *F) {
return const_cast<DxilFunctionProps &>( return const_cast<DxilFunctionProps &>(
@ -828,29 +852,15 @@ DxilFunctionProps &DxilModule::GetDxilFunctionProps(const llvm::Function *F) {
const DxilFunctionProps & const DxilFunctionProps &
DxilModule::GetDxilFunctionProps(const llvm::Function *F) const { DxilModule::GetDxilFunctionProps(const llvm::Function *F) const {
DXASSERT(m_DxilFunctionPropsMap.count(F) != 0, "cannot find F in map"); DXASSERT(m_DxilEntryPropsMap.count(F) != 0, "cannot find F in map");
return *(m_DxilFunctionPropsMap.find(F))->second.get(); return m_DxilEntryPropsMap.find(F)->second.get()->props;
} }
void DxilModule::AddDxilFunctionProps(
const llvm::Function *F, std::unique_ptr<DxilFunctionProps> &info) {
DXASSERT(m_DxilFunctionPropsMap.count(F) == 0,
"F already in map, info will be overwritten");
DXASSERT_NOMSG(info->shaderKind != DXIL::ShaderKind::Invalid);
m_DxilFunctionPropsMap[F] = std::move(info);
}
void DxilModule::ReplaceDxilFunctionProps(llvm::Function *F,
llvm::Function *NewF) {
DXASSERT(m_DxilFunctionPropsMap.count(F) != 0, "cannot find F in map");
std::unique_ptr<DxilFunctionProps> props =
std::move(m_DxilFunctionPropsMap[F]);
m_DxilFunctionPropsMap.erase(F);
m_DxilFunctionPropsMap[NewF] = std::move(props);
}
void DxilModule::SetPatchConstantFunctionForHS(llvm::Function *hullShaderFunc, llvm::Function *patchConstantFunc) { void DxilModule::SetPatchConstantFunctionForHS(llvm::Function *hullShaderFunc, llvm::Function *patchConstantFunc) {
auto propIter = m_DxilFunctionPropsMap.find(hullShaderFunc); auto propIter = m_DxilEntryPropsMap.find(hullShaderFunc);
DXASSERT(propIter != m_DxilFunctionPropsMap.end(), "Hull shader must already have function props!"); DXASSERT(propIter != m_DxilEntryPropsMap.end(),
DxilFunctionProps &props = *(propIter->second); "Hull shader must already have function props!");
DxilFunctionProps &props = propIter->second->props;
DXASSERT(props.IsHS(), "else hullShaderFunc is not a Hull Shader"); DXASSERT(props.IsHS(), "else hullShaderFunc is not a Hull Shader");
if (props.ShaderProps.HS.patchConstantFunc) if (props.ShaderProps.HS.patchConstantFunc)
m_PatchConstantFunctions.erase(props.ShaderProps.HS.patchConstantFunc); m_PatchConstantFunctions.erase(props.ShaderProps.HS.patchConstantFunc);
@ -868,9 +878,9 @@ bool DxilModule::IsComputeShader(const llvm::Function *F) const {
return HasDxilFunctionProps(F) && GetDxilFunctionProps(F).IsCS(); return HasDxilFunctionProps(F) && GetDxilFunctionProps(F).IsCS();
} }
bool DxilModule::IsEntryThatUsesSignatures(const llvm::Function *F) const { bool DxilModule::IsEntryThatUsesSignatures(const llvm::Function *F) const {
auto propIter = m_DxilFunctionPropsMap.find(F); auto propIter = m_DxilEntryPropsMap.find(F);
if (propIter != m_DxilFunctionPropsMap.end()) { if (propIter != m_DxilEntryPropsMap.end()) {
DxilFunctionProps &props = *(propIter->second); DxilFunctionProps &props = propIter->second->props;
return props.IsGraphics() || props.IsCS(); return props.IsGraphics() || props.IsCS();
} }
// Otherwise, return true if patch constant function // Otherwise, return true if patch constant function
@ -888,10 +898,6 @@ void DxilModule::UpdateValidatorVersionMetadata() {
m_pMDHelper->EmitValidatorVersion(m_ValMajor, m_ValMinor); m_pMDHelper->EmitValidatorVersion(m_ValMajor, m_ValMinor);
} }
void DxilModule::ResetEntrySignature(DxilEntrySignature *pValue) {
m_EntrySignature.reset(pValue);
}
void DxilModule::ResetRootSignature(RootSignatureHandle *pValue) { void DxilModule::ResetRootSignature(RootSignatureHandle *pValue) {
m_RootSignature.reset(pValue); m_RootSignature.reset(pValue);
} }
@ -913,12 +919,10 @@ void DxilModule::ResetTypeSystem(DxilTypeSystem *pValue) {
void DxilModule::ResetOP(hlsl::OP *hlslOP) { m_pOP.reset(hlslOP); } void DxilModule::ResetOP(hlsl::OP *hlslOP) { m_pOP.reset(hlslOP); }
void DxilModule::ResetFunctionPropsMap(DxilFunctionPropsMap &&propsMap) { void DxilModule::ResetEntryPropsMap(DxilEntryPropsMap &&PropMap) {
m_DxilFunctionPropsMap = std::move(propsMap); m_DxilEntryPropsMap.clear();
} std::move(PropMap.begin(), PropMap.end(),
inserter(m_DxilEntryPropsMap, m_DxilEntryPropsMap.begin()));
void DxilModule::ResetEntrySignatureMap(DxilEntrySignatureMap &&SigMap) {
m_DxilEntrySignatureMap = std::move(SigMap);
} }
static const StringRef llvmUsedName = "llvm.used"; static const StringRef llvmUsedName = "llvm.used";
@ -995,9 +999,6 @@ void DxilModule::ClearDxilMetadata(Module &M) {
name == DxilMDHelper::kDxilResourcesMDName || name == DxilMDHelper::kDxilResourcesMDName ||
name == DxilMDHelper::kDxilTypeSystemMDName || name == DxilMDHelper::kDxilTypeSystemMDName ||
name == DxilMDHelper::kDxilViewIdStateMDName || name == DxilMDHelper::kDxilViewIdStateMDName ||
name == DxilMDHelper::kDxilFunctionPropertiesMDName || // used in libraries
name == DxilMDHelper::kDxilEntrySignaturesMDName || // used in libraries
name == DxilMDHelper::kDxilResourcesLinkInfoMDName || // used in libraries
name.startswith(DxilMDHelper::kDxilTypeSystemHelperVariablePrefix)) { name.startswith(DxilMDHelper::kDxilTypeSystemHelperVariablePrefix)) {
nodes.push_back(b); nodes.push_back(b);
} }
@ -1012,9 +1013,24 @@ void DxilModule::EmitDxilMetadata() {
m_pMDHelper->EmitValidatorVersion(m_ValMajor, m_ValMinor); m_pMDHelper->EmitValidatorVersion(m_ValMajor, m_ValMinor);
m_pMDHelper->EmitDxilShaderModel(m_pSM); m_pMDHelper->EmitDxilShaderModel(m_pSM);
MDTuple *pMDProperties = EmitDxilShaderProperties(); MDTuple *pMDProperties = nullptr;
uint64_t flag = m_ShaderFlags.GetShaderFlagsRaw();
if (m_pSM->IsLib()) {
DxilFunctionProps props;
props.shaderKind = DXIL::ShaderKind::Library;
pMDProperties = m_pMDHelper->EmitDxilEntryProperties(flag, props,
GetAutoBindingSpace());
} else {
pMDProperties = m_pMDHelper->EmitDxilEntryProperties(
flag, m_DxilEntryPropsMap.begin()->second->props,
GetAutoBindingSpace());
}
MDTuple *pMDSignatures = m_pMDHelper->EmitDxilSignatures(*m_EntrySignature); MDTuple *pMDSignatures = nullptr;
if (!m_pSM->IsLib()) {
pMDSignatures = m_pMDHelper->EmitDxilSignatures(
m_DxilEntryPropsMap.begin()->second->sig);
}
MDTuple *pMDResources = EmitDxilResources(); MDTuple *pMDResources = EmitDxilResources();
if (pMDResources) if (pMDResources)
m_pMDHelper->EmitDxilResources(pMDResources); m_pMDHelper->EmitDxilResources(pMDResources);
@ -1028,53 +1044,37 @@ void DxilModule::EmitDxilMetadata() {
MDTuple *pEntry = m_pMDHelper->EmitDxilEntryPointTuple(GetEntryFunction(), m_EntryName, pMDSignatures, pMDResources, pMDProperties); MDTuple *pEntry = m_pMDHelper->EmitDxilEntryPointTuple(GetEntryFunction(), m_EntryName, pMDSignatures, pMDResources, pMDProperties);
vector<MDNode *> Entries; vector<MDNode *> Entries;
Entries.emplace_back(pEntry); Entries.emplace_back(pEntry);
if (m_pSM->IsLib()) {
// Sort functions by name to keep metadata deterministic
vector<const Function *> funcOrder;
funcOrder.reserve(m_DxilEntryPropsMap.size());
std::transform( m_DxilEntryPropsMap.begin(),
m_DxilEntryPropsMap.end(),
std::back_inserter(funcOrder),
[](auto &p) -> const Function* { return p.first; } );
std::sort(funcOrder.begin(), funcOrder.end(), [](const Function *F1, const Function *F2) {
return F1->getName() < F2->getName();
});
for (auto F : funcOrder) {
auto &entryProps = m_DxilEntryPropsMap[F];
MDTuple *pProps = m_pMDHelper->EmitDxilEntryProperties(0, entryProps->props, 0);
MDTuple *pSig = m_pMDHelper->EmitDxilSignatures(entryProps->sig);
MDTuple *pSubEntry = m_pMDHelper->EmitDxilEntryPointTuple(
const_cast<Function *>(F), F->getName(), pSig, nullptr, pProps);
Entries.emplace_back(pSubEntry);
}
funcOrder.clear();
}
m_pMDHelper->EmitDxilEntryPoints(Entries); m_pMDHelper->EmitDxilEntryPoints(Entries);
if (!m_RootSignature->IsEmpty()) { if (!m_RootSignature->IsEmpty()) {
m_pMDHelper->EmitRootSignature(*m_RootSignature.get()); m_pMDHelper->EmitRootSignature(*m_RootSignature.get());
} }
if (m_pSM->IsLib()) {
NamedMDNode *fnProps = m_pModule->getOrInsertNamedMetadata(
DxilMDHelper::kDxilFunctionPropertiesMDName);
// Sort functions by name to keep metadata deterministic
vector<const Function *> funcOrder;
funcOrder.reserve(std::max(m_DxilFunctionPropsMap.size(),
m_DxilEntrySignatureMap.size()));
std::transform( m_DxilFunctionPropsMap.begin(),
m_DxilFunctionPropsMap.end(),
std::back_inserter(funcOrder),
[](auto &p) -> const Function* { return p.first; } );
std::sort(funcOrder.begin(), funcOrder.end(), [](const Function *F1, const Function *F2) {
return F1->getName() < F2->getName();
});
for (auto F : funcOrder) {
MDTuple *pProps = m_pMDHelper->EmitDxilFunctionProps(&GetDxilFunctionProps(F), F);
fnProps->addOperand(pProps);
}
funcOrder.clear();
NamedMDNode *entrySigs = m_pModule->getOrInsertNamedMetadata(
DxilMDHelper::kDxilEntrySignaturesMDName);
// Sort functions by name to keep metadata deterministic
std::transform( m_DxilEntrySignatureMap.begin(),
m_DxilEntrySignatureMap.end(),
std::back_inserter(funcOrder),
[](auto &p) -> const Function* { return p.first; } );
std::sort(funcOrder.begin(), funcOrder.end(), [](const Function *F1, const Function *F2) {
return F1->getName() < F2->getName();
});
for (auto F : funcOrder) {
DxilEntrySignature *Sig = &GetDxilEntrySignature(F);
MDTuple *pSig = m_pMDHelper->EmitDxilSignatures(*Sig);
entrySigs->addOperand(
MDTuple::get(m_Ctx, {ValueAsMetadata::get(const_cast<Function*>(F)), pSig}));
}
}
} }
bool DxilModule::IsKnownNamedMetaData(llvm::NamedMDNode &Node) { bool DxilModule::IsKnownNamedMetaData(llvm::NamedMDNode &Node) {
@ -1087,22 +1087,73 @@ void DxilModule::LoadDxilMetadata() {
const ShaderModel *loadedModule; const ShaderModel *loadedModule;
m_pMDHelper->LoadDxilShaderModel(loadedModule); m_pMDHelper->LoadDxilShaderModel(loadedModule);
SetShaderModel(loadedModule); SetShaderModel(loadedModule);
DXASSERT(m_EntrySignature != nullptr, "else SetShaderModel didn't create entry signature");
const llvm::NamedMDNode *pEntries = m_pMDHelper->GetDxilEntryPoints(); const llvm::NamedMDNode *pEntries = m_pMDHelper->GetDxilEntryPoints();
IFTBOOL(pEntries->getNumOperands() == 1, DXC_E_INCORRECT_DXIL_METADATA); if (!loadedModule->IsLib()) {
IFTBOOL(pEntries->getNumOperands() == 1, DXC_E_INCORRECT_DXIL_METADATA);
}
Function *pEntryFunc; Function *pEntryFunc;
string EntryName; string EntryName;
const llvm::MDOperand *pSignatures, *pResources, *pProperties; const llvm::MDOperand *pSignatures, *pResources, *pProperties;
m_pMDHelper->GetDxilEntryPoint(pEntries->getOperand(0), pEntryFunc, EntryName, pSignatures, pResources, pProperties); m_pMDHelper->GetDxilEntryPoint(pEntries->getOperand(0), pEntryFunc, EntryName, pSignatures, pResources, pProperties);
if (loadedModule->IsLib()) {
for (unsigned i = 1; i < pEntries->getNumOperands(); i++) {
Function *pFunc;
string Name;
const llvm::MDOperand *pSignatures, *pResources, *pProperties;
m_pMDHelper->GetDxilEntryPoint(pEntries->getOperand(i), pFunc, Name,
pSignatures, pResources, pProperties);
DxilFunctionProps props;
uint64_t rawShaderFlags = 0;
unsigned autoBindingSpace = 0;
m_pMDHelper->LoadDxilEntryProperties(
*pProperties, rawShaderFlags, props, autoBindingSpace);
if (props.IsHS() && props.ShaderProps.HS.patchConstantFunc) {
// Add patch constant function to m_PatchConstantFunctions
m_PatchConstantFunctions.insert(props.ShaderProps.HS.patchConstantFunc);
}
std::unique_ptr<DxilEntryProps> pEntryProps =
llvm::make_unique<DxilEntryProps>(props, GetUseMinPrecision());
DXASSERT(pSignatures->get() == nullptr || !props.IsRay(),
"Raytracing has no signature");
m_pMDHelper->LoadDxilSignatures(*pSignatures, pEntryProps->sig);
m_DxilEntryPropsMap[pFunc] = std::move(pEntryProps);
}
} else {
DxilFunctionProps props;
props.shaderKind = loadedModule->GetKind();
std::unique_ptr<DxilEntryProps> pEntryProps =
llvm::make_unique<DxilEntryProps>(props, GetUseMinPrecision());
m_pMDHelper->LoadDxilSignatures(*pSignatures, pEntryProps->sig);
m_DxilEntryPropsMap[pEntryFunc] = std::move(pEntryProps);
}
SetEntryFunction(pEntryFunc); SetEntryFunction(pEntryFunc);
SetEntryFunctionName(EntryName); SetEntryFunctionName(EntryName);
LoadDxilShaderProperties(*pProperties); uint64_t rawShaderFlags = 0;
if (m_pSM->IsLib()) {
m_pMDHelper->LoadDxilSignatures(*pSignatures, *m_EntrySignature); DxilFunctionProps props;
m_pMDHelper->LoadDxilEntryProperties(*pProperties, rawShaderFlags, props,
m_AutoBindingSpace);
} else {
DxilFunctionProps &props = m_DxilEntryPropsMap.begin()->second->props;
m_pMDHelper->LoadDxilEntryProperties(
*pProperties, rawShaderFlags,
props, m_AutoBindingSpace);
SetShaderProperties(&props);
}
if (rawShaderFlags) {
m_ShaderFlags.SetShaderFlagsRaw(rawShaderFlags);
m_bUseMinPrecision = !m_ShaderFlags.GetUseNativeLowPrecision();
m_bDisableOptimizations = m_ShaderFlags.GetDisableOptimizations();
m_bAllResourcesBound = m_ShaderFlags.GetAllResourcesBound();
}
LoadDxilResources(*pResources); LoadDxilResources(*pResources);
m_pMDHelper->LoadDxilTypeSystem(*m_pTypeSystem.get()); m_pMDHelper->LoadDxilTypeSystem(*m_pTypeSystem.get());
@ -1110,49 +1161,6 @@ void DxilModule::LoadDxilMetadata() {
m_pMDHelper->LoadRootSignature(*m_RootSignature.get()); m_pMDHelper->LoadRootSignature(*m_RootSignature.get());
m_pMDHelper->LoadDxilViewIdState(*m_pViewIdState.get()); m_pMDHelper->LoadDxilViewIdState(*m_pViewIdState.get());
if (loadedModule->IsLib()) {
NamedMDNode *fnProps = m_pModule->getNamedMetadata(
DxilMDHelper::kDxilFunctionPropertiesMDName);
size_t propIdx = 0;
while (propIdx < fnProps->getNumOperands()) {
MDTuple *pProps = dyn_cast<MDTuple>(fnProps->getOperand(propIdx++));
std::unique_ptr<hlsl::DxilFunctionProps> props =
llvm::make_unique<hlsl::DxilFunctionProps>();
Function *F = m_pMDHelper->LoadDxilFunctionProps(pProps, props.get());
if (props->IsHS() && props->ShaderProps.HS.patchConstantFunc) {
// Add patch constant function to m_PatchConstantFunctions
m_PatchConstantFunctions.insert(props->ShaderProps.HS.patchConstantFunc);
}
m_DxilFunctionPropsMap[F] = std::move(props);
}
NamedMDNode *entrySigs = m_pModule->getOrInsertNamedMetadata(
DxilMDHelper::kDxilEntrySignaturesMDName);
size_t sigIdx = 0;
while (sigIdx < entrySigs->getNumOperands()) {
MDTuple *pSig = dyn_cast<MDTuple>(entrySigs->getOperand(sigIdx++));
unsigned idx = 0;
Function *F = dyn_cast<Function>(
dyn_cast<ValueAsMetadata>(pSig->getOperand(idx++))->getValue());
// Entry must have props.
IFTBOOL(m_DxilFunctionPropsMap.count(F), DXC_E_INCORRECT_DXIL_METADATA);
DXIL::ShaderKind shaderKind = m_DxilFunctionPropsMap[F]->shaderKind;
std::unique_ptr<hlsl::DxilEntrySignature> Sig =
llvm::make_unique<hlsl::DxilEntrySignature>(shaderKind, GetUseMinPrecision());
m_pMDHelper->LoadDxilSignatures(pSig->getOperand(idx), *Sig);
m_DxilEntrySignatureMap[F] = std::move(Sig);
}
}
} }
MDTuple *DxilModule::EmitDxilResources() { MDTuple *DxilModule::EmitDxilResources() {
@ -1254,132 +1262,6 @@ void DxilModule::LoadDxilResources(const llvm::MDOperand &MDO) {
} }
} }
MDTuple *DxilModule::EmitDxilShaderProperties() {
vector<Metadata *> MDVals;
// DXIL shader flags.
uint64_t flag = m_ShaderFlags.GetShaderFlagsRaw();
if (flag != 0) {
MDVals.emplace_back(m_pMDHelper->Uint32ToConstMD(DxilMDHelper::kDxilShaderFlagsTag));
MDVals.emplace_back(m_pMDHelper->Uint64ToConstMD(flag));
}
// Compute shader.
if (m_pSM->IsCS()) {
MDVals.emplace_back(m_pMDHelper->Uint32ToConstMD(DxilMDHelper::kDxilNumThreadsTag));
vector<Metadata *> NumThreadVals;
NumThreadVals.emplace_back(m_pMDHelper->Uint32ToConstMD(m_NumThreads[0]));
NumThreadVals.emplace_back(m_pMDHelper->Uint32ToConstMD(m_NumThreads[1]));
NumThreadVals.emplace_back(m_pMDHelper->Uint32ToConstMD(m_NumThreads[2]));
MDVals.emplace_back(MDNode::get(m_Ctx, NumThreadVals));
}
// Geometry shader.
if (m_pSM->IsGS()) {
MDVals.emplace_back(m_pMDHelper->Uint32ToConstMD(DxilMDHelper::kDxilGSStateTag));
MDTuple *pMDTuple = m_pMDHelper->EmitDxilGSState(m_InputPrimitive,
m_MaxVertexCount,
GetActiveStreamMask(),
m_StreamPrimitiveTopology,
m_NumGSInstances);
MDVals.emplace_back(pMDTuple);
}
// Domain shader.
if (m_pSM->IsDS()) {
MDVals.emplace_back(m_pMDHelper->Uint32ToConstMD(DxilMDHelper::kDxilDSStateTag));
MDTuple *pMDTuple = m_pMDHelper->EmitDxilDSState(m_TessellatorDomain,
m_InputControlPointCount);
MDVals.emplace_back(pMDTuple);
}
// Hull shader.
if (m_pSM->IsHS()) {
MDVals.emplace_back(m_pMDHelper->Uint32ToConstMD(DxilMDHelper::kDxilHSStateTag));
MDTuple *pMDTuple = m_pMDHelper->EmitDxilHSState(m_pPatchConstantFunc,
m_InputControlPointCount,
m_OutputControlPointCount,
m_TessellatorDomain,
m_TessellatorPartitioning,
m_TessellatorOutputPrimitive,
m_MaxTessellationFactor);
MDVals.emplace_back(pMDTuple);
}
if (GetAutoBindingSpace() != UINT_MAX && m_pSM->IsSMAtLeast(6, 3)) {
MDVals.emplace_back(m_pMDHelper->Uint32ToConstMD(DxilMDHelper::kDxilAutoBindingSpaceTag));
MDVals.emplace_back(MDNode::get(m_Ctx, { m_pMDHelper->Uint32ToConstMD(GetAutoBindingSpace()) }));
}
if (!MDVals.empty())
return MDNode::get(m_Ctx, MDVals);
else
return nullptr;
}
void DxilModule::LoadDxilShaderProperties(const MDOperand &MDO) {
if (MDO.get() == nullptr)
return;
const MDTuple *pTupleMD = dyn_cast<MDTuple>(MDO.get());
IFTBOOL(pTupleMD != nullptr, DXC_E_INCORRECT_DXIL_METADATA);
IFTBOOL((pTupleMD->getNumOperands() & 0x1) == 0, DXC_E_INCORRECT_DXIL_METADATA);
for (unsigned iNode = 0; iNode < pTupleMD->getNumOperands(); iNode += 2) {
unsigned Tag = DxilMDHelper::ConstMDToUint32(pTupleMD->getOperand(iNode));
const MDOperand &MDO = pTupleMD->getOperand(iNode + 1);
IFTBOOL(MDO.get() != nullptr, DXC_E_INCORRECT_DXIL_METADATA);
switch (Tag) {
case DxilMDHelper::kDxilShaderFlagsTag:
m_ShaderFlags.SetShaderFlagsRaw(DxilMDHelper::ConstMDToUint64(MDO));
m_bUseMinPrecision = !m_ShaderFlags.GetUseNativeLowPrecision();
m_bDisableOptimizations = m_ShaderFlags.GetDisableOptimizations();
m_bAllResourcesBound = m_ShaderFlags.GetAllResourcesBound();
break;
case DxilMDHelper::kDxilNumThreadsTag: {
MDNode *pNode = cast<MDNode>(MDO.get());
m_NumThreads[0] = DxilMDHelper::ConstMDToUint32(pNode->getOperand(0));
m_NumThreads[1] = DxilMDHelper::ConstMDToUint32(pNode->getOperand(1));
m_NumThreads[2] = DxilMDHelper::ConstMDToUint32(pNode->getOperand(2));
break;
}
case DxilMDHelper::kDxilGSStateTag: {
m_pMDHelper->LoadDxilGSState(MDO, m_InputPrimitive, m_MaxVertexCount, m_ActiveStreamMask,
m_StreamPrimitiveTopology, m_NumGSInstances);
break;
}
case DxilMDHelper::kDxilDSStateTag:
m_pMDHelper->LoadDxilDSState(MDO, m_TessellatorDomain, m_InputControlPointCount);
break;
case DxilMDHelper::kDxilHSStateTag:
m_pMDHelper->LoadDxilHSState(MDO,
m_pPatchConstantFunc,
m_InputControlPointCount,
m_OutputControlPointCount,
m_TessellatorDomain,
m_TessellatorPartitioning,
m_TessellatorOutputPrimitive,
m_MaxTessellationFactor);
break;
case DxilMDHelper::kDxilAutoBindingSpaceTag: {
MDNode *pNode = cast<MDNode>(MDO.get());
SetAutoBindingSpace(DxilMDHelper::ConstMDToUint32(pNode->getOperand(0)));
break;
}
default:
DXASSERT(false, "Unknown extended shader properties tag");
break;
}
}
}
void DxilModule::StripDebugRelatedCode() { void DxilModule::StripDebugRelatedCode() {
// Remove all users of global resources. // Remove all users of global resources.
for (GlobalVariable &GV : m_pModule->globals()) { for (GlobalVariable &GV : m_pModule->globals()) {

Просмотреть файл

@ -172,8 +172,7 @@ Function *StripFunctionParameter(Function *F, DxilModule &DM,
} }
NewFunc->takeName(F); NewFunc->takeName(F);
if (DM.HasDxilFunctionProps(F)) { if (DM.HasDxilFunctionProps(F)) {
DM.ReplaceDxilEntrySignature(F, NewFunc); DM.ReplaceDxilEntryProps(F, NewFunc);
DM.ReplaceDxilFunctionProps(F, NewFunc);
} }
DM.GetTypeSystem().EraseFunctionAnnotation(F); DM.GetTypeSystem().EraseFunctionAnnotation(F);
F->eraseFromParent(); F->eraseFromParent();
@ -360,16 +359,19 @@ private:
if (Function *PatchConstantFunc = DM.GetPatchConstantFunction()) { if (Function *PatchConstantFunc = DM.GetPatchConstantFunction()) {
PatchConstantFunc = PatchConstantFunc =
StripFunctionParameter(PatchConstantFunc, DM, FunctionDIs); StripFunctionParameter(PatchConstantFunc, DM, FunctionDIs);
if (PatchConstantFunc) if (PatchConstantFunc) {
DM.SetPatchConstantFunction(PatchConstantFunc); DM.SetPatchConstantFunction(PatchConstantFunc);
DM.SetPatchConstantFunctionForHS(DM.GetEntryFunction(), PatchConstantFunc);
}
} }
if (Function *EntryFunc = DM.GetEntryFunction()) { if (Function *EntryFunc = DM.GetEntryFunction()) {
StringRef Name = DM.GetEntryFunctionName(); StringRef Name = DM.GetEntryFunctionName();
EntryFunc->setName(Name); EntryFunc->setName(Name);
EntryFunc = StripFunctionParameter(EntryFunc, DM, FunctionDIs); EntryFunc = StripFunctionParameter(EntryFunc, DM, FunctionDIs);
if (EntryFunc) if (EntryFunc) {
DM.SetEntryFunction(EntryFunc); DM.SetEntryFunction(EntryFunc);
}
} }
} else { } else {
std::vector<Function *> entries; std::vector<Function *> entries;

Просмотреть файл

@ -3115,20 +3115,6 @@ static void ValidateTypeAnnotation(ValidationContext &ValCtx) {
} }
} }
static bool IsLibMetadata(ValidationContext &ValCtx, StringRef name) {
if (!ValCtx.isLibProfile)
return false;
// Skip dx.func.props and dx.func.signatures for now.
// And these 2 need validation also.
// Or we merge them into Entry, and validate as entry.
const char * libMetaNames[] = {"dx.func.props","dx.func.signatures"};
for (const char *libName : libMetaNames) {
if (name.equals(libName))
return true;
}
return false;
}
static void ValidateMetadata(ValidationContext &ValCtx) { static void ValidateMetadata(ValidationContext &ValCtx) {
Module *pModule = &ValCtx.M; Module *pModule = &ValCtx.M;
const std::string &target = pModule->getTargetTriple(); const std::string &target = pModule->getTargetTriple();
@ -3148,8 +3134,6 @@ static void ValidateMetadata(ValidationContext &ValCtx) {
for (auto &NamedMetaNode : pModule->named_metadata()) { for (auto &NamedMetaNode : pModule->named_metadata()) {
if (!DxilModule::IsKnownNamedMetaData(NamedMetaNode)) { if (!DxilModule::IsKnownNamedMetaData(NamedMetaNode)) {
StringRef name = NamedMetaNode.getName(); StringRef name = NamedMetaNode.getName();
if (IsLibMetadata(ValCtx, name))
continue;
if (!name.startswith_lower("llvm.")) { if (!name.startswith_lower("llvm.")) {
ValCtx.EmitFormatError(ValidationRule::MetaKnown, {name.str()}); ValCtx.EmitFormatError(ValidationRule::MetaKnown, {name.str()});
} }
@ -3986,6 +3970,8 @@ static void ValidateNoInterpModeSignature(ValidationContext &ValCtx, const DxilS
} }
static void ValidateSignatures(ValidationContext &ValCtx) { static void ValidateSignatures(ValidationContext &ValCtx) {
if (ValCtx.isLibProfile)
return;
DxilModule &M = ValCtx.DxilMod; DxilModule &M = ValCtx.DxilMod;
bool isPS = M.GetShaderModel()->IsPS(); bool isPS = M.GetShaderModel()->IsPS();
bool isVS = M.GetShaderModel()->IsVS(); bool isVS = M.GetShaderModel()->IsVS();
@ -4475,6 +4461,8 @@ static void ValidateFlowControl(ValidationContext &ValCtx) {
} }
static void ValidateUninitializedOutput(ValidationContext &ValCtx) { static void ValidateUninitializedOutput(ValidationContext &ValCtx) {
if (ValCtx.isLibProfile)
return;
// For HS only need to check Tessfactor which is in patch constant sig. // For HS only need to check Tessfactor which is in patch constant sig.
if (ValCtx.DxilMod.GetShaderModel()->IsHS()) { if (ValCtx.DxilMod.GetShaderModel()->IsHS()) {
std::vector<unsigned> &patchConstCols = ValCtx.patchConstCols; std::vector<unsigned> &patchConstCols = ValCtx.patchConstCols;
@ -4794,10 +4782,10 @@ HRESULT ValidateDxilContainerParts(llvm::Module *pModule,
} }
// Verify required parts found // Verify required parts found
if (FourCCFound.find(DFCC_InputSignature) == FourCCFound.end()) { if (FourCCFound.find(DFCC_InputSignature) == FourCCFound.end() && !ValCtx.isLibProfile) {
VerifySignatureMatches(ValCtx, DXIL::SignatureKind::Input, nullptr, 0); VerifySignatureMatches(ValCtx, DXIL::SignatureKind::Input, nullptr, 0);
} }
if (FourCCFound.find(DFCC_OutputSignature) == FourCCFound.end()) { if (FourCCFound.find(DFCC_OutputSignature) == FourCCFound.end() && !ValCtx.isLibProfile) {
VerifySignatureMatches(ValCtx, DXIL::SignatureKind::Output, nullptr, 0); VerifySignatureMatches(ValCtx, DXIL::SignatureKind::Output, nullptr, 0);
} }
if (bTess && FourCCFound.find(DFCC_PatchConstantSignature) == FourCCFound.end() && if (bTess && FourCCFound.find(DFCC_PatchConstantSignature) == FourCCFound.end() &&

Просмотреть файл

@ -509,7 +509,7 @@ void HLModule::LoadHLMetadata() {
std::unique_ptr<hlsl::DxilFunctionProps> props = std::unique_ptr<hlsl::DxilFunctionProps> props =
llvm::make_unique<hlsl::DxilFunctionProps>(); llvm::make_unique<hlsl::DxilFunctionProps>();
Function *F = m_pMDHelper->LoadDxilFunctionProps(pProps, props.get()); const Function *F = m_pMDHelper->LoadDxilFunctionProps(pProps, props.get());
if (props->IsHS() && props->ShaderProps.HS.patchConstantFunc) { if (props->IsHS() && props->ShaderProps.HS.patchConstantFunc) {
// Add patch constant function to m_PatchConstantFunctions // Add patch constant function to m_PatchConstantFunctions

Просмотреть файл

@ -12,10 +12,11 @@
// CHECK: @"\01?entry // CHECK: @"\01?entry
// Make sure function props exist. // Make sure function props exist.
// CHECK: dx.func.props // CHECK: !dx.entryPoints = !{{{.*}}, {{.*}}}
// Make sure function props is correct for [numthreads(8,8,1)]. // Make sure function props is correct for [numthreads(8,8,1)].
// CHECK: @entry, i32 5, i32 8, i32 8, i32 1 // CHECK: @entry,
// CHECK: !{i32 8, i32 8, i32 1}
cbuffer A { cbuffer A {
float a; float a;

Просмотреть файл

@ -9,11 +9,14 @@
// CHECK: @"\01?entry2 // CHECK: @"\01?entry2
// Make sure function props exist. // Make sure function props exist.
// CHECK: dx.func.props // CHECK: !dx.entryPoints = !{{{.*}}, {{.*}}, {{.*}}}
// Make sure function props is correct for [numthreads(8,8,1)]. // Make sure function props is correct for [numthreads(8,8,1)].
// CHECK: @entry{{.*}}, i32 5, i32 8, i32 8, i32 1 // CHECK: @entry, !"entry", null, null, [[PROPS:![0-9]+]]}
// CHECK: @entry{{.*}}, i32 5, i32 8, i32 8, i32 1 // CHECK: [[PROPS]] = !{i32 8, i32 5, i32 4, [[CS:![0-9]+]],
// CHECK: [[CS]] = !{i32 8, i32 8, i32 1}
// CHECK: @entry2, !"entry2", null, null, [[PROPS]]
[numthreads(8,8,1)] [numthreads(8,8,1)]
void entry( uint2 tid : SV_DispatchThreadID, uint2 gid : SV_GroupID, uint2 gtid : SV_GroupThreadID, uint gidx : SV_GroupIndex ) void entry( uint2 tid : SV_DispatchThreadID, uint2 gid : SV_GroupID, uint2 gtid : SV_GroupThreadID, uint gidx : SV_GroupIndex )

Просмотреть файл

@ -63,9 +63,9 @@
// Make sure function entrys exist. // Make sure function entrys exist.
// CHECK: dx.func.signatures // CHECK: !dx.entryPoints = !{{{.*}}, {{.*}}, {{.*}}, {{.*}}, {{.*}}, {{.*}}, {{.*}}}
// Make sure cs don't have signature. // Make sure cs don't have signature.
// CHECK: @cs_main, null // CHECK: !"cs_main", null
void StoreCSOutput(uint2 tid, uint2 gid); void StoreCSOutput(uint2 tid, uint2 gid);

Просмотреть файл

@ -59,9 +59,9 @@
// Make sure function entrys exist. // Make sure function entrys exist.
// CHECK: dx.func.signatures // CHECK: !dx.entryPoints = !{{{.*}}, {{.*}}, {{.*}}, {{.*}}, {{.*}}, {{.*}}, {{.*}}}
// Make sure cs don't have signature. // Make sure cs don't have signature.
// CHECK: @cs_main, null // CHECK: !"cs_main", null
void StoreCSOutput(uint2 tid, uint2 gid); void StoreCSOutput(uint2 tid, uint2 gid);

Просмотреть файл

@ -1,7 +1,8 @@
// RUN: %dxc -T lib_6_3 -auto-binding-space 11 -enable-16bit-types %s | FileCheck %s // RUN: %dxc -T lib_6_3 -auto-binding-space 11 -enable-16bit-types %s | FileCheck %s
/////////////////////////////////////// ///////////////////////////////////////
// CHECK: !{void (%struct.Payload_20*, %struct.BuiltInTriangleIntersectionAttributes*)* @"\01?anyhit1@@YAXUPayload_20@@UBuiltInTriangleIntersectionAttributes@@@Z", i32 9, i32 20, i32 8} // CHECK: !{void (%struct.Payload_20*, %struct.BuiltInTriangleIntersectionAttributes*)* @"\01?anyhit1@@YAXUPayload_20@@UBuiltInTriangleIntersectionAttributes@@@Z",
// CHECK: !{i32 8, i32 9, i32 6, i32 20, i32 7, i32 8,
struct Payload_20 { struct Payload_20 {
float3 color; float3 color;
@ -16,7 +17,8 @@ void anyhit1( inout Payload_20 payload,
} }
/////////////////////////////////////// ///////////////////////////////////////
// CHECK: !{void (%struct.Params_16*)* @"\01?callable4@@YAXUParams_16@@@Z", i32 12, i32 16} // CHECK: !{void (%struct.Params_16*)* @"\01?callable4@@YAXUParams_16@@@Z",
// CHECK: !{i32 8, i32 12, i32 6, i32 16
struct Params_16 { struct Params_16 {
int64_t i; int64_t i;
@ -30,7 +32,8 @@ void callable4( inout Params_16 params )
} }
/////////////////////////////////////// ///////////////////////////////////////
// CHECK: !{void (%struct.Payload_16*, %struct.Attributes_12*)* @"\01?closesthit2@@YAXUPayload_16@@UAttributes_12@@@Z", i32 10, i32 16, i32 12} // CHECK: !{void (%struct.Payload_16*, %struct.Attributes_12*)* @"\01?closesthit2@@YAXUPayload_16@@UAttributes_12@@@Z",
// CHECK: !{i32 8, i32 10, i32 6, i32 16, i32 7, i32 12
struct Payload_16 { struct Payload_16 {
half a; half a;
@ -57,7 +60,8 @@ void closesthit2( inout Payload_16 payload,
} }
/////////////////////////////////////// ///////////////////////////////////////
// CHECK: !{void (%struct.Payload_10*, %struct.Attributes_40*)* @"\01?closesthit3@@YAXUPayload_10@@UAttributes_40@@@Z", i32 10, i32 10, i32 40} // CHECK: !{void (%struct.Payload_10*, %struct.Attributes_40*)* @"\01?closesthit3@@YAXUPayload_10@@UAttributes_40@@@Z",
// CHECK: !{i32 8, i32 10, i32 6, i32 10, i32 7, i32 40
struct Payload_10 { struct Payload_10 {
half4 color; half4 color;
@ -83,7 +87,8 @@ void closesthit3( inout Payload_10 payload,
} }
/////////////////////////////////////// ///////////////////////////////////////
// CHECK: !{void (%struct.Payload_8*)* @"\01?miss4@@YAXUPayload_8@@@Z", i32 11, i32 8} // CHECK: !{void (%struct.Payload_8*)* @"\01?miss4@@YAXUPayload_8@@@Z",
// CHECK: !{i32 8, i32 11, i32 6, i32 8
struct Payload_8 { struct Payload_8 {
half color; half color;

Просмотреть файл

@ -1366,13 +1366,15 @@ HRESULT Disassemble(IDxcBlob *pProgram, raw_string_ostream &Stream) {
if (pModule->getNamedMetadata("dx.version")) { if (pModule->getNamedMetadata("dx.version")) {
DxilModule &dxilModule = pModule->GetOrCreateDxilModule(); DxilModule &dxilModule = pModule->GetOrCreateDxilModule();
PrintDxilSignature("Input", dxilModule.GetInputSignature(), Stream, if (!dxilModule.GetShaderModel()->IsLib()) {
/*comment*/ ";"); PrintDxilSignature("Input", dxilModule.GetInputSignature(), Stream,
PrintDxilSignature("Output", dxilModule.GetOutputSignature(), Stream, /*comment*/ ";");
/*comment*/ ";"); PrintDxilSignature("Output", dxilModule.GetOutputSignature(), Stream,
PrintDxilSignature("Patch Constant signature", /*comment*/ ";");
dxilModule.GetPatchConstantSignature(), Stream, PrintDxilSignature("Patch Constant signature",
/*comment*/ ";"); dxilModule.GetPatchConstantSignature(), Stream,
/*comment*/ ";");
}
PrintBufferDefinitions(dxilModule, Stream, /*comment*/ ";"); PrintBufferDefinitions(dxilModule, Stream, /*comment*/ ";");
PrintResourceBindings(dxilModule, Stream, /*comment*/ ";"); PrintResourceBindings(dxilModule, Stream, /*comment*/ ";");
PrintViewIdState(dxilModule, Stream, /*comment*/ ";"); PrintViewIdState(dxilModule, Stream, /*comment*/ ";");