summaryrefslogtreecommitdiff
path: root/tools/slang-test
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2018-12-17 09:22:14 -0500
committerGitHub <noreply@github.com>2018-12-17 09:22:14 -0500
commitd2ddc590601778f309c81f7d19d5e7fed34210de (patch)
tree8ad5dd912fe43e946a4e40cce3eb6c8410254600 /tools/slang-test
parentd43c566fa29bbc0da1534aea236d54ee5ca104b8 (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.cpp94
-rw-r--r--tools/slang-test/slang-test.vcxproj2
-rw-r--r--tools/slang-test/slang-test.vcxproj.filters6
-rw-r--r--tools/slang-test/slangc-tool.cpp57
-rw-r--r--tools/slang-test/slangc-tool.h15
-rw-r--r--tools/slang-test/test-context.cpp32
-rw-r--r--tools/slang-test/test-context.h4
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();