Skip to content

Commit feef2ff

Browse files
authored
Validator/Dxil version error improvements (#3623) (#3627)
- Move validator/dxil version checks up-front These should fail first rather than side effects of trying to validate details of a version we don't support. - Improve message for unsupported validator or dxil version These errors are most likely if compiling separately from validation and failing to override the validator version properly, or running on an external validator that doesn't support a newer dxil. - Use dxil version from metadata for DxilModule when loading, rather than just setting it to minimum based on shader model. - Remove TODO from validator messages that shouldn't be there (cherry picked from commit 6244ab8)
1 parent 0b1c006 commit feef2ff

7 files changed

Lines changed: 63 additions & 17 deletions

File tree

docs/DXIL.rst

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2969,7 +2969,7 @@ The set of validation rules that are known to hold for a DXIL program is identif
29692969
========================================= ========================================================================================================================================================================================================================================================================================================
29702970
Rule Code Description
29712971
========================================= ========================================================================================================================================================================================================================================================================================================
2972-
BITCODE.VALID TODO - Module must be bitcode-valid
2972+
BITCODE.VALID Module must be bitcode-valid
29732973
CONTAINER.PARTINVALID DXIL Container must not contain unknown parts
29742974
CONTAINER.PARTMATCHES DXIL Container Parts must match Module
29752975
CONTAINER.PARTMISSING DXIL Container requires certain parts, corresponding to module
@@ -3096,7 +3096,7 @@ META.KNOWN Named metadata should be known
30963096
META.MAXTESSFACTOR Hull Shader MaxTessFactor must be [%0..%1]. %2 specified.
30973097
META.NOENTRYPROPSFORENTRY Entry point %0 must have entry properties.
30983098
META.NOSEMANTICOVERLAP Semantics must not overlap
3099-
META.REQUIRED TODO - Required metadata missing.
3099+
META.REQUIRED Required metadata missing.
31003100
META.SEMAKINDMATCHESNAME Semantic name must match system value, when defined.
31013101
META.SEMAKINDVALID Semantic kind must be valid
31023102
META.SEMANTICCOMPTYPE %0 must be %1.
@@ -3120,7 +3120,8 @@ META.TEXTURETYPE elements of typed buffers and textures
31203120
META.USED All metadata must be used by dxil.
31213121
META.VALIDSAMPLERMODE Invalid sampler mode on sampler .
31223122
META.VALUERANGE Metadata value must be within range.
3123-
META.WELLFORMED TODO - Metadata must be well-formed in operand count and types.
3123+
META.VERSIONSUPPORTED Version in metadata must be supported.
3124+
META.WELLFORMED Metadata must be well-formed in operand count and types.
31243125
SM.64BITRAWBUFFERLOADSTORE i64/f64 rawBufferLoad/Store overloads are allowed after SM 6.3.
31253126
SM.AMPLIFICATIONSHADERPAYLOADSIZE For amplification shader with entry '%0', payload size %1 is greater than maximum size of %2 bytes.
31263127
SM.AMPLIFICATIONSHADERPAYLOADSIZEDECLARED For amplification shader with entry '%0', payload size %1 is greater than declared size of %2 bytes.

include/dxc/HLSL/DxilValidation.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ namespace hlsl {
3131
// Known validation rules
3232
enum class ValidationRule : unsigned {
3333
// Bitcode
34-
BitcodeValid, // TODO - Module must be bitcode-valid
34+
BitcodeValid, // Module must be bitcode-valid
3535

3636
// Container
3737
ContainerPartInvalid, // DXIL Container must not contain unknown parts
@@ -162,7 +162,7 @@ enum class ValidationRule : unsigned {
162162
MetaMaxTessFactor, // Hull Shader MaxTessFactor must be [%0..%1]. %2 specified.
163163
MetaNoEntryPropsForEntry, // Entry point %0 must have entry properties.
164164
MetaNoSemanticOverlap, // Semantics must not overlap
165-
MetaRequired, // TODO - Required metadata missing.
165+
MetaRequired, // Required metadata missing.
166166
MetaSemaKindMatchesName, // Semantic name must match system value, when defined.
167167
MetaSemaKindValid, // Semantic kind must be valid
168168
MetaSemanticCompType, // %0 must be %1.
@@ -186,7 +186,8 @@ enum class ValidationRule : unsigned {
186186
MetaUsed, // All metadata must be used by dxil.
187187
MetaValidSamplerMode, // Invalid sampler mode on sampler .
188188
MetaValueRange, // Metadata value must be within range.
189-
MetaWellFormed, // TODO - Metadata must be well-formed in operand count and types.
189+
MetaVersionSupported, // Version in metadata must be supported.
190+
MetaWellFormed, // Metadata must be well-formed in operand count and types.
190191

191192
// Program flow
192193
FlowDeadLoop, // Loop must have break.

lib/DXIL/DxilModule.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1517,7 +1517,6 @@ bool DxilModule::HasMetadataErrors() {
15171517

15181518
void DxilModule::LoadDxilMetadata() {
15191519
m_bMetadataErrors = false;
1520-
m_pMDHelper->LoadDxilVersion(m_DxilMajor, m_DxilMinor);
15211520
m_pMDHelper->LoadValidatorVersion(m_ValMajor, m_ValMinor);
15221521
const ShaderModel *loadedSM;
15231522
m_pMDHelper->LoadDxilShaderModel(loadedSM);
@@ -1559,6 +1558,9 @@ void DxilModule::LoadDxilMetadata() {
15591558

15601559
// Now that we have the UseMinPrecision flag, set shader model:
15611560
SetShaderModel(loadedSM, m_bUseMinPrecision);
1561+
// SetShaderModel will initialize m_DxilMajor/m_DxilMinor to min for SM,
1562+
// so, load here after shader model so it matches the metadata.
1563+
m_pMDHelper->LoadDxilVersion(m_DxilMajor, m_DxilMinor);
15621564

15631565
if (loadedSM->IsLib()) {
15641566
for (unsigned i = 1; i < pEntries->getNumOperands(); i++) {

lib/HLSL/DxilValidation.cpp

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -74,11 +74,12 @@ const char *hlsl::GetValidationRuleText(ValidationRule value) {
7474
case hlsl::ValidationRule::ContainerPartMissing: return "Missing part '%0' required by module.";
7575
case hlsl::ValidationRule::ContainerPartInvalid: return "Unknown part '%0' found in DXIL container.";
7676
case hlsl::ValidationRule::ContainerRootSignatureIncompatible: return "Root Signature in DXIL container is not compatible with shader.";
77-
case hlsl::ValidationRule::MetaRequired: return "TODO - Required metadata missing.";
77+
case hlsl::ValidationRule::MetaRequired: return "Required metadata missing.";
7878
case hlsl::ValidationRule::MetaKnown: return "Named metadata '%0' is unknown.";
7979
case hlsl::ValidationRule::MetaUsed: return "All metadata must be used by dxil.";
8080
case hlsl::ValidationRule::MetaTarget: return "Unknown target triple '%0'.";
81-
case hlsl::ValidationRule::MetaWellFormed: return "TODO - Metadata must be well-formed in operand count and types.";
81+
case hlsl::ValidationRule::MetaWellFormed: return "Metadata must be well-formed in operand count and types.";
82+
case hlsl::ValidationRule::MetaVersionSupported: return "%0 version in metadata (%1.%2) is not supported; maximum: (%3.%4).";
8283
case hlsl::ValidationRule::MetaSemanticLen: return "Semantic length must be at least 1 and at most 64.";
8384
case hlsl::ValidationRule::MetaInterpModeValid: return "Invalid interpolation mode for '%0'.";
8485
case hlsl::ValidationRule::MetaSemaKindValid: return "Semantic kind for '%0' is invalid.";
@@ -208,7 +209,7 @@ const char *hlsl::GetValidationRuleText(ValidationRule value) {
208209
case hlsl::ValidationRule::TypesNoPtrToPtr: return "Pointers to pointers, or pointers in structures are not allowed.";
209210
case hlsl::ValidationRule::TypesI8: return "I8 can only be used as immediate value for intrinsic or as i8* via bitcast by lifetime intrinsics.";
210211
case hlsl::ValidationRule::SmName: return "Unknown shader model '%0'.";
211-
case hlsl::ValidationRule::SmDxilVersion: return "Shader model requires Dxil Version %0,%1.";
212+
case hlsl::ValidationRule::SmDxilVersion: return "Shader model requires Dxil Version %0.%1.";
212213
case hlsl::ValidationRule::SmOpcode: return "Opcode %0 not valid in shader model %1.";
213214
case hlsl::ValidationRule::SmOperand: return "Operand must be defined in target shader model.";
214215
case hlsl::ValidationRule::SmSemantic: return "Semantic '%0' is invalid as %1 %2.";
@@ -3899,6 +3900,12 @@ static void ValidateValidatorVersion(ValidationContext &ValCtx) {
38993900
// depending on the degree of compat across versions.
39003901
if (majorVer == curMajor && minorVer <= curMinor) {
39013902
return;
3903+
} else {
3904+
ValCtx.EmitFormatError(
3905+
ValidationRule::MetaVersionSupported,
3906+
{"Validator", std::to_string(majorVer), std::to_string(minorVer),
3907+
std::to_string(curMajor), std::to_string(curMinor)});
3908+
return;
39023909
}
39033910
}
39043911
}
@@ -3920,9 +3927,15 @@ static void ValidateDxilVersion(ValidationContext &ValCtx) {
39203927
GetNodeOperandAsInt(ValCtx, pVerValues, 1, &minorVer)) {
39213928
// This will need to be updated as dxil major/minor versions evolve,
39223929
// depending on the degree of compat across versions.
3923-
if ((majorVer == 1 && minorVer <= DXIL::kDxilMinor) &&
3930+
if ((majorVer == DXIL::kDxilMajor && minorVer <= DXIL::kDxilMinor) &&
39243931
(majorVer == ValCtx.m_DxilMajor && minorVer == ValCtx.m_DxilMinor)) {
39253932
return;
3933+
} else {
3934+
ValCtx.EmitFormatError(
3935+
ValidationRule::MetaVersionSupported,
3936+
{"Dxil", std::to_string(majorVer), std::to_string(minorVer),
3937+
std::to_string(DXIL::kDxilMajor), std::to_string(DXIL::kDxilMinor)});
3938+
return;
39263939
}
39273940
}
39283941
}
@@ -3964,6 +3977,9 @@ static void ValidateBitcode(ValidationContext &ValCtx) {
39643977
}
39653978

39663979
static void ValidateMetadata(ValidationContext &ValCtx) {
3980+
ValidateValidatorVersion(ValCtx);
3981+
ValidateDxilVersion(ValCtx);
3982+
39673983
Module *pModule = &ValCtx.M;
39683984
const std::string &target = pModule->getTargetTriple();
39693985
if (target != "dxil-ms-dx") {
@@ -4011,8 +4027,6 @@ static void ValidateMetadata(ValidationContext &ValCtx) {
40114027
}
40124028
}
40134029

4014-
ValidateDxilVersion(ValCtx);
4015-
ValidateValidatorVersion(ValCtx);
40164030
ValidateTypeAnnotation(ValCtx);
40174031
}
40184032

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// RUN: %dxc -E main -T ps_6_0 %s
2+
3+
float4 main() : SV_Target {
4+
return float4(1, 0, 0, 1);
5+
}

tools/clang/unittests/HLSL/ValidationTest.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,8 @@ class ValidationTest : public ::testing::Test {
297297
TEST_METHOD(ValidateRootSigContainer)
298298
TEST_METHOD(ValidatePrintfNotAllowed)
299299

300+
TEST_METHOD(ValidateVersionNotAllowed)
301+
300302
dxc::DxcDllSupport m_dllSupport;
301303
VersionSupportInfo m_ver;
302304

@@ -3836,3 +3838,23 @@ TEST_F(ValidationTest, ValidateRootSigContainer) {
38363838
TEST_F(ValidationTest, ValidatePrintfNotAllowed) {
38373839
TestCheck(L"..\\CodeGenHLSL\\printf.hlsl");
38383840
}
3841+
3842+
TEST_F(ValidationTest, ValidateVersionNotAllowed) {
3843+
if (m_ver.SkipDxilVersion(1, 6)) return;
3844+
std::string maxValMinor = std::to_string(m_ver.m_ValMinor);
3845+
std::string higherValMinor = std::to_string(m_ver.m_ValMinor + 1);
3846+
std::string maxDxilMinor = std::to_string(m_ver.m_DxilMinor);
3847+
std::string higherDxilMinor = std::to_string(m_ver.m_DxilMinor + 1);
3848+
RewriteAssemblyCheckMsg(L"..\\CodeGenHLSL\\basic.hlsl", "ps_6_0",
3849+
("= !{i32 1, i32 " + maxValMinor + "}").c_str(),
3850+
("= !{i32 1, i32 " + higherValMinor + "}").c_str(),
3851+
("error: Validator version in metadata (1." + higherValMinor + ") is not supported; maximum: (1." + maxValMinor + ")").c_str());
3852+
RewriteAssemblyCheckMsg(L"..\\CodeGenHLSL\\basic.hlsl", "ps_6_0",
3853+
"= !{i32 1, i32 0}",
3854+
"= !{i32 1, i32 1}",
3855+
"error: Shader model requires Dxil Version 1.0");
3856+
RewriteAssemblyCheckMsg(L"..\\CodeGenHLSL\\basic.hlsl", "ps_6_0",
3857+
"= !{i32 1, i32 0}",
3858+
("= !{i32 1, i32 " + higherDxilMinor + "}").c_str(),
3859+
("error: Dxil version in metadata (1." + higherDxilMinor + ") is not supported; maximum: (1." + maxDxilMinor + ")").c_str());
3860+
}

utils/hct/hctdb.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2438,19 +2438,20 @@ def build_semantics(self):
24382438
self.interpretation_table = table
24392439

24402440
def build_valrules(self):
2441-
self.add_valrule_msg("Bitcode.Valid", "TODO - Module must be bitcode-valid", "Module bitcode is invalid.")
2441+
self.add_valrule_msg("Bitcode.Valid", "Module must be bitcode-valid", "Module bitcode is invalid.")
24422442

24432443
self.add_valrule_msg("Container.PartMatches", "DXIL Container Parts must match Module", "Container part '%0' does not match expected for module.")
24442444
self.add_valrule_msg("Container.PartRepeated", "DXIL Container must have only one of each part type", "More than one container part '%0'.")
24452445
self.add_valrule_msg("Container.PartMissing", "DXIL Container requires certain parts, corresponding to module", "Missing part '%0' required by module.")
24462446
self.add_valrule_msg("Container.PartInvalid", "DXIL Container must not contain unknown parts", "Unknown part '%0' found in DXIL container.")
24472447
self.add_valrule_msg("Container.RootSignatureIncompatible", "Root Signature in DXIL Container must be compatible with shader", "Root Signature in DXIL container is not compatible with shader.")
24482448

2449-
self.add_valrule("Meta.Required", "TODO - Required metadata missing.")
2449+
self.add_valrule("Meta.Required", "Required metadata missing.")
24502450
self.add_valrule_msg("Meta.Known", "Named metadata should be known", "Named metadata '%0' is unknown.")
24512451
self.add_valrule("Meta.Used", "All metadata must be used by dxil.")
24522452
self.add_valrule_msg("Meta.Target", "Target triple must be 'dxil-ms-dx'", "Unknown target triple '%0'.")
2453-
self.add_valrule("Meta.WellFormed", "TODO - Metadata must be well-formed in operand count and types.")
2453+
self.add_valrule("Meta.WellFormed", "Metadata must be well-formed in operand count and types.") # TODO: add string arg for what metadata is malformed (this is emitted from a lot of places and provides no context whatsoever)
2454+
self.add_valrule_msg("Meta.VersionSupported", "Version in metadata must be supported.", "%0 version in metadata (%1.%2) is not supported; maximum: (%3.%4).")
24542455
self.add_valrule("Meta.SemanticLen", "Semantic length must be at least 1 and at most 64.")
24552456
self.add_valrule_msg("Meta.InterpModeValid", "Interpolation mode must be valid", "Invalid interpolation mode for '%0'.")
24562457
self.add_valrule_msg("Meta.SemaKindValid", "Semantic kind must be valid", "Semantic kind for '%0' is invalid.")
@@ -2602,7 +2603,7 @@ def build_valrules(self):
26022603
self.add_valrule("Types.I8", "I8 can only be used as immediate value for intrinsic or as i8* via bitcast by lifetime intrinsics.")
26032604

26042605
self.add_valrule_msg("Sm.Name", "Target shader model name must be known", "Unknown shader model '%0'.")
2605-
self.add_valrule_msg("Sm.DxilVersion", "Target shader model requires specific Dxil Version", "Shader model requires Dxil Version %0,%1.")
2606+
self.add_valrule_msg("Sm.DxilVersion", "Target shader model requires specific Dxil Version", "Shader model requires Dxil Version %0.%1.")
26062607
self.add_valrule_msg("Sm.Opcode", "Opcode must be defined in target shader model", "Opcode %0 not valid in shader model %1.")
26072608
self.add_valrule("Sm.Operand", "Operand must be defined in target shader model.")
26082609
self.add_valrule_msg("Sm.Semantic", "Semantic must be defined in target shader model", "Semantic '%0' is invalid as %1 %2.")

0 commit comments

Comments
 (0)