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; const InputsContributingToOutputType &getPCInputsContributingToOutputs() const;
void Compute(); void Compute();
void Serialize();
const std::vector<unsigned> &GetSerialized(); const std::vector<unsigned> &GetSerialized();
const std::vector<unsigned> &GetSerialized() const; // returns previously serialized data
void Deserialize(const unsigned *pData, unsigned DataSize); void Deserialize(const unsigned *pData, unsigned DataSize);
void PrintSets(llvm::raw_ostream &OS); void PrintSets(llvm::raw_ostream &OS);

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

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

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

@ -188,6 +188,7 @@ public:
// Validator version. // Validator version.
static const char kDxilValidatorVersionMDName[]; static const char kDxilValidatorVersionMDName[];
// Validator version uses the same constants for fields as kDxilVersion*
// Extended shader property tags. // Extended shader property tags.
static const unsigned kDxilShaderFlagsTag = 0; static const unsigned kDxilShaderFlagsTag = 0;
@ -257,6 +258,10 @@ public:
void EmitDxilVersion(unsigned Major, unsigned Minor); void EmitDxilVersion(unsigned Major, unsigned Minor);
void LoadDxilVersion(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. // Shader model.
void EmitDxilShaderModel(const ShaderModel *pSM); void EmitDxilShaderModel(const ShaderModel *pSM);
void LoadDxilShaderModel(const ShaderModel *&pSM); void LoadDxilShaderModel(const ShaderModel *&pSM);

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

@ -51,6 +51,14 @@ public:
void SetShaderModel(const ShaderModel *pSM); void SetShaderModel(const ShaderModel *pSM);
const ShaderModel *GetShaderModel() const; const ShaderModel *GetShaderModel() const;
void GetDxilVersion(unsigned &DxilMajor, unsigned &DxilMinor) 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. // Entry functions.
llvm::Function *GetEntryFunction(); llvm::Function *GetEntryFunction();
@ -106,6 +114,8 @@ public:
// Remove Root Signature from module metadata // Remove Root Signature from module metadata
void StripRootSignatureFromMetadata(); void StripRootSignatureFromMetadata();
// Update validator version metadata to current setting
void UpdateValidatorVersionMetadata();
// DXIL type system. // DXIL type system.
DxilTypeSystem &GetTypeSystem(); DxilTypeSystem &GetTypeSystem();
@ -116,6 +126,7 @@ public:
// ViewId state. // ViewId state.
DxilViewIdState &GetViewIdState(); DxilViewIdState &GetViewIdState();
const DxilViewIdState &GetViewIdState() const;
// DXIL metadata manipulation. // DXIL metadata manipulation.
/// Serialize DXIL in-memory form to metadata form. /// Serialize DXIL in-memory form to metadata form.
@ -288,6 +299,8 @@ private:
const ShaderModel *m_pSM; const ShaderModel *m_pSM;
unsigned m_DxilMajor; unsigned m_DxilMajor;
unsigned m_DxilMinor; unsigned m_DxilMinor;
unsigned m_ValMajor;
unsigned m_ValMinor;
std::unique_ptr<OP> m_pOP; std::unique_ptr<OP> m_pOP;
size_t m_pUnused; size_t m_pUnused;

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

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

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

@ -44,7 +44,7 @@ public:
unsigned GetMajor() const { return m_Major; } unsigned GetMajor() const { return m_Major; }
unsigned GetMinor() const { return m_Minor; } unsigned GetMinor() const { return m_Minor; }
void GetDxilVersion(unsigned &DxilMajor, unsigned &DxilMinor) const; 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 IsSM50Plus() const { return m_Major >= 5; }
bool IsSM51Plus() const { return m_Major > 5 || (m_Major == 5 && m_Minor >= 1); } bool IsSM51Plus() const { return m_Major > 5 || (m_Major == 5 && m_Minor >= 1); }
bool IsSM60Plus() const { return m_Major >= 6; } bool IsSM60Plus() const { return m_Major >= 6; }

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

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

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

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

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

@ -349,8 +349,8 @@ private:
if (SE.GetKind() == DXIL::SemanticKind::Arbitrary && strlen(SE.GetName()) > 0) { if (SE.GetKind() == DXIL::SemanticKind::Arbitrary && strlen(SE.GetName()) > 0) {
E.SemanticName = (uint32_t)m_StringBuffer.size(); E.SemanticName = (uint32_t)m_StringBuffer.size();
StringRef Name(SE.GetName()); StringRef Name(SE.GetName());
m_StringBuffer.append('\0', Name.size()+1); m_StringBuffer.append(Name.size()+1, '\0');
memcpy(m_StringBuffer.data(), Name.data(), Name.size()); memcpy(m_StringBuffer.data() + E.SemanticName, Name.data(), Name.size());
} else { } else {
// m_StringBuffer always starts with '\0' so offset 0 is empty string: // m_StringBuffer always starts with '\0' so offset 0 is empty string:
E.SemanticName = 0; E.SemanticName = 0;
@ -374,7 +374,7 @@ private:
} }
if (!match) { if (!match) {
E.SemanticIndexes = m_SemanticIndexBuffer.size(); 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]); m_SemanticIndexBuffer.push_back((uint32_t)SemIdx[row]);
} }
} }
@ -395,15 +395,38 @@ private:
E.DynamicMaskAndStream = (uint8_t)((SE.GetOutputStream() & 0x3) << 4); E.DynamicMaskAndStream = (uint8_t)((SE.GetOutputStream() & 0x3) << 4);
// TODO: Fill Dynamic Index Mask in! // TODO: Fill Dynamic Index Mask in!
//DXASSERT_NOMSG((SE.GetDynamicIndexMask() & ~0xF) == 0); E.DynamicMaskAndStream |= (SE.GetDynIdxCompMask()) & 0xF;
//E.DynamicMaskAndStream |= (SE.GetDynamicIndexMask()) & 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: public:
DxilPSVWriter(const DxilModule &module) DxilPSVWriter(const DxilModule &module, uint32_t PSVVersion = 0)
: m_Module(module), : 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 uCBuffers = m_Module.GetCBuffers().size();
UINT uSamplers = m_Module.GetSamplers().size(); UINT uSamplers = m_Module.GetSamplers().size();
UINT uSRVs = m_Module.GetSRVs().size(); UINT uSRVs = m_Module.GetSRVs().size();
@ -623,7 +646,18 @@ public:
memcpy(pPatchConstantElement, &m_SigPatchConstantElements[i], sizeof(PSVSignatureElement0)); 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; ULONG cbWritten;
@ -632,8 +666,8 @@ public:
} }
}; };
DxilPartWriter *hlsl::NewPSVWriter(const DxilModule &M) { DxilPartWriter *hlsl::NewPSVWriter(const DxilModule &M, uint32_t PSVVersion) {
return new DxilPSVWriter(M); return new DxilPSVWriter(M, PSVVersion);
} }
class DxilContainerWriter_impl : public DxilContainerWriter { class DxilContainerWriter_impl : public DxilContainerWriter {
@ -745,6 +779,11 @@ void hlsl::SerializeDxilContainerForModule(DxilModule *pModule,
DXASSERT_NOMSG(pModuleBitcode != nullptr); DXASSERT_NOMSG(pModuleBitcode != nullptr);
DXASSERT_NOMSG(pFinalStream != nullptr); DXASSERT_NOMSG(pFinalStream != nullptr);
unsigned ValMajor, ValMinor;
pModule->GetValidatorVersion(ValMajor, ValMinor);
if (ValMajor == 1 && ValMinor == 0)
Flags &= ~SerializeDxilFlags::IncludeDebugNamePart;
DxilProgramSignatureWriter inputSigWriter(pModule->GetInputSignature(), DxilProgramSignatureWriter inputSigWriter(pModule->GetInputSignature(),
pModule->GetTessellatorDomain(), pModule->GetTessellatorDomain(),
/*IsInput*/ true); /*IsInput*/ true);

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

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

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

@ -108,6 +108,44 @@ void DxilMDHelper::LoadDxilVersion(unsigned &Major, unsigned &Minor) {
Minor = ConstMDToUint32(pVersionMD->getOperand(kDxilVersionMinorIdx)); 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. // DXIL shader model.
// //

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

@ -68,6 +68,8 @@ DxilModule::DxilModule(Module *pModule)
, m_pSM(nullptr) , m_pSM(nullptr)
, m_DxilMajor(DXIL::kDxilMajor) , m_DxilMajor(DXIL::kDxilMajor)
, m_DxilMinor(DXIL::kDxilMinor) , m_DxilMinor(DXIL::kDxilMinor)
, m_ValMajor(1)
, m_ValMinor(0)
, m_InputPrimitive(DXIL::InputPrimitive::Undefined) , m_InputPrimitive(DXIL::InputPrimitive::Undefined)
, m_MaxVertexCount(0) , m_MaxVertexCount(0)
, m_StreamPrimitiveTopology(DXIL::PrimitiveTopology::Undefined) , m_StreamPrimitiveTopology(DXIL::PrimitiveTopology::Undefined)
@ -149,6 +151,42 @@ void DxilModule::GetDxilVersion(unsigned &DxilMajor, unsigned &DxilMinor) const
DxilMinor = m_DxilMinor; 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() { Function *DxilModule::GetEntryFunction() {
return m_pEntryFunc; 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) { void DxilModule::ResetInputSignature(DxilSignature *pValue) {
m_InputSignature.reset(pValue); m_InputSignature.reset(pValue);
} }
@ -896,6 +938,9 @@ DxilTypeSystem &DxilModule::GetTypeSystem() {
DxilViewIdState &DxilModule::GetViewIdState() { DxilViewIdState &DxilModule::GetViewIdState() {
return *m_pViewIdState; return *m_pViewIdState;
} }
const DxilViewIdState &DxilModule::GetViewIdState() const {
return *m_pViewIdState;
}
void DxilModule::ResetTypeSystem(DxilTypeSystem *pValue) { void DxilModule::ResetTypeSystem(DxilTypeSystem *pValue) {
m_pTypeSystem.reset(pValue); m_pTypeSystem.reset(pValue);
@ -947,6 +992,7 @@ vector<GlobalVariable* > &DxilModule::GetLLVMUsed() {
// DXIL metadata serialization/deserialization. // DXIL metadata serialization/deserialization.
void DxilModule::EmitDxilMetadata() { void DxilModule::EmitDxilMetadata() {
m_pMDHelper->EmitDxilVersion(m_DxilMajor, m_DxilMinor); m_pMDHelper->EmitDxilVersion(m_DxilMajor, m_DxilMinor);
m_pMDHelper->EmitValidatorVersion(m_ValMajor, m_ValMinor);
m_pMDHelper->EmitDxilShaderModel(m_pSM); m_pMDHelper->EmitDxilShaderModel(m_pSM);
MDTuple *pMDSignatures = m_pMDHelper->EmitDxilSignatures(*m_InputSignature, MDTuple *pMDSignatures = m_pMDHelper->EmitDxilSignatures(*m_InputSignature,
@ -955,7 +1001,8 @@ void DxilModule::EmitDxilMetadata() {
MDTuple *pMDResources = EmitDxilResources(); MDTuple *pMDResources = EmitDxilResources();
MDTuple *pMDProperties = EmitDxilShaderProperties(); MDTuple *pMDProperties = EmitDxilShaderProperties();
m_pMDHelper->EmitDxilTypeSystem(GetTypeSystem(), m_LLVMUsed); 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()); m_pMDHelper->EmitDxilViewIdState(GetViewIdState());
} }
EmitLLVMUsed(); EmitLLVMUsed();
@ -975,6 +1022,7 @@ bool DxilModule::IsKnownNamedMetaData(llvm::NamedMDNode &Node) {
void DxilModule::LoadDxilMetadata() { void DxilModule::LoadDxilMetadata() {
m_pMDHelper->LoadDxilVersion(m_DxilMajor, m_DxilMinor); m_pMDHelper->LoadDxilVersion(m_DxilMajor, m_DxilMinor);
m_pMDHelper->LoadValidatorVersion(m_ValMajor, m_ValMinor);
const ShaderModel *loadedModule; const ShaderModel *loadedModule;
m_pMDHelper->LoadDxilShaderModel(loadedModule); m_pMDHelper->LoadDxilShaderModel(loadedModule);
SetShaderModel(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) { switch (m_Minor) {
case 0: return 0; case 0:
case 1: return 1; ValMinor = 0;
break;
case 1:
ValMinor = 1;
break;
default: default:
DXASSERT(0, "IsValidForDxil() should have caught this."); DXASSERT(0, "IsValidForDxil() should have caught this.");
break; break;
} }
return (unsigned)-1;
} }
std::string ShaderModel::GetKindName() const { std::string ShaderModel::GetKindName() const {
return std::string(m_pszName).substr(0, 2); return std::string(m_pszName).substr(0, 2);
} }

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

@ -4248,8 +4248,14 @@ bool VerifySignatureMatches(llvm::Module *pModule,
static void VerifyPSVMatches(_In_ ValidationContext &ValCtx, static void VerifyPSVMatches(_In_ ValidationContext &ValCtx,
_In_reads_bytes_(PSVSize) const void *pPSVData, _In_reads_bytes_(PSVSize) const void *pPSVData,
_In_ uint32_t PSVSize) { _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 // generate PSV data from module and memcmp
unique_ptr<DxilPartWriter> pWriter(NewPSVWriter(ValCtx.DxilMod));
VerifyBlobPartMatches(ValCtx, "Pipeline State Validation", pWriter.get(), pPSVData, PSVSize); VerifyBlobPartMatches(ValCtx, "Pipeline State Validation", pWriter.get(), pPSVData, PSVSize);
} }
@ -4494,7 +4500,7 @@ HRESULT ValidateDxilBitcode(
DxilModule &dxilModule = pModule->GetDxilModule(); DxilModule &dxilModule = pModule->GetDxilModule();
if (!dxilModule.GetRootSignature().IsEmpty()) { if (!dxilModule.GetRootSignature().IsEmpty()) {
unique_ptr<DxilPartWriter> pWriter(NewPSVWriter(dxilModule)); unique_ptr<DxilPartWriter> pWriter(NewPSVWriter(dxilModule, 0));
DXASSERT_NOMSG(pWriter->size()); DXASSERT_NOMSG(pWriter->size());
CComPtr<IMalloc> pMalloc; CComPtr<IMalloc> pMalloc;
IFT(CoGetMalloc(1, &pMalloc)); IFT(CoGetMalloc(1, &pMalloc));

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

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

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

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

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

@ -3699,21 +3699,6 @@ void CodeGenModule::EmitVersionIdentMetadata() {
llvm::Metadata *IdentNode[] = {llvm::MDString::get(Ctx, Version)}; llvm::Metadata *IdentNode[] = {llvm::MDString::get(Ctx, Version)};
IdentMetadata->addOperand(llvm::MDNode::get(Ctx, IdentNode)); 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() { void CodeGenModule::EmitTargetMetadata() {

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

@ -17,6 +17,7 @@
#include "dxc/Support/FileIOHelper.h" #include "dxc/Support/FileIOHelper.h"
#include "dxc/HLSL/DxilModule.h" #include "dxc/HLSL/DxilModule.h"
#include "dxc/Support/dxcapi.impl.h" #include "dxc/Support/dxcapi.impl.h"
#include "dxillib.h"
#include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/MemoryBuffer.h"
#include "llvm/IRReader/IRReader.h" #include "llvm/IRReader/IRReader.h"
@ -27,6 +28,9 @@
using namespace llvm; using namespace llvm;
using namespace hlsl; using namespace hlsl;
// This declaration is used for the locally-linked validator.
HRESULT CreateDxcValidator(_In_ REFIID riid, _Out_ LPVOID *ppv);
class DxcAssembler : public IDxcAssembler { class DxcAssembler : public IDxcAssembler {
private: private:
DXC_MICROCOM_REF_FIELD(m_dwRef) DXC_MICROCOM_REF_FIELD(m_dwRef)
@ -115,6 +119,25 @@ HRESULT STDMETHODCALLTYPE DxcAssembler::AssembleToContainer(
return S_OK; 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); WriteBitcodeToFile(M.get(), outStream);
outStream.flush(); outStream.flush();

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

@ -120,21 +120,6 @@ HRESULT RunInternalValidator(_In_ IDxcValidator *pValidator,
_In_ IDxcBlob *pShader, UINT32 Flags, _In_ IDxcBlob *pShader, UINT32 Flags,
_In_ IDxcOperationResult **ppResult); _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 { enum class HandleKind {
Special = 0, Special = 0,
File = 1, File = 1,
@ -2368,8 +2353,7 @@ public:
SerializeDxilFlags SerializeFlags = SerializeDxilFlags::None; SerializeDxilFlags SerializeFlags = SerializeDxilFlags::None;
if (opts.DebugInfo) { 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. // Unless we want to strip it right away, include it in the container.
if (!opts.StripDebug || ppDebugBlob == nullptr) { if (!opts.StripDebug || ppDebugBlob == nullptr) {
SerializeFlags |= SerializeDxilFlags::IncludeDebugInfoPart; SerializeFlags |= SerializeDxilFlags::IncludeDebugInfoPart;