|
@@ -16,14 +16,17 @@
|
|
#include "llvm/ADT/StringRef.h"
|
|
#include "llvm/ADT/StringRef.h"
|
|
#include "llvm/Support/Regex.h"
|
|
#include "llvm/Support/Regex.h"
|
|
#include "llvm/ADT/ArrayRef.h"
|
|
#include "llvm/ADT/ArrayRef.h"
|
|
|
|
+#include "dxc/HLSL/DxilContainer.h"
|
|
|
|
|
|
#include <atlbase.h>
|
|
#include <atlbase.h>
|
|
|
|
+#include "dxc/Support/FileIOHelper.h"
|
|
|
|
|
|
#include "WexTestClass.h"
|
|
#include "WexTestClass.h"
|
|
#include "DxcTestUtils.h"
|
|
#include "DxcTestUtils.h"
|
|
#include "HlslTestUtils.h"
|
|
#include "HlslTestUtils.h"
|
|
|
|
|
|
using namespace std;
|
|
using namespace std;
|
|
|
|
+using namespace hlsl;
|
|
|
|
|
|
void CheckOperationSucceeded(IDxcOperationResult *pResult, IDxcBlob **ppBlob) {
|
|
void CheckOperationSucceeded(IDxcOperationResult *pResult, IDxcBlob **ppBlob) {
|
|
HRESULT status;
|
|
HRESULT status;
|
|
@@ -66,6 +69,7 @@ public:
|
|
TEST_METHOD(WhenMultipleModulesThenFail);
|
|
TEST_METHOD(WhenMultipleModulesThenFail);
|
|
TEST_METHOD(WhenUnexpectedEOFThenFail);
|
|
TEST_METHOD(WhenUnexpectedEOFThenFail);
|
|
TEST_METHOD(WhenUnknownBlocksThenFail);
|
|
TEST_METHOD(WhenUnknownBlocksThenFail);
|
|
|
|
+ TEST_METHOD(WhenZeroInputPatchCountWithInputThenFail);
|
|
|
|
|
|
TEST_METHOD(LoadOutputControlPointNotInPatchConstantFunction);
|
|
TEST_METHOD(LoadOutputControlPointNotInPatchConstantFunction);
|
|
TEST_METHOD(StorePatchControlNotInPatchConstantFunction);
|
|
TEST_METHOD(StorePatchControlNotInPatchConstantFunction);
|
|
@@ -125,8 +129,9 @@ public:
|
|
TEST_METHOD(I8Type)
|
|
TEST_METHOD(I8Type)
|
|
TEST_METHOD(EmptyStructInBuffer)
|
|
TEST_METHOD(EmptyStructInBuffer)
|
|
TEST_METHOD(BigStructInBuffer)
|
|
TEST_METHOD(BigStructInBuffer)
|
|
- TEST_METHOD(TGSMRaceCond)
|
|
|
|
- TEST_METHOD(TGSMRaceCond2)
|
|
|
|
|
|
+ // TODO: enable this.
|
|
|
|
+ //TEST_METHOD(TGSMRaceCond)
|
|
|
|
+ //TEST_METHOD(TGSMRaceCond2)
|
|
TEST_METHOD(AddUint64Odd)
|
|
TEST_METHOD(AddUint64Odd)
|
|
|
|
|
|
TEST_METHOD(ClipCullMaxComponents)
|
|
TEST_METHOD(ClipCullMaxComponents)
|
|
@@ -188,6 +193,36 @@ public:
|
|
TEST_METHOD(WhenMetaFlagsUsageDeclThenOK);
|
|
TEST_METHOD(WhenMetaFlagsUsageDeclThenOK);
|
|
TEST_METHOD(WhenMetaFlagsUsageThenFail);
|
|
TEST_METHOD(WhenMetaFlagsUsageThenFail);
|
|
|
|
|
|
|
|
+ TEST_METHOD(WhenRootSigMismatchThenFail);
|
|
|
|
+ TEST_METHOD(WhenRootSigCompatThenSucceed);
|
|
|
|
+ TEST_METHOD(WhenRootSigMatchShaderSucceed_RootConstVis);
|
|
|
|
+ TEST_METHOD(WhenRootSigMatchShaderFail_RootConstVis);
|
|
|
|
+ TEST_METHOD(WhenRootSigMatchShaderSucceed_RootCBV);
|
|
|
|
+ TEST_METHOD(WhenRootSigMatchShaderFail_RootCBV_Range);
|
|
|
|
+ TEST_METHOD(WhenRootSigMatchShaderFail_RootCBV_Space);
|
|
|
|
+ TEST_METHOD(WhenRootSigMatchShaderSucceed_RootSRV);
|
|
|
|
+ TEST_METHOD(WhenRootSigMatchShaderFail_RootSRV_ResType);
|
|
|
|
+ TEST_METHOD(WhenRootSigMatchShaderSucceed_RootUAV);
|
|
|
|
+ TEST_METHOD(WhenRootSigMatchShaderSucceed_DescTable);
|
|
|
|
+ TEST_METHOD(WhenRootSigMatchShaderSucceed_DescTable_GoodRange);
|
|
|
|
+ TEST_METHOD(WhenRootSigMatchShaderSucceed_DescTable_Unbounded);
|
|
|
|
+ TEST_METHOD(WhenRootSigMatchShaderFail_DescTable_Range1);
|
|
|
|
+ TEST_METHOD(WhenRootSigMatchShaderFail_DescTable_Range2);
|
|
|
|
+ TEST_METHOD(WhenRootSigMatchShaderFail_DescTable_Range3);
|
|
|
|
+ TEST_METHOD(WhenRootSigMatchShaderFail_DescTable_Space);
|
|
|
|
+ TEST_METHOD(WhenRootSigMatchShaderSucceed_Unbounded);
|
|
|
|
+ TEST_METHOD(WhenRootSigMatchShaderFail_Unbounded1);
|
|
|
|
+ TEST_METHOD(WhenRootSigMatchShaderFail_Unbounded2);
|
|
|
|
+ TEST_METHOD(WhenRootSigMatchShaderFail_Unbounded3);
|
|
|
|
+ TEST_METHOD(WhenProgramOutSigMissingThenFail);
|
|
|
|
+ TEST_METHOD(WhenProgramOutSigUnexpectedThenFail);
|
|
|
|
+ TEST_METHOD(WhenProgramSigMismatchThenFail);
|
|
|
|
+ TEST_METHOD(WhenProgramInSigMissingThenFail);
|
|
|
|
+ TEST_METHOD(WhenProgramSigMismatchThenFail2);
|
|
|
|
+ TEST_METHOD(WhenProgramPCSigMissingThenFail);
|
|
|
|
+ TEST_METHOD(WhenPSVMismatchThenFail);
|
|
|
|
+ TEST_METHOD(WhenFeatureInfoMismatchThenFail);
|
|
|
|
+
|
|
dxc::DxcDllSupport m_dllSupport;
|
|
dxc::DxcDllSupport m_dllSupport;
|
|
|
|
|
|
void TestCheck(LPCWSTR name) {
|
|
void TestCheck(LPCWSTR name) {
|
|
@@ -200,12 +235,13 @@ public:
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- bool CheckOperationResultMsg(IDxcOperationResult *pResult,
|
|
|
|
- const char *pErrorMsg, bool maySucceedAnyway,
|
|
|
|
|
|
+ bool CheckOperationResultMsgs(IDxcOperationResult *pResult,
|
|
|
|
+ llvm::ArrayRef<LPCSTR> pErrorMsgs, bool maySucceedAnyway,
|
|
bool bRegex) {
|
|
bool bRegex) {
|
|
HRESULT status;
|
|
HRESULT status;
|
|
VERIFY_SUCCEEDED(pResult->GetStatus(&status));
|
|
VERIFY_SUCCEEDED(pResult->GetStatus(&status));
|
|
- if (pErrorMsg == nullptr) {
|
|
|
|
|
|
+ if (pErrorMsgs.empty() ||
|
|
|
|
+ (pErrorMsgs.size() == 1 && !pErrorMsgs[0])) {
|
|
VERIFY_SUCCEEDED(status);
|
|
VERIFY_SUCCEEDED(status);
|
|
}
|
|
}
|
|
else {
|
|
else {
|
|
@@ -215,27 +251,29 @@ public:
|
|
//VERIFY_FAILED(status);
|
|
//VERIFY_FAILED(status);
|
|
CComPtr<IDxcBlobEncoding> text;
|
|
CComPtr<IDxcBlobEncoding> text;
|
|
VERIFY_SUCCEEDED(pResult->GetErrorBuffer(&text));
|
|
VERIFY_SUCCEEDED(pResult->GetErrorBuffer(&text));
|
|
- if (bRegex) {
|
|
|
|
- llvm::Regex RE(pErrorMsg);
|
|
|
|
- std::string reErrors;
|
|
|
|
- VERIFY_IS_TRUE(RE.isValid(reErrors));
|
|
|
|
- VERIFY_IS_TRUE(RE.match(llvm::StringRef((const char *)text->GetBufferPointer(), text->GetBufferSize())));
|
|
|
|
- } else {
|
|
|
|
- const char *pStart = (const char *)text->GetBufferPointer();
|
|
|
|
- const char *pEnd = pStart + text->GetBufferSize();
|
|
|
|
- const char *pMatch = std::search(pStart, pEnd, pErrorMsg, pErrorMsg + strlen(pErrorMsg));
|
|
|
|
- if (pEnd == pMatch) {
|
|
|
|
- WEX::Logging::Log::Comment(WEX::Common::String().Format(
|
|
|
|
- L"Unable to find '%S' in text:\r\n%.*S", pErrorMsg, (pEnd - pStart),
|
|
|
|
- pStart));
|
|
|
|
|
|
+ for (auto pErrorMsg : pErrorMsgs) {
|
|
|
|
+ if (bRegex) {
|
|
|
|
+ llvm::Regex RE(pErrorMsg);
|
|
|
|
+ std::string reErrors;
|
|
|
|
+ VERIFY_IS_TRUE(RE.isValid(reErrors));
|
|
|
|
+ VERIFY_IS_TRUE(RE.match(llvm::StringRef((const char *)text->GetBufferPointer(), text->GetBufferSize())));
|
|
|
|
+ } else {
|
|
|
|
+ const char *pStart = (const char *)text->GetBufferPointer();
|
|
|
|
+ const char *pEnd = pStart + text->GetBufferSize();
|
|
|
|
+ const char *pMatch = std::search(pStart, pEnd, pErrorMsg, pErrorMsg + strlen(pErrorMsg));
|
|
|
|
+ if (pEnd == pMatch) {
|
|
|
|
+ WEX::Logging::Log::Comment(WEX::Common::String().Format(
|
|
|
|
+ L"Unable to find '%S' in text:\r\n%.*S", pErrorMsg, (pEnd - pStart),
|
|
|
|
+ pStart));
|
|
|
|
+ }
|
|
|
|
+ VERIFY_ARE_NOT_EQUAL(pEnd, pMatch);
|
|
}
|
|
}
|
|
- VERIFY_ARE_NOT_EQUAL(pEnd, pMatch);
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
|
|
- void CheckValidationMsg(IDxcBlob *pBlob, const char *pErrorMsg, bool bRegex = false) {
|
|
|
|
|
|
+ void CheckValidationMsgs(IDxcBlob *pBlob, llvm::ArrayRef<LPCSTR> pErrorMsgs, bool bRegex = false) {
|
|
CComPtr<IDxcValidator> pValidator;
|
|
CComPtr<IDxcValidator> pValidator;
|
|
CComPtr<IDxcOperationResult> pResult;
|
|
CComPtr<IDxcOperationResult> pResult;
|
|
|
|
|
|
@@ -246,10 +284,10 @@ public:
|
|
VERIFY_SUCCEEDED(m_dllSupport.CreateInstance(CLSID_DxcValidator, &pValidator));
|
|
VERIFY_SUCCEEDED(m_dllSupport.CreateInstance(CLSID_DxcValidator, &pValidator));
|
|
VERIFY_SUCCEEDED(pValidator->Validate(pBlob, DxcValidatorFlags_Default, &pResult));
|
|
VERIFY_SUCCEEDED(pValidator->Validate(pBlob, DxcValidatorFlags_Default, &pResult));
|
|
|
|
|
|
- CheckOperationResultMsg(pResult, pErrorMsg, false, bRegex);
|
|
|
|
|
|
+ CheckOperationResultMsgs(pResult, pErrorMsgs, false, bRegex);
|
|
}
|
|
}
|
|
|
|
|
|
- void CheckValidationMsg(const char *pBlob, size_t blobSize, const char *pErrorMsg, bool bRegex = false) {
|
|
|
|
|
|
+ void CheckValidationMsgs(const char *pBlob, size_t blobSize, llvm::ArrayRef<LPCSTR> pErrorMsgs, bool bRegex = false) {
|
|
if (!m_dllSupport.IsEnabled()) {
|
|
if (!m_dllSupport.IsEnabled()) {
|
|
VERIFY_SUCCEEDED(m_dllSupport.Initialize());
|
|
VERIFY_SUCCEEDED(m_dllSupport.Initialize());
|
|
}
|
|
}
|
|
@@ -257,7 +295,7 @@ public:
|
|
CComPtr<IDxcBlobEncoding> pBlobEncoding; // Encoding doesn't actually matter, it's binary.
|
|
CComPtr<IDxcBlobEncoding> pBlobEncoding; // Encoding doesn't actually matter, it's binary.
|
|
VERIFY_SUCCEEDED(m_dllSupport.CreateInstance(CLSID_DxcLibrary, &pLibrary));
|
|
VERIFY_SUCCEEDED(m_dllSupport.CreateInstance(CLSID_DxcLibrary, &pLibrary));
|
|
VERIFY_SUCCEEDED(pLibrary->CreateBlobWithEncodingFromPinned((LPBYTE)pBlob, blobSize, CP_UTF8, &pBlobEncoding));
|
|
VERIFY_SUCCEEDED(pLibrary->CreateBlobWithEncodingFromPinned((LPBYTE)pBlob, blobSize, CP_UTF8, &pBlobEncoding));
|
|
- CheckValidationMsg(pBlobEncoding, pErrorMsg, bRegex);
|
|
|
|
|
|
+ CheckValidationMsgs(pBlobEncoding, pErrorMsgs, bRegex);
|
|
}
|
|
}
|
|
|
|
|
|
void CompileSource(IDxcBlobEncoding *pSource, LPCSTR pShaderModel,
|
|
void CompileSource(IDxcBlobEncoding *pSource, LPCSTR pShaderModel,
|
|
@@ -276,6 +314,9 @@ public:
|
|
VERIFY_SUCCEEDED(pCompiler->Compile(pSource, L"hlsl.hlsl", L"main",
|
|
VERIFY_SUCCEEDED(pCompiler->Compile(pSource, L"hlsl.hlsl", L"main",
|
|
shWide, nullptr, 0, nullptr, 0, nullptr,
|
|
shWide, nullptr, 0, nullptr, 0, nullptr,
|
|
&pResult));
|
|
&pResult));
|
|
|
|
+ HRESULT hr;
|
|
|
|
+ VERIFY_SUCCEEDED(pResult->GetStatus(&hr));
|
|
|
|
+ VERIFY_SUCCEEDED(hr);
|
|
VERIFY_SUCCEEDED(pResult->GetResult(pResultBlob));
|
|
VERIFY_SUCCEEDED(pResult->GetResult(pResultBlob));
|
|
}
|
|
}
|
|
|
|
|
|
@@ -313,13 +354,11 @@ public:
|
|
m_dllSupport.CreateInstance(CLSID_DxcAssembler, &pAssembler));
|
|
m_dllSupport.CreateInstance(CLSID_DxcAssembler, &pAssembler));
|
|
VERIFY_SUCCEEDED(pAssembler->AssembleToContainer(pText, &pAssembleResult));
|
|
VERIFY_SUCCEEDED(pAssembler->AssembleToContainer(pText, &pAssembleResult));
|
|
|
|
|
|
- for (auto pErrorMsg : pErrorMsgs) {
|
|
|
|
- if (!CheckOperationResultMsg(pAssembleResult, pErrorMsg, true, bRegex)) {
|
|
|
|
- // Assembly succeeded, try validation.
|
|
|
|
- CComPtr<IDxcBlob> pBlob;
|
|
|
|
- VERIFY_SUCCEEDED(pAssembleResult->GetResult(&pBlob));
|
|
|
|
- CheckValidationMsg(pBlob, pErrorMsg, bRegex);
|
|
|
|
- }
|
|
|
|
|
|
+ if (!CheckOperationResultMsgs(pAssembleResult, pErrorMsgs, true, bRegex)) {
|
|
|
|
+ // Assembly succeeded, try validation.
|
|
|
|
+ CComPtr<IDxcBlob> pBlob;
|
|
|
|
+ VERIFY_SUCCEEDED(pAssembleResult->GetResult(&pBlob));
|
|
|
|
+ CheckValidationMsgs(pBlob, pErrorMsgs, bRegex);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -384,21 +423,81 @@ public:
|
|
VERIFY_SUCCEEDED(
|
|
VERIFY_SUCCEEDED(
|
|
m_dllSupport.CreateInstance(CLSID_DxcAssembler, &pAssembler));
|
|
m_dllSupport.CreateInstance(CLSID_DxcAssembler, &pAssembler));
|
|
VERIFY_SUCCEEDED(pAssembler->AssembleToContainer(pText, &pAssembleResult));
|
|
VERIFY_SUCCEEDED(pAssembler->AssembleToContainer(pText, &pAssembleResult));
|
|
- for (auto pErrorMsg : pErrorMsgs) {
|
|
|
|
- if (!CheckOperationResultMsg(pAssembleResult, pErrorMsg, true, bRegex)) {
|
|
|
|
- // Assembly succeeded, try validation.
|
|
|
|
- CComPtr<IDxcBlob> pBlob;
|
|
|
|
- VERIFY_SUCCEEDED(pAssembleResult->GetResult(&pBlob));
|
|
|
|
- CheckValidationMsg(pBlob, pErrorMsg, bRegex);
|
|
|
|
|
|
+ if (!CheckOperationResultMsgs(pAssembleResult, pErrorMsgs, true, bRegex)) {
|
|
|
|
+ // Assembly succeeded, try validation.
|
|
|
|
+ CComPtr<IDxcBlob> pBlob;
|
|
|
|
+ VERIFY_SUCCEEDED(pAssembleResult->GetResult(&pBlob));
|
|
|
|
+ CheckValidationMsgs(pBlob, pErrorMsgs, bRegex);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // compile one or two sources, validate module from 1 with container parts from 2, check messages
|
|
|
|
+ void ReplaceContainerPartsCheckMsgs(LPCSTR pSource1, LPCSTR pSource2, LPCSTR pShaderModel,
|
|
|
|
+ llvm::ArrayRef<DxilFourCC> PartsToReplace,
|
|
|
|
+ llvm::ArrayRef<LPCSTR> pErrorMsgs) {
|
|
|
|
+ CComPtr<IDxcBlob> pProgram1, pProgram2;
|
|
|
|
+ CompileSource(pSource1, pShaderModel, &pProgram1);
|
|
|
|
+ VERIFY_IS_NOT_NULL(pProgram1);
|
|
|
|
+ if (pSource2) {
|
|
|
|
+ CompileSource(pSource2, pShaderModel, &pProgram2);
|
|
|
|
+ VERIFY_IS_NOT_NULL(pProgram2);
|
|
|
|
+ } else {
|
|
|
|
+ pProgram2 = pProgram1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // construct container with moudle from pProgram1 with other parts from pProgram2:
|
|
|
|
+ const DxilContainerHeader *pHeader1 = IsDxilContainerLike(pProgram1->GetBufferPointer(), pProgram1->GetBufferSize());
|
|
|
|
+ VERIFY_IS_NOT_NULL(pHeader1);
|
|
|
|
+ const DxilContainerHeader *pHeader2 = IsDxilContainerLike(pProgram2->GetBufferPointer(), pProgram2->GetBufferSize());
|
|
|
|
+ VERIFY_IS_NOT_NULL(pHeader2);
|
|
|
|
+
|
|
|
|
+ DxilContainerWriter *pContainerWriter = NewDxilContainerWriter();
|
|
|
|
+
|
|
|
|
+ // Add desired parts from first container
|
|
|
|
+ for (auto pPart : pHeader1) {
|
|
|
|
+ for (auto dfcc : PartsToReplace) {
|
|
|
|
+ if (dfcc == pPart->PartFourCC) {
|
|
|
|
+ pPart = nullptr;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
+ if (!pPart)
|
|
|
|
+ continue;
|
|
|
|
+ pContainerWriter->AddPart(pPart->PartFourCC, pPart->PartSize, [=](AbstractMemoryStream *pStream) {
|
|
|
|
+ ULONG cbWritten = 0;
|
|
|
|
+ pStream->Write(GetDxilPartData(pPart), pPart->PartSize, &cbWritten);
|
|
|
|
+ });
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ // Add desired parts from second container
|
|
|
|
+ for (auto pPart : pHeader2) {
|
|
|
|
+ for (auto dfcc : PartsToReplace) {
|
|
|
|
+ if (dfcc == pPart->PartFourCC) {
|
|
|
|
+ pContainerWriter->AddPart(pPart->PartFourCC, pPart->PartSize, [=](AbstractMemoryStream *pStream) {
|
|
|
|
+ ULONG cbWritten = 0;
|
|
|
|
+ pStream->Write(GetDxilPartData(pPart), pPart->PartSize, &cbWritten);
|
|
|
|
+ });
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Write the container
|
|
|
|
+ CComPtr<IMalloc> pMalloc;
|
|
|
|
+ VERIFY_SUCCEEDED(CoGetMalloc(1, &pMalloc));
|
|
|
|
+ CComPtr<AbstractMemoryStream> pOutputStream;
|
|
|
|
+ VERIFY_SUCCEEDED(CreateMemoryStream(pMalloc, &pOutputStream));
|
|
|
|
+ pOutputStream->Reserve(pContainerWriter->size());
|
|
|
|
+ pContainerWriter->write(pOutputStream);
|
|
|
|
+
|
|
|
|
+ CheckValidationMsgs((const char *)pOutputStream->GetPtr(), pOutputStream->GetPtrSize(), pErrorMsgs, /*bRegex*/false);
|
|
}
|
|
}
|
|
};
|
|
};
|
|
|
|
|
|
TEST_F(ValidationTest, WhenCorrectThenOK) {
|
|
TEST_F(ValidationTest, WhenCorrectThenOK) {
|
|
CComPtr<IDxcBlob> pProgram;
|
|
CComPtr<IDxcBlob> pProgram;
|
|
CompileSource("float4 main() : SV_Target { return 1; }", "ps_6_0", &pProgram);
|
|
CompileSource("float4 main() : SV_Target { return 1; }", "ps_6_0", &pProgram);
|
|
- CheckValidationMsg(pProgram, nullptr);
|
|
|
|
|
|
+ CheckValidationMsgs(pProgram, nullptr);
|
|
}
|
|
}
|
|
|
|
|
|
// Lots of these going on below for simplicity in setting up payloads.
|
|
// Lots of these going on below for simplicity in setting up payloads.
|
|
@@ -413,7 +512,7 @@ TEST_F(ValidationTest, WhenMisalignedThenFail) {
|
|
const char blob[] = {
|
|
const char blob[] = {
|
|
'B', 'C',
|
|
'B', 'C',
|
|
};
|
|
};
|
|
- CheckValidationMsg(blob, _countof(blob), "Invalid bitcode size");
|
|
|
|
|
|
+ CheckValidationMsgs(blob, _countof(blob), "Invalid bitcode size");
|
|
}
|
|
}
|
|
|
|
|
|
TEST_F(ValidationTest, WhenEmptyFileThenFail) {
|
|
TEST_F(ValidationTest, WhenEmptyFileThenFail) {
|
|
@@ -421,7 +520,7 @@ TEST_F(ValidationTest, WhenEmptyFileThenFail) {
|
|
const char blob[] = {
|
|
const char blob[] = {
|
|
'B', 'C', 0xc0, 0xde
|
|
'B', 'C', 0xc0, 0xde
|
|
};
|
|
};
|
|
- CheckValidationMsg(blob, _countof(blob), "Malformed IR file");
|
|
|
|
|
|
+ CheckValidationMsgs(blob, _countof(blob), "Malformed IR file");
|
|
}
|
|
}
|
|
|
|
|
|
TEST_F(ValidationTest, WhenIncorrectMagicThenFail) {
|
|
TEST_F(ValidationTest, WhenIncorrectMagicThenFail) {
|
|
@@ -429,14 +528,14 @@ TEST_F(ValidationTest, WhenIncorrectMagicThenFail) {
|
|
const char blob[] = {
|
|
const char blob[] = {
|
|
'B', 'C', 0xc0, 0xdd
|
|
'B', 'C', 0xc0, 0xdd
|
|
};
|
|
};
|
|
- CheckValidationMsg(blob, _countof(blob), "Invalid bitcode signature");
|
|
|
|
|
|
+ CheckValidationMsgs(blob, _countof(blob), "Invalid bitcode signature");
|
|
}
|
|
}
|
|
|
|
|
|
TEST_F(ValidationTest, WhenIncorrectTargetTripleThenFail) {
|
|
TEST_F(ValidationTest, WhenIncorrectTargetTripleThenFail) {
|
|
const char blob[] = {
|
|
const char blob[] = {
|
|
'B', 'C', 0xc0, 0xde
|
|
'B', 'C', 0xc0, 0xde
|
|
};
|
|
};
|
|
- CheckValidationMsg(blob, _countof(blob), "Malformed IR file");
|
|
|
|
|
|
+ CheckValidationMsgs(blob, _countof(blob), "Malformed IR file");
|
|
}
|
|
}
|
|
|
|
|
|
TEST_F(ValidationTest, WhenMultipleModulesThenFail) {
|
|
TEST_F(ValidationTest, WhenMultipleModulesThenFail) {
|
|
@@ -449,7 +548,7 @@ TEST_F(ValidationTest, WhenMultipleModulesThenFail) {
|
|
// Trigger the case we're looking for now
|
|
// Trigger the case we're looking for now
|
|
0x21, 0x0c, 0x00, 0x00, // Enter sub-block, BlockID = 8, Code Size=3, padding x2
|
|
0x21, 0x0c, 0x00, 0x00, // Enter sub-block, BlockID = 8, Code Size=3, padding x2
|
|
};
|
|
};
|
|
- CheckValidationMsg(blob, _countof(blob), "Unused bits in buffer");
|
|
|
|
|
|
+ CheckValidationMsgs(blob, _countof(blob), "Unused bits in buffer");
|
|
}
|
|
}
|
|
|
|
|
|
TEST_F(ValidationTest, WhenUnexpectedEOFThenFail) {
|
|
TEST_F(ValidationTest, WhenUnexpectedEOFThenFail) {
|
|
@@ -459,7 +558,7 @@ TEST_F(ValidationTest, WhenUnexpectedEOFThenFail) {
|
|
0x21, 0x0c, 0x00, 0x00, // Enter sub-block, BlockID = 8, Code Size=3, padding x2
|
|
0x21, 0x0c, 0x00, 0x00, // Enter sub-block, BlockID = 8, Code Size=3, padding x2
|
|
0x00, 0x00, 0x00, 0x00, // NumWords = 0
|
|
0x00, 0x00, 0x00, 0x00, // NumWords = 0
|
|
};
|
|
};
|
|
- CheckValidationMsg(blob, _countof(blob), "Invalid record");
|
|
|
|
|
|
+ CheckValidationMsgs(blob, _countof(blob), "Invalid record");
|
|
}
|
|
}
|
|
|
|
|
|
TEST_F(ValidationTest, WhenUnknownBlocksThenFail) {
|
|
TEST_F(ValidationTest, WhenUnknownBlocksThenFail) {
|
|
@@ -467,7 +566,15 @@ TEST_F(ValidationTest, WhenUnknownBlocksThenFail) {
|
|
'B', 'C', 0xc0, 0xde, // Signature
|
|
'B', 'C', 0xc0, 0xde, // Signature
|
|
0x31, 0x00, 0x00, 0x00 // Enter sub-block, BlockID != 8
|
|
0x31, 0x00, 0x00, 0x00 // Enter sub-block, BlockID != 8
|
|
};
|
|
};
|
|
- CheckValidationMsg(blob, _countof(blob), "Unrecognized block found");
|
|
|
|
|
|
+ CheckValidationMsgs(blob, _countof(blob), "Unrecognized block found");
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+TEST_F(ValidationTest, WhenZeroInputPatchCountWithInputThenFail) {
|
|
|
|
+ RewriteAssemblyCheckMsg(
|
|
|
|
+ L"..\\CodeGenHLSL\\SimpleHs1.hlsl", "hs_6_0",
|
|
|
|
+ "void ()* @\"\\01?HSPerPatchFunc@@YA?AUHSPerPatchData@@V?$InputPatch@UPSSceneIn@@$02@@@Z.flat\", i32 3, i32 3",
|
|
|
|
+ "void ()* @\"\\01?HSPerPatchFunc@@YA?AUHSPerPatchData@@V?$InputPatch@UPSSceneIn@@$02@@@Z.flat\", i32 0, i32 3",
|
|
|
|
+ "When HS input control point count is 0, no input signature should exist");
|
|
}
|
|
}
|
|
|
|
|
|
TEST_F(ValidationTest, WhenInstrDisallowedThenFail) {
|
|
TEST_F(ValidationTest, WhenInstrDisallowedThenFail) {
|
|
@@ -599,7 +706,7 @@ TEST_F(ValidationTest, HsAttributeFail) {
|
|
},
|
|
},
|
|
{"i32 36, i32 36, i32 0, i32 0, i32 0, float 6.500000e+01"
|
|
{"i32 36, i32 36, i32 0, i32 0, i32 0, float 6.500000e+01"
|
|
},
|
|
},
|
|
- {"HS input control point count must be [1..32]. 36 specified",
|
|
|
|
|
|
+ {"HS input control point count must be [0..32]. 36 specified",
|
|
"Invalid Tessellator Domain specified. Must be isoline, tri or quad",
|
|
"Invalid Tessellator Domain specified. Must be isoline, tri or quad",
|
|
"Invalid Tessellator Partitioning specified",
|
|
"Invalid Tessellator Partitioning specified",
|
|
"Invalid Tessellator Output Primitive specified",
|
|
"Invalid Tessellator Output Primitive specified",
|
|
@@ -821,14 +928,7 @@ TEST_F(ValidationTest, UavBarrierFail) {
|
|
"sync in a non-Compute Shader must only sync UAV (sync_uglobal)"});
|
|
"sync in a non-Compute Shader must only sync UAV (sync_uglobal)"});
|
|
}
|
|
}
|
|
TEST_F(ValidationTest, UndefValueFail) {
|
|
TEST_F(ValidationTest, UndefValueFail) {
|
|
- RewriteAssemblyCheckMsg(
|
|
|
|
- L"..\\CodeGenHLSL\\UndefValue.hlsl", "ps_6_0",
|
|
|
|
- {"fadd fast float %([0-9]+)"
|
|
|
|
- },
|
|
|
|
- {"fadd fast float undef"
|
|
|
|
- },
|
|
|
|
- {"Instructions should not read uninitialized value"},
|
|
|
|
- /*bRegex*/ true);
|
|
|
|
|
|
+ TestCheck(L"..\\CodeGenHLSL\\UndefValue.hlsl");
|
|
}
|
|
}
|
|
TEST_F(ValidationTest, UpdateCounterFail) {
|
|
TEST_F(ValidationTest, UpdateCounterFail) {
|
|
RewriteAssemblyCheckMsg(
|
|
RewriteAssemblyCheckMsg(
|
|
@@ -1320,17 +1420,19 @@ TEST_F(ValidationTest, BigStructInBuffer) {
|
|
TestCheck(L"..\\CodeGenHLSL\\BigStructInBuffer.hlsl");
|
|
TestCheck(L"..\\CodeGenHLSL\\BigStructInBuffer.hlsl");
|
|
}
|
|
}
|
|
|
|
|
|
-TEST_F(ValidationTest, TGSMRaceCond) {
|
|
|
|
- TestCheck(L"..\\CodeGenHLSL\\RaceCond.hlsl");
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-TEST_F(ValidationTest, TGSMRaceCond2) {
|
|
|
|
- RewriteAssemblyCheckMsg(L"..\\CodeGenHLSL\\structInBuffer.hlsl", "cs_6_0",
|
|
|
|
- "ret void",
|
|
|
|
- "store i32 0, i32 addrspace(3)* @\"\\01?sharedData@@3UFoo@@A.3\", align 4\n"
|
|
|
|
- "ret void",
|
|
|
|
- "Race condition writing to shared memory detected, consider making this write conditional");
|
|
|
|
-}
|
|
|
|
|
|
+// TODO: enable this.
|
|
|
|
+//TEST_F(ValidationTest, TGSMRaceCond) {
|
|
|
|
+// TestCheck(L"..\\CodeGenHLSL\\RaceCond.hlsl");
|
|
|
|
+//}
|
|
|
|
+//
|
|
|
|
+//TEST_F(ValidationTest, TGSMRaceCond2) {
|
|
|
|
+// RewriteAssemblyCheckMsg(L"..\\CodeGenHLSL\\structInBuffer.hlsl", "cs_6_0",
|
|
|
|
+// "ret void",
|
|
|
|
+// "%TID = call i32 @dx.op.flattenedThreadIdInGroup.i32(i32 96)\n"
|
|
|
|
+// "store i32 %TID, i32 addrspace(3)* @\"\\01?sharedData@@3UFoo@@A.3\", align 4\n"
|
|
|
|
+// "ret void",
|
|
|
|
+// "Race condition writing to shared memory detected, consider making this write conditional");
|
|
|
|
+//}
|
|
|
|
|
|
TEST_F(ValidationTest, AddUint64Odd) {
|
|
TEST_F(ValidationTest, AddUint64Odd) {
|
|
TestCheck(L"..\\CodeGenHLSL\\AddUint64Odd.hlsl");
|
|
TestCheck(L"..\\CodeGenHLSL\\AddUint64Odd.hlsl");
|
|
@@ -2017,6 +2119,685 @@ float4 main(float4 f4 : Input, out float d0 : SV_Depth, out float d1 : SV_Target
|
|
/*bRegex*/true);
|
|
/*bRegex*/true);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+TEST_F(ValidationTest, WhenRootSigMismatchThenFail) {
|
|
|
|
+ ReplaceContainerPartsCheckMsgs(
|
|
|
|
+ "float c; [RootSignature ( \"RootConstants(b0, num32BitConstants = 1)\" )] float4 main() : semantic { return c; }",
|
|
|
|
+ "[RootSignature ( \"\" )] float4 main() : semantic { return 0; }",
|
|
|
|
+ "vs_6_0",
|
|
|
|
+ {DFCC_RootSignature},
|
|
|
|
+ {
|
|
|
|
+ "Root Signature in DXIL container is not compatible with shader.",
|
|
|
|
+ "Validation failed."
|
|
|
|
+ }
|
|
|
|
+ );
|
|
|
|
+}
|
|
|
|
+TEST_F(ValidationTest, WhenRootSigCompatThenSucceed) {
|
|
|
|
+ ReplaceContainerPartsCheckMsgs(
|
|
|
|
+ "[RootSignature ( \"\" )] float4 main() : semantic { return 0; }",
|
|
|
|
+ "float c; [RootSignature ( \"RootConstants(b0, num32BitConstants = 1)\" )] float4 main() : semantic { return c; }",
|
|
|
|
+ "vs_6_0",
|
|
|
|
+ {DFCC_RootSignature},
|
|
|
|
+ {}
|
|
|
|
+ );
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+TEST_F(ValidationTest, WhenRootSigMatchShaderSucceed_RootConstVis) {
|
|
|
|
+ ReplaceContainerPartsCheckMsgs(
|
|
|
|
+ "float c; float4 main() : semantic { return c; }",
|
|
|
|
+ "[RootSignature ( \"RootConstants(b0, visibility = SHADER_VISIBILITY_VERTEX, num32BitConstants = 1)\" )]"
|
|
|
|
+ " float4 main() : semantic { return 0; }",
|
|
|
|
+ "vs_6_0",
|
|
|
|
+ {DFCC_RootSignature},
|
|
|
|
+ {}
|
|
|
|
+ );
|
|
|
|
+}
|
|
|
|
+TEST_F(ValidationTest, WhenRootSigMatchShaderFail_RootConstVis) {
|
|
|
|
+ ReplaceContainerPartsCheckMsgs(
|
|
|
|
+ "float c; float4 main() : semantic { return c; }",
|
|
|
|
+ "[RootSignature ( \"RootConstants(b0, visibility = SHADER_VISIBILITY_PIXEL, num32BitConstants = 1)\" )]"
|
|
|
|
+ " float4 main() : semantic { return 0; }",
|
|
|
|
+ "vs_6_0",
|
|
|
|
+ {DFCC_RootSignature},
|
|
|
|
+ {
|
|
|
|
+ "Root Signature in DXIL container is not compatible with shader.",
|
|
|
|
+ "Validation failed."
|
|
|
|
+ }
|
|
|
|
+ );
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+TEST_F(ValidationTest, WhenRootSigMatchShaderSucceed_RootCBV) {
|
|
|
|
+ ReplaceContainerPartsCheckMsgs(
|
|
|
|
+ "struct Foo { float a; int4 b; }; "
|
|
|
|
+ "ConstantBuffer<Foo> cb1 : register(b2, space5); "
|
|
|
|
+ "float4 main() : semantic { return cb1.b.x; }",
|
|
|
|
+ "[RootSignature ( \"CBV(b2, space = 5)\" )]"
|
|
|
|
+ " float4 main() : semantic { return 0; }",
|
|
|
|
+ "vs_6_0",
|
|
|
|
+ {DFCC_RootSignature},
|
|
|
|
+ {}
|
|
|
|
+ );
|
|
|
|
+}
|
|
|
|
+TEST_F(ValidationTest, WhenRootSigMatchShaderFail_RootCBV_Range) {
|
|
|
|
+ ReplaceContainerPartsCheckMsgs(
|
|
|
|
+ "struct Foo { float a; int4 b; }; "
|
|
|
|
+ "ConstantBuffer<Foo> cb1 : register(b0, space5); "
|
|
|
|
+ "float4 main() : semantic { return cb1.b.x; }",
|
|
|
|
+ "[RootSignature ( \"CBV(b2, space = 5)\" )]"
|
|
|
|
+ " float4 main() : semantic { return 0; }",
|
|
|
|
+ "vs_6_0",
|
|
|
|
+ {DFCC_RootSignature},
|
|
|
|
+ {
|
|
|
|
+ "Root Signature in DXIL container is not compatible with shader.",
|
|
|
|
+ "Validation failed."
|
|
|
|
+ }
|
|
|
|
+ );
|
|
|
|
+}
|
|
|
|
+TEST_F(ValidationTest, WhenRootSigMatchShaderFail_RootCBV_Space) {
|
|
|
|
+ ReplaceContainerPartsCheckMsgs(
|
|
|
|
+ "struct Foo { float a; int4 b; }; "
|
|
|
|
+ "ConstantBuffer<Foo> cb1 : register(b2, space7); "
|
|
|
|
+ "float4 main() : semantic { return cb1.b.x; }",
|
|
|
|
+ "[RootSignature ( \"CBV(b2, space = 5)\" )]"
|
|
|
|
+ " float4 main() : semantic { return 0; }",
|
|
|
|
+ "vs_6_0",
|
|
|
|
+ {DFCC_RootSignature},
|
|
|
|
+ {
|
|
|
|
+ "Root Signature in DXIL container is not compatible with shader.",
|
|
|
|
+ "Validation failed."
|
|
|
|
+ }
|
|
|
|
+ );
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+TEST_F(ValidationTest, WhenRootSigMatchShaderSucceed_RootSRV) {
|
|
|
|
+ ReplaceContainerPartsCheckMsgs(
|
|
|
|
+ "struct Foo { float4 a; }; "
|
|
|
|
+ "StructuredBuffer<Foo> buf1 : register(t1, space3); "
|
|
|
|
+ "float4 main(float4 a : AAA) : SV_Target { return buf1[a.x].a; }",
|
|
|
|
+ "[RootSignature ( \"SRV(t1, space = 3)\" )]"
|
|
|
|
+ " float4 main() : SV_Target { return 0; }",
|
|
|
|
+ "ps_6_0",
|
|
|
|
+ {DFCC_RootSignature},
|
|
|
|
+ {}
|
|
|
|
+ );
|
|
|
|
+}
|
|
|
|
+TEST_F(ValidationTest, WhenRootSigMatchShaderFail_RootSRV_ResType) {
|
|
|
|
+ ReplaceContainerPartsCheckMsgs(
|
|
|
|
+ "struct Foo { float4 a; }; "
|
|
|
|
+ "StructuredBuffer<Foo> buf1 : register(t1, space3); "
|
|
|
|
+ "float4 main(float4 a : AAA) : SV_Target { return buf1[a.x].a; }",
|
|
|
|
+ "[RootSignature ( \"UAV(u1, space = 3)\" )]"
|
|
|
|
+ " float4 main() : SV_Target { return 0; }",
|
|
|
|
+ "ps_6_0",
|
|
|
|
+ {DFCC_RootSignature},
|
|
|
|
+ {
|
|
|
|
+ "Root Signature in DXIL container is not compatible with shader.",
|
|
|
|
+ "Validation failed."
|
|
|
|
+ }
|
|
|
|
+ );
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+TEST_F(ValidationTest, WhenRootSigMatchShaderSucceed_RootUAV) {
|
|
|
|
+ ReplaceContainerPartsCheckMsgs(
|
|
|
|
+ "struct Foo { float4 a; }; "
|
|
|
|
+ "RWStructuredBuffer<Foo> buf1 : register(u1, space3); "
|
|
|
|
+ "float4 main(float4 a : AAA) : SV_Target { return buf1[a.x].a; }",
|
|
|
|
+ "[RootSignature ( \"UAV(u1, space = 3)\" )]"
|
|
|
|
+ " float4 main() : SV_Target { return 0; }",
|
|
|
|
+ "ps_6_0",
|
|
|
|
+ {DFCC_RootSignature},
|
|
|
|
+ {}
|
|
|
|
+ );
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+TEST_F(ValidationTest, WhenRootSigMatchShaderSucceed_DescTable) {
|
|
|
|
+ ReplaceContainerPartsCheckMsgs(
|
|
|
|
+ "struct Foo { int a; float4 b; };"
|
|
|
|
+ ""
|
|
|
|
+ "ConstantBuffer<Foo> cb1[4] : register(b2, space5);"
|
|
|
|
+ "Texture2D<float4> tex1[8] : register(t1, space3);"
|
|
|
|
+ "RWBuffer<float4> buf1[6] : register(u33, space17);"
|
|
|
|
+ "SamplerState sampler1[5] : register(s0, space0);"
|
|
|
|
+ ""
|
|
|
|
+ "float4 main(float4 a : AAA) : SV_TARGET"
|
|
|
|
+ "{"
|
|
|
|
+ " return buf1[a.x][a.y] + cb1[a.x].b + tex1[a.x].Sample(sampler1[a.x], a.xy);"
|
|
|
|
+ "}",
|
|
|
|
+ "[RootSignature(\"DescriptorTable( SRV(t1,space=3,numDescriptors=8), "
|
|
|
|
+ "CBV(b2,space=5,numDescriptors=4), "
|
|
|
|
+ "UAV(u33,space=17,numDescriptors=6)), "
|
|
|
|
+ "DescriptorTable(Sampler(s0, numDescriptors=5))\")]"
|
|
|
|
+ " float4 main() : SV_Target { return 0; }",
|
|
|
|
+ "ps_6_0",
|
|
|
|
+ {DFCC_RootSignature},
|
|
|
|
+ {}
|
|
|
|
+ );
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+TEST_F(ValidationTest, WhenRootSigMatchShaderSucceed_DescTable_GoodRange) {
|
|
|
|
+ ReplaceContainerPartsCheckMsgs(
|
|
|
|
+ "struct Foo { int a; float4 b; };"
|
|
|
|
+ ""
|
|
|
|
+ "ConstantBuffer<Foo> cb1[4] : register(b2, space5);"
|
|
|
|
+ "Texture2D<float4> tex1[8] : register(t1, space3);"
|
|
|
|
+ "RWBuffer<float4> buf1[6] : register(u33, space17);"
|
|
|
|
+ "SamplerState sampler1[5] : register(s0, space0);"
|
|
|
|
+ ""
|
|
|
|
+ "float4 main(float4 a : AAA) : SV_TARGET"
|
|
|
|
+ "{"
|
|
|
|
+ " return buf1[a.x][a.y] + cb1[a.x].b + tex1[a.x].Sample(sampler1[a.x], a.xy);"
|
|
|
|
+ "}",
|
|
|
|
+ "[RootSignature(\"DescriptorTable( SRV(t0,space=3,numDescriptors=20), "
|
|
|
|
+ "CBV(b2,space=5,numDescriptors=4), "
|
|
|
|
+ "UAV(u33,space=17,numDescriptors=6)), "
|
|
|
|
+ "DescriptorTable(Sampler(s0, numDescriptors=5))\")]"
|
|
|
|
+ " float4 main() : SV_Target { return 0; }",
|
|
|
|
+ "ps_6_0",
|
|
|
|
+ {DFCC_RootSignature},
|
|
|
|
+ {}
|
|
|
|
+ );
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+TEST_F(ValidationTest, WhenRootSigMatchShaderSucceed_DescTable_Unbounded) {
|
|
|
|
+ ReplaceContainerPartsCheckMsgs(
|
|
|
|
+ "struct Foo { int a; float4 b; };"
|
|
|
|
+ ""
|
|
|
|
+ "ConstantBuffer<Foo> cb1[4] : register(b2, space5);"
|
|
|
|
+ "Texture2D<float4> tex1[8] : register(t1, space3);"
|
|
|
|
+ "RWBuffer<float4> buf1[6] : register(u33, space17);"
|
|
|
|
+ "SamplerState sampler1[5] : register(s0, space0);"
|
|
|
|
+ ""
|
|
|
|
+ "float4 main(float4 a : AAA) : SV_TARGET"
|
|
|
|
+ "{"
|
|
|
|
+ " return buf1[a.x][a.y] + cb1[a.x].b + tex1[a.x].Sample(sampler1[a.x], a.xy);"
|
|
|
|
+ "}",
|
|
|
|
+ "[RootSignature(\"DescriptorTable( CBV(b2,space=5,numDescriptors=4), "
|
|
|
|
+ "SRV(t1,space=3,numDescriptors=8), "
|
|
|
|
+ "UAV(u10,space=17,numDescriptors=unbounded)), "
|
|
|
|
+ "DescriptorTable(Sampler(s0, numDescriptors=5))\")]"
|
|
|
|
+ " float4 main() : SV_Target { return 0; }",
|
|
|
|
+ "ps_6_0",
|
|
|
|
+ {DFCC_RootSignature},
|
|
|
|
+ {}
|
|
|
|
+ );
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+TEST_F(ValidationTest, WhenRootSigMatchShaderFail_DescTable_Range1) {
|
|
|
|
+ ReplaceContainerPartsCheckMsgs(
|
|
|
|
+ "struct Foo { int a; float4 b; };"
|
|
|
|
+ ""
|
|
|
|
+ "ConstantBuffer<Foo> cb1[4] : register(b2, space5);"
|
|
|
|
+ "Texture2D<float4> tex1[8] : register(t1, space3);"
|
|
|
|
+ "RWBuffer<float4> buf1[6] : register(u33, space17);"
|
|
|
|
+ "SamplerState sampler1[5] : register(s0, space0);"
|
|
|
|
+ ""
|
|
|
|
+ "float4 main(float4 a : AAA) : SV_TARGET"
|
|
|
|
+ "{"
|
|
|
|
+ " return buf1[a.x][a.y] + cb1[a.x].b + tex1[a.x].Sample(sampler1[a.x], a.xy);"
|
|
|
|
+ "}",
|
|
|
|
+ "[RootSignature(\"DescriptorTable( CBV(b2,space=5,numDescriptors=4), "
|
|
|
|
+ "SRV(t2,space=3,numDescriptors=8), "
|
|
|
|
+ "UAV(u33,space=17,numDescriptors=6)), "
|
|
|
|
+ "DescriptorTable(Sampler(s0, numDescriptors=5))\")]"
|
|
|
|
+ " float4 main() : SV_Target { return 0; }",
|
|
|
|
+ "ps_6_0",
|
|
|
|
+ {DFCC_RootSignature},
|
|
|
|
+ {
|
|
|
|
+ "Shader SRV descriptor range (RegisterSpace=3, NumDescriptors=8, BaseShaderRegister=1) is not fully bound in root signature.",
|
|
|
|
+ "Root Signature in DXIL container is not compatible with shader.",
|
|
|
|
+ "Validation failed."
|
|
|
|
+ }
|
|
|
|
+ );
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+TEST_F(ValidationTest, WhenRootSigMatchShaderFail_DescTable_Range2) {
|
|
|
|
+ ReplaceContainerPartsCheckMsgs(
|
|
|
|
+ "struct Foo { int a; float4 b; };"
|
|
|
|
+ ""
|
|
|
|
+ "ConstantBuffer<Foo> cb1[4] : register(b2, space5);"
|
|
|
|
+ "Texture2D<float4> tex1[8] : register(t1, space3);"
|
|
|
|
+ "RWBuffer<float4> buf1[6] : register(u33, space17);"
|
|
|
|
+ "SamplerState sampler1[5] : register(s0, space0);"
|
|
|
|
+ ""
|
|
|
|
+ "float4 main(float4 a : AAA) : SV_TARGET"
|
|
|
|
+ "{"
|
|
|
|
+ " return buf1[a.x][a.y] + cb1[a.x].b + tex1[a.x].Sample(sampler1[a.x], a.xy);"
|
|
|
|
+ "}",
|
|
|
|
+ "[RootSignature(\"DescriptorTable( SRV(t2,space=3,numDescriptors=8), "
|
|
|
|
+ "CBV(b20,space=5,numDescriptors=4), "
|
|
|
|
+ "UAV(u33,space=17,numDescriptors=6)), "
|
|
|
|
+ "DescriptorTable(Sampler(s0, numDescriptors=5))\")]"
|
|
|
|
+ " float4 main() : SV_Target { return 0; }",
|
|
|
|
+ "ps_6_0",
|
|
|
|
+ {DFCC_RootSignature},
|
|
|
|
+ {
|
|
|
|
+ "Root Signature in DXIL container is not compatible with shader.",
|
|
|
|
+ "Validation failed."
|
|
|
|
+ }
|
|
|
|
+ );
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+TEST_F(ValidationTest, WhenRootSigMatchShaderFail_DescTable_Range3) {
|
|
|
|
+ ReplaceContainerPartsCheckMsgs(
|
|
|
|
+ "struct Foo { int a; float4 b; };"
|
|
|
|
+ ""
|
|
|
|
+ "ConstantBuffer<Foo> cb1[4] : register(b2, space5);"
|
|
|
|
+ "Texture2D<float4> tex1[8] : register(t1, space3);"
|
|
|
|
+ "RWBuffer<float4> buf1[6] : register(u33, space17);"
|
|
|
|
+ "SamplerState sampler1[5] : register(s0, space0);"
|
|
|
|
+ ""
|
|
|
|
+ "float4 main(float4 a : AAA) : SV_TARGET"
|
|
|
|
+ "{"
|
|
|
|
+ " return buf1[a.x][a.y] + cb1[a.x].b + tex1[a.x].Sample(sampler1[a.x], a.xy);"
|
|
|
|
+ "}",
|
|
|
|
+ "[RootSignature(\"DescriptorTable( CBV(b2,space=5,numDescriptors=4), "
|
|
|
|
+ "SRV(t1,space=3,numDescriptors=8), "
|
|
|
|
+ "UAV(u33,space=17,numDescriptors=5)), "
|
|
|
|
+ "DescriptorTable(Sampler(s0, numDescriptors=5))\")]"
|
|
|
|
+ " float4 main() : SV_Target { return 0; }",
|
|
|
|
+ "ps_6_0",
|
|
|
|
+ {DFCC_RootSignature},
|
|
|
|
+ {
|
|
|
|
+ "Root Signature in DXIL container is not compatible with shader.",
|
|
|
|
+ "Validation failed."
|
|
|
|
+ }
|
|
|
|
+ );
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+TEST_F(ValidationTest, WhenRootSigMatchShaderFail_DescTable_Space) {
|
|
|
|
+ ReplaceContainerPartsCheckMsgs(
|
|
|
|
+ "struct Foo { int a; float4 b; };"
|
|
|
|
+ ""
|
|
|
|
+ "ConstantBuffer<Foo> cb1[4] : register(b2, space5);"
|
|
|
|
+ "Texture2D<float4> tex1[8] : register(t1, space3);"
|
|
|
|
+ "RWBuffer<float4> buf1[6] : register(u33, space17);"
|
|
|
|
+ "SamplerState sampler1[5] : register(s0, space0);"
|
|
|
|
+ ""
|
|
|
|
+ "float4 main(float4 a : AAA) : SV_TARGET"
|
|
|
|
+ "{"
|
|
|
|
+ " return buf1[a.x][a.y] + cb1[a.x].b + tex1[a.x].Sample(sampler1[a.x], a.xy);"
|
|
|
|
+ "}",
|
|
|
|
+ "[RootSignature(\"DescriptorTable( SRV(t2,space=3,numDescriptors=8), "
|
|
|
|
+ "CBV(b2,space=5,numDescriptors=4), "
|
|
|
|
+ "UAV(u33,space=0,numDescriptors=6)), "
|
|
|
|
+ "DescriptorTable(Sampler(s0, numDescriptors=5))\")]"
|
|
|
|
+ " float4 main() : SV_Target { return 0; }",
|
|
|
|
+ "ps_6_0",
|
|
|
|
+ {DFCC_RootSignature},
|
|
|
|
+ {
|
|
|
|
+ "Root Signature in DXIL container is not compatible with shader.",
|
|
|
|
+ "Validation failed."
|
|
|
|
+ }
|
|
|
|
+ );
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+TEST_F(ValidationTest, WhenRootSigMatchShaderSucceed_Unbounded) {
|
|
|
|
+ ReplaceContainerPartsCheckMsgs(
|
|
|
|
+ "struct Foo { int a; float4 b; };"
|
|
|
|
+ ""
|
|
|
|
+ "ConstantBuffer<Foo> cb1[] : register(b2, space5);"
|
|
|
|
+ "Texture2D<float4> tex1[] : register(t1, space3);"
|
|
|
|
+ "RWBuffer<float4> buf1[] : register(u33, space17);"
|
|
|
|
+ "SamplerState sampler1[] : register(s0, space0);"
|
|
|
|
+ ""
|
|
|
|
+ "float4 main(float4 a : AAA) : SV_TARGET"
|
|
|
|
+ "{"
|
|
|
|
+ " return buf1[a.x][a.y] + cb1[a.x].b + tex1[a.x].Sample(sampler1[a.x], a.xy);"
|
|
|
|
+ "}",
|
|
|
|
+ "[RootSignature(\"DescriptorTable( CBV(b2,space=5,numDescriptors=1)), "
|
|
|
|
+ "DescriptorTable( SRV(t1,space=3,numDescriptors=unbounded)), "
|
|
|
|
+ "DescriptorTable( UAV(u10,space=17,numDescriptors=100)), "
|
|
|
|
+ "DescriptorTable(Sampler(s0, numDescriptors=5))\")]"
|
|
|
|
+ " float4 main() : SV_Target { return 0; }",
|
|
|
|
+ "ps_6_0",
|
|
|
|
+ {DFCC_RootSignature},
|
|
|
|
+ {}
|
|
|
|
+ );
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+TEST_F(ValidationTest, WhenRootSigMatchShaderFail_Unbounded1) {
|
|
|
|
+ ReplaceContainerPartsCheckMsgs(
|
|
|
|
+ "struct Foo { int a; float4 b; };"
|
|
|
|
+ ""
|
|
|
|
+ "ConstantBuffer<Foo> cb1[] : register(b2, space5);"
|
|
|
|
+ "Texture2D<float4> tex1[] : register(t1, space3);"
|
|
|
|
+ "RWBuffer<float4> buf1[] : register(u33, space17);"
|
|
|
|
+ "SamplerState sampler1[] : register(s0, space0);"
|
|
|
|
+ ""
|
|
|
|
+ "float4 main(float4 a : AAA) : SV_TARGET"
|
|
|
|
+ "{"
|
|
|
|
+ " return buf1[a.x][a.y] + cb1[a.x].b + tex1[a.x].Sample(sampler1[a.x], a.xy);"
|
|
|
|
+ "}",
|
|
|
|
+ "[RootSignature(\"DescriptorTable( CBV(b3,space=5,numDescriptors=1)), "
|
|
|
|
+ "DescriptorTable( SRV(t1,space=3,numDescriptors=unbounded)), "
|
|
|
|
+ "DescriptorTable( UAV(u10,space=17,numDescriptors=unbounded)), "
|
|
|
|
+ "DescriptorTable( Sampler(s0, numDescriptors=5))\")]"
|
|
|
|
+ " float4 main() : SV_Target { return 0; }",
|
|
|
|
+ "ps_6_0",
|
|
|
|
+ {DFCC_RootSignature},
|
|
|
|
+ {
|
|
|
|
+ "Root Signature in DXIL container is not compatible with shader.",
|
|
|
|
+ "Validation failed."
|
|
|
|
+ }
|
|
|
|
+ );
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+TEST_F(ValidationTest, WhenRootSigMatchShaderFail_Unbounded2) {
|
|
|
|
+ ReplaceContainerPartsCheckMsgs(
|
|
|
|
+ "struct Foo { int a; float4 b; };"
|
|
|
|
+ ""
|
|
|
|
+ "ConstantBuffer<Foo> cb1[] : register(b2, space5);"
|
|
|
|
+ "Texture2D<float4> tex1[] : register(t1, space3);"
|
|
|
|
+ "RWBuffer<float4> buf1[] : register(u33, space17);"
|
|
|
|
+ "SamplerState sampler1[] : register(s0, space0);"
|
|
|
|
+ ""
|
|
|
|
+ "float4 main(float4 a : AAA) : SV_TARGET"
|
|
|
|
+ "{"
|
|
|
|
+ " return buf1[a.x][a.y] + cb1[a.x].b + tex1[a.x].Sample(sampler1[a.x], a.xy);"
|
|
|
|
+ "}",
|
|
|
|
+ "[RootSignature(\"DescriptorTable( CBV(b2,space=5,numDescriptors=1)), "
|
|
|
|
+ "DescriptorTable( SRV(t1,space=3,numDescriptors=unbounded)), "
|
|
|
|
+ "DescriptorTable( UAV(u10,space=17,numDescriptors=unbounded)), "
|
|
|
|
+ "DescriptorTable( Sampler(s5, numDescriptors=unbounded))\")]"
|
|
|
|
+ " float4 main() : SV_Target { return 0; }",
|
|
|
|
+ "ps_6_0",
|
|
|
|
+ {DFCC_RootSignature},
|
|
|
|
+ {
|
|
|
|
+ "Root Signature in DXIL container is not compatible with shader.",
|
|
|
|
+ "Validation failed."
|
|
|
|
+ }
|
|
|
|
+ );
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+TEST_F(ValidationTest, WhenRootSigMatchShaderFail_Unbounded3) {
|
|
|
|
+ ReplaceContainerPartsCheckMsgs(
|
|
|
|
+ "struct Foo { int a; float4 b; };"
|
|
|
|
+ ""
|
|
|
|
+ "ConstantBuffer<Foo> cb1[] : register(b2, space5);"
|
|
|
|
+ "Texture2D<float4> tex1[] : register(t1, space3);"
|
|
|
|
+ "RWBuffer<float4> buf1[] : register(u33, space17);"
|
|
|
|
+ "SamplerState sampler1[] : register(s0, space0);"
|
|
|
|
+ ""
|
|
|
|
+ "float4 main(float4 a : AAA) : SV_TARGET"
|
|
|
|
+ "{"
|
|
|
|
+ " return buf1[a.x][a.y] + cb1[a.x].b + tex1[a.x].Sample(sampler1[a.x], a.xy);"
|
|
|
|
+ "}",
|
|
|
|
+ "[RootSignature(\"DescriptorTable( CBV(b2,space=5,numDescriptors=1)), "
|
|
|
|
+ "DescriptorTable( SRV(t1,space=3,numDescriptors=unbounded)), "
|
|
|
|
+ "DescriptorTable( UAV(u10,space=17,numDescriptors=7)), "
|
|
|
|
+ "DescriptorTable(Sampler(s0, numDescriptors=5))\")]"
|
|
|
|
+ " float4 main() : SV_Target { return 0; }",
|
|
|
|
+ "ps_6_0",
|
|
|
|
+ {DFCC_RootSignature},
|
|
|
|
+ {
|
|
|
|
+ "Root Signature in DXIL container is not compatible with shader.",
|
|
|
|
+ "Validation failed."
|
|
|
|
+ }
|
|
|
|
+ );
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+#define VERTEX_STRUCT1 \
|
|
|
|
+ "struct PSSceneIn \n\
|
|
|
|
+ { \n\
|
|
|
|
+ float4 pos : SV_Position; \n\
|
|
|
|
+ float2 tex : TEXCOORD0; \n\
|
|
|
|
+ float3 norm : NORMAL; \n\
|
|
|
|
+ }; \n"
|
|
|
|
+#define VERTEX_STRUCT2 \
|
|
|
|
+ "struct PSSceneIn \n\
|
|
|
|
+ { \n\
|
|
|
|
+ float4 pos : SV_Position; \n\
|
|
|
|
+ float2 tex : TEXCOORD0; \n\
|
|
|
|
+ }; \n"
|
|
|
|
+#define PC_STRUCT1 "struct HSPerPatchData { \n\
|
|
|
|
+ float edges[ 3 ] : SV_TessFactor; \n\
|
|
|
|
+ float inside : SV_InsideTessFactor; \n\
|
|
|
|
+ float foo : FOO; \n\
|
|
|
|
+ }; \n"
|
|
|
|
+#define PC_STRUCT2 "struct HSPerPatchData { \n\
|
|
|
|
+ float edges[ 3 ] : SV_TessFactor; \n\
|
|
|
|
+ float inside : SV_InsideTessFactor; \n\
|
|
|
|
+ }; \n"
|
|
|
|
+#define PC_FUNC "HSPerPatchData HSPerPatchFunc( InputPatch< PSSceneIn, 3 > points, \n\
|
|
|
|
+ OutputPatch<PSSceneIn, 3> outpoints) { \n\
|
|
|
|
+ HSPerPatchData d = (HSPerPatchData)0; \n\
|
|
|
|
+ d.edges[ 0 ] = points[0].tex.x + outpoints[0].tex.x; \n\
|
|
|
|
+ d.edges[ 1 ] = 1; \n\
|
|
|
|
+ d.edges[ 2 ] = 1; \n\
|
|
|
|
+ d.inside = 1; \n\
|
|
|
|
+ return d; \n\
|
|
|
|
+ } \n"
|
|
|
|
+#define PC_FUNC_NOOUT "HSPerPatchData HSPerPatchFunc( InputPatch< PSSceneIn, 3 > points ) { \n\
|
|
|
|
+ HSPerPatchData d = (HSPerPatchData)0; \n\
|
|
|
|
+ d.edges[ 0 ] = points[0].tex.x; \n\
|
|
|
|
+ d.edges[ 1 ] = 1; \n\
|
|
|
|
+ d.edges[ 2 ] = 1; \n\
|
|
|
|
+ d.inside = 1; \n\
|
|
|
|
+ return d; \n\
|
|
|
|
+ } \n"
|
|
|
|
+#define PC_FUNC_NOIN "HSPerPatchData HSPerPatchFunc( OutputPatch<PSSceneIn, 3> outpoints) { \n\
|
|
|
|
+ HSPerPatchData d = (HSPerPatchData)0; \n\
|
|
|
|
+ d.edges[ 0 ] = outpoints[0].tex.x; \n\
|
|
|
|
+ d.edges[ 1 ] = 1; \n\
|
|
|
|
+ d.edges[ 2 ] = 1; \n\
|
|
|
|
+ d.inside = 1; \n\
|
|
|
|
+ return d; \n\
|
|
|
|
+ } \n"
|
|
|
|
+#define HS_ATTR "[domain(\"tri\")] \n\
|
|
|
|
+ [partitioning(\"fractional_odd\")] \n\
|
|
|
|
+ [outputtopology(\"triangle_cw\")] \n\
|
|
|
|
+ [patchconstantfunc(\"HSPerPatchFunc\")] \n\
|
|
|
|
+ [outputcontrolpoints(3)] \n"
|
|
|
|
+#define HS_FUNC \
|
|
|
|
+ "PSSceneIn main(const uint id : SV_OutputControlPointID, \n\
|
|
|
|
+ const InputPatch< PSSceneIn, 3 > points ) { \n\
|
|
|
|
+ return points[ id ]; \n\
|
|
|
|
+ } \n"
|
|
|
|
+#define HS_FUNC_NOOUT \
|
|
|
|
+ "void main(const uint id : SV_OutputControlPointID, \n\
|
|
|
|
+ const InputPatch< PSSceneIn, 3 > points ) { \n\
|
|
|
|
+ } \n"
|
|
|
|
+#define HS_FUNC_NOIN \
|
|
|
|
+ "PSSceneIn main( const uint id : SV_OutputControlPointID ) { \n\
|
|
|
|
+ return (PSSceneIn)0; \n\
|
|
|
|
+ } \n"
|
|
|
|
+#define DS_FUNC \
|
|
|
|
+ "[domain(\"tri\")] PSSceneIn main(const float3 bary : SV_DomainLocation, \n\
|
|
|
|
+ const OutputPatch<PSSceneIn, 3> patch, \n\
|
|
|
|
+ const HSPerPatchData perPatchData) { \n\
|
|
|
|
+ PSSceneIn v = patch[0]; \n\
|
|
|
|
+ v.pos = patch[0].pos * bary.x; \n\
|
|
|
|
+ v.pos += patch[1].pos * bary.y; \n\
|
|
|
|
+ v.pos += patch[2].pos * bary.z; \n\
|
|
|
|
+ return v; \n\
|
|
|
|
+ } \n"
|
|
|
|
+#define DS_FUNC_NOPC \
|
|
|
|
+ "[domain(\"tri\")] PSSceneIn main(const float3 bary : SV_DomainLocation, \n\
|
|
|
|
+ const OutputPatch<PSSceneIn, 3> patch) { \n\
|
|
|
|
+ PSSceneIn v = patch[0]; \n\
|
|
|
|
+ v.pos = patch[0].pos * bary.x; \n\
|
|
|
|
+ v.pos += patch[1].pos * bary.y; \n\
|
|
|
|
+ v.pos += patch[2].pos * bary.z; \n\
|
|
|
|
+ return v; \n\
|
|
|
|
+ } \n"
|
|
|
|
+
|
|
|
|
+TEST_F(ValidationTest, WhenProgramOutSigMissingThenFail) {
|
|
|
|
+ ReplaceContainerPartsCheckMsgs(
|
|
|
|
+ VERTEX_STRUCT1
|
|
|
|
+ PC_STRUCT1
|
|
|
|
+ PC_FUNC
|
|
|
|
+ HS_ATTR
|
|
|
|
+ HS_FUNC,
|
|
|
|
+
|
|
|
|
+ VERTEX_STRUCT1
|
|
|
|
+ PC_STRUCT1
|
|
|
|
+ PC_FUNC_NOOUT
|
|
|
|
+ HS_ATTR
|
|
|
|
+ HS_FUNC_NOOUT,
|
|
|
|
+
|
|
|
|
+ "hs_6_0",
|
|
|
|
+ {DFCC_InputSignature, DFCC_OutputSignature, DFCC_PatchConstantSignature},
|
|
|
|
+ {
|
|
|
|
+ "Container part 'Program Output Signature' does not match expected for module.",
|
|
|
|
+ "Validation failed."
|
|
|
|
+ }
|
|
|
|
+ );
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+TEST_F(ValidationTest, WhenProgramOutSigUnexpectedThenFail) {
|
|
|
|
+ ReplaceContainerPartsCheckMsgs(
|
|
|
|
+ VERTEX_STRUCT1
|
|
|
|
+ PC_STRUCT1
|
|
|
|
+ PC_FUNC_NOOUT
|
|
|
|
+ HS_ATTR
|
|
|
|
+ HS_FUNC_NOOUT,
|
|
|
|
+
|
|
|
|
+ VERTEX_STRUCT1
|
|
|
|
+ PC_STRUCT1
|
|
|
|
+ PC_FUNC
|
|
|
|
+ HS_ATTR
|
|
|
|
+ HS_FUNC,
|
|
|
|
+
|
|
|
|
+ "hs_6_0",
|
|
|
|
+ {DFCC_InputSignature, DFCC_OutputSignature, DFCC_PatchConstantSignature},
|
|
|
|
+ {
|
|
|
|
+ "Container part 'Program Output Signature' does not match expected for module.",
|
|
|
|
+ "Validation failed."
|
|
|
|
+ }
|
|
|
|
+ );
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+TEST_F(ValidationTest, WhenProgramSigMismatchThenFail) {
|
|
|
|
+ ReplaceContainerPartsCheckMsgs(
|
|
|
|
+ VERTEX_STRUCT1
|
|
|
|
+ PC_STRUCT1
|
|
|
|
+ PC_FUNC
|
|
|
|
+ HS_ATTR
|
|
|
|
+ HS_FUNC,
|
|
|
|
+
|
|
|
|
+ VERTEX_STRUCT2
|
|
|
|
+ PC_STRUCT2
|
|
|
|
+ PC_FUNC
|
|
|
|
+ HS_ATTR
|
|
|
|
+ HS_FUNC,
|
|
|
|
+
|
|
|
|
+ "hs_6_0",
|
|
|
|
+ {DFCC_InputSignature, DFCC_OutputSignature, DFCC_PatchConstantSignature},
|
|
|
|
+ {
|
|
|
|
+ "Container part 'Program Input Signature' does not match expected for module.",
|
|
|
|
+ "Container part 'Program Output Signature' does not match expected for module.",
|
|
|
|
+ "Container part 'Program Patch Constant Signature' does not match expected for module.",
|
|
|
|
+ "Validation failed."
|
|
|
|
+ }
|
|
|
|
+ );
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+TEST_F(ValidationTest, WhenProgramInSigMissingThenFail) {
|
|
|
|
+ ReplaceContainerPartsCheckMsgs(
|
|
|
|
+ VERTEX_STRUCT1
|
|
|
|
+ PC_STRUCT1
|
|
|
|
+ PC_FUNC
|
|
|
|
+ HS_ATTR
|
|
|
|
+ HS_FUNC,
|
|
|
|
+
|
|
|
|
+ // Compiling the HS_FUNC_NOIN produces the following error
|
|
|
|
+ //error: validation errors
|
|
|
|
+ //HS input control point count must be [1..32]. 0 specified
|
|
|
|
+ VERTEX_STRUCT1
|
|
|
|
+ PC_STRUCT1
|
|
|
|
+ PC_FUNC_NOIN
|
|
|
|
+ HS_ATTR
|
|
|
|
+ HS_FUNC_NOIN,
|
|
|
|
+ "hs_6_0",
|
|
|
|
+ {DFCC_InputSignature, DFCC_OutputSignature, DFCC_PatchConstantSignature},
|
|
|
|
+ {
|
|
|
|
+ "Container part 'Program Input Signature' does not match expected for module.",
|
|
|
|
+ "Validation failed."
|
|
|
|
+ }
|
|
|
|
+ );
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+TEST_F(ValidationTest, WhenProgramSigMismatchThenFail2) {
|
|
|
|
+ ReplaceContainerPartsCheckMsgs(
|
|
|
|
+ VERTEX_STRUCT1
|
|
|
|
+ PC_STRUCT1
|
|
|
|
+ DS_FUNC,
|
|
|
|
+
|
|
|
|
+ VERTEX_STRUCT2
|
|
|
|
+ PC_STRUCT2
|
|
|
|
+ DS_FUNC,
|
|
|
|
+
|
|
|
|
+ "ds_6_0",
|
|
|
|
+ {DFCC_InputSignature, DFCC_OutputSignature, DFCC_PatchConstantSignature},
|
|
|
|
+ {
|
|
|
|
+ "Container part 'Program Input Signature' does not match expected for module.",
|
|
|
|
+ "Container part 'Program Output Signature' does not match expected for module.",
|
|
|
|
+ "Container part 'Program Patch Constant Signature' does not match expected for module.",
|
|
|
|
+ "Validation failed."
|
|
|
|
+ }
|
|
|
|
+ );
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+TEST_F(ValidationTest, WhenProgramPCSigMissingThenFail) {
|
|
|
|
+ ReplaceContainerPartsCheckMsgs(
|
|
|
|
+ VERTEX_STRUCT1
|
|
|
|
+ PC_STRUCT1
|
|
|
|
+ DS_FUNC,
|
|
|
|
+
|
|
|
|
+ VERTEX_STRUCT2
|
|
|
|
+ PC_STRUCT2
|
|
|
|
+ DS_FUNC_NOPC,
|
|
|
|
+
|
|
|
|
+ "ds_6_0",
|
|
|
|
+ {DFCC_InputSignature, DFCC_OutputSignature, DFCC_PatchConstantSignature},
|
|
|
|
+ {
|
|
|
|
+ "Container part 'Program Input Signature' does not match expected for module.",
|
|
|
|
+ "Container part 'Program Output Signature' does not match expected for module.",
|
|
|
|
+ "Missing part 'Program Patch Constant Signature' required by module.",
|
|
|
|
+ "Validation failed."
|
|
|
|
+ }
|
|
|
|
+ );
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+#undef VERTEX_STRUCT1
|
|
|
|
+#undef VERTEX_STRUCT2
|
|
|
|
+#undef PC_STRUCT1
|
|
|
|
+#undef PC_STRUCT2
|
|
|
|
+#undef PC_FUNC
|
|
|
|
+#undef PC_FUNC_NOOUT
|
|
|
|
+#undef PC_FUNC_NOIN
|
|
|
|
+#undef HS_ATTR
|
|
|
|
+#undef HS_FUNC
|
|
|
|
+#undef HS_FUNC_NOOUT
|
|
|
|
+#undef HS_FUNC_NOIN
|
|
|
|
+#undef DS_FUNC
|
|
|
|
+#undef DS_FUNC_NOPC
|
|
|
|
+
|
|
|
|
+TEST_F(ValidationTest, WhenPSVMismatchThenFail) {
|
|
|
|
+ ReplaceContainerPartsCheckMsgs(
|
|
|
|
+ "float c; [RootSignature ( \"RootConstants(b0, num32BitConstants = 1)\" )] float4 main() : semantic { return c; }",
|
|
|
|
+ "[RootSignature ( \"\" )] float4 main() : semantic { return 0; }",
|
|
|
|
+ "vs_6_0",
|
|
|
|
+ {DFCC_PipelineStateValidation},
|
|
|
|
+ {
|
|
|
|
+ "Container part 'Pipeline State Validation' does not match expected for module.",
|
|
|
|
+ "Validation failed."
|
|
|
|
+ }
|
|
|
|
+ );
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+TEST_F(ValidationTest, WhenFeatureInfoMismatchThenFail) {
|
|
|
|
+ ReplaceContainerPartsCheckMsgs(
|
|
|
|
+ "float4 main(uint2 foo : FOO) : SV_Target { return asdouble(foo.x, foo.y) * 2.0; }",
|
|
|
|
+ "float4 main() : SV_Target { return 0; }",
|
|
|
|
+ "ps_6_0",
|
|
|
|
+ {DFCC_FeatureInfo},
|
|
|
|
+ {
|
|
|
|
+ "Container part 'Feature Info' does not match expected for module.",
|
|
|
|
+ "Validation failed."
|
|
|
|
+ }
|
|
|
|
+ );
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
|
|
|
|
|
|
|
|
|