blob: fa13f6d76682cb1aae5511710b262dc153135f87 [file] [log] [blame] [edit]
///////////////////////////////////////////////////////////////////////////////
// //
// DxilMetadataHelper.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. //
// //
// Helper to serialize/desialize metadata for DxilModule. //
// //
///////////////////////////////////////////////////////////////////////////////
#pragma once
#include "dxc/DXIL/DxilConstants.h"
#include "dxc/DXIL/DxilFunctionProps.h"
#include "llvm/ADT/ArrayRef.h"
#include <memory>
#include <string>
#include <vector>
namespace llvm {
class LLVMContext;
class Module;
class Function;
class Instruction;
class DbgDeclareInst;
class Value;
class MDOperand;
class Metadata;
class ConstantAsMetadata;
class MDTuple;
class MDNode;
class NamedMDNode;
class GlobalVariable;
class StringRef;
class Type;
} // namespace llvm
namespace hlsl {
class ShaderModel;
class DxilSignature;
struct DxilEntrySignature;
class DxilSignatureElement;
class DxilModule;
class DxilResourceBase;
class DxilCBuffer;
class DxilResource;
class DxilSampler;
class DxilTypeSystem;
class DxilStructAnnotation;
class DxilFieldAnnotation;
class DxilPayloadAnnotation;
class DxilPayloadFieldAnnotation;
class DxilTemplateArgAnnotation;
class DxilFunctionAnnotation;
class DxilParameterAnnotation;
class RootSignatureHandle;
struct DxilFunctionProps;
class DxilSubobjects;
class DxilSubobject;
struct DxilCounters;
// Additional debug information for SROA'ed array variables,
// where adjacent elements in DXIL might not have been adjacent
// in the original user variable.
struct DxilDIArrayDim {
unsigned StrideInBits;
unsigned NumElements;
};
/// Use this class to manipulate DXIL-spcific metadata.
// In our code, only DxilModule and HLModule should use this class.
class DxilMDHelper {
public:
//
// Constants for metadata names and field positions.
//
// Dxil version.
static const char kDxilVersionMDName[];
static const unsigned kDxilVersionNumFields = 2;
static const unsigned kDxilVersionMajorIdx = 0; // DXIL version major.
static const unsigned kDxilVersionMinorIdx = 1; // DXIL version minor.
// Shader model.
static const char kDxilShaderModelMDName[];
static const unsigned kDxilShaderModelNumFields = 3;
static const unsigned kDxilShaderModelTypeIdx =
0; // Shader type (vs,ps,cs,gs,ds,hs).
static const unsigned kDxilShaderModelMajorIdx = 1; // Shader model major.
static const unsigned kDxilShaderModelMinorIdx = 2; // Shader model minor.
// Intermediate codegen/optimizer options, not valid in final DXIL module.
static const char kDxilIntermediateOptionsMDName[];
static const unsigned kDxilIntermediateOptionsFlags = 0; // Unique element ID.
// DxilCounters
static const char kDxilCountersMDName[];
// !{!"<counter>", i32 <count>, !"<counter>", i32 <count>, ...}
// Entry points.
static const char kDxilEntryPointsMDName[];
// Root Signature, for intermediate use, not valid in final DXIL module.
static const char kDxilRootSignatureMDName[];
// ViewId state.
static const char kDxilViewIdStateMDName[];
// Subobjects
static const char kDxilSubobjectsMDName[];
// Source info.
static const char kDxilSourceContentsMDName[];
static const char kDxilSourceDefinesMDName[];
static const char kDxilSourceMainFileNameMDName[];
static const char kDxilSourceArgsMDName[];
// Resource binding data
static const char kDxilDxcBindingTableMDName[];
static const unsigned kDxilDxcBindingTableResourceName = 0;
static const unsigned kDxilDxcBindingTableResourceClass = 1;
static const unsigned kDxilDxcBindingTableResourceIndex = 2;
static const unsigned kDxilDxcBindingTableResourceSpace = 3;
// Old source info.
static const char kDxilSourceContentsOldMDName[];
static const char kDxilSourceDefinesOldMDName[];
static const char kDxilSourceMainFileNameOldMDName[];
static const char kDxilSourceArgsOldMDName[];
static const unsigned kDxilEntryPointNumFields = 5;
static const unsigned kDxilEntryPointFunction =
0; // Entry point function symbol.
static const unsigned kDxilEntryPointName = 1; // Entry point unmangled name.
static const unsigned kDxilEntryPointSignatures =
2; // Entry point signature tuple.
static const unsigned kDxilEntryPointResources =
3; // Entry point resource tuple.
static const unsigned kDxilEntryPointProperties =
4; // Entry point properties tuple.
// Signatures.
static const unsigned kDxilNumSignatureFields = 3;
static const unsigned kDxilInputSignature = 0; // Shader input signature.
static const unsigned kDxilOutputSignature = 1; // Shader output signature.
static const unsigned kDxilPatchConstantSignature =
2; // Shader patch constant (PC) signature.
// Signature Element.
static const unsigned kDxilSignatureElementNumFields = 11;
static const unsigned kDxilSignatureElementID = 0; // Unique element ID.
static const unsigned kDxilSignatureElementName = 1; // Element name.
static const unsigned kDxilSignatureElementType = 2; // Element type.
static const unsigned kDxilSignatureElementSystemValue =
3; // Effective system value.
static const unsigned kDxilSignatureElementIndexVector =
4; // Semantic index vector.
static const unsigned kDxilSignatureElementInterpMode =
5; // Interpolation mode.
static const unsigned kDxilSignatureElementRows = 6; // Number of rows.
static const unsigned kDxilSignatureElementCols = 7; // Number of columns.
static const unsigned kDxilSignatureElementStartRow =
8; // Element packing start row.
static const unsigned kDxilSignatureElementStartCol =
9; // Element packing start column.
static const unsigned kDxilSignatureElementNameValueList =
10; // Name-value list for extended properties.
// Signature Element Extended Properties.
static const unsigned kDxilSignatureElementOutputStreamTag = 0;
static const unsigned kHLSignatureElementGlobalSymbolTag = 1;
static const unsigned kDxilSignatureElementDynIdxCompMaskTag = 2;
static const unsigned kDxilSignatureElementUsageCompMaskTag = 3;
// Resources.
static const char kDxilResourcesMDName[];
static const unsigned kDxilNumResourceFields = 4;
static const unsigned kDxilResourceSRVs = 0;
static const unsigned kDxilResourceUAVs = 1;
static const unsigned kDxilResourceCBuffers = 2;
static const unsigned kDxilResourceSamplers = 3;
// ResourceBase.
static const unsigned kDxilResourceBaseNumFields = 6;
static const unsigned kDxilResourceBaseID =
0; // Unique (per type) resource ID.
static const unsigned kDxilResourceBaseVariable =
1; // Resource global variable.
static const unsigned kDxilResourceBaseName =
2; // Original (HLSL) name of the resource.
static const unsigned kDxilResourceBaseSpaceID =
3; // Resource range space ID.
static const unsigned kDxilResourceBaseLowerBound =
4; // Resource range lower bound.
static const unsigned kDxilResourceBaseRangeSize = 5; // Resource range size.
// SRV-specific.
static const unsigned kDxilSRVNumFields = 9;
static const unsigned kDxilSRVShape = 6; // SRV shape.
static const unsigned kDxilSRVSampleCount = 7; // SRV sample count.
static const unsigned kDxilSRVNameValueList =
8; // Name-value list for extended properties.
// UAV-specific.
static const unsigned kDxilUAVNumFields = 11;
static const unsigned kDxilUAVShape = 6; // UAV shape.
static const unsigned kDxilUAVGloballyCoherent = 7; // Globally-coherent UAV.
static const unsigned kDxilUAVCounter = 8; // UAV with a counter.
static const unsigned kDxilUAVRasterizerOrderedView = 9; // UAV that is a ROV.
static const unsigned kDxilUAVNameValueList =
10; // Name-value list for extended properties.
// CBuffer-specific.
static const unsigned kDxilCBufferNumFields = 8;
static const unsigned kDxilCBufferSizeInBytes = 6; // CBuffer size in bytes.
static const unsigned kDxilCBufferNameValueList =
7; // Name-value list for extended properties.
// CBuffer extended properties
static const unsigned kHLCBufferIsTBufferTag =
0; // CBuffer is actually TBuffer, not yet converted to SRV.
// Sampler-specific.
static const unsigned kDxilSamplerNumFields = 8;
static const unsigned kDxilSamplerType = 6; // Sampler type.
static const unsigned kDxilSamplerNameValueList =
7; // Name-value list for extended properties.
// Resource extended property tags.
static const unsigned kDxilTypedBufferElementTypeTag = 0;
static const unsigned kDxilStructuredBufferElementStrideTag = 1;
static const unsigned kDxilSamplerFeedbackKindTag = 2;
static const unsigned kDxilAtomic64UseTag = 3;
// Type system.
static const char kDxilTypeSystemMDName[];
static const char kDxilTypeSystemHelperVariablePrefix[];
static const unsigned kDxilTypeSystemStructTag = 0;
static const unsigned kDxilTypeSystemFunctionTag = 1;
static const unsigned kDxilFieldAnnotationSNormTag = 0;
static const unsigned kDxilFieldAnnotationUNormTag = 1;
static const unsigned kDxilFieldAnnotationMatrixTag = 2;
static const unsigned kDxilFieldAnnotationCBufferOffsetTag = 3;
static const unsigned kDxilFieldAnnotationSemanticStringTag = 4;
static const unsigned kDxilFieldAnnotationInterpolationModeTag = 5;
static const unsigned kDxilFieldAnnotationFieldNameTag = 6;
static const unsigned kDxilFieldAnnotationCompTypeTag = 7;
static const unsigned kDxilFieldAnnotationPreciseTag = 8;
static const unsigned kDxilFieldAnnotationCBUsedTag = 9;
static const unsigned kDxilFieldAnnotationResPropTag = 10;
static const unsigned kDxilFieldAnnotationBitFieldsTag = 11;
static const unsigned kDxilFieldAnnotationBitFieldWidthTag = 12;
static const unsigned kDxilFieldAnnotationVectorSizeTag = 13;
// DXR Payload Annotations
static const unsigned kDxilPayloadAnnotationStructTag = 0;
static const unsigned kDxilPayloadFieldAnnotationAccessTag = 0;
// StructAnnotation extended property tags (DXIL 1.5+ only, appended)
static const unsigned kDxilTemplateArgumentsTag =
0; // Name for name-value list of extended struct properties
// TemplateArgument tags
static const unsigned kDxilTemplateArgTypeTag =
0; // Type template argument, followed by undef of type
static const unsigned kDxilTemplateArgIntegralTag =
1; // Integral template argument, followed by i64 value
static const unsigned kDxilTemplateArgValue =
1; // Position of template arg value (type or int)
// Control flow hint.
static const char kDxilControlFlowHintMDName[];
// Precise attribute.
static const char kDxilPreciseAttributeMDName[];
// NonUniform attribute.
static const char kDxilNonUniformAttributeMDName[];
// Variable debug layout metadata.
static const char kDxilVariableDebugLayoutMDName[];
// Indication of temporary storage metadata.
static const char kDxilTempAllocaMDName[];
// Validator version.
static const char kDxilValidatorVersionMDName[];
// Validator version uses the same constants for fields as kDxilVersion*
// DXR Payload Annotations metadata.
static const char kDxilDxrPayloadAnnotationsMDName[];
// Extended shader property tags.
static const unsigned kDxilShaderFlagsTag = 0;
static const unsigned kDxilGSStateTag = 1;
static const unsigned kDxilDSStateTag = 2;
static const unsigned kDxilHSStateTag = 3;
static const unsigned kDxilNumThreadsTag = 4;
static const unsigned kDxilAutoBindingSpaceTag = 5;
static const unsigned kDxilRayPayloadSizeTag = 6;
static const unsigned kDxilRayAttribSizeTag = 7;
static const unsigned kDxilShaderKindTag = 8;
static const unsigned kDxilMSStateTag = 9;
static const unsigned kDxilASStateTag = 10;
static const unsigned kDxilWaveSizeTag = 11;
static const unsigned kDxilEntryRootSigTag = 12;
// Node Tags ( extension of shader property tags)
static const unsigned kDxilNodeLaunchTypeTag = 13;
static const unsigned kDxilNodeIsProgramEntryTag = 14;
static const unsigned kDxilNodeIdTag = 15;
static const unsigned kDxilNodeLocalRootArgumentsTableIndexTag = 16;
static const unsigned kDxilShareInputOfTag = 17;
static const unsigned kDxilNodeDispatchGridTag = 18;
static const unsigned kDxilNodeMaxRecursionDepthTag = 19;
static const unsigned kDxilNodeInputsTag = 20;
static const unsigned kDxilNodeOutputsTag = 21;
static const unsigned kDxilNodeMaxDispatchGridTag = 22;
static const unsigned kDxilRangedWaveSizeTag = 23;
// Node Input/Output State.
static const unsigned kDxilNodeOutputIDTag = 0;
static const unsigned kDxilNodeIOFlagsTag = 1;
static const unsigned kDxilNodeRecordTypeTag = 2;
static const unsigned kDxilNodeMaxRecordsTag = 3;
static const unsigned kDxilNodeMaxRecordsSharedWithTag = 4;
static const unsigned kDxilNodeOutputArraySizeTag = 5;
static const unsigned kDxilNodeAllowSparseNodesTag = 6;
// Node Record Type
static const unsigned kDxilNodeRecordSizeTag = 0;
static const unsigned kDxilNodeSVDispatchGridTag = 1;
static const unsigned kDxilNodeRecordAlignmentTag = 2;
// GSState.
static const unsigned kDxilGSStateNumFields = 5;
static const unsigned kDxilGSStateInputPrimitive = 0;
static const unsigned kDxilGSStateMaxVertexCount = 1;
static const unsigned kDxilGSStateActiveStreamMask = 2;
static const unsigned kDxilGSStateOutputStreamTopology = 3;
static const unsigned kDxilGSStateGSInstanceCount = 4;
// DSState.
static const unsigned kDxilDSStateNumFields = 2;
static const unsigned kDxilDSStateTessellatorDomain = 0;
static const unsigned kDxilDSStateInputControlPointCount = 1;
// HSState.
static const unsigned kDxilHSStateNumFields = 7;
static const unsigned kDxilHSStatePatchConstantFunction = 0;
static const unsigned kDxilHSStateInputControlPointCount = 1;
static const unsigned kDxilHSStateOutputControlPointCount = 2;
static const unsigned kDxilHSStateTessellatorDomain = 3;
static const unsigned kDxilHSStateTessellatorPartitioning = 4;
static const unsigned kDxilHSStateTessellatorOutputPrimitive = 5;
static const unsigned kDxilHSStateMaxTessellationFactor = 6;
// MSState.
static const unsigned kDxilMSStateNumFields = 5;
static const unsigned kDxilMSStateNumThreads = 0;
static const unsigned kDxilMSStateMaxVertexCount = 1;
static const unsigned kDxilMSStateMaxPrimitiveCount = 2;
static const unsigned kDxilMSStateOutputTopology = 3;
static const unsigned kDxilMSStatePayloadSizeInBytes = 4;
// ASState.
static const unsigned kDxilASStateNumFields = 2;
static const unsigned kDxilASStateNumThreads = 0;
static const unsigned kDxilASStatePayloadSizeInBytes = 1;
public:
/// Use this class to manipulate metadata of DXIL or high-level DX IR specific
/// fields in the record.
class ExtraPropertyHelper {
public:
ExtraPropertyHelper(llvm::Module *pModule);
virtual ~ExtraPropertyHelper() {}
virtual void EmitSRVProperties(const DxilResource &SRV,
std::vector<llvm::Metadata *> &MDVals) = 0;
virtual void LoadSRVProperties(const llvm::MDOperand &MDO,
DxilResource &SRV) = 0;
virtual void EmitUAVProperties(const DxilResource &UAV,
std::vector<llvm::Metadata *> &MDVals) = 0;
virtual void LoadUAVProperties(const llvm::MDOperand &MDO,
DxilResource &UAV) = 0;
virtual void
EmitCBufferProperties(const DxilCBuffer &CB,
std::vector<llvm::Metadata *> &MDVals) = 0;
virtual void LoadCBufferProperties(const llvm::MDOperand &MDO,
DxilCBuffer &CB) = 0;
virtual void
EmitSamplerProperties(const DxilSampler &S,
std::vector<llvm::Metadata *> &MDVals) = 0;
virtual void LoadSamplerProperties(const llvm::MDOperand &MDO,
DxilSampler &S) = 0;
virtual void
EmitSignatureElementProperties(const DxilSignatureElement &SE,
std::vector<llvm::Metadata *> &MDVals) = 0;
virtual void LoadSignatureElementProperties(const llvm::MDOperand &MDO,
DxilSignatureElement &SE) = 0;
protected:
llvm::LLVMContext &m_Ctx;
llvm::Module *m_pModule;
public:
unsigned m_ValMajor, m_ValMinor; // Reported validation version in DXIL
unsigned m_MinValMajor,
m_MinValMinor; // Minimum validation version dictated by shader model
bool m_bExtraMetadata;
};
public:
DxilMDHelper(llvm::Module *pModule, std::unique_ptr<ExtraPropertyHelper> EPH);
~DxilMDHelper();
void SetShaderModel(const ShaderModel *pSM);
const ShaderModel *GetShaderModel() const;
// Dxil version.
void EmitDxilVersion(unsigned Major, unsigned Minor);
void LoadDxilVersion(unsigned &Major, unsigned &Minor);
// Validator version.
void EmitValidatorVersion(unsigned Major, unsigned Minor);
void LoadValidatorVersion(unsigned &Major, unsigned &Minor);
// Shader model.
void EmitDxilShaderModel(const ShaderModel *pSM);
void LoadDxilShaderModel(const ShaderModel *&pSM);
// Intermediate flags
void EmitDxilIntermediateOptions(uint32_t flags);
void LoadDxilIntermediateOptions(uint32_t &flags);
// Entry points.
void EmitDxilEntryPoints(std::vector<llvm::MDNode *> &MDEntries);
void UpdateDxilEntryPoints(std::vector<llvm::MDNode *> &MDEntries);
const llvm::NamedMDNode *GetDxilEntryPoints();
llvm::MDTuple *EmitDxilEntryPointTuple(llvm::Function *pFunc,
const std::string &Name,
llvm::MDTuple *pSignatures,
llvm::MDTuple *pResources,
llvm::MDTuple *pProperties);
void GetDxilEntryPoint(const llvm::MDNode *MDO, llvm::Function *&pFunc,
std::string &Name, const llvm::MDOperand *&pSignatures,
const llvm::MDOperand *&pResources,
const llvm::MDOperand *&pProperties);
// Signatures.
llvm::MDTuple *EmitDxilSignatures(const DxilEntrySignature &EntrySig);
void LoadDxilSignatures(const llvm::MDOperand &MDO,
DxilEntrySignature &EntrySig);
llvm::MDTuple *EmitSignatureMetadata(const DxilSignature &Sig);
void EmitRootSignature(std::vector<uint8_t> &SerializedRootSignature);
void LoadSignatureMetadata(const llvm::MDOperand &MDO, DxilSignature &Sig);
llvm::MDTuple *EmitSignatureElement(const DxilSignatureElement &SE);
void LoadSignatureElement(const llvm::MDOperand &MDO,
DxilSignatureElement &SE);
void LoadRootSignature(std::vector<uint8_t> &SerializedRootSignature);
// Resources.
llvm::MDTuple *EmitDxilResourceTuple(llvm::MDTuple *pSRVs,
llvm::MDTuple *pUAVs,
llvm::MDTuple *pCBuffers,
llvm::MDTuple *pSamplers);
void EmitDxilResources(llvm::MDTuple *pDxilResourceTuple);
void UpdateDxilResources(llvm::MDTuple *pDxilResourceTuple);
void GetDxilResources(const llvm::MDOperand &MDO, 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 LoadDxilResourceBase(const llvm::MDOperand &MDO, DxilResourceBase &R);
llvm::MDTuple *EmitDxilSRV(const DxilResource &SRV);
void LoadDxilSRV(const llvm::MDOperand &MDO, DxilResource &SRV);
llvm::MDTuple *EmitDxilUAV(const DxilResource &UAV);
void LoadDxilUAV(const llvm::MDOperand &MDO, DxilResource &UAV);
llvm::MDTuple *EmitDxilCBuffer(const DxilCBuffer &CB);
void LoadDxilCBuffer(const llvm::MDOperand &MDO, DxilCBuffer &CB);
llvm::MDTuple *EmitDxilSampler(const DxilSampler &S);
void LoadDxilSampler(const llvm::MDOperand &MDO, DxilSampler &S);
const llvm::MDOperand &GetResourceClass(llvm::MDNode *MD,
DXIL::ResourceClass &RC);
// Type system.
void EmitDxilTypeSystem(DxilTypeSystem &TypeSystem,
std::vector<llvm::GlobalVariable *> &LLVMUsed);
void LoadDxilTypeSystemNode(const llvm::MDTuple &MDT,
DxilTypeSystem &TypeSystem);
void LoadDxilTypeSystem(DxilTypeSystem &TypeSystem);
llvm::Metadata *EmitDxilStructAnnotation(const DxilStructAnnotation &SA);
void LoadDxilStructAnnotation(const llvm::MDOperand &MDO,
DxilStructAnnotation &SA);
llvm::Metadata *EmitDxilFieldAnnotation(const DxilFieldAnnotation &FA);
void LoadDxilFieldAnnotation(const llvm::MDOperand &MDO,
DxilFieldAnnotation &FA);
llvm::Metadata *EmitDxilFunctionAnnotation(const DxilFunctionAnnotation &FA);
void LoadDxilFunctionAnnotation(const llvm::MDOperand &MDO,
DxilFunctionAnnotation &FA);
llvm::Metadata *EmitDxilParamAnnotation(const DxilParameterAnnotation &PA);
void LoadDxilParamAnnotation(const llvm::MDOperand &MDO,
DxilParameterAnnotation &PA);
llvm::Metadata *EmitDxilParamAnnotations(const DxilFunctionAnnotation &FA);
void LoadDxilParamAnnotations(const llvm::MDOperand &MDO,
DxilFunctionAnnotation &FA);
llvm::Metadata *
EmitDxilTemplateArgAnnotation(const DxilTemplateArgAnnotation &annotation);
void LoadDxilTemplateArgAnnotation(const llvm::MDOperand &MDO,
DxilTemplateArgAnnotation &annotation);
// DXR Payload Annotations
void EmitDxrPayloadAnnotations(DxilTypeSystem &TypeSystem);
llvm::Metadata *
EmitDxrPayloadStructAnnotation(const DxilPayloadAnnotation &SA);
llvm::Metadata *
EmitDxrPayloadFieldAnnotation(const DxilPayloadFieldAnnotation &FA,
llvm::Type *fieldType);
void LoadDxrPayloadAnnotationNode(const llvm::MDTuple &MDT,
DxilTypeSystem &TypeSystem);
void LoadDxrPayloadAnnotations(DxilTypeSystem &TypeSystem);
void LoadDxrPayloadFieldAnnoations(const llvm::MDOperand &MDO,
DxilPayloadAnnotation &SA);
void LoadDxrPayloadFieldAnnoation(const llvm::MDOperand &MDO,
DxilPayloadFieldAnnotation &FA);
void LoadDxrPayloadAccessQualifiers(const llvm::MDOperand &MDO,
DxilPayloadFieldAnnotation &FA);
// Function props.
void SerializeNodeProps(llvm::SmallVectorImpl<llvm::Metadata *> &MDVals,
unsigned &valIdx,
const hlsl::DxilFunctionProps *props);
void DeserializeNodeProps(const llvm::MDTuple *pProps, unsigned &idx,
hlsl::DxilFunctionProps *props);
llvm::MDTuple *EmitDxilFunctionProps(const hlsl::DxilFunctionProps *props,
const llvm::Function *F);
const llvm::Function *LoadDxilFunctionProps(const llvm::MDTuple *pProps,
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.
void EmitDxilViewIdState(std::vector<unsigned> &SerializedState);
void LoadDxilViewIdState(std::vector<unsigned> &SerializedState);
// Control flow hints.
static llvm::MDNode *
EmitControlFlowHints(llvm::LLVMContext &Ctx,
std::vector<DXIL::ControlFlowHint> &hints);
static unsigned GetControlFlowHintMask(const llvm::Instruction *I);
static bool HasControlFlowHintToPreventFlatten(const llvm::Instruction *I);
// Subobjects
void EmitSubobjects(const DxilSubobjects &Subobjects);
void LoadSubobjects(DxilSubobjects &Subobjects);
llvm::Metadata *EmitSubobject(const DxilSubobject &obj);
void LoadSubobject(const llvm::MDNode &MDO, DxilSubobjects &Subobjects);
// Extra metadata present
bool HasExtraMetadata() { return m_bExtraMetadata; }
// Instruction Counters
void EmitDxilCounters(const DxilCounters &counters);
void LoadDxilCounters(DxilCounters &counters) const;
// Shader specific.
private:
llvm::MDTuple *
EmitDxilGSState(DXIL::InputPrimitive Primitive, unsigned MaxVertexCount,
unsigned ActiveStreamMask,
DXIL::PrimitiveTopology StreamPrimitiveTopology,
unsigned GSInstanceCount);
void LoadDxilGSState(const llvm::MDOperand &MDO,
DXIL::InputPrimitive &Primitive,
unsigned &MaxVertexCount, unsigned &ActiveStreamMask,
DXIL::PrimitiveTopology &StreamPrimitiveTopology,
unsigned &GSInstanceCount);
llvm::MDTuple *EmitDxilDSState(DXIL::TessellatorDomain Domain,
unsigned InputControlPointCount);
void LoadDxilDSState(const llvm::MDOperand &MDO,
DXIL::TessellatorDomain &Domain,
unsigned &InputControlPointCount);
llvm::MDTuple *EmitDxilHSState(
llvm::Function *pPatchConstantFunction, unsigned InputControlPointCount,
unsigned OutputControlPointCount, DXIL::TessellatorDomain TessDomain,
DXIL::TessellatorPartitioning TessPartitioning,
DXIL::TessellatorOutputPrimitive TessOutputPrimitive,
float MaxTessFactor);
void LoadDxilHSState(const llvm::MDOperand &MDO,
llvm::Function *&pPatchConstantFunction,
unsigned &InputControlPointCount,
unsigned &OutputControlPointCount,
DXIL::TessellatorDomain &TessDomain,
DXIL::TessellatorPartitioning &TessPartitioning,
DXIL::TessellatorOutputPrimitive &TessOutputPrimitive,
float &MaxTessFactor);
llvm::MDTuple *EmitDxilMSState(const unsigned *NumThreads,
unsigned MaxVertexCount,
unsigned MaxPrimitiveCount,
DXIL::MeshOutputTopology OutputTopology,
unsigned payloadSizeInBytes);
void LoadDxilMSState(const llvm::MDOperand &MDO, unsigned *NumThreads,
unsigned &MaxVertexCount, unsigned &MaxPrimitiveCount,
DXIL::MeshOutputTopology &OutputTopology,
unsigned &payloadSizeInBytes);
llvm::MDTuple *EmitDxilASState(const unsigned *NumThreads,
unsigned payloadSizeInBytes);
void LoadDxilASState(const llvm::MDOperand &MDO, unsigned *NumThreads,
unsigned &payloadSizeInBytes);
llvm::MDTuple *EmitDxilNodeIOState(const NodeIOProperties &Node);
llvm::MDTuple *EmitDxilNodeRecordType(const NodeRecordType &RecordType);
hlsl::NodeIOProperties LoadDxilNodeIOState(const llvm::MDOperand &MDO);
hlsl::NodeRecordType LoadDxilNodeRecordType(const llvm::MDOperand &MDO);
void EmitDxilNodeState(std::vector<llvm::Metadata *> &MDVals,
const DxilFunctionProps &props);
void AddCounterIfNonZero(uint32_t value, llvm::StringRef name,
std::vector<llvm::Metadata *> &MDVals);
void LoadCounterMD(const llvm::MDOperand &MDName,
const llvm::MDOperand &MDValue,
DxilCounters &counters) const;
public:
// Utility functions.
static bool IsKnownNamedMetaData(const llvm::NamedMDNode &Node);
static bool IsKnownMetadataID(llvm::LLVMContext &Ctx, unsigned ID);
static void GetKnownMetadataIDs(llvm::LLVMContext &Ctx,
llvm::SmallVectorImpl<unsigned> *pIDs);
static void combineDxilMetadata(llvm::Instruction *K,
const llvm::Instruction *J);
static llvm::ConstantAsMetadata *Int32ToConstMD(int32_t v,
llvm::LLVMContext &Ctx);
llvm::ConstantAsMetadata *Int32ToConstMD(int32_t v);
static llvm::ConstantAsMetadata *Uint32ToConstMD(unsigned v,
llvm::LLVMContext &Ctx);
llvm::ConstantAsMetadata *Uint32ToConstMD(unsigned v);
static llvm::ConstantAsMetadata *Uint64ToConstMD(uint64_t v,
llvm::LLVMContext &Ctx);
llvm::ConstantAsMetadata *Uint64ToConstMD(uint64_t v);
llvm::ConstantAsMetadata *Int8ToConstMD(int8_t v);
llvm::ConstantAsMetadata *Uint8ToConstMD(uint8_t v);
static llvm::ConstantAsMetadata *BoolToConstMD(bool v,
llvm::LLVMContext &Ctx);
llvm::ConstantAsMetadata *BoolToConstMD(bool v);
llvm::ConstantAsMetadata *FloatToConstMD(float v);
static int32_t ConstMDToInt32(const llvm::MDOperand &MDO);
static unsigned ConstMDToUint32(const llvm::MDOperand &MDO);
static uint64_t ConstMDToUint64(const llvm::MDOperand &MDO);
static int8_t ConstMDToInt8(const llvm::MDOperand &MDO);
static uint8_t ConstMDToUint8(const llvm::MDOperand &MDO);
static bool ConstMDToBool(const llvm::MDOperand &MDO);
static float ConstMDToFloat(const llvm::MDOperand &MDO);
static std::string StringMDToString(const llvm::MDOperand &MDO);
static llvm::StringRef StringMDToStringRef(const llvm::MDOperand &MDO);
static llvm::Value *ValueMDToValue(const llvm::MDOperand &MDO);
llvm::MDTuple *Uint32VectorToConstMDTuple(const std::vector<unsigned> &Vec);
void ConstMDTupleToUint32Vector(llvm::MDTuple *pTupleMD,
std::vector<unsigned> &Vec);
static bool IsMarkedPrecise(const llvm::Instruction *inst);
static void MarkPrecise(llvm::Instruction *inst);
static bool IsMarkedNonUniform(const llvm::Instruction *inst);
static void MarkNonUniform(llvm::Instruction *inst);
static bool GetVariableDebugLayout(llvm::DbgDeclareInst *inst,
unsigned &StartOffsetInBits,
std::vector<DxilDIArrayDim> &ArrayDims);
static void
SetVariableDebugLayout(llvm::DbgDeclareInst *inst, unsigned StartOffsetInBits,
const std::vector<DxilDIArrayDim> &ArrayDims);
static void
CopyMetadata(llvm::Instruction &I, llvm::Instruction &SrcInst,
llvm::ArrayRef<unsigned> WL = llvm::ArrayRef<unsigned>());
private:
llvm::LLVMContext &m_Ctx;
llvm::Module *m_pModule;
const ShaderModel *m_pSM;
std::unique_ptr<ExtraPropertyHelper> m_ExtraPropertyHelper;
unsigned m_ValMajor, m_ValMinor; // Reported validation version in DXIL
unsigned m_MinValMajor,
m_MinValMinor; // Minimum validation version dictated by shader model
// Non-fatal if extra metadata is found, but will fail validation.
// This is how metadata can be exteneded.
bool m_bExtraMetadata;
};
/// Use this class to manipulate metadata of extra metadata record properties
/// that are specific to DXIL.
class DxilExtraPropertyHelper : public DxilMDHelper::ExtraPropertyHelper {
public:
DxilExtraPropertyHelper(llvm::Module *pModule);
virtual ~DxilExtraPropertyHelper() {}
virtual void EmitSRVProperties(const DxilResource &SRV,
std::vector<llvm::Metadata *> &MDVals);
virtual void LoadSRVProperties(const llvm::MDOperand &MDO, DxilResource &SRV);
virtual void EmitUAVProperties(const DxilResource &UAV,
std::vector<llvm::Metadata *> &MDVals);
virtual void LoadUAVProperties(const llvm::MDOperand &MDO, DxilResource &UAV);
virtual void EmitCBufferProperties(const DxilCBuffer &CB,
std::vector<llvm::Metadata *> &MDVals);
virtual void LoadCBufferProperties(const llvm::MDOperand &MDO,
DxilCBuffer &CB);
virtual void EmitSamplerProperties(const DxilSampler &S,
std::vector<llvm::Metadata *> &MDVals);
virtual void LoadSamplerProperties(const llvm::MDOperand &MDO,
DxilSampler &S);
virtual void
EmitSignatureElementProperties(const DxilSignatureElement &SE,
std::vector<llvm::Metadata *> &MDVals);
virtual void LoadSignatureElementProperties(const llvm::MDOperand &MDO,
DxilSignatureElement &SE);
};
} // namespace hlsl