Copy ViewID state to PSV data and select PSV version based on validator (#291)

* Make validator version a first-class citizen of DxilModule

* Add validator version checks to DxilContainerAssembler
- eliminates need to check validator version in dxcompilerobj.cpp

* Copy dynamic index mask and ViewID state to PSV data
- Make const version of DxilViewIDState::GetSerialized() that just returns serialized state
This commit is contained in:
Tex Riddell 2017-05-12 14:27:22 -07:00 коммит произвёл GitHub
Родитель 35f727ac33
Коммит c95244404a
19 изменённых файлов: 260 добавлений и 69 удалений

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

@ -61,7 +61,9 @@ public:
const InputsContributingToOutputType &getPCInputsContributingToOutputs() const;
void Compute();
void Serialize();
const std::vector<unsigned> &GetSerialized();
const std::vector<unsigned> &GetSerialized() const; // returns previously serialized data
void Deserialize(const unsigned *pData, unsigned DataSize);
void PrintSets(llvm::raw_ostream &OS);

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

@ -423,7 +423,7 @@ public:
DxilPartWriter *NewProgramSignatureWriter(const DxilModule &M, DXIL::SignatureKind Kind);
DxilPartWriter *NewRootSignatureWriter(const RootSignatureHandle &S);
DxilPartWriter *NewFeatureInfoWriter(const DxilModule &M);
DxilPartWriter *NewPSVWriter(const DxilModule &M);
DxilPartWriter *NewPSVWriter(const DxilModule &M, uint32_t PSVVersion = 0);
class DxilContainerWriter : public DxilPartWriter {
public:
@ -434,7 +434,7 @@ public:
DxilContainerWriter *NewDxilContainerWriter();
enum class SerializeDxilFlags {
enum class SerializeDxilFlags : uint32_t {
None = 0, // No flags defined.
IncludeDebugInfoPart = 1, // Include the debug info part in the container.
IncludeDebugNamePart = 2, // Include the debug name part in the container.
@ -444,9 +444,16 @@ inline SerializeDxilFlags& operator |=(SerializeDxilFlags& l, const SerializeDxi
l = static_cast<SerializeDxilFlags>(static_cast<int>(l) | static_cast<int>(r));
return l;
}
inline SerializeDxilFlags& operator &=(SerializeDxilFlags& l, const SerializeDxilFlags& r) {
l = static_cast<SerializeDxilFlags>(static_cast<int>(l) & static_cast<int>(r));
return l;
}
inline int operator&(SerializeDxilFlags l, SerializeDxilFlags r) {
return static_cast<int>(l) & static_cast<int>(r);
}
inline SerializeDxilFlags operator~(SerializeDxilFlags l) {
return static_cast<SerializeDxilFlags>(~static_cast<uint32_t>(l));
}
void SerializeDxilContainerForModule(hlsl::DxilModule *pModule,
AbstractMemoryStream *pModuleBitcode,

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

@ -188,6 +188,7 @@ public:
// Validator version.
static const char kDxilValidatorVersionMDName[];
// Validator version uses the same constants for fields as kDxilVersion*
// Extended shader property tags.
static const unsigned kDxilShaderFlagsTag = 0;
@ -257,6 +258,10 @@ public:
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);

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

@ -51,6 +51,14 @@ public:
void SetShaderModel(const ShaderModel *pSM);
const ShaderModel *GetShaderModel() const;
void GetDxilVersion(unsigned &DxilMajor, unsigned &DxilMinor) const;
void SetValidatorVersion(unsigned ValMajor, unsigned ValMinor);
bool UpgradeValidatorVersion(unsigned ValMajor, unsigned ValMinor);
void GetValidatorVersion(unsigned &ValMajor, unsigned &ValMinor) const;
// Return true on success, requires valid shader model and CollectShaderFlags to have been set
bool GetMinValidatorVersion(unsigned &ValMajor, unsigned &ValMinor) const;
// Update validator version to minimum if higher than current (ex: after CollectShaderFlags)
bool UpgradeToMinValidatorVersion();
// Entry functions.
llvm::Function *GetEntryFunction();
@ -106,6 +114,8 @@ public:
// Remove Root Signature from module metadata
void StripRootSignatureFromMetadata();
// Update validator version metadata to current setting
void UpdateValidatorVersionMetadata();
// DXIL type system.
DxilTypeSystem &GetTypeSystem();
@ -116,6 +126,7 @@ public:
// ViewId state.
DxilViewIdState &GetViewIdState();
const DxilViewIdState &GetViewIdState() const;
// DXIL metadata manipulation.
/// Serialize DXIL in-memory form to metadata form.
@ -288,6 +299,8 @@ private:
const ShaderModel *m_pSM;
unsigned m_DxilMajor;
unsigned m_DxilMinor;
unsigned m_ValMajor;
unsigned m_ValMinor;
std::unique_ptr<OP> m_pOP;
size_t m_pUnused;

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

@ -449,10 +449,18 @@ public:
if(!(pSize)) return false;
if (initInfo.PSVVersion > 1) return false;
// Versioned structure sizes
m_uPSVRuntimeInfoSize = sizeof(PSVRuntimeInfo0);
m_uPSVResourceBindInfoSize = sizeof(PSVResourceBindInfo0);
m_uPSVSignatureElementSize = sizeof(PSVSignatureElement0);
if (initInfo.PSVVersion > 0) {
m_uPSVRuntimeInfoSize = sizeof(PSVRuntimeInfo1);
}
// PSVVersion 0
uint32_t size = sizeof(PSVRuntimeInfo1) + sizeof(uint32_t) * 2;
uint32_t size = m_uPSVRuntimeInfoSize + sizeof(uint32_t) * 2;
if (initInfo.ResourceCount) {
size += sizeof(uint32_t) + (sizeof(PSVResourceBindInfo0) * initInfo.ResourceCount);
size += sizeof(uint32_t) + (m_uPSVResourceBindInfoSize * initInfo.ResourceCount);
}
// PSVVersion 1
@ -462,9 +470,9 @@ public:
if (initInfo.SigInputElements || initInfo.SigOutputElements || initInfo.SigPatchConstantElements) {
size += sizeof(uint32_t); // PSVSignatureElement_size
}
size += sizeof(PSVSignatureElement0) * initInfo.SigInputElements;
size += sizeof(PSVSignatureElement0) * initInfo.SigOutputElements;
size += sizeof(PSVSignatureElement0) * initInfo.SigPatchConstantElements;
size += m_uPSVSignatureElementSize * initInfo.SigInputElements;
size += m_uPSVSignatureElementSize * initInfo.SigOutputElements;
size += m_uPSVSignatureElementSize * initInfo.SigPatchConstantElements;
if (initInfo.UsesViewID) {
size += sizeof(uint32_t) * PSVComputeMaskDwordsFromVectors(initInfo.SigOutputVectors);
@ -494,10 +502,6 @@ public:
// PSVVersion 0
memset(pBuffer, 0, size);
m_uPSVRuntimeInfoSize = sizeof(PSVRuntimeInfo0);
if (initInfo.PSVVersion > 0) {
m_uPSVRuntimeInfoSize = sizeof(PSVRuntimeInfo1);
}
uint8_t* pCurBits = (uint8_t*)pBuffer;
*(uint32_t*)pCurBits = m_uPSVRuntimeInfoSize;
pCurBits += sizeof(uint32_t);
@ -505,14 +509,13 @@ public:
if (initInfo.PSVVersion > 0) {
m_pPSVRuntimeInfo1 = (PSVRuntimeInfo1*)pCurBits;
}
pCurBits += sizeof(PSVRuntimeInfo1);
pCurBits += m_uPSVRuntimeInfoSize;
// Set resource info:
m_uResourceCount = initInfo.ResourceCount;
*(uint32_t*)pCurBits = m_uResourceCount;
pCurBits += sizeof(uint32_t);
if (m_uResourceCount > 0) {
m_uPSVResourceBindInfoSize = sizeof(PSVResourceBindInfo0);
*(uint32_t*)pCurBits = m_uPSVResourceBindInfoSize;
pCurBits += sizeof(uint32_t);
m_pPSVResourceBindInfo = pCurBits;
@ -547,7 +550,6 @@ public:
// Dxil Signature Elements
if (m_pPSVRuntimeInfo1->SigInputElements || m_pPSVRuntimeInfo1->SigOutputElements || m_pPSVRuntimeInfo1->SigPatchConstantElements) {
m_uPSVSignatureElementSize = sizeof(PSVSignatureElement0);
*(uint32_t*)pCurBits = m_uPSVSignatureElementSize;
pCurBits += sizeof(uint32_t);
}

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

@ -44,7 +44,7 @@ public:
unsigned GetMajor() const { return m_Major; }
unsigned GetMinor() const { return m_Minor; }
void GetDxilVersion(unsigned &DxilMajor, unsigned &DxilMinor) const;
uint32_t GetPSVVersion() const;
void GetMinValidatorVersion(unsigned &ValMajor, unsigned &ValMinor) const;
bool IsSM50Plus() const { return m_Major >= 5; }
bool IsSM51Plus() const { return m_Major > 5 || (m_Major == 5 && m_Minor >= 1); }
bool IsSM60Plus() const { return m_Major >= 6; }

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

@ -114,6 +114,8 @@ public:
OP *GetOP() const;
void SetShaderModel(const ShaderModel *pSM);
const ShaderModel *GetShaderModel() const;
void SetValidatorVersion(unsigned ValMajor, unsigned ValMinor);
void GetValidatorVersion(unsigned &ValMajor, unsigned &ValMinor) const;
// HLOptions
void SetHLOptions(HLOptions &opts);
@ -299,6 +301,8 @@ private:
const ShaderModel *m_pSM;
unsigned m_DxilMajor;
unsigned m_DxilMinor;
unsigned m_ValMajor;
unsigned m_ValMinor;
HLOptions m_Options;
std::unique_ptr<OP> m_pOP;
size_t m_pUnused;

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

@ -657,9 +657,9 @@ static unsigned RoundUpToUINT(unsigned x) {
return (x + 31)/32;
}
const vector<unsigned> &DxilViewIdState::GetSerialized() {
void DxilViewIdState::Serialize() {
if (!m_SerializedState.empty())
return m_SerializedState;
return;
const ShaderModel *pSM = m_pModule->GetShaderModel();
unsigned NumOutUINTs = RoundUpToUINT(m_NumOutputSigScalars);
@ -689,7 +689,13 @@ const vector<unsigned> &DxilViewIdState::GetSerialized() {
m_OutputsDependentOnViewId, m_PCInputsContributingToOutputs, pData);
}
DXASSERT_NOMSG(pData == (&m_SerializedState[0] + Size));
}
const vector<unsigned> &DxilViewIdState::GetSerialized() {
if (m_SerializedState.empty())
Serialize();
return m_SerializedState;
}
const vector<unsigned> &DxilViewIdState::GetSerialized() const {
return m_SerializedState;
}
@ -732,6 +738,8 @@ void DxilViewIdState::Serialize1(unsigned NumInputs, unsigned NumOutputs,
void DxilViewIdState::Deserialize(const unsigned *pData, unsigned DataSize) {
Clear();
m_SerializedState.resize(DataSize);
memcpy(m_SerializedState.data(), pData, DataSize * 4);
const ShaderModel *pSM = m_pModule->GetShaderModel();
unsigned ConsumedUINTs;

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

@ -349,8 +349,8 @@ private:
if (SE.GetKind() == DXIL::SemanticKind::Arbitrary && strlen(SE.GetName()) > 0) {
E.SemanticName = (uint32_t)m_StringBuffer.size();
StringRef Name(SE.GetName());
m_StringBuffer.append('\0', Name.size()+1);
memcpy(m_StringBuffer.data(), Name.data(), Name.size());
m_StringBuffer.append(Name.size()+1, '\0');
memcpy(m_StringBuffer.data() + E.SemanticName, Name.data(), Name.size());
} else {
// m_StringBuffer always starts with '\0' so offset 0 is empty string:
E.SemanticName = 0;
@ -374,7 +374,7 @@ private:
}
if (!match) {
E.SemanticIndexes = m_SemanticIndexBuffer.size();
for (uint32_t row = 0; row < E.SemanticIndexes; row++) {
for (uint32_t row = 0; row < SemIdx.size(); row++) {
m_SemanticIndexBuffer.push_back((uint32_t)SemIdx[row]);
}
}
@ -395,15 +395,38 @@ private:
E.DynamicMaskAndStream = (uint8_t)((SE.GetOutputStream() & 0x3) << 4);
// TODO: Fill Dynamic Index Mask in!
//DXASSERT_NOMSG((SE.GetDynamicIndexMask() & ~0xF) == 0);
//E.DynamicMaskAndStream |= (SE.GetDynamicIndexMask()) & 0xF;
E.DynamicMaskAndStream |= (SE.GetDynIdxCompMask()) & 0xF;
}
const uint32_t *CopyViewIDState(const uint32_t *pSrc, const PSVComponentMasks &ViewIDMask, const PSVDependencyTable &IOTable) {
uint32_t InputScalars = *(pSrc++);
uint32_t OutputScalars = *(pSrc++);
unsigned MaskDwords = PSVComputeMaskDwordsFromVectors(PSVALIGN4(OutputScalars) / 4);
if (ViewIDMask.Masks) {
DXASSERT_NOMSG(!IOTable.Table || ViewIDMask.NumVectors == IOTable.OutputVectors);
memcpy(ViewIDMask.Masks, pSrc, 4 * MaskDwords);
}
pSrc += MaskDwords;
if (IOTable.Table && IOTable.InputVectors && IOTable.OutputVectors) {
DXASSERT_NOMSG((InputScalars <= IOTable.InputVectors * 4) && (IOTable.InputVectors * 4 - InputScalars < 4));
DXASSERT_NOMSG((OutputScalars <= IOTable.OutputVectors * 4) && (IOTable.OutputVectors * 4 - OutputScalars < 4));
memcpy(IOTable.Table, pSrc, 4 * MaskDwords * InputScalars);
}
pSrc += MaskDwords * InputScalars;
return pSrc;
}
public:
DxilPSVWriter(const DxilModule &module)
DxilPSVWriter(const DxilModule &module, uint32_t PSVVersion = 0)
: m_Module(module),
m_PSVInitInfo(1)//module.GetShaderModel()->GetPSVVersion())
m_PSVInitInfo(PSVVersion)
{
unsigned ValMajor, ValMinor;
m_Module.GetValidatorVersion(ValMajor, ValMinor);
// Allow PSVVersion to be upgraded
if (m_PSVInitInfo.PSVVersion < 1 && (ValMajor > 1 || (ValMajor == 1 && ValMinor >= 1)))
m_PSVInitInfo.PSVVersion = 1;
UINT uCBuffers = m_Module.GetCBuffers().size();
UINT uSamplers = m_Module.GetSamplers().size();
UINT uSRVs = m_Module.GetSRVs().size();
@ -623,7 +646,18 @@ public:
memcpy(pPatchConstantElement, &m_SigPatchConstantElements[i], sizeof(PSVSignatureElement0));
}
// TODO: Write ViewID Output masks and Input to Output dependency tables
// Gather ViewID dependency information
auto &viewState = m_Module.GetViewIdState().GetSerialized();
if (!viewState.empty()) {
const uint32_t *pSrc = viewState.data();
pSrc = CopyViewIDState(pSrc, m_PSV.GetViewIDOutputMasks(), m_PSV.GetInputToOutputTable());
if (m_Module.GetShaderModel()->IsHS()) {
pSrc = CopyViewIDState(pSrc, m_PSV.GetViewIDPCOutputMasks(), m_PSV.GetInputToPCOutputTable());
} else if (m_Module.GetShaderModel()->IsDS()) {
pSrc = CopyViewIDState(pSrc, PSVComponentMasks(), m_PSV.GetPCInputToOutputTable());
}
DXASSERT_NOMSG(viewState.data() + viewState.size() == pSrc);
}
}
ULONG cbWritten;
@ -632,8 +666,8 @@ public:
}
};
DxilPartWriter *hlsl::NewPSVWriter(const DxilModule &M) {
return new DxilPSVWriter(M);
DxilPartWriter *hlsl::NewPSVWriter(const DxilModule &M, uint32_t PSVVersion) {
return new DxilPSVWriter(M, PSVVersion);
}
class DxilContainerWriter_impl : public DxilContainerWriter {
@ -745,6 +779,11 @@ void hlsl::SerializeDxilContainerForModule(DxilModule *pModule,
DXASSERT_NOMSG(pModuleBitcode != nullptr);
DXASSERT_NOMSG(pFinalStream != nullptr);
unsigned ValMajor, ValMinor;
pModule->GetValidatorVersion(ValMajor, ValMinor);
if (ValMajor == 1 && ValMinor == 0)
Flags &= ~SerializeDxilFlags::IncludeDebugNamePart;
DxilProgramSignatureWriter inputSigWriter(pModule->GetInputSignature(),
pModule->GetTessellatorDomain(),
/*IsInput*/ true);

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

@ -105,6 +105,9 @@ void InitResource(const DxilResource *pSource, DxilResource *pDest) {
void InitDxilModuleFromHLModule(HLModule &H, DxilModule &M, bool HasDebugInfo) {
// Subsystems.
unsigned ValMajor, ValMinor;
H.GetValidatorVersion(ValMajor, ValMinor);
M.SetValidatorVersion(ValMajor, ValMinor);
M.SetShaderModel(H.GetShaderModel());
// Entry function.
@ -231,6 +234,9 @@ void InitDxilModuleFromHLModule(HLModule &H, DxilModule &M, bool HasDebugInfo) {
M.ResetOP(H.ReleaseOP());
// Keep llvm used.
M.EmitLLVMUsed();
// Update Validator Version
M.UpgradeToMinValidatorVersion();
}
class DxilGenerationPass : public ModulePass {
@ -2996,6 +3002,8 @@ public:
}
DM.CollectShaderFlags(); // Update flags to reflect any changes.
// Update Validator Version
DM.UpgradeToMinValidatorVersion();
DM.EmitDxilMetadata();
return true;
}

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

@ -108,6 +108,44 @@ void DxilMDHelper::LoadDxilVersion(unsigned &Major, unsigned &Minor) {
Minor = ConstMDToUint32(pVersionMD->getOperand(kDxilVersionMinorIdx));
}
//
// Validator version.
//
void DxilMDHelper::EmitValidatorVersion(unsigned Major, unsigned Minor) {
NamedMDNode *pDxilValidatorVersionMD = m_pModule->getNamedMetadata(kDxilValidatorVersionMDName);
// Allow re-writing the validator version, since this can be changed at later points.
if (pDxilValidatorVersionMD)
m_pModule->eraseNamedMetadata(pDxilValidatorVersionMD);
pDxilValidatorVersionMD = m_pModule->getOrInsertNamedMetadata(kDxilValidatorVersionMDName);
Metadata *MDVals[kDxilVersionNumFields];
MDVals[kDxilVersionMajorIdx] = Uint32ToConstMD(Major);
MDVals[kDxilVersionMinorIdx] = Uint32ToConstMD(Minor);
pDxilValidatorVersionMD->addOperand(MDNode::get(m_Ctx, MDVals));
}
void DxilMDHelper::LoadValidatorVersion(unsigned &Major, unsigned &Minor) {
NamedMDNode *pDxilValidatorVersionMD = m_pModule->getNamedMetadata(kDxilValidatorVersionMDName);
if (pDxilValidatorVersionMD == nullptr) {
// If no validator version metadata, assume 1.0
Major = 1;
Minor = 0;
return;
}
IFTBOOL(pDxilValidatorVersionMD->getNumOperands() == 1, DXC_E_INCORRECT_DXIL_METADATA);
MDNode *pVersionMD = pDxilValidatorVersionMD->getOperand(0);
IFTBOOL(pVersionMD->getNumOperands() == kDxilVersionNumFields, DXC_E_INCORRECT_DXIL_METADATA);
Major = ConstMDToUint32(pVersionMD->getOperand(kDxilVersionMajorIdx));
Minor = ConstMDToUint32(pVersionMD->getOperand(kDxilVersionMinorIdx));
}
//
// DXIL shader model.
//

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

@ -68,6 +68,8 @@ DxilModule::DxilModule(Module *pModule)
, m_pSM(nullptr)
, m_DxilMajor(DXIL::kDxilMajor)
, m_DxilMinor(DXIL::kDxilMinor)
, m_ValMajor(1)
, m_ValMinor(0)
, m_InputPrimitive(DXIL::InputPrimitive::Undefined)
, m_MaxVertexCount(0)
, m_StreamPrimitiveTopology(DXIL::PrimitiveTopology::Undefined)
@ -149,6 +151,42 @@ void DxilModule::GetDxilVersion(unsigned &DxilMajor, unsigned &DxilMinor) const
DxilMinor = m_DxilMinor;
}
void DxilModule::SetValidatorVersion(unsigned ValMajor, unsigned ValMinor) {
m_ValMajor = ValMajor;
m_ValMinor = ValMinor;
}
bool DxilModule::UpgradeValidatorVersion(unsigned ValMajor, unsigned ValMinor) {
if (ValMajor > m_ValMajor || (ValMajor == m_ValMajor && ValMinor > m_ValMinor)) {
// Module requires higher validator version than previously set
SetValidatorVersion(ValMajor, ValMinor);
return true;
}
return false;
}
void DxilModule::GetValidatorVersion(unsigned &ValMajor, unsigned &ValMinor) const {
ValMajor = m_ValMajor;
ValMinor = m_ValMinor;
}
bool DxilModule::GetMinValidatorVersion(unsigned &ValMajor, unsigned &ValMinor) const {
if (!m_pSM)
return false;
m_pSM->GetMinValidatorVersion(ValMajor, ValMinor);
if (ValMajor == 1 && ValMinor == 0 && (m_ShaderFlags.GetFeatureInfo() & hlsl::ShaderFeatureInfo_ViewID))
ValMinor = 1;
return true;
}
bool DxilModule::UpgradeToMinValidatorVersion() {
unsigned ValMajor = 1, ValMinor = 0;
if (GetMinValidatorVersion(ValMajor, ValMinor)) {
return UpgradeValidatorVersion(ValMajor, ValMinor);
}
return false;
}
Function *DxilModule::GetEntryFunction() {
return m_pEntryFunc;
}
@ -873,6 +911,10 @@ void DxilModule::StripRootSignatureFromMetadata() {
}
}
void DxilModule::UpdateValidatorVersionMetadata() {
m_pMDHelper->EmitValidatorVersion(m_ValMajor, m_ValMinor);
}
void DxilModule::ResetInputSignature(DxilSignature *pValue) {
m_InputSignature.reset(pValue);
}
@ -896,6 +938,9 @@ DxilTypeSystem &DxilModule::GetTypeSystem() {
DxilViewIdState &DxilModule::GetViewIdState() {
return *m_pViewIdState;
}
const DxilViewIdState &DxilModule::GetViewIdState() const {
return *m_pViewIdState;
}
void DxilModule::ResetTypeSystem(DxilTypeSystem *pValue) {
m_pTypeSystem.reset(pValue);
@ -947,6 +992,7 @@ vector<GlobalVariable* > &DxilModule::GetLLVMUsed() {
// DXIL metadata serialization/deserialization.
void DxilModule::EmitDxilMetadata() {
m_pMDHelper->EmitDxilVersion(m_DxilMajor, m_DxilMinor);
m_pMDHelper->EmitValidatorVersion(m_ValMajor, m_ValMinor);
m_pMDHelper->EmitDxilShaderModel(m_pSM);
MDTuple *pMDSignatures = m_pMDHelper->EmitDxilSignatures(*m_InputSignature,
@ -955,7 +1001,8 @@ void DxilModule::EmitDxilMetadata() {
MDTuple *pMDResources = EmitDxilResources();
MDTuple *pMDProperties = EmitDxilShaderProperties();
m_pMDHelper->EmitDxilTypeSystem(GetTypeSystem(), m_LLVMUsed);
if (!m_pSM->IsCS()) {
if (!m_pSM->IsCS() &&
(m_ValMajor > 1 || (m_ValMajor == 1 && m_ValMinor >= 1))) {
m_pMDHelper->EmitDxilViewIdState(GetViewIdState());
}
EmitLLVMUsed();
@ -975,6 +1022,7 @@ bool DxilModule::IsKnownNamedMetaData(llvm::NamedMDNode &Node) {
void DxilModule::LoadDxilMetadata() {
m_pMDHelper->LoadDxilVersion(m_DxilMajor, m_DxilMinor);
m_pMDHelper->LoadValidatorVersion(m_ValMajor, m_ValMinor);
const ShaderModel *loadedModule;
m_pMDHelper->LoadDxilShaderModel(loadedModule);
SetShaderModel(loadedModule);

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

@ -133,18 +133,22 @@ void ShaderModel::GetDxilVersion(unsigned &DxilMajor, unsigned &DxilMinor) const
}
}
uint32_t ShaderModel::GetPSVVersion() const {
void ShaderModel::GetMinValidatorVersion(unsigned &ValMajor, unsigned &ValMinor) const {
DXASSERT(IsValidForDxil(), "invalid shader model");
ValMajor = 1;
switch (m_Minor) {
case 0: return 0;
case 1: return 1;
case 0:
ValMinor = 0;
break;
case 1:
ValMinor = 1;
break;
default:
DXASSERT(0, "IsValidForDxil() should have caught this.");
break;
}
return (unsigned)-1;
}
std::string ShaderModel::GetKindName() const {
return std::string(m_pszName).substr(0, 2);
}

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

@ -4248,8 +4248,14 @@ bool VerifySignatureMatches(llvm::Module *pModule,
static void VerifyPSVMatches(_In_ ValidationContext &ValCtx,
_In_reads_bytes_(PSVSize) const void *pPSVData,
_In_ uint32_t PSVSize) {
uint32_t PSVVersion = 1; // This should be set to the newest version
unique_ptr<DxilPartWriter> pWriter(NewPSVWriter(ValCtx.DxilMod, PSVVersion));
// Try each version in case an earlier version matches module
while (PSVVersion && pWriter->size() != PSVSize) {
PSVVersion --;
pWriter.reset(NewPSVWriter(ValCtx.DxilMod, PSVVersion));
}
// generate PSV data from module and memcmp
unique_ptr<DxilPartWriter> pWriter(NewPSVWriter(ValCtx.DxilMod));
VerifyBlobPartMatches(ValCtx, "Pipeline State Validation", pWriter.get(), pPSVData, PSVSize);
}
@ -4494,7 +4500,7 @@ HRESULT ValidateDxilBitcode(
DxilModule &dxilModule = pModule->GetDxilModule();
if (!dxilModule.GetRootSignature().IsEmpty()) {
unique_ptr<DxilPartWriter> pWriter(NewPSVWriter(dxilModule));
unique_ptr<DxilPartWriter> pWriter(NewPSVWriter(dxilModule, 0));
DXASSERT_NOMSG(pWriter->size());
CComPtr<IMalloc> pMalloc;
IFT(CoGetMalloc(1, &pMalloc));

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

@ -80,6 +80,16 @@ LLVMContext &HLModule::GetCtx() const { return m_Ctx; }
Module *HLModule::GetModule() const { return m_pModule; }
OP *HLModule::GetOP() const { return m_pOP.get(); }
void HLModule::SetValidatorVersion(unsigned ValMajor, unsigned ValMinor) {
m_ValMajor = ValMajor;
m_ValMinor = ValMinor;
}
void HLModule::GetValidatorVersion(unsigned &ValMajor, unsigned &ValMinor) const {
ValMajor = m_ValMajor;
ValMinor = m_ValMinor;
}
void HLModule::SetShaderModel(const ShaderModel *pSM) {
DXASSERT(m_pSM == nullptr, "shader model must not change for the module");
DXASSERT(pSM != nullptr && pSM->IsValidForDxil(), "shader model must be valid");
@ -411,6 +421,7 @@ static const StringRef kHLDxilResourceTypeAnnotationMDName = "dx.resource.
// DXIL metadata serialization/deserialization.
void HLModule::EmitHLMetadata() {
m_pMDHelper->EmitDxilVersion(m_DxilMajor, m_DxilMinor);
m_pMDHelper->EmitValidatorVersion(m_ValMajor, m_ValMinor);
m_pMDHelper->EmitDxilShaderModel(m_pSM);
MDTuple *pMDSignatures = m_pMDHelper->EmitDxilSignatures(*m_InputSignature,
@ -483,6 +494,7 @@ void HLModule::EmitHLMetadata() {
void HLModule::LoadHLMetadata() {
m_pMDHelper->LoadDxilVersion(m_DxilMajor, m_DxilMinor);
m_pMDHelper->LoadValidatorVersion(m_ValMajor, m_ValMinor);
m_pMDHelper->LoadDxilShaderModel(m_pSM);
CreateSignatures(m_pSM, m_InputSignature, m_OutputSignature, m_PatchConstantSignature, m_RootSignature);
@ -570,6 +582,7 @@ void HLModule::ClearHLMetadata(llvm::Module &M) {
name == DxilMDHelper::kDxilRootSignatureMDName ||
name == DxilMDHelper::kDxilResourcesMDName ||
name == DxilMDHelper::kDxilTypeSystemMDName ||
name == DxilMDHelper::kDxilValidatorVersionMDName ||
name == kHLDxilFunctionPropertiesMDName || // TODO: adjust to proper name
name == kHLDxilResourceTypeAnnotationMDName ||
name == kHLDxilOptionsMDName ||

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

@ -308,7 +308,7 @@ CGMSHLSLRuntime::CGMSHLSLRuntime(CodeGenModule &CGM)
}
// TODO: add AllResourceBound.
if (CGM.getCodeGenOpts().HLSLAvoidControlFlow && !CGM.getCodeGenOpts().HLSLAllResourcesBound) {
if (SM->GetMajor() >= 5 && SM->GetMinor() >= 1) {
if (SM->IsSM51Plus()) {
DiagnosticsEngine &Diags = CGM.getDiags();
unsigned DiagID =
Diags.getCustomDiagID(DiagnosticsEngine::Error,
@ -331,6 +331,8 @@ CGMSHLSLRuntime::CGMSHLSLRuntime(CodeGenModule &CGM)
opts.PackingStrategy = CGM.getCodeGenOpts().HLSLSignaturePackingStrategy;
m_pHLModule->SetHLOptions(opts);
m_pHLModule->SetValidatorVersion(CGM.getCodeGenOpts().HLSLValidatorMajorVer, CGM.getCodeGenOpts().HLSLValidatorMinorVer);
m_bDebugInfo = CGM.getCodeGenOpts().getDebugInfo() == CodeGenOptions::FullDebugInfo;
// set profile

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

@ -3699,21 +3699,6 @@ void CodeGenModule::EmitVersionIdentMetadata() {
llvm::Metadata *IdentNode[] = {llvm::MDString::get(Ctx, Version)};
IdentMetadata->addOperand(llvm::MDNode::get(Ctx, IdentNode));
// HLSL Change Starts
if (getCodeGenOpts().HLSLValidatorMajorVer != 0 ||
getCodeGenOpts().HLSLValidatorMinorVer != 0) {
llvm::NamedMDNode *VerMetadata =
TheModule.getOrInsertNamedMetadata("dx.valver");
llvm::Metadata *VerValues[] = {
llvm::ValueAsMetadata::get(llvm::ConstantInt::get(
Ctx, llvm::APInt(32, getCodeGenOpts().HLSLValidatorMajorVer))),
llvm::ValueAsMetadata::get(llvm::ConstantInt::get(
Ctx, llvm::APInt(32, getCodeGenOpts().HLSLValidatorMinorVer)))};
llvm::MDTuple *VerNode = llvm::MDTuple::get(Ctx, VerValues);
VerMetadata->addOperand(VerNode);
}
// HLSL Change Ends
}
void CodeGenModule::EmitTargetMetadata() {

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

@ -17,6 +17,7 @@
#include "dxc/Support/FileIOHelper.h"
#include "dxc/HLSL/DxilModule.h"
#include "dxc/Support/dxcapi.impl.h"
#include "dxillib.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/IRReader/IRReader.h"
@ -27,6 +28,9 @@
using namespace llvm;
using namespace hlsl;
// This declaration is used for the locally-linked validator.
HRESULT CreateDxcValidator(_In_ REFIID riid, _Out_ LPVOID *ppv);
class DxcAssembler : public IDxcAssembler {
private:
DXC_MICROCOM_REF_FIELD(m_dwRef)
@ -115,6 +119,25 @@ HRESULT STDMETHODCALLTYPE DxcAssembler::AssembleToContainer(
return S_OK;
}
// Upgrade Validator Version if necessary:
{
CComPtr<IDxcValidator> pValidator;
if (DxilLibIsEnabled()) {
DxilLibCreateInstance(CLSID_DxcValidator, &pValidator);
}
if (pValidator == nullptr) {
CreateDxcValidator(IID_PPV_ARGS(&pValidator));
}
CComPtr<IDxcVersionInfo> pVersionInfo;
if (pValidator && SUCCEEDED(pValidator.QueryInterface(&pVersionInfo))) {
UINT32 majorVer, minorVer;
IFT(pVersionInfo->GetVersion(&majorVer, &minorVer));
if (program.UpgradeValidatorVersion(majorVer, minorVer)) {
program.UpdateValidatorVersionMetadata();
}
}
}
WriteBitcodeToFile(M.get(), outStream);
outStream.flush();

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

@ -120,21 +120,6 @@ HRESULT RunInternalValidator(_In_ IDxcValidator *pValidator,
_In_ IDxcBlob *pShader, UINT32 Flags,
_In_ IDxcOperationResult **ppResult);
static HRESULT GetValidatorVersion(IDxcValidator *pValidator, UINT32 *pMajor,
UINT32 *pMinor) {
CComPtr<IDxcVersionInfo> pVersionInfo;
IFR(pValidator->QueryInterface(&pVersionInfo));
IFR(pVersionInfo->GetVersion(pMajor, pMinor));
return S_OK;
}
static bool DoesValidatorSupportDebugNamePart(IDxcValidator *pValidator) {
UINT32 Major, Minor;
if (FAILED((GetValidatorVersion(pValidator, &Major, &Minor))))
return false;
return Major > 1 || (Major == 1 && Minor >= 1);
}
enum class HandleKind {
Special = 0,
File = 1,
@ -2368,8 +2353,7 @@ public:
SerializeDxilFlags SerializeFlags = SerializeDxilFlags::None;
if (opts.DebugInfo) {
if (DoesValidatorSupportDebugNamePart(pValidator))
SerializeFlags = SerializeDxilFlags::IncludeDebugNamePart;
SerializeFlags = SerializeDxilFlags::IncludeDebugNamePart;
// Unless we want to strip it right away, include it in the container.
if (!opts.StripDebug || ppDebugBlob == nullptr) {
SerializeFlags |= SerializeDxilFlags::IncludeDebugInfoPart;