diff options
| author | Yong He <yonghe@outlook.com> | 2023-09-01 01:25:31 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-09-01 01:25:31 -0700 |
| commit | 9c11a87f8f811a9a110d73a24ab93443ea347506 (patch) | |
| tree | 9b1b0f154cff0faf7efd8d77fcd7f7911aea4a44 /tools | |
| parent | b7d19330c2d42937835d674758a05af3891e025b (diff) | |
Fix GLSL code gen around RayQuery and HitObject types. (#3173)
* Update slang-llvm.
* Fix.
* fix.
* Fix unit tests for multi-thread execution.
* Fix tests.
* fixes.
* update tests.
* Add gfx-smoke to linux expected failure list.
* Try fix test.
---------
Co-authored-by: Yong He <yhe@nvidia.com>
Diffstat (limited to 'tools')
| -rw-r--r-- | tools/gfx-unit-test/copy-texture-tests.cpp | 12 | ||||
| -rw-r--r-- | tools/gfx-unit-test/shader-cache-tests.cpp | 7 | ||||
| -rw-r--r-- | tools/slang-test/slang-test-main.cpp | 213 | ||||
| -rw-r--r-- | tools/slang-test/test-context.h | 4 | ||||
| -rw-r--r-- | tools/slang-unit-test/unit-test-lock-file.cpp | 3 | ||||
| -rw-r--r-- | tools/slang-unit-test/unit-test-persistent-cache.cpp | 3 | ||||
| -rw-r--r-- | tools/slang-unit-test/unit-test-translation-unit-import.cpp | 14 |
7 files changed, 161 insertions, 95 deletions
diff --git a/tools/gfx-unit-test/copy-texture-tests.cpp b/tools/gfx-unit-test/copy-texture-tests.cpp index 0129dd818..68ca193ae 100644 --- a/tools/gfx-unit-test/copy-texture-tests.cpp +++ b/tools/gfx-unit-test/copy-texture-tests.cpp @@ -749,20 +749,20 @@ namespace gfx_test // Skip Type::Unknown and Type::Buffer as well as Format::Unknown // TODO: Add support for TextureCube + Format formats[] = { Format::R8G8B8A8_UNORM, Format::R16_FLOAT, Format::R16G16_FLOAT, Format::R10G10B10A2_UNORM, Format::B5G5R5A1_UNORM }; for (uint32_t i = 2; i < (uint32_t)ITextureResource::Type::_Count - 1; ++i) { - for (uint32_t j = 1; j < (uint32_t)Format::_Count; ++j) + for (auto format : formats) { // Fails validation VUID-VkImageCreateInfo-imageCreateMaxMipLevels-02251 - if(isVkd3d && ((Format)j == Format::R32G32B32_TYPELESS || - (Format)j == Format::R32G32B32_FLOAT || - (Format)j == Format::R32G32B32_UINT || - (Format)j == Format::R32G32B32_SINT)) + if(isVkd3d && (format == Format::R32G32B32_TYPELESS || + format == Format::R32G32B32_FLOAT || + format == Format::R32G32B32_UINT || + format == Format::R32G32B32_SINT)) { continue; } auto type = (ITextureResource::Type)i; - auto format = (Format)j; auto validationFormat = getValidationTextureFormat(format); if (!validationFormat) continue; diff --git a/tools/gfx-unit-test/shader-cache-tests.cpp b/tools/gfx-unit-test/shader-cache-tests.cpp index de699c2d6..3879fd630 100644 --- a/tools/gfx-unit-test/shader-cache-tests.cpp +++ b/tools/gfx-unit-test/shader-cache-tests.cpp @@ -7,7 +7,7 @@ #include "source/core/slang-string-util.h" #include "source/core/slang-io.h" #include "source/core/slang-file-system.h" - +#include "source/core/slang-process.h" #include "gfx-test-texture-util.h" using namespace gfx; @@ -112,9 +112,8 @@ namespace gfx_test { this->context = context; this->api = api; - - testDirectory = Path::simplify(Path::getParentDirectory(Path::getExecutablePath()) + "/shader-cache-test"); - cacheDirectory = Path::simplify(testDirectory + "/cache"); + testDirectory = Path::simplify(Path::getParentDirectory(Path::getExecutablePath()) + "/shader-cache-test" + String(Process::getId())); + cacheDirectory = Path::simplify(testDirectory + "/cache" + String(Process::getId())); // Cleanup if there are stale files from a previously aborted test. removeDirectory(cacheDirectory); diff --git a/tools/slang-test/slang-test-main.cpp b/tools/slang-test/slang-test-main.cpp index c910d83cc..b726caea3 100644 --- a/tools/slang-test/slang-test-main.cpp +++ b/tools/slang-test/slang-test-main.cpp @@ -879,7 +879,11 @@ static Result _executeRPC(TestContext* context, SpawnType spawnType, const Unown } // Execute - SLANG_RETURN_ON_FAIL(rpcConnection->sendCall(method, rttiInfo, args)); + if (SLANG_FAILED(rpcConnection->sendCall(method, rttiInfo, args))) + { + context->destroyRPCConnection(); + return SLANG_FAIL; + } // Wait for the result rpcConnection->waitForResult(context->connectionTimeOutInMs); @@ -893,12 +897,17 @@ static Result _executeRPC(TestContext* context, SpawnType spawnType, const Unown if (rpcConnection->getMessageType() != JSONRPCMessageType::Result) { + context->destroyRPCConnection(); return SLANG_FAIL; } // Get the result TestServerProtocol::ExecutionResult exeRes; - SLANG_RETURN_ON_FAIL(rpcConnection->getMessage(&exeRes)); + if (SLANG_FAILED(rpcConnection->getMessage(&exeRes))) + { + context->destroyRPCConnection(); + return SLANG_FAIL; + } outRes.resultCode = exeRes.returnCode; outRes.standardError = exeRes.stdError; @@ -1648,7 +1657,10 @@ TestResult runExecutableTest(TestContext* context, TestInput& input) // Just use shared library now, TestServer spawn mode seems to cause slangc to fail to find its own // executable path, and thus failed to find the `gfx.slang` file sitting along side `slangc.exe`. // We need to figure out what happened to `Path::getExecutablePath()` inside test-server. - TEST_RETURN_ON_DONE(spawnAndWait(context, outputStem, SpawnType::UseSharedLibrary, cmdLine, exeRes)); + SpawnType slangcSpawnType = input.spawnType; + if (slangcSpawnType == SpawnType::UseTestServer) + slangcSpawnType = SpawnType::UseExe; + TEST_RETURN_ON_DONE(spawnAndWait(context, outputStem, slangcSpawnType, cmdLine, exeRes)); String actualOutput; @@ -1702,6 +1714,9 @@ TestResult runExecutableTest(TestContext* context, TestInput& input) TestResult runLanguageServerTest(TestContext* context, TestInput& input) { + // We don't support running language server tests in parallel yet. + std::lock_guard lock(context->mutex); + if (!context->m_languageServerConnection) { if (SLANG_FAILED(context->createLanguageServerJSONRPCConnection(context->m_languageServerConnection))) @@ -4072,6 +4087,42 @@ void getFilesInDirectory(String directoryPath, List<String>& files) } } +template<typename F> +void runTestsInParallel(TestContext* context, int count, const F& f) +{ + auto originalReporter = context->getTestReporter(); + std::atomic<int> consumePtr; + consumePtr = 0; + auto threadFunc = [&](int threadId) + { + TestReporter reporter; + reporter.init(context->options.outputMode, context->options.expectedFailureList, true); + TestReporter::SuiteScope suiteScope(&reporter, "tests"); + context->setThreadIndex(threadId); + context->setTestReporter(&reporter); + do + { + int index = consumePtr.fetch_add(1); + if (index >= count) + break; + f(index); + } while (true); + { + std::lock_guard<std::mutex> lock(context->mutex); + originalReporter->consolidateWith(&reporter); + } + context->setTestReporter(nullptr); + }; + List<std::thread> threads; + for (int threadId = 0; threadId < context->options.serverCount; threadId++) + { + threads.add(std::thread(threadFunc, threadId)); + } + for (auto& t : threads) + t.join(); + context->setTestReporter(originalReporter); +} + void runTestsInDirectory( TestContext* context, String directoryPath) @@ -4119,37 +4170,10 @@ void runTestsInDirectory( } else { - auto originalReporter = context->getTestReporter(); - std::atomic<int> consumePtr; - consumePtr = 0; - auto threadFunc = [&](int threadId) - { - TestReporter reporter; - reporter.init(context->options.outputMode, context->options.expectedFailureList, true); - TestReporter::SuiteScope suiteScope(&reporter, "tests"); - context->setThreadIndex(threadId); - context->setTestReporter(&reporter); - do + runTestsInParallel(context, (int)files.getCount(), [&](int index) { - int index = consumePtr.fetch_add(1); - if (index >= (int)files.getCount()) - break; processFile(files[index]); - } while (true); - { - std::lock_guard<std::mutex> lock(context->mutex); - originalReporter->consolidateWith(&reporter); - } - context->setTestReporter(nullptr); - }; - List<std::thread> threads; - for (int threadId = 0; threadId < context->options.serverCount; threadId++) - { - threads.add(std::thread(threadFunc, threadId)); - } - for (auto& t : threads) - t.join(); - context->setTestReporter(originalReporter); + }); } } @@ -4205,10 +4229,6 @@ static SlangResult runUnitTestModule(TestContext* context, TestOptions& testOpti if (!testModule) return SLANG_FAIL; - auto reporter = TestReporter::get(); - - testModule->setTestReporter(reporter); - UnitTestContext unitTestContext; unitTestContext.slangGlobalSession = context->getSession(); unitTestContext.workDirectory = ""; @@ -4217,6 +4237,16 @@ static SlangResult runUnitTestModule(TestContext* context, TestOptions& testOpti auto testCount = testModule->getTestCount(); + struct TestItem + { + UnitTestFunc testFunc; + String testName; + String command; + }; + + List<TestItem> tests; + + // Discover all tests first. for (SlangInt i = 0; i < testCount; i++) { auto testFunc = testModule->getTestFunc(i); @@ -4224,59 +4254,94 @@ static SlangResult runUnitTestModule(TestContext* context, TestOptions& testOpti StringBuilder filePath; filePath << moduleName << "/" << testName << ".internal"; + auto command = filePath.produceString(); - testOptions.command = filePath; - - if (shouldRunTest(context, testOptions.command)) + if (shouldRunTest(context, command)) { if (testPassesCategoryMask(context, testOptions)) { - if (spawnType == SpawnType::UseTestServer || - spawnType == SpawnType::UseFullyIsolatedTestServer) - { - TestServerProtocol::ExecuteUnitTestArgs args; - args.enabledApis = context->options.enabledApis; - args.moduleName = moduleName; - args.testName = testName; + tests.add(TestItem{ testFunc, testName, command }); + } + } + } - { - TestReporter::TestScope scopeTest(reporter, testOptions.command); - ExecuteResult exeRes; + auto runUnitTest = [&](TestItem test) + { + auto reporter = context->getTestReporter(); + TestOptions options = testOptions; + options.command = test.command; - SlangResult rpcRes = _executeRPC(context, spawnType, TestServerProtocol::ExecuteUnitTestArgs::g_methodName, &args, exeRes); - const auto testResult = _asTestResult(ToolReturnCode(exeRes.resultCode)); + if (spawnType == SpawnType::UseTestServer || + spawnType == SpawnType::UseFullyIsolatedTestServer) + { + TestServerProtocol::ExecuteUnitTestArgs args; + args.enabledApis = context->options.enabledApis; + args.moduleName = moduleName; + args.testName = test.testName; - // If the test fails, output any output - which might give information about individual tests that have failed. - if (SLANG_FAILED(rpcRes) || testResult == TestResult::Fail) - { - String output = getOutput(exeRes); - reporter->message(TestMessageType::TestFailure, output.getBuffer()); - } + { + TestReporter::TestScope scopeTest(reporter, options.command); + ExecuteResult exeRes; - reporter->addResult(testResult); - } - } - else + SlangResult rpcRes = _executeRPC(context, spawnType, TestServerProtocol::ExecuteUnitTestArgs::g_methodName, &args, exeRes); + const auto testResult = _asTestResult(ToolReturnCode(exeRes.resultCode)); + + // If the test fails, output any output - which might give information about individual tests that have failed. + if (SLANG_FAILED(rpcRes) || testResult == TestResult::Fail) { - TestReporter::TestScope scopeTest(reporter, testOptions.command); + String output = getOutput(exeRes); + reporter->message(TestMessageType::TestFailure, output.getBuffer()); + } - // TODO(JS): Problem here could be exception not handled properly across - // shared library boundary. + reporter->addResult(testResult); + } + } + else + { + TestReporter::TestScope scopeTest(reporter, options.command); - try - { - testFunc(&unitTestContext); - } - catch (...) - { - reporter->message(TestMessageType::TestFailure, "Exception was thrown during execution"); - reporter->addResult(TestResult::Fail); - } - } + // TODO(JS): Problem here could be exception not handled properly across + // shared library boundary. + testModule->setTestReporter(reporter); + try + { + test.testFunc(&unitTestContext); } + catch (...) + { + reporter->message(TestMessageType::TestFailure, "Exception was thrown during execution"); + reporter->addResult(TestResult::Fail); + } + } + }; + + bool useMultiThread = false; + if (spawnType == SpawnType::UseTestServer || + spawnType == SpawnType::UseFullyIsolatedTestServer) + { + if (context->options.serverCount > 1) + { + useMultiThread = true; } } + if (useMultiThread) + { + runTestsInParallel(context, (int)tests.getCount(), [&](int index) + { + runUnitTest(tests[index]); + }); + } + else + { + auto reporter = TestReporter::get(); + + testModule->setTestReporter(reporter); + + for (auto t : tests) + runUnitTest(t); + } + testModule->destroy(); return SLANG_OK; } diff --git a/tools/slang-test/test-context.h b/tools/slang-test/test-context.h index 00aad5888..ad8a45042 100644 --- a/tools/slang-test/test-context.h +++ b/tools/slang-test/test-context.h @@ -159,8 +159,8 @@ class TestContext /// TODO(JS): We could split the stdlib compilation from other actions, and have timeout specific for /// that. To do this we could have a 'compileStdLib' RPC method. /// - /// Current default is 2 mins. - Slang::Int connectionTimeOutInMs = 2 * 60 * 1000; + /// Current default is 20 seconds. + Slang::Int connectionTimeOutInMs = 20 * 1000; void setThreadIndex(int index); void setMaxTestRunnerThreadCount(int count); diff --git a/tools/slang-unit-test/unit-test-lock-file.cpp b/tools/slang-unit-test/unit-test-lock-file.cpp index be767a5ee..4915770fe 100644 --- a/tools/slang-unit-test/unit-test-lock-file.cpp +++ b/tools/slang-unit-test/unit-test-lock-file.cpp @@ -2,6 +2,7 @@ #include "tools/unit-test/slang-unit-test.h" #include "../../source/core/slang-io.h" +#include "../../source/core/slang-process.h" #include <atomic> #include <future> @@ -10,7 +11,7 @@ using namespace Slang; -static const String fileName = Path::simplify(Path::getParentDirectory(Path::getExecutablePath()) + "/test_lock_file"); +static const String fileName = Path::simplify(Path::getParentDirectory(Path::getExecutablePath()) + "/test_lock_file" + String(Process::getId())); SLANG_UNIT_TEST(lockFileOpenClose) { diff --git a/tools/slang-unit-test/unit-test-persistent-cache.cpp b/tools/slang-unit-test/unit-test-persistent-cache.cpp index d2d8aeb25..cb7ebcab2 100644 --- a/tools/slang-unit-test/unit-test-persistent-cache.cpp +++ b/tools/slang-unit-test/unit-test-persistent-cache.cpp @@ -5,6 +5,7 @@ #include "../../source/core/slang-io.h" #include "../../source/core/slang-file-system.h" #include "../../source/core/slang-random-generator.h" +#include "../../source/core/slang-process.h" #include <chrono> #include <thread> @@ -86,7 +87,7 @@ struct PersistentCacheTest PersistentCacheTest(Count maxEntryCount = 0) { osFileSystem = OSFileSystem::getMutableSingleton(); - cacheDirectory = Path::simplify(Path::getParentDirectory(Path::getExecutablePath()) + "/persistent-cache-test"); + cacheDirectory = Path::simplify(Path::getParentDirectory(Path::getExecutablePath()) + "/persistent-cache-test" + String(Process::getId())); removeCacheFiles(); diff --git a/tools/slang-unit-test/unit-test-translation-unit-import.cpp b/tools/slang-unit-test/unit-test-translation-unit-import.cpp index 9e79831e5..3a0a98e17 100644 --- a/tools/slang-unit-test/unit-test-translation-unit-import.cpp +++ b/tools/slang-unit-test/unit-test-translation-unit-import.cpp @@ -8,6 +8,7 @@ #include "tools/unit-test/slang-unit-test.h" #include "../../slang-com-ptr.h" #include "../../source/core/slang-io.h" +#include "../../source/core/slang-process.h" using namespace Slang; @@ -31,8 +32,7 @@ SLANG_UNIT_TEST(translationUnitImport) )"; // Source for a module that transitively uses the generated source via a file. - const char* userSource = R"( - import moduleG; + const char* userSourceBody = R"( [shader("compute")] [numthreads(4,1,1)] void computeMain( @@ -42,11 +42,12 @@ SLANG_UNIT_TEST(translationUnitImport) buffer[sv_dispatchThreadID.x] = g(); })"; - + auto moduleName = "moduleG" + String(Process::getId()); + String userSource = "import " + moduleName + ";\n" + userSourceBody; auto session = spCreateSession(); auto request = spCreateCompileRequest(session); - File::writeAllText("moduleG.slang", fileSource); + File::writeAllText(moduleName + ".slang", fileSource); spAddCodeGenTarget(request, SLANG_HLSL); int generatedTranslationUnitIndex = spAddTranslationUnit(request, SLANG_SOURCE_LANGUAGE_SLANG, "generatedUnit"); @@ -55,7 +56,7 @@ SLANG_UNIT_TEST(translationUnitImport) int entryPointTranslationUnitIndex = spAddTranslationUnit(request, SLANG_SOURCE_LANGUAGE_SLANG, "userUnit"); spAddTranslationUnitSourceString( - request, entryPointTranslationUnitIndex, "userFile", userSource); + request, entryPointTranslationUnitIndex, "userFile", userSource.getUnownedSlice().begin()); spAddEntryPoint(request, entryPointTranslationUnitIndex, "computeMain", SLANG_STAGE_COMPUTE); auto compileResult = spCompile(request); @@ -67,7 +68,6 @@ SLANG_UNIT_TEST(translationUnitImport) spDestroyCompileRequest(request); spDestroySession(session); - - File::remove("moduleG.slang"); + File::remove(moduleName + ".slang"); } |
