[spirv] Add CL option for stage I/O location assignment order (#578)

A new CL option -fvk-stage-io-order={alpha|decl} is added to
control the order for assigning stage I/O location numbers.
The default is also changed to declaration order (decl) instead
of alphabetical order (alpha).

Also extended testing fixtures to support additional CL options.
This commit is contained in:
Lei Zhang 2017-08-17 23:59:45 -04:00 коммит произвёл David Peixotto
Родитель 65d17b4f7c
Коммит 0e0e014232
25 изменённых файлов: 185 добавлений и 59 удалений

Просмотреть файл

@ -232,9 +232,6 @@ HLSL variables and resources
This section lists how various HLSL variables and resources are mapped.
Variable definition
+++++++++++++++++++
Variables are defined in HLSL using the following
`syntax <https://msdn.microsoft.com/en-us/library/windows/desktop/bb509706(v=vs.85).aspx>`_
rules::
@ -331,7 +328,7 @@ to ``Location`` 1.
[TODO] Another explicit way: using command-line options
Please note that the compiler does prohibits mixing the explicit and implicit
Please note that the compiler prohibits mixing the explicit and implicit
approach for the same SigPoint to avoid complexity and fallibility. However,
for a certain shader stage, one SigPoint using the explicit approach while the
other adopting the implicit approach is permitted.
@ -375,8 +372,10 @@ corresponding SPIR-V ``Builtin`` decorations according to the above table.
SV semantic strings not translated into SPIR-V BuiltIn decorations will be
handled similarly as non-SV (arbitrary) semantic strings: a SPIR-V variable
of the ``Input``/``Output`` storage class will be created for each entity with
such semantic string. Then sort all semantic strings alphabetically, and assign
``Location`` numbers sequentially to each SPIR-V variable. Note that this means
such semantic string. Then sort all semantic strings according to declaration
(the default, or if ``-fvk-stage-io-order=decl`` is given) or alphabetical
(if ``-fvk-stage-io-order=alpha`` is given) order, and assign ``Location``
numbers sequentially to the corresponding SPIR-V variables. Note that this means
flattening all structs if structs are used as function parameters or returns.
There is an exception to the above rule for SV_Target[N]. It will always be

Просмотреть файл

@ -112,7 +112,6 @@ public:
bool AllResourcesBound; // OPT_all_resources_bound
bool AstDump; // OPT_ast_dump
bool GenSPIRV; // OPT_spirv // SPIRV change
bool ColorCodeAssembly; // OPT_Cc
bool CodeGenHighLevel; // OPT_fcgl
bool DebugInfo; // OPT__SLASH_Zi
@ -157,6 +156,13 @@ public:
bool DisaseembleHex; //OPT_Lx
bool IsRootSignatureProfile();
bool IsLibraryProfile();
// SPIRV Change Starts
#ifdef ENABLE_SPIRV_CODEGEN
bool GenSPIRV; // OPT_spirv
llvm::StringRef VkStageIoOrder;
#endif
// SPIRV Change Ends
};
/// Use this class to capture, convert and handle the lifetime for the

Просмотреть файл

@ -67,6 +67,8 @@ def hlsloptz_Group : OptionGroup<"HLSL Optimization">, HelpText<"Optimization Op
def hlslutil_Group : OptionGroup<"HLSL Utility">, HelpText<"Utility Options">;
def hlslcore_Group : OptionGroup<"HLSL Core">, HelpText<"Common Options">;
def spirv_Group : OptionGroup<"SPIR-V CodeGen">, HelpText<"SPIR-V CodeGen Options">; // SPIRV Change
//////////////////////////////////////////////////////////////////////////////
// Options
@ -209,8 +211,6 @@ def _help_question : Flag<["-", "/"], "?">, Flags<[DriverOption]>, Alias<help>;
def ast_dump : Flag<["-", "/"], "ast-dump">, Flags<[CoreOption, DriverOption, HelpHidden]>,
HelpText<"Dumps the parsed Abstract Syntax Tree.">; // should not be core, but handy workaround until explicit API written
def spirv : Flag<["-"], "spirv">, Flags<[CoreOption, DriverOption, HelpHidden]>, // SPIRV change: temporary solution to support
HelpText<"Generates SPIR-V binary code">; // SPIRV change: SPIR-V gen in a command line tool
def external_lib : Separate<["-", "/"], "external">, Group<hlslcore_Group>, Flags<[DriverOption, HelpHidden]>,
HelpText<"External DLL name to load for compiler support">;
def external_fn : Separate<["-", "/"], "external-fn">, Group<hlslcore_Group>, Flags<[DriverOption, HelpHidden]>,
@ -233,6 +233,13 @@ def no_min_precision: Flag<["-", "/"], "no-min-precision">, Flags<[CoreOption, D
HelpText<"Do not use min precision but use strict precision types.">;
def ignore_line_directives : Flag<["-", "/"], "ignore-line-directives">, HelpText<"Ignore line directives">, Flags<[CoreOption]>, Group<hlslcomp_Group>;
// SPIRV Change Starts
def spirv : Flag<["-"], "spirv">, Group<spirv_Group>, Flags<[CoreOption, DriverOption, HelpHidden]>,
HelpText<"Generate SPIR-V binary code">;
def fvk_stage_io_order_EQ : Joined<["-"], "fvk-stage-io-order=">, Group<spirv_Group>, Flags<[CoreOption, DriverOption, HelpHidden]>,
HelpText<"Specify Vulkan stage I/O location assignment order">;
// SPIRV Change Ends
//////////////////////////////////////////////////////////////////////////////
// fxc-based flags that don't match those previously defined.

Просмотреть файл

@ -278,7 +278,6 @@ int ReadDxcOpts(const OptTable *optionTable, unsigned flagsToInclude,
opts.UseHexLiterals = Args.hasFlag(OPT_Lx, OPT_INVALID);
opts.Preprocess = Args.getLastArgValue(OPT_P);
opts.AstDump = Args.hasFlag(OPT_ast_dump, OPT_INVALID, false);
opts.GenSPIRV = Args.hasFlag(OPT_spirv, OPT_INVALID, false); // SPIRV change
opts.CodeGenHighLevel = Args.hasFlag(OPT_fcgl, OPT_INVALID, false);
opts.DebugInfo = Args.hasFlag(OPT__SLASH_Zi, OPT_INVALID, false);
opts.DebugNameForBinary = Args.hasFlag(OPT_Zsb, OPT_INVALID, false);
@ -432,6 +431,25 @@ int ReadDxcOpts(const OptTable *optionTable, unsigned flagsToInclude,
return 1;
}
// SPIRV Change Starts
#ifdef ENABLE_SPIRV_CODEGEN
opts.GenSPIRV = Args.hasFlag(OPT_spirv, OPT_INVALID, false);
opts.VkStageIoOrder = Args.getLastArgValue(OPT_fvk_stage_io_order_EQ, "decl");
if (opts.VkStageIoOrder != "alpha" && opts.VkStageIoOrder != "decl") {
errors << "Unknown Vulkan stage I/O location assignment order : "
<< opts.VkStageIoOrder;
return 1;
}
#else
if (Args.hasFlag(OPT_spirv, OPT_INVALID, false) ||
!Args.getLastArgValue(OPT_fvk_stage_io_order_EQ).empty()) {
errors << "SPIR-V CodeGen not available. "
"Please recompile with -DENABLE_SPIRV_CODEGEN=ON.";
return 1;
}
#endif
// SPIRV Change Ends
opts.Args = std::move(Args);
return 0;
}

Просмотреть файл

@ -11,12 +11,20 @@
#include "clang/Frontend/FrontendAction.h"
#include "clang/SPIRV/EmitSPIRVOptions.h"
namespace clang {
class EmitSPIRVAction : public ASTFrontendAction {
public:
EmitSPIRVAction(const EmitSPIRVOptions &opts) : options(opts) {}
protected:
std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
StringRef InFile) override;
private:
EmitSPIRVOptions options;
};
} // end namespace clang

Просмотреть файл

@ -0,0 +1,21 @@
//===-- EmitSPIRVOptions.h - Options for SPIR-V CodeGen ---------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_SPIRV_EMITSPIRVOPTIONS_H
#define LLVM_CLANG_SPIRV_EMITSPIRVOPTIONS_H
#include "llvm/ADT/StringRef.h"
namespace clang {
/// Structs for controlling behaviors of SPIR-V codegen.
struct EmitSPIRVOptions {
llvm::StringRef stageIoOrder;
};
} // end namespace clang
#endif

Просмотреть файл

@ -361,12 +361,13 @@ bool DeclResultIdMapper::finalizeStageIOLocations(bool forInput) {
}
}
// Sort stage input/output variables alphabetically
const auto comp = [](const StageVar *a, const StageVar *b) {
return a->getSemanticStr() < b->getSemanticStr();
};
std::sort(vars.begin(), vars.end(), comp);
if (spirvOptions.stageIoOrder == "alpha") {
// Sort stage input/output variables alphabetically
std::sort(vars.begin(), vars.end(),
[](const StageVar *a, const StageVar *b) {
return a->getSemanticStr() < b->getSemanticStr();
});
}
for (const auto *var : vars)
theBuilder.decorateLocation(var->getSpirvId(), locSet.useNextLoc());

Просмотреть файл

@ -17,6 +17,7 @@
#include "dxc/HLSL/DxilSigPoint.h"
#include "spirv/1.0/spirv.hpp11"
#include "clang/AST/Attr.h"
#include "clang/SPIRV/EmitSPIRVOptions.h"
#include "clang/SPIRV/ModuleBuilder.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/Optional.h"
@ -115,7 +116,8 @@ private:
class DeclResultIdMapper {
public:
inline DeclResultIdMapper(const hlsl::ShaderModel &stage, ASTContext &context,
ModuleBuilder &builder, DiagnosticsEngine &diag);
ModuleBuilder &builder, DiagnosticsEngine &diag,
const EmitSPIRVOptions &spirvOptions);
/// \brief Creates the stage output variables by parsing the semantics
/// attached to the given function's parameter or return value and returns
@ -236,9 +238,11 @@ private:
private:
const hlsl::ShaderModel &shaderModel;
ModuleBuilder &theBuilder;
TypeTranslator typeTranslator;
const EmitSPIRVOptions &spirvOptions;
DiagnosticsEngine &diags;
TypeTranslator typeTranslator;
uint32_t entryFunctionId;
/// Mapping of all Clang AST decls to their <result-id>s.
@ -252,9 +256,10 @@ private:
DeclResultIdMapper::DeclResultIdMapper(const hlsl::ShaderModel &model,
ASTContext &context,
ModuleBuilder &builder,
DiagnosticsEngine &diag)
: shaderModel(model), theBuilder(builder),
typeTranslator(context, builder, diag), diags(diag), entryFunctionId(0) {}
DiagnosticsEngine &diag,
const EmitSPIRVOptions &options)
: shaderModel(model), theBuilder(builder), spirvOptions(options),
diags(diag), typeTranslator(context, builder, diag), entryFunctionId(0) {}
bool DeclResultIdMapper::decorateStageIOLocations() {
// Try both input and output even if input location assignment failed

Просмотреть файл

@ -18,6 +18,6 @@ namespace clang {
std::unique_ptr<ASTConsumer>
EmitSPIRVAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
return llvm::make_unique<spirv::SPIRVEmitter>(CI);
return llvm::make_unique<spirv::SPIRVEmitter>(CI, options);
}
} // end namespace clang

Просмотреть файл

@ -135,14 +135,15 @@ bool isLoopStmt(const Stmt *stmt) {
} // namespace
SPIRVEmitter::SPIRVEmitter(CompilerInstance &ci)
SPIRVEmitter::SPIRVEmitter(CompilerInstance &ci,
const EmitSPIRVOptions &options)
: theCompilerInstance(ci), astContext(ci.getASTContext()),
diags(ci.getDiagnostics()),
diags(ci.getDiagnostics()), spirvOptions(options),
entryFunctionName(ci.getCodeGenOpts().HLSLEntryFunction),
shaderModel(*hlsl::ShaderModel::GetByName(
ci.getCodeGenOpts().HLSLProfile.c_str())),
theContext(), theBuilder(&theContext),
declIdMapper(shaderModel, astContext, theBuilder, diags),
declIdMapper(shaderModel, astContext, theBuilder, diags, spirvOptions),
typeTranslator(astContext, theBuilder, diags), entryFunctionId(0),
curFunction(nullptr) {
if (shaderModel.GetKind() == hlsl::ShaderModel::Kind::Invalid)

Просмотреть файл

@ -26,6 +26,7 @@
#include "clang/AST/ASTContext.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/SPIRV/EmitSPIRVOptions.h"
#include "clang/SPIRV/ModuleBuilder.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SetVector.h"
@ -42,7 +43,7 @@ namespace spirv {
/// through the AST is done manually instead of using ASTConsumer's harness.
class SPIRVEmitter : public ASTConsumer {
public:
explicit SPIRVEmitter(CompilerInstance &ci);
explicit SPIRVEmitter(CompilerInstance &ci, const EmitSPIRVOptions &options);
void HandleTranslationUnit(ASTContext &context) override;
@ -433,6 +434,8 @@ private:
ASTContext &astContext;
DiagnosticsEngine &diags;
EmitSPIRVOptions spirvOptions;
/// Entry function name and shader stage. Both of them are derived from the
/// command line and should be const.
const llvm::StringRef entryFunctionName;

Просмотреть файл

@ -37,8 +37,8 @@ PSInput VSmain(float4 position: POSITION, float4 color: COLOR) {
// OpName %color "color"
// OpName %result "result"
// OpDecorate %gl_Position BuiltIn Position
// OpDecorate %in_var_COLOR Location 0
// OpDecorate %in_var_POSITION Location 1
// OpDecorate %in_var_POSITION Location 0
// OpDecorate %in_var_COLOR Location 1
// OpDecorate %out_var_COLOR Location 0
// %int = OpTypeInt 32 1
// %void = OpTypeVoid

Просмотреть файл

@ -1,4 +1,4 @@
// Run: %dxc -T vs_6_0 -E main
// Run: %dxc -T vs_6_0 -E main -fvk-stage-io-order=alpha
struct S {
float c: C;

Просмотреть файл

@ -0,0 +1,44 @@
// Run: %dxc -T vs_6_0 -E main
struct S {
float c: C;
float a: A;
float b: B;
};
struct T {
float e: E;
S s;
float d: D;
};
// CHECK: OpDecorate %in_var_N Location 0
// CHECK-NEXT: OpDecorate %in_var_E Location 1
// CHECK-NEXT: OpDecorate %in_var_C Location 2
// CHECK-NEXT: OpDecorate %in_var_A Location 3
// CHECK-NEXT: OpDecorate %in_var_B Location 4
// CHECK-NEXT: OpDecorate %in_var_D Location 5
// CHECK-NEXT: OpDecorate %in_var_M Location 6
// CHECK-NEXT: OpDecorate %out_var_E Location 0
// CHECK-NEXT: OpDecorate %out_var_C Location 1
// CHECK-NEXT: OpDecorate %out_var_A Location 2
// CHECK-NEXT: OpDecorate %out_var_B Location 3
// CHECK-NEXT: OpDecorate %out_var_D Location 4
// CHECK-NEXT: OpDecorate %out_var_Q Location 5
// CHECK-NEXT: OpDecorate %out_var_P Location 6
// Input semantics by declaration order: N, E, C, A, B, D, M
// by alphabetic order: A, B, C, D, E, M, N
// Output semantics by declaration order: E, C, A, B, D, Q, P
// by alphabetic order: A, B, C, D, E, P, Q
void main(in float input1 : N,
in T input2 ,
in float input3 : M,
out T output1,
out float output2: Q,
out float output3: P
) {
}

Просмотреть файл

@ -28,7 +28,7 @@ float main([[vk::location(0)]] in uint m: M, // On function parameter --- M -
// CHECK: OpDecorate %in_var_B Location 1
// CHECK: OpDecorate %in_var_A Location 2
// Alphabetical assignment
// CHECK: OpDecorate %out_var_C Location 0
// Declaration order assignment
// CHECK: OpDecorate %out_var_R Location 0
// CHECK: OpDecorate %out_var_N Location 1
// CHECK: OpDecorate %out_var_R Location 2
// CHECK: OpDecorate %out_var_C Location 2

Просмотреть файл

@ -24,13 +24,12 @@ float main( in uint m: M,
return 1.0;
}
// Alphabetical assignment
// CHECK: OpDecorate %in_var_A Location 0
// Declaration order assignment
// CHECK: OpDecorate %in_var_M Location 0
// CHECK: OpDecorate %in_var_B Location 1
// CHECK: OpDecorate %in_var_M Location 2
// CHECK: OpDecorate %in_var_A Location 2
// Explicit assignment
// CHECK: OpDecorate %out_var_R Location 2
// CHECK: OpDecorate %out_var_N Location 0
// CHECK: OpDecorate %out_var_C Location 1

Просмотреть файл

@ -970,11 +970,6 @@ int __cdecl wmain(int argc, const wchar_t **argv_) {
fprintf(stderr, "-spirv requires -Fo for output object file name.");
return 1;
}
#else
if (dxcOpts.GenSPIRV) {
fprintf(stderr, "SPIR-V codegen not configured via ENABLE_SPIRV_CODEGEN");
return 1;
}
#endif
// SPIRV change ends

Просмотреть файл

@ -462,7 +462,9 @@ public:
// SPIRV change starts
#ifdef ENABLE_SPIRV_CODEGEN
else if (opts.GenSPIRV) {
clang::EmitSPIRVAction action;
clang::EmitSPIRVOptions spirvOpts;
spirvOpts.stageIoOrder = opts.VkStageIoOrder;
clang::EmitSPIRVAction action(spirvOpts);
FrontendInputFile file(utf8SourceName.m_psz, IK_HLSL);
action.BeginSourceFile(compiler, file);
action.Execute();

Просмотреть файл

@ -286,8 +286,11 @@ TEST_F(FileTest, SemanticIsFrontFacePS) {
runFileTest("semantic.is-front-face.ps.hlsl");
}
TEST_F(FileTest, SemanticArbitrary) { runFileTest("semantic.arbitrary.hlsl"); }
TEST_F(FileTest, SemanticArbitraryLocation) {
runFileTest("semantic.arbitrary.location.hlsl");
TEST_F(FileTest, SemanticArbitraryDeclLocation) {
runFileTest("semantic.arbitrary.location.decl.hlsl");
}
TEST_F(FileTest, SemanticArbitraryAlphaLocation) {
runFileTest("semantic.arbitrary.location.alpha.hlsl");
}
TEST_F(FileTest, SemanticDuplication) {
runFileTest("semantic.duplication.hlsl", /*expectSuccess*/ false);

Просмотреть файл

@ -46,8 +46,8 @@ bool FileTest::parseInputFile() {
if (runCmdStartPos != std::string::npos) {
const auto runCmdEndPos = checkCommands.find('\n', runCmdStartPos);
const auto runCommand = checkCommands.substr(runCmdStartPos, runCmdEndPos);
if (!utils::processRunCommandArgs(runCommand, &targetProfile,
&entryPoint)) {
if (!utils::processRunCommandArgs(runCommand, &targetProfile, &entryPoint,
&restArgs)) {
// An error has occured when parsing the Run command.
return false;
}
@ -71,7 +71,7 @@ void FileTest::runFileTest(llvm::StringRef filename, bool expectSuccess,
// Feed the HLSL source into the Compiler.
const bool compileOk = utils::runCompilerWithSpirvGeneration(
inputFilePath, entryPoint, targetProfile, &generatedBinary,
inputFilePath, entryPoint, targetProfile, restArgs, &generatedBinary,
&errorMessages);
effcee::Result result(effcee::Result::Status::Ok);

Просмотреть файл

@ -34,6 +34,7 @@ private:
std::string targetProfile; ///< Target profile (argument of -T)
std::string entryPoint; ///< Entry point name (argument of -E)
std::string restArgs; ///< All the other arguments
std::string inputFilePath; ///< Path to the input test file
std::vector<uint32_t> generatedBinary; ///< The generated SPIR-V Binary
std::string checkCommands; ///< CHECK commands that verify output

Просмотреть файл

@ -10,6 +10,7 @@
#include "FileTestUtils.h"
#include <algorithm>
#include <sstream>
#include "SpirvTestOptions.h"
#include "gtest/gtest.h"
@ -40,24 +41,29 @@ bool validateSpirvBinary(std::vector<uint32_t> &binary) {
}
bool processRunCommandArgs(const llvm::StringRef runCommandLine,
std::string *targetProfile,
std::string *entryPoint) {
std::string *targetProfile, std::string *entryPoint,
std::string *restArgs) {
std::istringstream buf(runCommandLine);
std::istream_iterator<std::string> start(buf), end;
std::vector<std::string> tokens(start, end);
if (tokens[1].find("Run") == std::string::npos ||
if (tokens.size() < 3 || tokens[1].find("Run") == std::string::npos ||
tokens[2].find("%dxc") == std::string::npos) {
fprintf(stderr, "The only supported format is: \"// Run: %%dxc -T "
"<profile> -E <entry>\"\n");
return false;
}
for (size_t i = 0; i < tokens.size(); ++i) {
if (tokens[i] == "-T" && i + 1 < tokens.size())
*targetProfile = tokens[i + 1];
else if (tokens[i] == "-E" && i + 1 < tokens.size())
*entryPoint = tokens[i + 1];
std::ostringstream rest;
for (uint32_t i = 3; i < tokens.size(); ++i) {
if (tokens[i] == "-T" && (++i) < tokens.size())
*targetProfile = tokens[i];
else if (tokens[i] == "-E" && (++i) < tokens.size())
*entryPoint = tokens[i];
else
rest << (restArgs->empty() ? "" : " ") << tokens[i];
}
*restArgs = rest.str();
if (targetProfile->empty()) {
fprintf(stderr, "Error: Missing target profile argument (-T).\n");
return false;
@ -100,11 +106,13 @@ std::string getAbsPathOfInputDataFile(const llvm::StringRef filename) {
bool runCompilerWithSpirvGeneration(const llvm::StringRef inputFilePath,
const llvm::StringRef entryPoint,
const llvm::StringRef targetProfile,
const llvm::StringRef restArgs,
std::vector<uint32_t> *generatedBinary,
std::string *errorMessages) {
std::wstring srcFile(inputFilePath.begin(), inputFilePath.end());
std::wstring entry(entryPoint.begin(), entryPoint.end());
std::wstring profile(targetProfile.begin(), targetProfile.end());
std::wstring rest(restArgs.begin(), restArgs.end());
bool success = true;
try {
@ -126,6 +134,7 @@ bool runCompilerWithSpirvGeneration(const llvm::StringRef inputFilePath,
flags.push_back(L"-T");
flags.push_back(profile.c_str());
flags.push_back(L"-spirv");
flags.push_back(rest.c_str());
IFT(dllSupport.CreateInstance(CLSID_DxcLibrary, &pLibrary));
IFT(pLibrary->CreateBlobFromFile(srcFile.c_str(), nullptr, &pSource));

Просмотреть файл

@ -35,10 +35,11 @@ bool disassembleSpirvBinary(std::vector<uint32_t> &binary,
bool validateSpirvBinary(std::vector<uint32_t> &binary);
/// \brief Parses the Target Profile and Entry Point from the Run command
/// Returns the target profile and entry point via arguments.
/// Returns the target profile, entry point, and the rest via arguments.
/// Returns true on success, and false otherwise.
bool processRunCommandArgs(const llvm::StringRef runCommandLine,
std::string *targetProfile, std::string *entryPoint);
std::string *targetProfile, std::string *entryPoint,
std::string *restArgs);
/// \brief Converts an IDxcBlob into a vector of 32-bit unsigned integers which
/// is returned via the 'binaryWords' argument.
@ -57,6 +58,7 @@ std::string getAbsPathOfInputDataFile(const llvm::StringRef filename);
bool runCompilerWithSpirvGeneration(const llvm::StringRef inputFilePath,
const llvm::StringRef entryPoint,
const llvm::StringRef targetProfile,
const llvm::StringRef restArgs,
std::vector<uint32_t> *generatedBinary,
std::string *errorMessages);

Просмотреть файл

@ -31,7 +31,8 @@ bool WholeFileTest::parseInputFile() {
for (std::string line; std::getline(inputFile, line);) {
if (line.find(hlslStartLabel) != std::string::npos) {
foundRunCommand = true;
if (!utils::processRunCommandArgs(line, &targetProfile, &entryPoint)) {
if (!utils::processRunCommandArgs(line, &targetProfile, &entryPoint,
&restArgs)) {
// An error has occured when parsing the Run command.
return false;
}
@ -94,7 +95,7 @@ void WholeFileTest::runWholeFileTest(llvm::StringRef filename,
// Feed the HLSL source into the Compiler.
ASSERT_TRUE(utils::runCompilerWithSpirvGeneration(
inputFilePath, entryPoint, targetProfile, &generatedBinary,
inputFilePath, entryPoint, targetProfile, restArgs, &generatedBinary,
&errorMessages));
// Disassemble the generated SPIR-V binary.

Просмотреть файл

@ -58,6 +58,7 @@ private:
std::string targetProfile; ///< Target profile (argument of -T)
std::string entryPoint; ///< Entry point name (argument of -E)
std::string restArgs; ///< All the other arguments
std::string inputFilePath; ///< Path to the input test file
std::vector<uint32_t> generatedBinary; ///< The generated SPIR-V Binary
std::string expectedSpirvAsm; ///< Expected SPIR-V parsed from input