|
31 | 31 | #include "dxc/Support/FileIOHelper.h"
|
32 | 32 | #include "dxc/Support/Global.h"
|
33 | 33 |
|
| 34 | +#include "dxc/DXIL/DxilShaderModel.h" |
34 | 35 | #include "dxc/Test/DxcTestUtils.h"
|
35 | 36 | #include "dxc/Test/HlslTestUtils.h"
|
36 | 37 |
|
@@ -300,6 +301,8 @@ class ValidationTest : public ::testing::Test {
|
300 | 301 |
|
301 | 302 | TEST_METHOD(ValidateWithHash)
|
302 | 303 | TEST_METHOD(ValidateVersionNotAllowed)
|
| 304 | + TEST_METHOD(ValidatePreviewBypassHash) |
| 305 | + TEST_METHOD(ValidateProgramVersionAgainstDxilModule) |
303 | 306 | TEST_METHOD(CreateHandleNotAllowedSM66)
|
304 | 307 |
|
305 | 308 | TEST_METHOD(AtomicsConsts)
|
@@ -537,18 +540,10 @@ class ValidationTest : public ::testing::Test {
|
537 | 540 | pLookFors, pReplacements, pErrorMsgs, bRegex);
|
538 | 541 | }
|
539 | 542 |
|
540 |
| - bool RewriteAssemblyToText(IDxcBlobEncoding *pSource, LPCSTR pShaderModel, |
541 |
| - LPCWSTR *pArguments, UINT32 argCount, |
542 |
| - const DxcDefine *pDefines, UINT32 defineCount, |
543 |
| - llvm::ArrayRef<LPCSTR> pLookFors, |
544 |
| - llvm::ArrayRef<LPCSTR> pReplacements, |
545 |
| - IDxcBlob **pBlob, bool bRegex = false) { |
546 |
| - CComPtr<IDxcBlob> pProgram; |
547 |
| - std::string disassembly; |
548 |
| - if (!CompileSource(pSource, pShaderModel, pArguments, argCount, pDefines, |
549 |
| - defineCount, &pProgram)) |
550 |
| - return false; |
551 |
| - DisassembleProgram(pProgram, &disassembly); |
| 543 | + void PerformReplacementOnDisassembly(std::string disassembly, |
| 544 | + llvm::ArrayRef<LPCSTR> pLookFors, |
| 545 | + llvm::ArrayRef<LPCSTR> pReplacements, |
| 546 | + IDxcBlob **pBlob, bool bRegex = false) { |
552 | 547 | for (unsigned i = 0; i < pLookFors.size(); ++i) {
|
553 | 548 | LPCSTR pLookFor = pLookFors[i];
|
554 | 549 | bool bOptional = false;
|
@@ -605,6 +600,22 @@ class ValidationTest : public ::testing::Test {
|
605 | 600 | }
|
606 | 601 | }
|
607 | 602 | Utf8ToBlob(m_dllSupport, disassembly.c_str(), pBlob);
|
| 603 | + } |
| 604 | + |
| 605 | + bool RewriteAssemblyToText(IDxcBlobEncoding *pSource, LPCSTR pShaderModel, |
| 606 | + LPCWSTR *pArguments, UINT32 argCount, |
| 607 | + const DxcDefine *pDefines, UINT32 defineCount, |
| 608 | + llvm::ArrayRef<LPCSTR> pLookFors, |
| 609 | + llvm::ArrayRef<LPCSTR> pReplacements, |
| 610 | + IDxcBlob **pBlob, bool bRegex = false) { |
| 611 | + CComPtr<IDxcBlob> pProgram; |
| 612 | + std::string disassembly; |
| 613 | + if (!CompileSource(pSource, pShaderModel, pArguments, argCount, pDefines, |
| 614 | + defineCount, &pProgram)) |
| 615 | + return false; |
| 616 | + DisassembleProgram(pProgram, &disassembly); |
| 617 | + PerformReplacementOnDisassembly(disassembly, pLookFors, pReplacements, |
| 618 | + pBlob, bRegex); |
608 | 619 | return true;
|
609 | 620 | }
|
610 | 621 |
|
@@ -4114,7 +4125,7 @@ TEST_F(ValidationTest, ValidatePrintfNotAllowed) {
|
4114 | 4125 | }
|
4115 | 4126 |
|
4116 | 4127 | TEST_F(ValidationTest, ValidateWithHash) {
|
4117 |
| - if (m_ver.SkipDxilVersion(1, 8)) |
| 4128 | + if (m_ver.SkipDxilVersion(1, ShaderModel::kHighestReleasedMinor)) |
4118 | 4129 | return;
|
4119 | 4130 | CComPtr<IDxcBlob> pProgram;
|
4120 | 4131 | CompileSource("float4 main(float a:A, float b:B) : SV_Target { return 1; }",
|
@@ -4149,6 +4160,113 @@ TEST_F(ValidationTest, ValidateWithHash) {
|
4149 | 4160 | VERIFY_ARE_EQUAL(memcmp(Result, pHeader->Hash.Digest, sizeof(Result)), 0);
|
4150 | 4161 | }
|
4151 | 4162 |
|
| 4163 | +TEST_F(ValidationTest, ValidatePreviewBypassHash) { |
| 4164 | + if (m_ver.SkipDxilVersion(1, ShaderModel::kHighestMinor)) |
| 4165 | + return; |
| 4166 | + // If there is no available pre-release version to test, return |
| 4167 | + if (DXIL::CompareVersions(ShaderModel::kHighestMajor, |
| 4168 | + ShaderModel::kHighestMinor, |
| 4169 | + ShaderModel::kHighestReleasedMajor, |
| 4170 | + ShaderModel::kHighestReleasedMinor) <= 0) { |
| 4171 | + return; |
| 4172 | + } |
| 4173 | + |
| 4174 | + // Now test a pre-release version. |
| 4175 | + CComPtr<IDxcBlob> pProgram; |
| 4176 | + LPCSTR pSource = |
| 4177 | + R"(float4 main(float a:A, float b:B) : SV_Target { return 1; })"; |
| 4178 | + |
| 4179 | + CComPtr<IDxcBlobEncoding> pSourceBlob; |
| 4180 | + Utf8ToBlob(m_dllSupport, pSource, &pSourceBlob); |
| 4181 | + |
| 4182 | + LPCSTR pShaderModel = |
| 4183 | + ShaderModel::Get(ShaderModel::Kind::Pixel, ShaderModel::kHighestMajor, |
| 4184 | + ShaderModel::kHighestMinor) |
| 4185 | + ->GetName(); |
| 4186 | + |
| 4187 | + bool result = CompileSource(pSourceBlob, pShaderModel, nullptr, 0, nullptr, 0, |
| 4188 | + &pProgram); |
| 4189 | + VERIFY_IS_TRUE(result); |
| 4190 | + |
| 4191 | + hlsl::DxilContainerHeader *pHeader = |
| 4192 | + (hlsl::DxilContainerHeader *)pProgram->GetBufferPointer(); |
| 4193 | + |
| 4194 | + // Should be equal, this proves the hash is set to the preview bypass hash |
| 4195 | + // when a prerelease version is used |
| 4196 | + VERIFY_ARE_EQUAL(memcmp(&hlsl::PreviewByPassHash, pHeader->Hash.Digest, |
| 4197 | + sizeof(hlsl::PreviewByPassHash)), |
| 4198 | + 0); |
| 4199 | +} |
| 4200 | + |
| 4201 | +TEST_F(ValidationTest, ValidateProgramVersionAgainstDxilModule) { |
| 4202 | + if (m_ver.SkipDxilVersion(1, 8)) |
| 4203 | + return; |
| 4204 | + |
| 4205 | + CComPtr<IDxcBlob> pProgram; |
| 4206 | + LPCSTR pSource = |
| 4207 | + R"(float4 main(float a:A, float b:B) : SV_Target { return 1; })"; |
| 4208 | + |
| 4209 | + CComPtr<IDxcBlobEncoding> pSourceBlob; |
| 4210 | + Utf8ToBlob(m_dllSupport, pSource, &pSourceBlob); |
| 4211 | + |
| 4212 | + LPCSTR pShaderModel = |
| 4213 | + ShaderModel::Get(ShaderModel::Kind::Pixel, 6, 0)->GetName(); |
| 4214 | + |
| 4215 | + bool result = CompileSource(pSourceBlob, pShaderModel, nullptr, 0, nullptr, 0, |
| 4216 | + &pProgram); |
| 4217 | + VERIFY_IS_TRUE(result); |
| 4218 | + |
| 4219 | + hlsl::DxilContainerHeader *pHeader = |
| 4220 | + (hlsl::DxilContainerHeader *)pProgram->GetBufferPointer(); |
| 4221 | + // test that when the program version differs from the dxil module shader |
| 4222 | + // model version, the validator fails |
| 4223 | + DxilPartHeader *pPart = GetDxilPartByType(pHeader, DxilFourCC::DFCC_DXIL); |
| 4224 | + |
| 4225 | + DxilProgramHeader *pMutableProgramHeader = |
| 4226 | + reinterpret_cast<DxilProgramHeader *>(GetDxilPartData(pPart)); |
| 4227 | + int oldMajor = 0; |
| 4228 | + int oldMinor = 0; |
| 4229 | + int newMajor = 0; |
| 4230 | + int newMinor = 0; |
| 4231 | + VERIFY_IS_NOT_NULL(pMutableProgramHeader); |
| 4232 | + uint32_t &PV = pMutableProgramHeader->ProgramVersion; |
| 4233 | + oldMajor = (PV >> 4) & 0xF; // Extract the major version (next 4 bits) |
| 4234 | + oldMinor = PV & 0xF; // Extract the minor version (lowest 4 bits) |
| 4235 | + |
| 4236 | + // Add one to the last bit of the program version, which is 0, because |
| 4237 | + // the program version (shader model version) is 6.0, and we want to |
| 4238 | + // test that the validation fails when the program version is changed to 6.1 |
| 4239 | + PV += 1; |
| 4240 | + |
| 4241 | + newMajor = (PV >> 4) & 0xF; // Extract the major version (next 4 bits) |
| 4242 | + newMinor = PV & 0xF; // Extract the new minor version (lowest 4 bits) |
| 4243 | + |
| 4244 | + // now test that the validation fails |
| 4245 | + CComPtr<IDxcValidator> pValidator; |
| 4246 | + CComPtr<IDxcOperationResult> pResult; |
| 4247 | + unsigned Flags = 0; |
| 4248 | + VERIFY_SUCCEEDED( |
| 4249 | + m_dllSupport.CreateInstance(CLSID_DxcValidator, &pValidator)); |
| 4250 | + |
| 4251 | + HRESULT status; |
| 4252 | + VERIFY_SUCCEEDED(pValidator->Validate(pProgram, Flags, &pResult)); |
| 4253 | + VERIFY_IS_NOT_NULL(pResult); |
| 4254 | + pResult->GetStatus(&status); |
| 4255 | + |
| 4256 | + // expect validation to fail |
| 4257 | + VERIFY_FAILED(status); |
| 4258 | + // validation succeeded prior, so by inference we know that oldMajor / |
| 4259 | + // oldMinor were the old dxil module shader model versions |
| 4260 | + char buffer[100]; |
| 4261 | + std::snprintf(buffer, sizeof(buffer), |
| 4262 | + "error: Program Version is %d.%d but Dxil Module shader model " |
| 4263 | + "version is %d.%d.\nValidation failed.\n", |
| 4264 | + newMajor, newMinor, oldMajor, oldMinor); |
| 4265 | + std::string formattedString = buffer; |
| 4266 | + |
| 4267 | + CheckOperationResultMsgs(pResult, {buffer}, false, false); |
| 4268 | +} |
| 4269 | + |
4152 | 4270 | TEST_F(ValidationTest, ValidateVersionNotAllowed) {
|
4153 | 4271 | if (m_ver.SkipDxilVersion(1, 6))
|
4154 | 4272 | return;
|
|
0 commit comments