blob: daaa4c0cbd13dc4a186da34f7881e1d8dce8e363 [file] [edit]
///////////////////////////////////////////////////////////////////////////////
// //
// DxilConvTest.cpp //
// Copyright (C) Microsoft Corporation. All rights reserved. //
// This file is distributed under the University of Illinois Open Source //
// License. See LICENSE.TXT for details. //
// //
// Provides tests for the dxilconv.dll API. //
// //
///////////////////////////////////////////////////////////////////////////////
#ifndef UNICODE
#define UNICODE
#endif
#include "dxc/DxilContainer/DxilContainer.h"
#include "dxc/Support/WinIncludes.h"
#include "dxc/dxcapi.h"
#include <algorithm>
#include <atlfile.h>
#include <cassert>
#include <cfloat>
#include <map>
#include <memory>
#include <sstream>
#include <string>
#include <vector>
#include "dxc/Test/DxcTestUtils.h"
#include "dxc/Test/HLSLTestData.h"
#include "dxc/Test/HlslTestUtils.h"
#include "dxc/Support/Global.h"
#include "dxc/Support/HLSLOptions.h"
#include "dxc/Support/Unicode.h"
#include "dxc/Support/dxcapi.use.h"
#include "dxc/Support/microcom.h"
#include "llvm/Support/raw_os_ostream.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MSFileSystem.h"
#include "llvm/Support/Path.h"
#include <fstream>
using namespace std;
class DxilConvTest {
public:
BEGIN_TEST_CLASS(DxilConvTest)
TEST_CLASS_PROPERTY(L"Parallel", L"true")
TEST_METHOD_PROPERTY(L"Priority", L"0")
END_TEST_CLASS()
TEST_CLASS_SETUP(InitSupport);
TEST_METHOD(BatchDxbc2dxil);
TEST_METHOD(BatchDxbc2dxilAsm);
TEST_METHOD(BatchDxilCleanup);
TEST_METHOD(BatchNormalizeDxil);
TEST_METHOD(BatchScopeNestIterator);
TEST_METHOD(RegressionTests);
BEGIN_TEST_METHOD(ManualFileCheckTest)
TEST_METHOD_PROPERTY(L"Ignore", L"true")
END_TEST_METHOD()
private:
dxc::DxcDllSupport m_dllSupport;
PluginToolsPaths m_TestToolPaths;
void DxilConvTestCheckFile(LPCWSTR path) {
FileRunTestResult t = FileRunTestResult::RunFromFileCommands(
path, m_dllSupport, &m_TestToolPaths);
if (t.RunResult != 0) {
CA2W commentWide(t.ErrorMessage.c_str(), CP_UTF8);
WEX::Logging::Log::Comment(commentWide);
WEX::Logging::Log::Error(L"Run result is not zero");
}
}
void DxilConvTestCheckBatchDir(std::wstring suitePath,
std::string fileExt = ".hlsl",
bool useRelativeFilename = false) {
using namespace llvm;
using namespace WEX::TestExecution;
::llvm::sys::fs::MSFileSystem *msfPtr;
VERIFY_SUCCEEDED(CreateMSFileSystemForDisk(&msfPtr));
std::unique_ptr<::llvm::sys::fs::MSFileSystem> msf(msfPtr);
::llvm::sys::fs::AutoPerThreadSystem pts(msf.get());
IFTLLVM(pts.error_code());
if (!useRelativeFilename) {
CW2A pUtf8Filename(suitePath.c_str());
if (!llvm::sys::path::is_absolute(pUtf8Filename.m_psz)) {
suitePath = hlsl_test::GetPathToHlslDataFile(suitePath.c_str());
}
}
CW2A utf8SuitePath(suitePath.c_str());
unsigned numTestsRun = 0;
std::error_code EC;
llvm::SmallString<128> DirNative;
llvm::StringRef filterExt(fileExt);
llvm::sys::path::native(utf8SuitePath.m_psz, DirNative);
for (llvm::sys::fs::recursive_directory_iterator Dir(DirNative, EC), DirEnd;
Dir != DirEnd && !EC; Dir.increment(EC)) {
if (!llvm::sys::path::extension(Dir->path()).equals(filterExt)) {
continue;
}
StringRef filename = Dir->path();
CA2W wRelPath(filename.data());
WEX::Logging::Log::StartGroup(wRelPath);
DxilConvTestCheckFile(wRelPath);
WEX::Logging::Log::EndGroup(wRelPath);
numTestsRun++;
}
VERIFY_IS_GREATER_THAN(numTestsRun, (unsigned)0,
L"No test files found in batch directory.");
}
bool GetCurrentBinDir(std::string &binDir) {
// get the test dll directory
HMODULE hModule;
if ((hModule = ::GetModuleHandleA("dxilconv-tests.dll")) == 0) {
hlsl_test::LogErrorFmt(L"GetModuleHandle failed.");
return false;
}
// get the path
char buffer[MAX_PATH];
DWORD size = sizeof(buffer);
if ((size = ::GetModuleFileNameA(hModule, buffer, size)) == 0) {
hlsl_test::LogErrorFmt(L"GetModuleFileName failed.");
return false;
}
std::string str = std::string(buffer, size);
size_t pos = str.find_last_of("\\");
if (pos != std::string::npos) {
str = str.substr(0, pos + 1);
}
binDir.assign(str);
return true;
}
// Find the binary in current bin dir and add it to m_TestToolPaths
// so that it can be invoked from RUN: lines by the refName
bool FindToolInBinDir(std::string refName, std::string binaryName) {
std::string binDir;
if (!GetCurrentBinDir(binDir)) {
return false;
}
std::string loc = binDir + binaryName;
if (::PathFileExistsA(loc.c_str())) {
m_TestToolPaths.emplace(refName, loc);
} else {
CA2W locW(loc.c_str(), CP_UTF8);
hlsl_test::LogErrorFmt(L"Cannot find %s.", locW.m_psz);
return false;
}
return true;
}
};
bool DxilConvTest::InitSupport() {
if (!m_dllSupport.IsEnabled()) {
VERIFY_SUCCEEDED(
m_dllSupport.InitializeForDll("dxilconv.dll", "DxcCreateInstance"));
}
if (!FindToolInBinDir("%dxbc2dxil", "dxbc2dxil.exe")) {
return false;
}
if (!FindToolInBinDir("%opt-exe", "opt.exe")) {
return false;
}
if (!FindToolInBinDir("%dxa", "dxa.exe")) {
return false;
}
return true;
}
TEST_F(DxilConvTest, ManualFileCheckTest) {
using namespace llvm;
using namespace WEX::TestExecution;
WEX::Common::String value;
VERIFY_SUCCEEDED(RuntimeParameters::TryGetValue(L"InputPath", value));
std::wstring path = static_cast<const wchar_t *>(value);
if (!llvm::sys::path::is_absolute(CW2A(path.c_str()).m_psz)) {
path = hlsl_test::GetPathToHlslDataFile(path.c_str());
}
bool isDirectory;
{
// Temporarily setup the filesystem for testing whether the path is a
// directory. If it is, CodeGenTestCheckBatchDir will create its own
// instance.
llvm::sys::fs::MSFileSystem *msfPtr;
VERIFY_SUCCEEDED(CreateMSFileSystemForDisk(&msfPtr));
std::unique_ptr<llvm::sys::fs::MSFileSystem> msf(msfPtr);
llvm::sys::fs::AutoPerThreadSystem pts(msf.get());
IFTLLVM(pts.error_code());
isDirectory = llvm::sys::fs::is_directory(CW2A(path.c_str()).m_psz);
}
if (isDirectory) {
DxilConvTestCheckBatchDir(path);
} else {
DxilConvTestCheckFile(path.c_str());
}
}
TEST_F(DxilConvTest, BatchDxbc2dxil) {
DxilConvTestCheckBatchDir(L"dxbc2dxil", ".hlsl");
}
TEST_F(DxilConvTest, BatchDxbc2dxilAsm) {
DxilConvTestCheckBatchDir(L"dxbc2dxil-asm", ".asm");
}
TEST_F(DxilConvTest, BatchDxilCleanup) {
// switch current directory to directory with test files and use relative
// paths because the reference files contain file path as ModuleID
wchar_t curDir[MAX_PATH];
IFT(GetCurrentDirectoryW(sizeof(curDir), curDir) == 0);
wstring testFilesPath = hlsl_test::GetPathToHlslDataFile(L"");
IFT(::SetCurrentDirectory(testFilesPath.c_str()));
DxilConvTestCheckBatchDir(L"dxil_cleanup", ".ll", true);
IFT(::SetCurrentDirectory(curDir));
}
TEST_F(DxilConvTest, BatchNormalizeDxil) {
DxilConvTestCheckBatchDir(L"normalize_dxil", ".ll");
}
TEST_F(DxilConvTest, BatchScopeNestIterator) {
DxilConvTestCheckBatchDir(L"scope_nest_iterator", ".ll");
}
TEST_F(DxilConvTest, RegressionTests) {
DxilConvTestCheckBatchDir(L"regression_tests", ".hlsl");
}