You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
170 lines
7.5 KiB
C++
170 lines
7.5 KiB
C++
/*
|
|
* Copyright (c) Contributors to the Open 3D Engine Project.
|
|
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
|
*
|
|
*/
|
|
|
|
#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>
|
|
|
|
namespace AZ
|
|
{
|
|
namespace RPI
|
|
{
|
|
void ShaderSourceData::Reflect(ReflectContext* context)
|
|
{
|
|
if (auto* serializeContext = azrtti_cast<SerializeContext*>(context))
|
|
{
|
|
serializeContext->Class<ShaderSourceData>()
|
|
->Version(5)
|
|
->Field("Source", &ShaderSourceData::m_source)
|
|
->Field("DrawList", &ShaderSourceData::m_drawListName)
|
|
->Field("DepthStencilState", &ShaderSourceData::m_depthStencilState)
|
|
->Field("RasterState", &ShaderSourceData::m_rasterState)
|
|
->Field("BlendState", &ShaderSourceData::m_blendState)
|
|
->Field("ProgramSettings", &ShaderSourceData::m_programSettings)
|
|
->Field("Definitions", &ShaderSourceData::m_definitions)
|
|
->Field("CompilerHints", &ShaderSourceData::m_compiler)
|
|
->Field("DisabledRHIBackends", &ShaderSourceData::m_disabledRhiBackends)
|
|
->Field("Supervariants", &ShaderSourceData::m_supervariants)
|
|
;
|
|
|
|
serializeContext->Class<ShaderSourceData::ProgramSettings>()
|
|
->Version(1)
|
|
->Field("EntryPoints", &ProgramSettings::m_entryPoints)
|
|
;
|
|
|
|
serializeContext->Class<ShaderSourceData::EntryPoint>()
|
|
->Version(1)
|
|
->Field("Name", &EntryPoint::m_name)
|
|
->Field("Type", &EntryPoint::m_type)
|
|
;
|
|
|
|
serializeContext->Class<ShaderSourceData::SupervariantInfo>()
|
|
->Version(1)
|
|
->Field("Name", &SupervariantInfo::m_name)
|
|
->Field("PlusArguments", &SupervariantInfo::m_plusArguments)
|
|
->Field("MinusArguments", &SupervariantInfo::m_minusArguments);
|
|
|
|
}
|
|
}
|
|
|
|
bool ShaderSourceData::IsRhiBackendDisabled(const AZ::Name& rhiName) const
|
|
{
|
|
return AZStd::any_of(AZ_BEGIN_END(m_disabledRhiBackends), [&](const AZStd::string& currentRhiName)
|
|
{
|
|
return currentRhiName == rhiName.GetStringView();
|
|
});
|
|
}
|
|
|
|
|
|
//! Helper function.
|
|
//! Parses a string of command line arguments looking for c-preprocessor macro definitions and appends the name of macro definition arguments.
|
|
//! Example:
|
|
//! Input string: "--switch1 -DMACRO1 -v -DMACRO2=23"
|
|
//! append the following items: ["MACRO1", "MACRO2"]
|
|
static void GetListOfMacroDefinitionNames(
|
|
const AZStd::string& stringWithArguments, AZStd::vector<AZStd::string>& macroDefinitionNames)
|
|
{
|
|
const AZStd::regex macroRegex(R"(-D\s*(\w+))", AZStd::regex::ECMAScript);
|
|
|
|
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)
|
|
{
|
|
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();
|
|
}
|
|
}
|
|
|
|
AZStd::vector<AZStd::string> ShaderSourceData::SupervariantInfo::GetCombinedListOfMacroDefinitionNamesToRemove() const
|
|
{
|
|
AZStd::vector<AZStd::string> macroDefinitionNames;
|
|
GetListOfMacroDefinitionNames(m_minusArguments, macroDefinitionNames);
|
|
GetListOfMacroDefinitionNames(m_plusArguments, macroDefinitionNames);
|
|
return macroDefinitionNames;
|
|
}
|
|
|
|
|
|
//! Helper function.
|
|
//! Parses a string of command line arguments looking for c-preprocessor macro definitions and appends macro definition
|
|
//! arguments. Example: Input string: "--switch1 -DMACRO1 -v -DMACRO2=23" append the following items: ["MACRO1", "MACRO2=23"]
|
|
static void GetListOfMacroDefinitions(
|
|
const AZStd::string& stringWithArguments, AZStd::vector<AZStd::string>& macroDefinitions)
|
|
{
|
|
const AZStd::regex macroRegex(R"(-D\s*(\w+)(=\w+)?)", AZStd::regex::ECMAScript);
|
|
|
|
AZStd::string hayStack(stringWithArguments);
|
|
AZStd::smatch match;
|
|
while (AZStd::regex_search(hayStack.c_str(), match, macroRegex))
|
|
{
|
|
if (match.size() > 1)
|
|
{
|
|
AZStd::string macro(match[1].str().c_str());
|
|
if (match.size() > 2)
|
|
{
|
|
macro += match[2].str().c_str();
|
|
}
|
|
macroDefinitions.push_back(macro);
|
|
}
|
|
hayStack = match.suffix();
|
|
}
|
|
}
|
|
|
|
AZStd::vector<AZStd::string> ShaderSourceData::SupervariantInfo::GetMacroDefinitionsToAdd() const
|
|
{
|
|
AZStd::vector<AZStd::string> parsedMacroDefinitions;
|
|
GetListOfMacroDefinitions(m_plusArguments, parsedMacroDefinitions);
|
|
return parsedMacroDefinitions;
|
|
}
|
|
|
|
AZStd::string ShaderSourceData::SupervariantInfo::GetCustomizedArgumentsForAzslc(
|
|
const AZStd::string& initialAzslcCompilerArguments) const
|
|
{
|
|
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 = 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 = RHI::CommandLineArgumentUtils::RemoveArgumentsFromCommandLineString(
|
|
azslcArgumentNamesToRemove, initialAzslcCompilerArguments);
|
|
customizedArguments += " " + plusArguments;
|
|
|
|
return RHI::CommandLineArgumentUtils::RemoveExtraSpaces(customizedArguments);
|
|
}
|
|
|
|
|
|
} // namespace RPI
|
|
} // namespace AZ
|