summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2021-05-22 16:03:30 -0400
committerGitHub <noreply@github.com>2021-05-22 16:03:30 -0400
commit34a1ff5226a526cc17c5baecd63637f69c324fc7 (patch)
tree3bbaf2a2812bc121210d0b1142a303e6aab01a68
parent7f8a9994d0bd99a171a1daa0bce46d92c02ccffd (diff)
Improvements in -X support (#1852)
* #include an absolute path didn't work - because paths were taken to always be relative. * Added SourceLoc handling for command line parsing. * Fix typo in debug. * Fix issue around the DiagnosticSink used in options parsing not having a writer available - by having DiagnosticSink parenting. * Small rename for clarity. * WIP extracting command line args for downstream tools. * Unit tests/bug fixes around extracting args. * Use DownstreamArgs in the EndToEndCompileRequest * Passing downstream compiler options downstream. * Fix issue with endToEndReq being nullptr. * Fix issue with diagnostics number change. * Small improvements to how the source line is displayed if it's too long. Default to 120, as suggested in previous review. * Make render test use x-args parsing and CommandArgReader. * Added missing diagnostics. * More DownstreamArgs to linkage so can be seen by 'components'. Added dxc-x-arg test. * Used combination of name and args instead of two Lists, which whilst equivalent was perhaps a little confusing. * Added documentation for -X support. * Added test for x-args parsing diagnostic. Improved diagnostic with list of known names. * Fix issues from merge. * Fix lookup for -matrix-layout-column-major in render test. * Remove commented out line.
-rw-r--r--build/visual-studio/render-test-tool/render-test-tool.vcxproj6
-rw-r--r--build/visual-studio/render-test-tool/render-test-tool.vcxproj.filters9
-rw-r--r--docs/command-line-slangc.md62
-rw-r--r--premake5.lua2
-rw-r--r--source/compiler-core/slang-command-line-args.cpp44
-rw-r--r--source/compiler-core/slang-command-line-args.h21
-rw-r--r--source/compiler-core/slang-misc-diagnostic-defs.h2
-rw-r--r--source/core/slang-token-reader.cpp9
-rw-r--r--source/core/slang-token-reader.h9
-rwxr-xr-xsource/slang/slang-compiler.cpp7
-rwxr-xr-xsource/slang/slang-compiler.h6
-rw-r--r--source/slang/slang-options.cpp12
-rw-r--r--source/slang/slang.cpp34
-rw-r--r--tests/diagnostics/command-line/x-arg-tool-unknown.slang3
-rw-r--r--tests/diagnostics/command-line/x-arg-tool-unknown.slang.expected8
-rw-r--r--tests/downstream/dxc-x-arg.slang18
-rw-r--r--tests/downstream/dxc-x-arg.slang.expected.txt4
-rw-r--r--tools/render-test/diagnostic-defs.h33
-rw-r--r--tools/render-test/diagnostics.cpp21
-rw-r--r--tools/render-test/diagnostics.h25
-rw-r--r--tools/render-test/options.cpp213
-rw-r--r--tools/render-test/options.h26
-rw-r--r--tools/render-test/render-test-main.cpp32
-rw-r--r--tools/render-test/shader-input-layout.cpp55
-rw-r--r--tools/render-test/slang-support.cpp21
-rw-r--r--tools/render-test/slang-support.h14
26 files changed, 439 insertions, 257 deletions
diff --git a/build/visual-studio/render-test-tool/render-test-tool.vcxproj b/build/visual-studio/render-test-tool/render-test-tool.vcxproj
index 1c913b878..9e7b64089 100644
--- a/build/visual-studio/render-test-tool/render-test-tool.vcxproj
+++ b/build/visual-studio/render-test-tool/render-test-tool.vcxproj
@@ -179,6 +179,8 @@
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
+ <ClInclude Include="..\..\..\tools\render-test\diagnostic-defs.h" />
+ <ClInclude Include="..\..\..\tools\render-test\diagnostics.h" />
<ClInclude Include="..\..\..\tools\render-test\options.h" />
<ClInclude Include="..\..\..\tools\render-test\png-serialize-util.h" />
<ClInclude Include="..\..\..\tools\render-test\shader-input-layout.h" />
@@ -186,6 +188,7 @@
<ClInclude Include="..\..\..\tools\render-test\slang-support.h" />
</ItemGroup>
<ItemGroup>
+ <ClCompile Include="..\..\..\tools\render-test\diagnostics.cpp" />
<ClCompile Include="..\..\..\tools\render-test\options.cpp" />
<ClCompile Include="..\..\..\tools\render-test\png-serialize-util.cpp" />
<ClCompile Include="..\..\..\tools\render-test\render-test-main.cpp" />
@@ -197,6 +200,9 @@
<ProjectReference Include="..\core\core.vcxproj">
<Project>{F9BE7957-8399-899E-0C49-E714FDDD4B65}</Project>
</ProjectReference>
+ <ProjectReference Include="..\compiler-core\compiler-core.vcxproj">
+ <Project>{12C1E89D-F5D0-41D3-8E8D-FB3F358F8126}</Project>
+ </ProjectReference>
<ProjectReference Include="..\slang\slang.vcxproj">
<Project>{DB00DA62-0533-4AFD-B59F-A67D5B3A0808}</Project>
</ProjectReference>
diff --git a/build/visual-studio/render-test-tool/render-test-tool.vcxproj.filters b/build/visual-studio/render-test-tool/render-test-tool.vcxproj.filters
index cef2cd3b7..689b8846d 100644
--- a/build/visual-studio/render-test-tool/render-test-tool.vcxproj.filters
+++ b/build/visual-studio/render-test-tool/render-test-tool.vcxproj.filters
@@ -9,6 +9,12 @@
</Filter>
</ItemGroup>
<ItemGroup>
+ <ClInclude Include="..\..\..\tools\render-test\diagnostic-defs.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\tools\render-test\diagnostics.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
<ClInclude Include="..\..\..\tools\render-test\options.h">
<Filter>Header Files</Filter>
</ClInclude>
@@ -26,6 +32,9 @@
</ClInclude>
</ItemGroup>
<ItemGroup>
+ <ClCompile Include="..\..\..\tools\render-test\diagnostics.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
<ClCompile Include="..\..\..\tools\render-test\options.cpp">
<Filter>Source Files</Filter>
</ClCompile>
diff --git a/docs/command-line-slangc.md b/docs/command-line-slangc.md
index 01c5f7312..9eaf2343a 100644
--- a/docs/command-line-slangc.md
+++ b/docs/command-line-slangc.md
@@ -149,6 +149,68 @@ For completeness, here are the options that `slangc` currently accepts:
* `-output-includes`: After pre-processing has been performed will output to via the diagnostics the hierarchy of paths to source files reached
+* -Xname to specify arguments to downstream tool `name` (covered in more detail in "Downstream Arguments")
+
+### Downstream Arguments
+
+During a Slang compilation work may be performed by multiple other stages including downstream compilers and linkers. It isn't possible in general or perhaps even desirable to provide Slang command line equivalents of every option available at every stage of compilation. It is useful to be able to set options specific to a particular compilation stage - to alter code generation, linkage and other options.
+
+The mechanism used here is based on the `-X` mechanism used in GCC, to specify arguments to the linker.
+
+```
+-Xlinker option
+```
+
+When used, option is not interpreted by GCC, but is passed to the linker once compilation is complete. Slang extends this idea in several ways. First there are many more 'downstream' stages available to Slang. These different stages are known as `SlangPassThrough` types in the API and have the following names
+
+* `fxc` - FXC HLSL compiler
+* `dxc` - DXC HLSL compiler
+* `glslang` - GLSLANG GLSL compiler
+* `visualstudio` - Visual Studio C/C++ compiler
+* `clang` - Clang C/C++ compiler
+* `gcc` - GCC C/C++ compiler
+* `genericcpp` - A generic C++ compiler (can be any one of visual studio, clang or gcc depending on system and availability)
+* `nvrtc` - NVRTC CUDA compiler
+
+The Slang command line allows you to specify an argument to these downstream compilers, by using their name after the -X. So for example to send an option `-Gfa` through to DXC you can use
+
+```
+-Xdxc -Gfa
+```
+
+Note that if an option is available via normal Slang command line options then these should be used. This will work on multiple targets, but also avoids options clashing. As it stands Slang does not determine if a command line setting using the `-X` option clashes with regular Slang options in any way. This mechanism is best used for options that are unavailable through normal Slang mechanisms.
+
+If you want to pass multiple options using this mechanism the `-Xdxc` needs to be in front of every options. For example
+
+```
+-Xdxc -Gfa -Xdxc -Vd
+```
+
+This can get a little repetitive especially if there are many parameters, so Slang adds a mechanism to have multiple options passed by using an ellipsis `...`. The syntax is as follows
+
+```
+-Xdxc... -Gfa -Vd -X.
+```
+
+The `...` at the end indicates all the following parameters should be sent to DXC until it reaches the terminating `-X` or the end of the command line.
+
+It is also worth noting that `-X...` options can be nested. This would allow a GCC downstream compilation to control linking, for example with
+
+```
+-Xgcc -Xlinker --split -X
+```
+
+Setting options for tools that aren't used in a Slang compilation has no effect. This allows for setting `-X` options specific for all downstream tools on a command line, and they are only used as part of a compilation that needs them.
+
+NOTE! Not all tools that Slang uses downstream make command line argument parsing available. Of note `FXC` and `GLSLANG` currently do not have any command line argument passing as part of their integration.
+
+The `-X` mechanism is also supported by render-test tool. In this usage `slang` becomes a downstream tool. Thus you can use the DXC option `-Gfa` in a render-test via
+
+```
+-Xslang... -Xdxc -Gfa -X.
+```
+
+
### Specifying where dlls/shared libraries are loaded from
On windows if you want a dll loaded from a specific path, the path must be specified absolutely. See the *'LoadLibrary'* documentation for more details. A relative path will cause Windows to check all locations along it's search procedure.
diff --git a/premake5.lua b/premake5.lua
index 062835109..a0a5dbb35 100644
--- a/premake5.lua
+++ b/premake5.lua
@@ -783,7 +783,7 @@ toolSharedLibrary "render-test"
uuid "61F7EB00-7281-4BF3-9470-7C2EA92620C3"
includedirs { ".", "external", "source", "tools/gfx", "tools/platform" }
- links { "core", "slang", "gfx", "gfx-util", "platform" }
+ links { "core", "compiler-core", "slang", "gfx", "gfx-util", "platform" }
if isTargetWindows then
addSourceDir "tools/render-test/windows"
diff --git a/source/compiler-core/slang-command-line-args.cpp b/source/compiler-core/slang-command-line-args.cpp
index 1d452bb10..d7a053b00 100644
--- a/source/compiler-core/slang-command-line-args.cpp
+++ b/source/compiler-core/slang-command-line-args.cpp
@@ -63,7 +63,6 @@ bool CommandLineArgs::hasArgs(const char*const* args, Index count) const
return true;
}
-
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
CommandLineReader
@@ -121,14 +120,11 @@ SlangResult CommandLineReader::expectArg(CommandLineArg& outArg)
Index DownstreamArgs::addName(const String& name)
{
- Index index = m_names.indexOf(name);
+ Index index = findName(name);
if (index < 0)
{
- index = m_names.getCount();
- m_names.add(name);
-
- CommandLineArgs args(m_context);
- m_args.add(args);
+ index = m_entries.getCount();
+ m_entries.add(Entry{name, CommandLineArgs(m_context) });
}
return index;
}
@@ -137,7 +133,10 @@ Index DownstreamArgs::_findOrAddName(SourceLoc loc, const UnownedStringSlice& na
{
if (name.getLength() <= 0)
{
- sink->diagnose(loc, MiscDiagnostics::downstreamToolNameNotDefined);
+ if (sink)
+ {
+ sink->diagnose(loc, MiscDiagnostics::downstreamToolNameNotDefined);
+ }
return -1;
}
@@ -152,15 +151,38 @@ Index DownstreamArgs::_findOrAddName(SourceLoc loc, const UnownedStringSlice& na
return index;
}
- sink->diagnose(loc, MiscDiagnostics::downstreamNameNotKnown);
+ if (sink)
+ {
+ StringBuilder names;
+
+ names << "[ ";
+ for (Index i = 0; i < m_entries.getCount(); ++i)
+ {
+ if (i)
+ {
+ names << ", ";
+ }
+ names << m_entries[i].name;
+ }
+ names << " ]";
+
+ sink->diagnose(loc, MiscDiagnostics::downstreamNameNotKnown, names);
+ }
return -1;
}
CommandLineArgs& DownstreamArgs::getArgsByName(char* name)
{
- Index index = findName(name);
+ const Index index = findName(name);
+ SLANG_ASSERT(index >= 0);
+ return m_entries[index].args;
+}
+
+const CommandLineArgs& DownstreamArgs::getArgsByName(char* name) const
+{
+ const Index index = findName(name);
SLANG_ASSERT(index >= 0);
- return m_args[index];
+ return m_entries[index].args;
}
SlangResult DownstreamArgs::stripDownstreamArgs(CommandLineArgs& ioArgs, Flags flags, DiagnosticSink* sink)
diff --git a/source/compiler-core/slang-command-line-args.h b/source/compiler-core/slang-command-line-args.h
index 7500c1a91..c18996005 100644
--- a/source/compiler-core/slang-command-line-args.h
+++ b/source/compiler-core/slang-command-line-args.h
@@ -17,6 +17,9 @@ struct CommandLineArg
SourceLoc loc; ///< The location of the arg
};
+/* This type ends up being really just a container for the sourceManager that has the CommandLine specific SourceLocs.
+That it would perhaps be better to just have SourceManager derive from RefObject, and then we could remove this
+type. */
class CommandLineContext : public RefObject
{
public:
@@ -27,6 +30,8 @@ public:
{
m_sourceManager.initialize(nullptr, fileSystemExt);
// Make range start from high value, so can be differentiated from other uses
+ // That this doesn't not assume exclusive use of this range - just that in normal use scenarios
+ // there is no confusion, and using the wrong source manager, will typically report nothing is found.
m_sourceManager.allocateSourceRange(~(~SourceLoc::RawValue(0) >> 1));
}
@@ -128,15 +133,22 @@ struct DownstreamArgs
};
};
+ struct Entry
+ {
+ String name; ///< The name of the 'tool' that these args are associated with
+ CommandLineArgs args; ///< The args to be passed to the tool
+ };
+
/// Add a name, returns the index
Index addName(const String& name);
/// Find the index of a name. Returns < 0 if not found.
- Index findName(const String& name) const { return m_names.indexOf(name); }
+ Index findName(const String& name) const { return m_entries.findFirstIndex([&](const Entry& entry) -> bool { return entry.name == name; }); }
/// Get the args at the nameIndex
- CommandLineArgs& getArgsAt(Index nameIndex) { return m_args[nameIndex]; }
+ CommandLineArgs& getArgsAt(Index nameIndex) { return m_entries[nameIndex].args; }
/// Get args by name - will assert if name isn't found
CommandLineArgs& getArgsByName(char* name);
+ const CommandLineArgs& getArgsByName(char* name) const;
/// Looks for '-X' expressions, removing them from ioArgs and putting in appropriate args
SlangResult stripDownstreamArgs(CommandLineArgs& ioArgs, Flags flags, DiagnosticSink* sink);
@@ -155,10 +167,9 @@ struct DownstreamArgs
protected:
Index _findOrAddName(SourceLoc loc, const UnownedStringSlice& name, Flags flags, DiagnosticSink* sink);
- List<String> m_names;
- List<CommandLineArgs> m_args;
+ List<Entry> m_entries; ///< All of the entries
- RefPtr<CommandLineContext> m_context;
+ RefPtr<CommandLineContext> m_context; ///< The context that is being used (primarily for loc tracking) across all entries/args
};
diff --git a/source/compiler-core/slang-misc-diagnostic-defs.h b/source/compiler-core/slang-misc-diagnostic-defs.h
index e5c7c335e..aa87f02f9 100644
--- a/source/compiler-core/slang-misc-diagnostic-defs.h
+++ b/source/compiler-core/slang-misc-diagnostic-defs.h
@@ -24,7 +24,7 @@
DIAGNOSTIC(-1, Note, seeTokenPasteLocation, "see token pasted location")
-DIAGNOSTIC(100000, Error, downstreamNameNotKnown, "downstream tool name not known")
+DIAGNOSTIC(100000, Error, downstreamNameNotKnown, "downstream tool name not known, allowed names are $0")
DIAGNOSTIC(100001, Error, expectedArgumentForOption, "expected an argument for command-line option '$0'")
DIAGNOSTIC(100002, Error, unbalancedDownstreamArguments, "unbalanced downstream arguments")
DIAGNOSTIC(100003, Error, closeOfUnopenDownstreamArgs, "close of an unopen downstream argument scope")
diff --git a/source/core/slang-token-reader.cpp b/source/core/slang-token-reader.cpp
index a15dcda9c..3be010751 100644
--- a/source/core/slang-token-reader.cpp
+++ b/source/core/slang-token-reader.cpp
@@ -1,7 +1,8 @@
#include "slang-token-reader.h"
-namespace Slang
-{
+namespace Slang {
+namespace Misc {
+
enum class TokenizeErrorType
{
InvalidCharacter, InvalidEscapeSequence
@@ -765,4 +766,6 @@ namespace Slang
this->tokens = TokenizeText("", text);
tokenPtr = 0;
}
-}
+
+} // namespace Misc
+} // namespace Slang
diff --git a/source/core/slang-token-reader.h b/source/core/slang-token-reader.h
index 18b56f31f..0d59eea76 100644
--- a/source/core/slang-token-reader.h
+++ b/source/core/slang-token-reader.h
@@ -3,8 +3,9 @@
#include "slang-basic.h"
-namespace Slang
-{
+namespace Slang {
+namespace Misc {
+
/* NOTE! This TokenReader is NOT used by the main slang compiler !*/
enum class TokenType
@@ -293,7 +294,9 @@ namespace Slang
result.add(lastStr);
return result;
}
-}
+
+} // namespace Misc
+} // namespace Slang
#endif
diff --git a/source/slang/slang-compiler.cpp b/source/slang/slang-compiler.cpp
index 31ead4cc3..9a2a69248 100755
--- a/source/slang/slang-compiler.cpp
+++ b/source/slang/slang-compiler.cpp
@@ -967,13 +967,14 @@ namespace Slang
/* Let's set the compiler specific options
We can only do this if the endToEndReq is set. */
- if (endToEndReq)
{
+ auto linkage = targetReq->getLinkage();
+
auto name = TypeTextUtil::getPassThroughName((SlangPassThrough)downstreamCompiler);
- const Index nameIndex = endToEndReq->m_downstreamArgs.findName(name);
+ const Index nameIndex = linkage->m_downstreamArgs.findName(name);
if (nameIndex >= 0)
{
- auto& args = endToEndReq->m_downstreamArgs.getArgsAt(nameIndex);
+ auto& args = linkage->m_downstreamArgs.getArgsAt(nameIndex);
for (const auto& arg : args.m_args)
{
options.compilerSpecificArguments.add(arg.value);
diff --git a/source/slang/slang-compiler.h b/source/slang/slang-compiler.h
index 603ee0bb5..e3d8e506c 100755
--- a/source/slang/slang-compiler.h
+++ b/source/slang/slang-compiler.h
@@ -1349,6 +1349,9 @@ namespace Slang
// Determine whether to output heterogeneity-related code
bool m_heterogeneous = false;
+ /// Holds any args that are destined for downstream compilers/tools etc
+ DownstreamArgs m_downstreamArgs;
+
// Name pool for looking up names
NamePool namePool;
@@ -2036,9 +2039,6 @@ namespace Slang
};
Dictionary<TargetRequest*, RefPtr<TargetInfo>> m_targetInfos;
- /// Holds any args that are destined for downstream compilers/tools etc
- DownstreamArgs m_downstreamArgs;
-
/// Writes the modules in a container to the stream
SlangResult writeContainerToStream(Stream* stream);
diff --git a/source/slang/slang-options.cpp b/source/slang/slang-options.cpp
index f4cd2e4ef..00372ca3c 100644
--- a/source/slang/slang-options.cpp
+++ b/source/slang/slang-options.cpp
@@ -410,7 +410,7 @@ struct OptionsParser
DiagnosticSink* requestSink = requestImpl->getSink();
- CommandLineContext* cmdLineContext = requestImpl->m_downstreamArgs.getContext();
+ CommandLineContext* cmdLineContext = requestImpl->getLinkage()->m_downstreamArgs.getContext();
// Why create a new DiagnosticSink?
// We *don't* want the lexer that comes as default (it's for Slang source!)
@@ -437,9 +437,6 @@ struct OptionsParser
parseSink.setFlag(DiagnosticSink::Flag::SourceLocationLine);
}
- // We don't know how big the terminal is.. let's guess 120 for now
- parseSink.setSourceLineMaxLength(120);
-
// All diagnostics will also be sent to requestSink
parseSink.setParentSink(requestSink);
@@ -451,8 +448,11 @@ struct OptionsParser
// Doing so will allocate some SourceLoc space from the CommandLineContext.
args.setArgs(argv, argc);
- // Before we do anything else lets strip out all of the downstream arguments.
- SLANG_RETURN_ON_FAIL(requestImpl->m_downstreamArgs.stripDownstreamArgs(args, 0, sink));
+ {
+ auto linkage = requestImpl->getLinkage();
+ // Before we do anything else lets strip out all of the downstream arguments.
+ SLANG_RETURN_ON_FAIL(linkage->m_downstreamArgs.stripDownstreamArgs(args, 0, sink));
+ }
CommandLineReader reader(&args, sink);
diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp
index 9a109f9d7..613992354 100644
--- a/source/slang/slang.cpp
+++ b/source/slang/slang.cpp
@@ -731,6 +731,24 @@ Linkage::Linkage(Session* session, ASTBuilder* astBuilder, Linkage* builtinLinka
mapNameToLoadedModules.Add(pair.Key, pair.Value);
}
}
+
+ {
+ RefPtr<CommandLineContext> context = new CommandLineContext;
+ m_downstreamArgs = DownstreamArgs(context);
+
+ // Add all of the possible names we allow for downstream tools
+ {
+ for (Index i = SLANG_PASS_THROUGH_NONE + 1; i < SLANG_PASS_THROUGH_COUNT_OF; ++i)
+ {
+ m_downstreamArgs.addName(TypeTextUtil::getPassThroughName(SlangPassThrough(i)));
+ }
+
+ // Generic downstream tool
+ m_downstreamArgs.addName("downstream");
+ // Generic downstream linker
+ m_downstreamArgs.addName("linker");
+ }
+ }
}
ISlangUnknown* Linkage::getInterface(const Guid& guid)
@@ -2047,22 +2065,6 @@ void EndToEndCompileRequest::init()
m_frontEndReq = new FrontEndCompileRequest(getLinkage(), m_writers, getSink());
m_backEndReq = new BackEndCompileRequest(getLinkage(), getSink());
-
- RefPtr<CommandLineContext> context = new CommandLineContext;
- m_downstreamArgs = DownstreamArgs(context);
-
- // Add all of the possible names we allow for downstream tools
- {
- for (Index i = SLANG_PASS_THROUGH_NONE + 1; i < SLANG_PASS_THROUGH_COUNT_OF; ++i)
- {
- m_downstreamArgs.addName(TypeTextUtil::getPassThroughName(SlangPassThrough(i)));
- }
-
- // Generic downstream tool
- m_downstreamArgs.addName("downstream");
- // Generic downstream linker
- m_downstreamArgs.addName("linker");
- }
}
SlangResult EndToEndCompileRequest::executeActionsInner()
diff --git a/tests/diagnostics/command-line/x-arg-tool-unknown.slang b/tests/diagnostics/command-line/x-arg-tool-unknown.slang
new file mode 100644
index 000000000..cfcb09a12
--- /dev/null
+++ b/tests/diagnostics/command-line/x-arg-tool-unknown.slang
@@ -0,0 +1,3 @@
+// x-arg-tool-unknown.slang
+
+//DIAGNOSTIC_TEST:SIMPLE:-entry main -stage compute -o myKernel.dxbc -o myKernel.dxbc -Xthingy
diff --git a/tests/diagnostics/command-line/x-arg-tool-unknown.slang.expected b/tests/diagnostics/command-line/x-arg-tool-unknown.slang.expected
new file mode 100644
index 000000000..73328c480
--- /dev/null
+++ b/tests/diagnostics/command-line/x-arg-tool-unknown.slang.expected
@@ -0,0 +1,8 @@
+result code = 1
+standard error = {
+(1): error 100000: downstream tool name not known, allowed names are [ fxc, dxc, glslang, clang, visualstudio, gcc, genericcpp, nvrtc, downstream, linker ]
+tests/diagnostics/command-line/x-arg-tool-unknown.slang -entry main -stage compute -o myKernel.dxbc -o myKernel.dxbc -Xthingy
+ ^
+}
+standard output = {
+}
diff --git a/tests/downstream/dxc-x-arg.slang b/tests/downstream/dxc-x-arg.slang
new file mode 100644
index 000000000..93b24a7ad
--- /dev/null
+++ b/tests/downstream/dxc-x-arg.slang
@@ -0,0 +1,18 @@
+//DISABLE_TEST(compute):COMPARE_COMPUTE_EX:-cuda -compute -shaderobj
+//DISABLE_TEST(compute):COMPARE_COMPUTE_EX:-cpu -compute -compile-arg -O3 -shaderobj
+//DISABLE_TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -shaderobj
+//DISABLE_TEST(compute, vulkan):COMPARE_COMPUTE_EX:-vk -compute -shaderobj
+
+// We are going to pass -Gis to DXC.
+// Test can only work on DXC.
+//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -dx12 -use-dxil -Xslang... -Xdxc -Gis -X. -shaderobj
+
+//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):out,name outputBuffer
+
+RWStructuredBuffer<int> outputBuffer;
+
+[numthreads(4, 1, 1)]
+void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID)
+{
+ outputBuffer[dispatchThreadID.x] = dispatchThreadID.x;
+} \ No newline at end of file
diff --git a/tests/downstream/dxc-x-arg.slang.expected.txt b/tests/downstream/dxc-x-arg.slang.expected.txt
new file mode 100644
index 000000000..bc856dafa
--- /dev/null
+++ b/tests/downstream/dxc-x-arg.slang.expected.txt
@@ -0,0 +1,4 @@
+0
+1
+2
+3
diff --git a/tools/render-test/diagnostic-defs.h b/tools/render-test/diagnostic-defs.h
new file mode 100644
index 000000000..e48012550
--- /dev/null
+++ b/tools/render-test/diagnostic-defs.h
@@ -0,0 +1,33 @@
+//
+
+// The file is meant to be included multiple times, to produce different
+// pieces of declaration/definition code related to diagnostic messages
+//
+// Each diagnostic is declared here with:
+//
+// DIAGNOSTIC(id, severity, name, messageFormat)
+//
+// Where `id` is the unique diagnostic ID, `severity` is the default
+// severity (from the `Severity` enum), `name` is a name used to refer
+// to this diagnostic from code, and `messageFormat` is the default
+// (non-localized) message for the diagnostic, with placeholders
+// for any arguments.
+
+#ifndef DIAGNOSTIC
+#error Need to #define DIAGNOSTIC(...) before including
+#define DIAGNOSTIC(id, severity, name, messageFormat) /* */
+#endif
+
+//
+// -1 - Notes that decorate another diagnostic.
+//
+
+
+DIAGNOSTIC(1001, Error, expectingCommaComputeDispatch, "expected 3 comma separated integers for compute dispatch size")
+DIAGNOSTIC(1002, Error, expectingPositiveComputeDispatch, "expected 3 comma positive integers for compute dispatch size")
+DIAGNOSTIC(1003, Error, unknownSourceLanguage, "unknown source language name")
+DIAGNOSTIC(1003, Error, unknown, "unknown source language name")
+DIAGNOSTIC(1004, Error, unknownCommandLineOption, "unknown command-line option '$0'")
+DIAGNOSTIC(1005, Error, unexpectedPositionalArg, "unexpected positional arg")
+
+#undef DIAGNOSTIC
diff --git a/tools/render-test/diagnostics.cpp b/tools/render-test/diagnostics.cpp
new file mode 100644
index 000000000..2bc337256
--- /dev/null
+++ b/tools/render-test/diagnostics.cpp
@@ -0,0 +1,21 @@
+// diagnostics.cpp
+#include "diagnostics.h"
+
+namespace Slang {
+
+namespace RenderTestDiagnostics
+{
+#define DIAGNOSTIC(id, severity, name, messageFormat) const DiagnosticInfo name = { id, Severity::severity, #name, messageFormat };
+#include "diagnostic-defs.h"
+#undef DIAGNOSTIC
+}
+
+static const DiagnosticInfo* const kDiagnostics[] =
+{
+#define DIAGNOSTIC(id, severity, name, messageFormat) &RenderTestDiagnostics::name,
+#include "diagnostic-defs.h"
+#undef DIAGNOSTIC
+};
+
+
+} // namespace Slang
diff --git a/tools/render-test/diagnostics.h b/tools/render-test/diagnostics.h
new file mode 100644
index 000000000..08ba28e27
--- /dev/null
+++ b/tools/render-test/diagnostics.h
@@ -0,0 +1,25 @@
+#ifndef SLANG_CORE_DIAGNOSTICS_H
+#define SLANG_CORE_DIAGNOSTICS_H
+
+#include "../../source/core/slang-basic.h"
+#include "../../source/core/slang-writer.h"
+
+#include "../../source/compiler-core/slang-source-loc.h"
+#include "../../source/compiler-core/slang-diagnostic-sink.h"
+
+#include "../../slang.h"
+
+namespace Slang
+{
+
+DiagnosticsLookup* getCoreDiagnosticsLookup();
+
+namespace RenderTestDiagnostics
+{
+#define DIAGNOSTIC(id, severity, name, messageFormat) extern const DiagnosticInfo name;
+#include "diagnostic-defs.h"
+}
+
+}
+
+#endif
diff --git a/tools/render-test/options.cpp b/tools/render-test/options.cpp
index dcf0b77b1..5d3560351 100644
--- a/tools/render-test/options.cpp
+++ b/tools/render-test/options.cpp
@@ -15,6 +15,10 @@
#include "../../source/core/slang-type-text-util.h"
+#include "../../source/compiler-core/slang-command-line-args.h"
+
+#include "diagnostics.h"
+
namespace renderer_test {
using namespace Slang;
@@ -34,173 +38,135 @@ static gfx::DeviceType _toRenderType(Slang::RenderApiType apiType)
}
}
-static SlangResult _setRendererType(DeviceType type, const char* arg, Slang::WriterHelper stdError, Options& ioOptions)
-{
- if (ioOptions.deviceType != DeviceType::Unknown)
- {
- stdError.print("Already has renderer option set. Found '%s'\n", arg);
- return SLANG_FAIL;
- }
- ioOptions.deviceType = type;
- return SLANG_OK;
-}
-
/* static */SlangResult Options::parse(int argc, const char*const* argv, Slang::WriterHelper stdError, Options& outOptions)
{
using namespace Slang;
+ RefPtr<CommandLineContext> cmdLineContext(new CommandLineContext);
+
+ DiagnosticSink sink(cmdLineContext->getSourceManager(), nullptr);
+ sink.writer = stdError.getWriter();
+ sink.setFlag(DiagnosticSink::Flag::SourceLocationLine);
+
outOptions = Options();
- List<const char*> positionalArgs;
+ CommandLineArgs args(cmdLineContext);
- typedef Options::ShaderProgramType ShaderProgramType;
- typedef Options::InputLanguageID InputLanguageID;
+ if (argc > 0)
+ {
+ // first argument is the application name
+ outOptions.appName = argv[0];
+ args.setArgs(argv + 1, argc - 1);
+ }
+ else
+ {
+ args.setArgs(argv, argc);
+ }
- //int argCount = argc;
+ SLANG_RETURN_ON_FAIL(outOptions.downstreamArgs.stripDownstreamArgs(args, 0, &sink));
- char const* const* argCursor = argv;
- char const* const* argEnd = argCursor + argc;
+ CommandLineReader reader(&args, &sink);
- // first argument is the application name
- if( argCursor != argEnd )
- {
- outOptions.appName = *argCursor++;
- }
+ List<CommandLineArg> positionalArgs;
+
+ typedef Options::ShaderProgramType ShaderProgramType;
+ typedef Options::InputLanguageID InputLanguageID;
// now iterate over arguments to collect options
- while(argCursor != argEnd)
+ while (reader.hasArg())
{
- char const* arg = *argCursor++;
- if( arg[0] != '-' )
+ CommandLineArg arg = reader.getArgAndAdvance();
+ const auto& argValue = arg.value;
+
+ if(!argValue.startsWith("-"))
{
positionalArgs.add(arg);
continue;
}
- if( strcmp(arg, "--") == 0 )
+ if (argValue == "--")
{
- while(argCursor != argEnd)
+ while (reader.hasArg())
{
- positionalArgs.add(*argCursor++);
+ positionalArgs.add(reader.getArgAndAdvance());
}
break;
}
- else if( strcmp(arg, "-o") == 0 )
+ else if(argValue == "-o")
{
- if( argCursor == argEnd )
- {
- stdError.print("expected argument for '%s' option\n", arg);
- return SLANG_FAIL;
- }
- outOptions.outputPath = *argCursor++;
+ SLANG_RETURN_ON_FAIL(reader.expectArg(outOptions.outputPath));
}
- else if (strcmp(arg, "-profile") == 0)
+ else if (argValue == "-profile")
{
- if (argCursor == argEnd)
- {
- stdError.print("expected argument for '%s' option\n", arg);
- return SLANG_FAIL;
- }
- outOptions.profileName = *argCursor++;
+ SLANG_RETURN_ON_FAIL(reader.expectArg(outOptions.profileName));
}
- else if (strcmp(arg, "-render-features") == 0 || strcmp(arg, "-render-feature") == 0)
+ else if (argValue == "-render-features" || argValue == "-render-feature")
{
- if (argCursor == argEnd)
- {
- stdError.print("expected argument for '%s' option\n", arg);
- return SLANG_FAIL;
- }
- const char* value = *argCursor++;
+ String features;
+ SLANG_RETURN_ON_FAIL(reader.expectArg(features));
List<UnownedStringSlice> values;
- StringUtil::split(UnownedStringSlice(value), ',', values);
+ StringUtil::split(features.getUnownedSlice(), ',', values);
for (const auto& value : values)
{
outOptions.renderFeatures.add(value);
}
}
- else if( strcmp(arg, "-xslang") == 0 )
+ else if( argValue == "-xslang" || argValue == "-compile-arg")
{
+ // This is legacy support, should use -Xslang now
// This is an option that we want to pass along to Slang
-
- if( argCursor == argEnd )
- {
- stdError.print("expected argument for '%s' option\n", arg);
- return SLANG_FAIL;
- }
- if( outOptions.slangArgCount == Options::kMaxSlangArgs )
- {
- stdError.print("maximum number of '%s' options exceeded (%d)\n", arg, Options::kMaxSlangArgs);
- return SLANG_FAIL;
- }
- outOptions.slangArgs[outOptions.slangArgCount++] = *argCursor++;
+ CommandLineArg slangArg;
+ SLANG_RETURN_ON_FAIL(reader.expectArg(slangArg));
+ outOptions.downstreamArgs.getArgsByName("slang").add(slangArg);
}
- else if (strcmp(arg, "-compute") == 0)
+ else if (argValue == "-compute")
{
outOptions.shaderType = ShaderProgramType::Compute;
}
- else if (strcmp(arg, "-graphics") == 0)
+ else if (argValue == "-graphics")
{
outOptions.shaderType = ShaderProgramType::Graphics;
}
- else if (strcmp(arg, "-gcompute") == 0)
+ else if (argValue == "-gcompute")
{
outOptions.shaderType = ShaderProgramType::GraphicsCompute;
}
- else if (strcmp(arg, "-rt") == 0)
+ else if (argValue == "-rt")
{
outOptions.shaderType = ShaderProgramType::RayTracing;
}
- else if( strcmp(arg, "-use-dxil") == 0 )
+ else if(argValue == "-use-dxil")
{
outOptions.useDXIL = true;
}
- else if (strcmp(arg, "-only-startup") == 0)
+ else if (argValue == "-only-startup")
{
outOptions.onlyStartup = true;
}
- else if (strcmp(arg, "-compile-arg") == 0)
- {
- if (argCursor == argEnd)
- {
- stdError.print("expected argument for '%s' option\n", arg);
- return SLANG_FAIL;
- }
-
- const char* compileArg = *argCursor++;
- outOptions.compileArgs.add(compileArg);
- }
- else if (strcmp(arg, "-performance-profile") == 0)
+ else if (argValue == "-performance-profile")
{
outOptions.performanceProfile = true;
}
- else if (strcmp(arg, "-adapter") == 0)
+ else if (argValue == "-adapter")
{
- if (argCursor == argEnd)
- {
- stdError.print("expected argument for '%s' option\n", arg);
- return SLANG_FAIL;
- }
-
- outOptions.adapter = *argCursor++;
+ SLANG_RETURN_ON_FAIL(reader.expectArg(outOptions.adapter));
}
- else if (strcmp(arg, "-output-using-type") == 0)
+ else if (argValue == "-output-using-type")
{
outOptions.outputUsingType = true;
}
- else if (strcmp(arg, "-compute-dispatch") == 0)
+ else if (argValue == "-compute-dispatch")
{
- if (argCursor == argEnd)
- {
- stdError.print("error: expecting a comma separated compute dispatch size for '%s'\n", arg);
- return SLANG_FAIL;
- }
+ CommandLineArg dispatchSize;
+ SLANG_RETURN_ON_FAIL(reader.expectArg(dispatchSize));
+
List<UnownedStringSlice> slices;
- StringUtil::split(UnownedStringSlice(*argCursor++), ',', slices);
+ StringUtil::split(dispatchSize.value.getUnownedSlice(), ',', slices);
if (slices.getCount() != 3)
{
- stdError.print("error: expected 3 comma separated integers for compute dispatch size for '%s'\n", arg);
+ sink.diagnose(dispatchSize.loc, RenderTestDiagnostics::expectingCommaComputeDispatch);
return SLANG_FAIL;
}
@@ -211,45 +177,35 @@ static SlangResult _setRendererType(DeviceType type, const char* arg, Slang::Wri
int v = StringToInt(string);
if (v < 1)
{
- stdError.print("error: expected 3 comma positive integers for compute dispatch size for '%s'\n", arg);
+ sink.diagnose(dispatchSize.loc, RenderTestDiagnostics::expectingPositiveComputeDispatch);
return SLANG_FAIL;
}
outOptions.computeDispatchSize[i] = v;
}
}
- else if (strcmp(arg, "-source-language") == 0)
+ else if (argValue == "-source-language")
{
- if (argCursor == argEnd)
- {
- stdError.print("error: expecting a source language name for '%s'\n", arg);
- return SLANG_FAIL;
- }
- UnownedStringSlice sourceLanguageText(*argCursor++);
-
- SlangSourceLanguage sourceLanguage = TypeTextUtil::findSourceLanguage(sourceLanguageText);
+ CommandLineArg sourceLanguageName;
+ SLANG_RETURN_ON_FAIL(reader.expectArg(sourceLanguageName));
+
+ const SlangSourceLanguage sourceLanguage = TypeTextUtil::findSourceLanguage(sourceLanguageName.value.getUnownedSlice());
if (sourceLanguage == SLANG_SOURCE_LANGUAGE_UNKNOWN)
{
- stdError.print("error: expecting unknown source language name '%s' for '%s'\n", String(sourceLanguageText).getBuffer(), arg);
+ sink.diagnose(sourceLanguageName.loc, RenderTestDiagnostics::unknownSourceLanguage);
return SLANG_FAIL;
}
outOptions.sourceLanguage = sourceLanguage;
}
- else if( strcmp(arg, "-no-default-entry-point") == 0 )
+ else if(argValue == "-no-default-entry-point")
{
outOptions.dontAddDefaultEntryPoints = true;
}
- else if (strcmp(arg, "-nvapi-slot") == 0)
+ else if (argValue == "-nvapi-slot")
{
- if (argCursor == argEnd)
- {
- stdError.print("error: expecting a register name for '%s'\n", arg);
- return SLANG_FAIL;
- }
-
- outOptions.nvapiExtnSlot = (*argCursor++);
+ SLANG_RETURN_ON_FAIL(reader.expectArg(outOptions.nvapiExtnSlot));
}
- else if (strcmp(arg, "-shaderobj") == 0)
+ else if (argValue == "-shaderobj")
{
// Note: We ignore this option because it is always enabled now.
//
@@ -258,11 +214,11 @@ static SlangResult _setRendererType(DeviceType type, const char* arg, Slang::Wri
else
{
// Lookup
- Slang::UnownedStringSlice argSlice(arg);
+ Slang::UnownedStringSlice argSlice = arg.value.getUnownedSlice();
if (argSlice.getLength() && argSlice[0] == '-')
{
// Look up the rendering API if set
- UnownedStringSlice argName = UnownedStringSlice(argSlice.begin() + 1, argSlice.end());
+ UnownedStringSlice argName = argSlice.tail(1);
DeviceType deviceType = _toRenderType(RenderApiUtil::findApiTypeByName(argName));
if (deviceType != DeviceType::Unknown)
@@ -272,17 +228,16 @@ static SlangResult _setRendererType(DeviceType type, const char* arg, Slang::Wri
}
// Lookup the target language type
- DeviceType languageRenderType =
- _toRenderType(RenderApiUtil::findImplicitLanguageRenderApiType(argName));
- if (languageRenderType != DeviceType::Unknown)
+ DeviceType targetLanguageDeviceType = _toRenderType(RenderApiUtil::findImplicitLanguageRenderApiType(argName));
+
+ if (targetLanguageDeviceType != DeviceType::Unknown)
{
- outOptions.targetLanguageDeviceType = languageRenderType;
+ outOptions.targetLanguageDeviceType = targetLanguageDeviceType;
outOptions.inputLanguageID = (argName == "hlsl" || argName == "glsl" || argName == "cpp" || argName == "cxx" || argName == "c") ? InputLanguageID::Native : InputLanguageID::Slang;
continue;
}
}
-
- stdError.print("unknown option '%s'\n", arg);
+ sink.diagnose(arg.loc, RenderTestDiagnostics::unknownCommandLineOption, arg.value);
return SLANG_FAIL;
}
}
@@ -295,14 +250,14 @@ static SlangResult _setRendererType(DeviceType type, const char* arg, Slang::Wri
// first positional argument is source shader path
if(positionalArgs.getCount())
{
- outOptions.sourcePath = positionalArgs[0];
+ outOptions.sourcePath = positionalArgs[0].value;
positionalArgs.removeAt(0);
}
// any remaining arguments represent an error
if(positionalArgs.getCount() != 0)
{
- stdError.print("unexpected arguments\n");
+ sink.diagnose(positionalArgs[0].loc, RenderTestDiagnostics::unexpectedPositionalArg);
return SLANG_FAIL;
}
diff --git a/tools/render-test/options.h b/tools/render-test/options.h
index 2945113fe..7940d0d42 100644
--- a/tools/render-test/options.h
+++ b/tools/render-test/options.h
@@ -12,6 +12,8 @@
#include "../../source/core/slang-process-util.h"
+#include "../../source/compiler-core/slang-command-line-args.h"
+
#include "../../slang-gfx.h"
namespace renderer_test {
@@ -20,12 +22,6 @@ using namespace gfx;
struct Options
{
- enum
- {
- // maximum number of command-line arguments to pass along to slang
- kMaxSlangArgs = 16,
- };
-
enum class InputLanguageID
{
// Slang being used as an HLSL-ish compiler
@@ -35,7 +31,6 @@ struct Options
Native,
};
-
enum class ShaderProgramType
{
Graphics,
@@ -44,9 +39,9 @@ struct Options
RayTracing,
};
- char const* appName = "render-test";
- char const* sourcePath = nullptr;
- char const* outputPath = nullptr;
+ Slang::String appName = "render-test";
+ Slang::String sourcePath;
+ Slang::String outputPath;
ShaderProgramType shaderType = ShaderProgramType::Graphics;
/// The renderer type inferred from the target language type. Used if a rendererType is not explicitly set.
@@ -57,10 +52,7 @@ struct Options
SlangSourceLanguage sourceLanguage = SLANG_SOURCE_LANGUAGE_UNKNOWN;
/// Can be used for overriding the profile
- const char* profileName = nullptr;
-
- char const* slangArgs[kMaxSlangArgs];
- int slangArgCount = 0;
+ Slang::String profileName;
bool outputUsingType = false;
@@ -73,14 +65,16 @@ struct Options
Slang::List<Slang::String> renderFeatures; /// Required render features for this test to run
- Slang::List<Slang::String> compileArgs;
-
Slang::String adapter; ///< The adapter to use either name or index
uint32_t computeDispatchSize[3] = { 1, 1, 1 };
Slang::String nvapiExtnSlot; ///< The nvapiRegister to use.
+ Slang::DownstreamArgs downstreamArgs; ///< Args to downstream tools. Here it's just slang
+
+ Options() { downstreamArgs.addName("slang"); }
+
static SlangResult parse(int argc, const char*const* argv, Slang::WriterHelper stdError, Options& outOptions);
};
diff --git a/tools/render-test/render-test-main.cpp b/tools/render-test/render-test-main.cpp
index 5feeeaf21..c04d6db00 100644
--- a/tools/render-test/render-test-main.cpp
+++ b/tools/render-test/render-test-main.cpp
@@ -99,9 +99,9 @@ public:
Result applyBinding(PipelineType pipelineType, ICommandEncoder* encoder);
void setProjectionMatrix(IShaderObject* rootObject);
- Result writeBindingOutput(const char* fileName);
+ Result writeBindingOutput(const String& fileName);
- Result writeScreen(const char* filename);
+ Result writeScreen(const String& filename);
protected:
/// Called in initialize
@@ -652,12 +652,12 @@ void RenderTestApp::finalize()
{
}
-Result RenderTestApp::writeBindingOutput(const char* fileName)
+Result RenderTestApp::writeBindingOutput(const String& fileName)
{
// Wait until everything is complete
m_queue->wait();
- FILE * f = fopen(fileName, "wb");
+ FILE * f = fopen(fileName.getBuffer(), "wb");
if (!f)
{
return SLANG_FAIL;
@@ -729,7 +729,7 @@ Result RenderTestApp::writeBindingOutput(const char* fileName)
return SLANG_OK;
}
-Result RenderTestApp::writeScreen(const char* filename)
+Result RenderTestApp::writeScreen(const String& filename)
{
size_t rowPitch, pixelSize;
ComPtr<ISlangBlob> blob;
@@ -738,7 +738,7 @@ Result RenderTestApp::writeScreen(const char* filename)
auto bufferSize = blob->getBufferSize();
uint32_t width = static_cast<uint32_t>(rowPitch / pixelSize);
uint32_t height = static_cast<uint32_t>(bufferSize / rowPitch);
- return PngSerializeUtil::write(filename, blob, width, height);
+ return PngSerializeUtil::write(filename.getBuffer(), blob, width, height);
}
Result RenderTestApp::update()
@@ -768,7 +768,7 @@ Result RenderTestApp::update()
m_queue->wait();
// If we are in a mode where output is requested, we need to snapshot the back buffer here
- if (m_options.outputPath || m_options.performanceProfile)
+ if (m_options.outputPath.getLength() || m_options.performanceProfile)
{
// Wait until everything is complete
@@ -807,7 +807,7 @@ Result RenderTestApp::update()
_outputProfileTime(m_startTicks, endTicks);
}
- if (m_options.outputPath)
+ if (m_options.outputPath.getLength())
{
if (m_options.shaderType == Options::ShaderProgramType::Compute || m_options.shaderType == Options::ShaderProgramType::GraphicsCompute)
{
@@ -909,8 +909,6 @@ static SlangResult _innerMain(Slang::StdWriters* stdWriters, SlangSession* sessi
input.profile = "";
input.target = SLANG_TARGET_NONE;
- input.args = &options.slangArgs[0];
- input.argCount = options.slangArgCount;
SlangSourceLanguage nativeLanguage = SLANG_SOURCE_LANGUAGE_UNKNOWN;
SlangPassThrough slangPassThrough = SLANG_PASS_THROUGH_NONE;
@@ -1020,7 +1018,7 @@ static SlangResult _innerMain(Slang::StdWriters* stdWriters, SlangSession* sessi
#endif
// Use the profile name set on options if set
- input.profile = options.profileName ? options.profileName : input.profile;
+ input.profile = options.profileName.getLength() ? options.profileName : input.profile;
StringBuilder rendererName;
auto info =
@@ -1085,11 +1083,17 @@ static SlangResult _innerMain(Slang::StdWriters* stdWriters, SlangSession* sessi
desc.requiredFeatures = requiredFeatureList.getBuffer();
desc.requiredFeatureCount = (int)requiredFeatureList.getCount();
- for (int i = 0; i < options.slangArgCount; i++)
+
+ // Look for args going to slang
{
- if (UnownedStringSlice(options.slangArgs[i]) == "-matrix-layout-column-major")
+ const auto& args = options.downstreamArgs.getArgsByName("slang");
+ for (const auto& arg : args)
{
- desc.slang.defaultMatrixLayoutMode = SLANG_MATRIX_LAYOUT_COLUMN_MAJOR;
+ if (arg.value == "-matrix-layout-column-major")
+ {
+ desc.slang.defaultMatrixLayoutMode = SLANG_MATRIX_LAYOUT_COLUMN_MAJOR;
+ break;
+ }
}
}
diff --git a/tools/render-test/shader-input-layout.cpp b/tools/render-test/shader-input-layout.cpp
index bece936dd..9362efb45 100644
--- a/tools/render-test/shader-input-layout.cpp
+++ b/tools/render-test/shader-input-layout.cpp
@@ -82,7 +82,7 @@ namespace renderer_test
RefPtr<ShaderInputLayout::ParentVal> parentVal;
List<RefPtr<ShaderInputLayout::ParentVal>> parentValStack;
- SlangResult parseOption(TokenReader& parser, String const& word, ShaderInputLayout::TextureVal* val)
+ SlangResult parseOption(Misc::TokenReader& parser, String const& word, ShaderInputLayout::TextureVal* val)
{
if (word == "depth")
{
@@ -133,7 +133,7 @@ namespace renderer_test
return SLANG_OK;
}
- SlangResult parseOption(TokenReader& parser, String const& word, ShaderInputLayout::SamplerVal* val)
+ SlangResult parseOption(Misc::TokenReader& parser, String const& word, ShaderInputLayout::SamplerVal* val)
{
if (word == "depthCompare")
{
@@ -146,7 +146,7 @@ namespace renderer_test
return SLANG_OK;
}
- SlangResult parseOption(TokenReader& parser, String const& word, ShaderInputLayout::DataValBase* val)
+ SlangResult parseOption(Misc::TokenReader& parser, String const& word, ShaderInputLayout::DataValBase* val)
{
if (word == "data")
{
@@ -157,13 +157,13 @@ namespace renderer_test
while (!parser.IsEnd() && !parser.LookAhead("]"))
{
bool negate = false;
- if(parser.NextToken().Type == TokenType::OpSub)
+ if(parser.NextToken().Type == Misc::TokenType::OpSub)
{
parser.ReadToken();
negate = true;
}
- if (parser.NextToken().Type == TokenType::IntLiteral)
+ if (parser.NextToken().Type == Misc::TokenType::IntLiteral)
{
uint32_t value = parser.ReadUInt();
if(negate) value = uint32_t(-int32_t(value));
@@ -186,7 +186,7 @@ namespace renderer_test
return SLANG_OK;
}
- SlangResult parseOption(TokenReader& parser, String const& word, ShaderInputLayout::BufferVal* val)
+ SlangResult parseOption(Misc::TokenReader& parser, String const& word, ShaderInputLayout::BufferVal* val)
{
if (word == "stride")
{
@@ -332,7 +332,7 @@ namespace renderer_test
return SLANG_OK;
}
- SlangResult parseOption(TokenReader& parser, String const& word, ShaderInputLayout::ObjectVal* val)
+ SlangResult parseOption(Misc::TokenReader& parser, String const& word, ShaderInputLayout::ObjectVal* val)
{
if( word == "type" )
{
@@ -346,7 +346,7 @@ namespace renderer_test
return SLANG_OK;
}
- Format parseFormatOption(TokenReader& parser)
+ Format parseFormatOption(Misc::TokenReader& parser)
{
parser.Read("=");
auto formatWord = parser.ReadWord();
@@ -355,7 +355,7 @@ namespace renderer_test
}
template<typename T>
- void maybeParseOptions(TokenReader& parser, T* val)
+ void maybeParseOptions(Misc::TokenReader& parser, T* val)
{
// parse options
if (parser.LookAhead("("))
@@ -378,11 +378,11 @@ namespace renderer_test
}
}
- RefPtr<ShaderInputLayout::Val> parseNumericValExpr(TokenReader& parser, bool negate = false)
+ RefPtr<ShaderInputLayout::Val> parseNumericValExpr(Misc::TokenReader& parser, bool negate = false)
{
switch(parser.NextToken().Type)
{
- case TokenType::IntLiteral:
+ case Misc::TokenType::IntLiteral:
{
RefPtr<ShaderInputLayout::DataVal> val = new ShaderInputLayout::DataVal;
@@ -394,7 +394,7 @@ namespace renderer_test
}
break;
- case TokenType::DoubleLiteral:
+ case Misc::TokenType::DoubleLiteral:
{
RefPtr<ShaderInputLayout::DataVal> val = new ShaderInputLayout::DataVal;
@@ -414,7 +414,7 @@ namespace renderer_test
}
}
- String parseTypeName(TokenReader& parser)
+ String parseTypeName(Misc::TokenReader& parser)
{
String typeName = parser.ReadWord();
if (parser.AdvanceIf("<"))
@@ -429,8 +429,10 @@ namespace renderer_test
return typeName;
}
- RefPtr<ShaderInputLayout::Val> parseValExpr(TokenReader& parser)
+ RefPtr<ShaderInputLayout::Val> parseValExpr(Misc::TokenReader& parser)
{
+ typedef Misc::TokenType TokenType;
+
switch(parser.NextToken().Type)
{
case TokenType::OpSub:
@@ -531,7 +533,7 @@ namespace renderer_test
}
}
- RefPtr<ShaderInputLayout::Val> parseVal(TokenReader& parser)
+ RefPtr<ShaderInputLayout::Val> parseVal(Misc::TokenReader& parser)
{
auto word = parser.NextToken().Content;
if (parser.AdvanceIf("begin_array"))
@@ -657,8 +659,11 @@ namespace renderer_test
parser.ReadToken();
}
- String parseName(TokenReader& parser)
+ String parseName(Misc::TokenReader& parser)
{
+ typedef Misc::Token Token;
+ typedef Misc::TokenType TokenType;
+
StringBuilder builder;
Token nameToken = parser.ReadToken();
@@ -695,7 +700,7 @@ namespace renderer_test
}
}
- void parseFieldBindings(TokenReader& parser, ShaderInputLayout::Field& ioField)
+ void parseFieldBindings(Misc::TokenReader& parser, ShaderInputLayout::Field& ioField)
{
// parse bindings
if (parser.LookAhead(":"))
@@ -710,7 +715,7 @@ namespace renderer_test
else if (parser.AdvanceIf("name"))
{
// Optionally consume '='
- if (parser.NextToken().Type == TokenType::OpAssign)
+ if (parser.NextToken().Type == Misc::TokenType::OpAssign)
{
parser.ReadToken();
}
@@ -735,7 +740,7 @@ namespace renderer_test
parentVal = val;
}
- void parseValEntry(TokenReader& parser)
+ void parseValEntry(Misc::TokenReader& parser)
{
auto parentForNewVal = parentVal;
@@ -746,19 +751,19 @@ namespace renderer_test
parentForNewVal->addField(field);
}
- void parseSetEntry(TokenReader& parser)
+ void parseSetEntry(Misc::TokenReader& parser)
{
auto parentForNewVal = parentVal;
ShaderInputLayout::Field field;
field.name = parseName(parser);
- parser.Read(TokenType::OpAssign);
+ parser.Read(Misc::TokenType::OpAssign);
field.val = parseValExpr(parser);
parentForNewVal->addField(field);
}
- void parseLine(TokenReader& parser)
+ void parseLine(Misc::TokenReader& parser)
{
if (parser.LookAhead("entryPointSpecializationArg")
|| parser.LookAhead("type")
@@ -804,18 +809,18 @@ namespace renderer_test
RefPtr<ShaderInputLayout::AggVal> rootVal = new ShaderInputLayout::AggVal;
parentVal = rootVal;
- auto lines = Split(source, '\n');
+ auto lines = Misc::Split(source, '\n');
for (auto & line : lines)
{
if (line.startsWith("//TEST_INPUT:"))
{
auto lineContent = line.subString(13, line.getLength() - 13);
- TokenReader parser(lineContent);
+ Misc::TokenReader parser(lineContent);
try
{
parseLine(parser);
}
- catch (const TextFormatException&)
+ catch (const Misc::TextFormatException&)
{
StringBuilder msg;
msg << "Invalid input syntax at line " << parser.NextToken().Position.Line;
diff --git a/tools/render-test/slang-support.cpp b/tools/render-test/slang-support.cpp
index 5470ea35a..adfea337c 100644
--- a/tools/render-test/slang-support.cpp
+++ b/tools/render-test/slang-support.cpp
@@ -88,18 +88,21 @@ void ShaderCompilerUtil::Output::reset()
out.session = session;
// Parse all the extra args
- if (request.compileArgs.getCount() > 0)
{
List<const char*> args;
- for (const auto& arg : request.compileArgs)
+ for (const auto& arg : options.downstreamArgs.getArgsByName("slang"))
{
- args.add(arg.getBuffer());
+ args.add(arg.value.getBuffer());
+ }
+
+ if (args.getCount())
+ {
+ SLANG_RETURN_ON_FAIL(spProcessCommandLineArguments(slangRequest, args.getBuffer(), int(args.getCount())));
}
- SLANG_RETURN_ON_FAIL(spProcessCommandLineArguments(slangRequest, args.getBuffer(), int(args.getCount())));
}
spSetCodeGenTarget(slangRequest, input.target);
- spSetTargetProfile(slangRequest, 0, spFindProfile(session, input.profile));
+ spSetTargetProfile(slangRequest, 0, spFindProfile(session, input.profile.getBuffer()));
// Define a macro so that shader code in a test can detect what language we
// are nominally working with.
@@ -140,10 +143,7 @@ void ShaderCompilerUtil::Output::reset()
spSetCompileFlags(slangRequest, SLANG_COMPILE_FLAG_NO_CODEGEN);
}
- // Process any additional command-line options specified for Slang using
- // the `-xslang <arg>` option to `render-test`.
- SLANG_RETURN_ON_FAIL(spProcessCommandLineArguments(slangRequest, input.args, input.argCount));
-
+
const auto sourceLanguage = input.sourceLanguage;
int translationUnitIndex = 0;
@@ -322,7 +322,6 @@ void ShaderCompilerUtil::Output::reset()
/* static */SlangResult ShaderCompilerUtil::compileWithLayout(SlangSession* session, const Options& options, const ShaderCompilerUtil::Input& input, OutputAndLayout& output)
{
String sourcePath = options.sourcePath;
- auto& compileArgs = options.compileArgs;
auto shaderType = options.shaderType;
List<char> sourceText;
@@ -377,8 +376,6 @@ void ShaderCompilerUtil::Output::reset()
ShaderCompileRequest compileRequest;
- compileRequest.compileArgs = compileArgs;
-
compileRequest.source = sourceInfo;
// Now we will add the "default" entry point names/stages that
diff --git a/tools/render-test/slang-support.h b/tools/render-test/slang-support.h
index 59d422bc7..3404aac1d 100644
--- a/tools/render-test/slang-support.h
+++ b/tools/render-test/slang-support.h
@@ -38,8 +38,6 @@ struct ShaderCompileRequest
Slang::List<Slang::String> globalSpecializationArgs;
Slang::List<Slang::String> entryPointSpecializationArgs;
-
- Slang::List<Slang::String> compileArgs;
};
@@ -47,13 +45,11 @@ struct ShaderCompilerUtil
{
struct Input
{
- SlangCompileTarget target;
- SlangSourceLanguage sourceLanguage;
- SlangPassThrough passThrough;
- PipelineType pipelineType = PipelineType::Unknown;
- char const* profile;
- const char** args;
- int argCount;
+ SlangCompileTarget target;
+ SlangSourceLanguage sourceLanguage;
+ SlangPassThrough passThrough;
+ PipelineType pipelineType = PipelineType::Unknown;
+ Slang::String profile;
};
struct Output