diff options
| author | jsmall-nvidia <jsmall@nvidia.com> | 2018-12-17 09:22:14 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-12-17 09:22:14 -0500 |
| commit | d2ddc590601778f309c81f7d19d5e7fed34210de (patch) | |
| tree | 8ad5dd912fe43e946a4e40cce3eb6c8410254600 /tools/slang-test | |
| parent | d43c566fa29bbc0da1534aea236d54ee5ca104b8 (diff) | |
Feature/test tool shared libraries (#758)
* Remove circular reference to renderer on Vk & D3D12 DescriptorSetImpl
* Refactor Stbi image loading such that memory is correctly freed when goes out of scope.
Added Crt memory dump at termination.
Reduced erroneous reporting by scoping TestContext.
* Used capitalized acronym for STBImage to keep Tim happy.
* Split out TestReporter - to just handle reporting test results
Split out Options
Made TestContext hold options, and the reporter
Removed remaining memory leaks.
* Small optimization for rawWrite, such that it directly writes over print..
* Improve comments on TestCategorySet
* Fix typos in TestCategorySet
* Made slangc a cpp file as part of slang-test (removing need for separate project/shared library).
* * Made all test tools only available as dlls.
* Made possible to invoke test tool dll from command line
slang-test slangc [--bindir xxx] options to slangc
* Fix Visual Studio projects that are no longer needed.
Diffstat (limited to 'tools/slang-test')
| -rw-r--r-- | tools/slang-test/main.cpp | 94 | ||||
| -rw-r--r-- | tools/slang-test/slang-test.vcxproj | 2 | ||||
| -rw-r--r-- | tools/slang-test/slang-test.vcxproj.filters | 6 | ||||
| -rw-r--r-- | tools/slang-test/slangc-tool.cpp | 57 | ||||
| -rw-r--r-- | tools/slang-test/slangc-tool.h | 15 | ||||
| -rw-r--r-- | tools/slang-test/test-context.cpp | 32 | ||||
| -rw-r--r-- | tools/slang-test/test-context.h | 4 |
7 files changed, 205 insertions, 5 deletions
diff --git a/tools/slang-test/main.cpp b/tools/slang-test/main.cpp index 774fbd6e2..ec2ad03e8 100644 --- a/tools/slang-test/main.cpp +++ b/tools/slang-test/main.cpp @@ -15,11 +15,11 @@ using namespace Slang; #include "test-context.h" #include "test-reporter.h" #include "options.h" +#include "slangc-tool.h" #define STB_IMAGE_IMPLEMENTATION #include "external/stb/stb_image.h" - #ifdef _WIN32 #define SLANG_TEST_SUPPORT_HLSL 1 #include <d3dcompiler.h> @@ -1745,12 +1745,88 @@ void runTestsInDirectory( } } +struct ToolInvoke +{ + /// Returns true if it is a tool invoke + bool parse(const char*const* argv, int argc) + { + m_args.Clear(); + + m_binDirectory = "."; + + if (argc < 2 || !_isToolName(argv[1])) + { + return false; + } + m_toolName = argv[1]; + + // Look for parameters that are for the slang-test, and should be skipped + int i = 2; + while (i < argc) + { + if (strcmp(argv[i], "-bindir") == 0 && i + 1 < argc) + { + m_binDirectory = argv[i + 1]; + i += 2; + } + // If nothing found, the rest must be parsed to the tool + break; + } + + m_args.Add(m_toolName.Buffer()); + m_args.AddRange(argv + i, argc - i); + return true; + } + + SlangResult invoke(AppContext* appContext, TestContext* testContext) + { + // Do I want to strip the -bindir directory that may be later + + // We will just parse everything onto the underlying tool + auto func = testContext->getInnerMainFunc(m_binDirectory, m_toolName); + if (!func) + { + AppContext::getStdError().print("error: Unable to launch tool '%s'\n", m_toolName.Buffer()); + return SLANG_FAIL; + } + + return func(AppContext::getSingleton(), testContext->getSession(), int(m_args.Count()), m_args.Buffer()); + } + + String m_binDirectory; + String m_toolName; + List<const char*> m_args; + +private: + static bool _isToolName(const char* name) + { + static const char* toolNames[] = + { + "slangc", + "render-test", + "slang-reflection-test", + }; + + for (int i = 0; i < SLANG_COUNT_OF(toolNames); ++i) + { + if (::strcmp(toolNames[i], name) == 0) + { + return true; + } + } + return false; + } +}; + + SlangResult innerMain(int argc, char** argv) { AppContext::initDefault(); // The context holds useful things used during testing TestContext context; + SLANG_RETURN_ON_FAIL(SLANG_FAILED(context.init())) + auto& categorySet = context.categorySet; // Set up our test categories here @@ -1766,9 +1842,21 @@ SlangResult innerMain(int argc, char** argv) // An un-categorized test will always belong to the `full` category categorySet.defaultCategory = fullTestCategory; - SLANG_RETURN_ON_FAIL(Options::parse(argc, argv, &categorySet, AppContext::getStdError(), &context.options)); - SLANG_RETURN_ON_FAIL(SLANG_FAILED(context.init())) + { + // We can set the slangc command line tool, to just use the function defined here + context.setInnerMainFunc("slangc", &SlangCTool::innerMain); + } + + { + ToolInvoke toolInvoke; + if (toolInvoke.parse(argv, argc)) + { + return toolInvoke.invoke(AppContext::getSingleton(), &context); + } + } + SLANG_RETURN_ON_FAIL(Options::parse(argc, argv, &categorySet, AppContext::getStdError(), &context.options)); + Options& options = context.options; if( options.includeCategories.Count() == 0 ) { diff --git a/tools/slang-test/slang-test.vcxproj b/tools/slang-test/slang-test.vcxproj index 82c3e652a..cbd00ad0e 100644 --- a/tools/slang-test/slang-test.vcxproj +++ b/tools/slang-test/slang-test.vcxproj @@ -165,6 +165,7 @@ <ClInclude Include="options.h" /> <ClInclude Include="os.h" /> <ClInclude Include="render-api-util.h" /> + <ClInclude Include="slangc-tool.h" /> <ClInclude Include="test-context.h" /> <ClInclude Include="test-reporter.h" /> </ItemGroup> @@ -173,6 +174,7 @@ <ClCompile Include="options.cpp" /> <ClCompile Include="os.cpp" /> <ClCompile Include="render-api-util.cpp" /> + <ClCompile Include="slangc-tool.cpp" /> <ClCompile Include="test-context.cpp" /> <ClCompile Include="test-reporter.cpp" /> <ClCompile Include="unit-test-byte-encode.cpp" /> diff --git a/tools/slang-test/slang-test.vcxproj.filters b/tools/slang-test/slang-test.vcxproj.filters index 24ba365a7..6c1bdf941 100644 --- a/tools/slang-test/slang-test.vcxproj.filters +++ b/tools/slang-test/slang-test.vcxproj.filters @@ -18,6 +18,9 @@ <ClInclude Include="render-api-util.h"> <Filter>Header Files</Filter> </ClInclude> + <ClInclude Include="slangc-tool.h"> + <Filter>Header Files</Filter> + </ClInclude> <ClInclude Include="test-context.h"> <Filter>Header Files</Filter> </ClInclude> @@ -38,6 +41,9 @@ <ClCompile Include="render-api-util.cpp"> <Filter>Source Files</Filter> </ClCompile> + <ClCompile Include="slangc-tool.cpp"> + <Filter>Source Files</Filter> + </ClCompile> <ClCompile Include="test-context.cpp"> <Filter>Source Files</Filter> </ClCompile> diff --git a/tools/slang-test/slangc-tool.cpp b/tools/slang-test/slangc-tool.cpp new file mode 100644 index 000000000..3085e2ab5 --- /dev/null +++ b/tools/slang-test/slangc-tool.cpp @@ -0,0 +1,57 @@ +// test-context.cpp +#include "slangc-tool.h" + +using namespace Slang; + +SLANG_API void spSetCommandLineCompilerMode(SlangCompileRequest* request); + +static void _diagnosticCallback(char const* message, void* /*userData*/) +{ + auto stdError = AppContext::getStdError(); + stdError.put(message); + stdError.flush(); +} + +SlangResult SlangCTool::innerMain(AppContext* appContext, SlangSession* session, int argc, const char*const* argv) +{ + SlangCompileRequest* compileRequest = spCreateCompileRequest(session); + spSetDiagnosticCallback(compileRequest, &_diagnosticCallback, nullptr); + + spSetCommandLineCompilerMode(compileRequest); + // Do any app specific configuration + appContext->configureRequest(compileRequest); + + { + const SlangResult res = spProcessCommandLineArguments(compileRequest, &argv[1], argc - 1); + if (SLANG_FAILED(res)) + { + // TODO: print usage message + return res; + } + } + + SlangResult res = SLANG_OK; + +#ifndef _DEBUG + try +#endif + { + // Run the compiler (this will produce any diagnostics through SLANG_WRITER_TARGET_TYPE_DIAGNOSTIC). + res = spCompile(compileRequest); + // If the compilation failed, then get out of here... + // Turn into an internal Result -> such that return code can be used to vary result to match previous behavior + res = SLANG_FAILED(res) ? SLANG_E_INTERNAL_FAIL : res; + } +#ifndef _DEBUG + catch (Exception & e) + { + AppContext::getStdOut().print("internal compiler error: %S\n", e.Message.ToWString().begin()); + res = SLANG_FAIL; + } +#endif + + // Now that we are done, clean up after ourselves + spDestroyCompileRequest(compileRequest); + return res; +} + diff --git a/tools/slang-test/slangc-tool.h b/tools/slang-test/slangc-tool.h new file mode 100644 index 000000000..dd6e1b977 --- /dev/null +++ b/tools/slang-test/slangc-tool.h @@ -0,0 +1,15 @@ +// slangc-tool.h + +#ifndef SLANGC_TOOL_H_INCLUDED +#define SLANGC_TOOL_H_INCLUDED + +#include "../../source/core/slang-app-context.h" + +/* The slangc 'tool' interface, such that slangc like functionality is available directly without invoking slangc command line tool, or +need for a dll/shared library. */ +struct SlangCTool +{ + static SlangResult innerMain(Slang::AppContext* appContext, SlangSession* session, int argc, const char*const* argv); +}; + +#endif // SLANGC_TOOL_H_INCLUDED diff --git a/tools/slang-test/test-context.cpp b/tools/slang-test/test-context.cpp index 06a9847bf..0030d6136 100644 --- a/tools/slang-test/test-context.cpp +++ b/tools/slang-test/test-context.cpp @@ -27,6 +27,15 @@ Result TestContext::init() TestContext::~TestContext() { + for (auto& pair : m_sharedLibTools) + { + const auto& tool = pair.Value; + if (tool.m_sharedLibrary) + { + SharedLibrary::unload(tool.m_sharedLibrary); + } + } + if (m_session) { spDestroySession(m_session); @@ -45,7 +54,7 @@ TestContext::InnerMainFunc TestContext::getInnerMainFunc(const String& dirPath, StringBuilder sharedLibToolBuilder; sharedLibToolBuilder.append(name); - sharedLibToolBuilder.append("-shared-library"); + sharedLibToolBuilder.append("-tool"); StringBuilder builder; SharedLibrary::appendPlatformFileName(sharedLibToolBuilder.getUnownedSlice(), builder); @@ -61,3 +70,24 @@ TestContext::InnerMainFunc TestContext::getInnerMainFunc(const String& dirPath, m_sharedLibTools.Add(name, tool); return tool.m_func; } + +void TestContext::setInnerMainFunc(const String& name, InnerMainFunc func) +{ + SharedLibraryTool* tool = m_sharedLibTools.TryGetValue(name); + if (tool) + { + if (tool->m_sharedLibrary) + { + SharedLibrary::unload(tool->m_sharedLibrary); + tool->m_sharedLibrary = nullptr; + } + + tool->m_func = func; + } + else + { + SharedLibraryTool tool = {}; + tool.m_func = func; + m_sharedLibTools.Add(name, tool); + } +} diff --git a/tools/slang-test/test-context.h b/tools/slang-test/test-context.h index 18034f4c7..cfa9837da 100644 --- a/tools/slang-test/test-context.h +++ b/tools/slang-test/test-context.h @@ -21,7 +21,9 @@ class TestContext SlangResult init(); /// Get the inner main function (from shared library) - TestContext::InnerMainFunc getInnerMainFunc(const Slang::String& dirPath, const Slang::String& name); + InnerMainFunc getInnerMainFunc(const Slang::String& dirPath, const Slang::String& name); + /// Set the function for the shared library + void setInnerMainFunc(const Slang::String& name, InnerMainFunc func); /// Ctor TestContext(); |
