[ATOM-15618] Shader Build Pipeline: Add UnitTest To Validate Shader C… (#918)
* [ATOM-15618] Shader Build Pipeline: Add UnitTest To Validate Shader Compiler Argument Processing Introduced With The New Supervariant System - Added new test suite in Gems/Atom/Asset/Shader/Code/Tests/SupervariantCmdArgumentTests.cpp - Refactored and improved the previously existing classes: GlobalBuildOptions, PreprocessorOptions and ShaderCompilerArguments to work well with the new ShaderSourceData::SupervariantInfo. - Moved command line argument processing function out of ShaderCompilerArguments and into its own utility namespace in Atom/RHI.Edit/Utils.h Signed-off-by: garrieta <garrieta@amazon.com>
This commit is contained in:
@@ -11,6 +11,8 @@
|
||||
*/
|
||||
|
||||
#include <Atom/RPI.Edit/Shader/ShaderSourceData.h>
|
||||
#include <Atom/RHI.Edit/Utils.h>
|
||||
#include <Atom/RHI.Edit/ShaderCompilerArguments.h>
|
||||
#include <AzCore/std/string/regex.h>
|
||||
#include <AzFramework/StringFunc/StringFunc.h>
|
||||
|
||||
@@ -57,7 +59,7 @@ namespace AZ
|
||||
|
||||
bool ShaderSourceData::IsRhiBackendDisabled(const AZ::Name& rhiName) const
|
||||
{
|
||||
return AZStd::any_of(m_disabledRhiBackends.begin(), m_disabledRhiBackends.end(), [&](const AZStd::string& currentRhiName)
|
||||
return AZStd::any_of(AZ_BEGIN_END(m_disabledRhiBackends), [&](const AZStd::string& currentRhiName)
|
||||
{
|
||||
return currentRhiName == rhiName.GetStringView();
|
||||
});
|
||||
@@ -72,19 +74,32 @@ namespace AZ
|
||||
static void GetListOfMacroDefinitionNames(
|
||||
const AZStd::string& stringWithArguments, AZStd::vector<AZStd::string>& macroDefinitionNames)
|
||||
{
|
||||
static const AZStd::regex macroRegex("-D\\s*(\\w+)", AZStd::regex::ECMAScript);
|
||||
const AZStd::regex macroRegex(R"(-D\s*(\w+))", AZStd::regex::ECMAScript);
|
||||
|
||||
AZStd::cmatch match;
|
||||
if (AZStd::regex_search(stringWithArguments.c_str(), match, macroRegex))
|
||||
AZStd::string hayStack(stringWithArguments);
|
||||
AZStd::smatch match;
|
||||
while (AZStd::regex_search(hayStack.c_str(), match, macroRegex))
|
||||
{
|
||||
// First pattern is always the entire string
|
||||
for (unsigned i = 1; i < match.size(); ++i)
|
||||
{
|
||||
if (match[i].matched)
|
||||
{
|
||||
macroDefinitionNames.push_back(match[i].str().c_str());
|
||||
AZStd::string macroToAdd(match[i].str().c_str());
|
||||
const bool isPresent = AZStd::any_of(AZ_BEGIN_END(macroDefinitionNames),
|
||||
[&](AZStd::string_view macroName) -> bool
|
||||
{
|
||||
return macroToAdd == macroName;
|
||||
}
|
||||
);
|
||||
if (isPresent)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
macroDefinitionNames.push_back(macroToAdd);
|
||||
}
|
||||
}
|
||||
hayStack = match.suffix();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,19 +118,22 @@ namespace AZ
|
||||
static void GetListOfMacroDefinitions(
|
||||
const AZStd::string& stringWithArguments, AZStd::vector<AZStd::string>& macroDefinitions)
|
||||
{
|
||||
static const AZStd::regex macroRegex("-D\\s*(\\w+(=\\w+)?)", AZStd::regex::ECMAScript);
|
||||
const AZStd::regex macroRegex(R"(-D\s*(\w+)(=\w+)?)", AZStd::regex::ECMAScript);
|
||||
|
||||
AZStd::cmatch match;
|
||||
if (AZStd::regex_search(stringWithArguments.c_str(), match, macroRegex))
|
||||
AZStd::string hayStack(stringWithArguments);
|
||||
AZStd::smatch match;
|
||||
while (AZStd::regex_search(hayStack.c_str(), match, macroRegex))
|
||||
{
|
||||
// First pattern is always the entire string
|
||||
for (unsigned i = 1; i < match.size(); ++i)
|
||||
if (match.size() > 1)
|
||||
{
|
||||
if (match[i].matched)
|
||||
AZStd::string macro(match[1].str().c_str());
|
||||
if (match.size() > 2)
|
||||
{
|
||||
macroDefinitions.push_back(match[i].str().c_str());
|
||||
macro += match[2].str().c_str();
|
||||
}
|
||||
macroDefinitions.push_back(macro);
|
||||
}
|
||||
hayStack = match.suffix();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,62 +144,27 @@ namespace AZ
|
||||
return parsedMacroDefinitions;
|
||||
}
|
||||
|
||||
|
||||
// Helper.
|
||||
// @arguments: A string with command line arguments for a console application of the form:
|
||||
// "-<arg1> --<arg2> --<arg3>[=<value3>] ..."
|
||||
// Example: "--use-spaces --namespace=vk"
|
||||
// Returns: A list with just the [-|--]<argument name>:
|
||||
// ["-<arg1>", "--<arg2>", "--arg3"]
|
||||
// For the example shown above it will return this vector:
|
||||
// ["--use-spaces", "--namespace"]
|
||||
AZStd::vector<AZStd::string> GetListOfArgumentNames(const AZStd::string& arguments)
|
||||
{
|
||||
AZStd::vector<AZStd::string> listOfTokens;
|
||||
AzFramework::StringFunc::Tokenize(arguments, listOfTokens);
|
||||
AZStd::vector<AZStd::string> listOfArguments;
|
||||
for (const AZStd::string& token : listOfTokens)
|
||||
{
|
||||
AZStd::vector<AZStd::string> splitArguments;
|
||||
AzFramework::StringFunc::Tokenize(token, splitArguments, "=");
|
||||
listOfArguments.push_back(splitArguments[0]);
|
||||
}
|
||||
return listOfArguments;
|
||||
}
|
||||
|
||||
AZStd::string ShaderSourceData::SupervariantInfo::GetCustomizedArgumentsForAzslc(
|
||||
const AZStd::string& initialAzslcCompilerArguments) const
|
||||
{
|
||||
static const AZStd::regex macroRegex("-D\\s*(\\w+(=\\S+)?)", AZStd::regex::ECMAScript);
|
||||
const AZStd::regex macroRegex(R"(-D\s*(\w+(=\S+)?))", AZStd::regex::ECMAScript);
|
||||
|
||||
// We are only concerned with AZSLc arguments. Let's remove the C-Preprocessor macro definitions
|
||||
// from @minusArguments.
|
||||
const AZStd::string minusArguments = AZStd::regex_replace(m_minusArguments, macroRegex, "");
|
||||
const AZStd::string plusArguments = AZStd::regex_replace(m_plusArguments, macroRegex, "");
|
||||
AZStd::string azslcArgumentsToRemove = minusArguments + " " + plusArguments;
|
||||
AZStd::vector<AZStd::string> azslcArgumentNamesToRemove = GetListOfArgumentNames(azslcArgumentsToRemove);
|
||||
AZStd::vector<AZStd::string> azslcArgumentNamesToRemove = RHI::CommandLineArgumentUtils::GetListOfArgumentNames(azslcArgumentsToRemove);
|
||||
|
||||
// At this moment @azslcArgumentsToRemove contains arguments for AZSLc that can be of the form:
|
||||
// -<arg>
|
||||
// --<arg>[=<value>]
|
||||
// We need to remove those from @initialAzslcCompilerArguments.
|
||||
AZStd::string customizedArguments = initialAzslcCompilerArguments;
|
||||
for (const AZStd::string& azslcArgumentName : azslcArgumentNamesToRemove)
|
||||
{
|
||||
AZStd::string regexStr = AZStd::string::format("%s(=\\S+)?", azslcArgumentName.c_str());
|
||||
AZStd::regex replaceRegex(regexStr, AZStd::regex::ECMAScript);
|
||||
customizedArguments = AZStd::regex_replace(customizedArguments, replaceRegex, "");
|
||||
}
|
||||
|
||||
AZStd::string customizedArguments = RHI::CommandLineArgumentUtils::RemoveArgumentsFromCommandLineString(
|
||||
azslcArgumentNamesToRemove, initialAzslcCompilerArguments);
|
||||
customizedArguments += " " + plusArguments;
|
||||
|
||||
// Will contain the results that will be joined by a space.
|
||||
// This is used to get a clean string to return without excess spaces.
|
||||
AZStd::vector<AZStd::string> argumentList;
|
||||
AzFramework::StringFunc::Tokenize(customizedArguments, argumentList, " \t\n");
|
||||
customizedArguments.clear(); // Need to clear because Join appends.
|
||||
AzFramework::StringFunc::Join(customizedArguments, argumentList.begin(), argumentList.end(), " ");
|
||||
return customizedArguments;
|
||||
return RHI::CommandLineArgumentUtils::RemoveExtraSpaces(customizedArguments);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user