Add ShaderProfileFeatures for more expendable shader feature sets
This commit is contained in:
@@ -55,6 +55,12 @@ namespace ShaderProcessing
|
||||
/// <returns>The graphics feature level</returns>
|
||||
virtual FeatureLevel GetFeatureLevel() const = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the parser feature flags for the Shader Profile of the target platform graphics backend.
|
||||
/// </summary>
|
||||
/// <returns>The shader profile features mask.</returns>
|
||||
virtual ShaderProfileFeatures GetFeatures() const = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the parser macros.
|
||||
/// </summary>
|
||||
|
||||
@@ -354,10 +354,7 @@ namespace ShaderProcessing
|
||||
|
||||
// Clear current meta
|
||||
auto& current = ShaderMetaReaderType::_current;
|
||||
current.Name.Clear();
|
||||
current.Permutations.Clear();
|
||||
current.Flags = ShaderFlags::Default;
|
||||
current.MinFeatureLevel = FeatureLevel::ES2;
|
||||
current = MetaType();
|
||||
_permutationReader->Clear();
|
||||
|
||||
// Here we read '(x, y)\n' where 'x' is a shader function 'visible' flag, and 'y' is mini feature level
|
||||
@@ -388,6 +385,7 @@ namespace ShaderProcessing
|
||||
};
|
||||
MinFeatureLevel levels[] =
|
||||
{
|
||||
{ FeatureLevel::ES2, "AUTO" },
|
||||
{ FeatureLevel::ES2, "FEATURE_LEVEL_ES2" },
|
||||
{ FeatureLevel::ES3, "FEATURE_LEVEL_ES3" },
|
||||
{ FeatureLevel::ES3_1, "FEATURE_LEVEL_ES3_1" },
|
||||
@@ -406,7 +404,7 @@ namespace ShaderProcessing
|
||||
}
|
||||
if (missing)
|
||||
{
|
||||
parser->OnError(TEXT("Invalid shader function \'minFeatureLevel\' option value."));
|
||||
parser->OnError(TEXT("Invalid shader function \'minFeatures\' option value."));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -433,7 +431,9 @@ namespace ShaderProcessing
|
||||
}
|
||||
|
||||
// Check if use this shader program
|
||||
if ((current.Flags & ShaderFlags::Hidden) == (ShaderFlags)0 && current.MinFeatureLevel <= parser->GetFeatureLevel())
|
||||
if ((current.Flags & ShaderFlags::Hidden) == (ShaderFlags)0 &&
|
||||
current.MinFeatureLevel <= parser->GetFeatureLevel() &&
|
||||
EnumHasAllFlags(parser->GetFeatures(), current.MinFeatures))
|
||||
{
|
||||
// Cache read function
|
||||
ShaderMetaReaderType::_cache.Add(current);
|
||||
|
||||
@@ -44,12 +44,17 @@ public:
|
||||
/// <summary>
|
||||
/// Function flags.
|
||||
/// </summary>
|
||||
ShaderFlags Flags;
|
||||
ShaderFlags Flags = ShaderFlags::Default;
|
||||
|
||||
/// <summary>
|
||||
/// The minimum graphics platform feature level to support this shader.
|
||||
/// The minimum graphics platform feature level to support for this shader.
|
||||
/// </summary>
|
||||
FeatureLevel MinFeatureLevel;
|
||||
FeatureLevel MinFeatureLevel = FeatureLevel::ES2;
|
||||
|
||||
/// <summary>
|
||||
/// The minimum shader profile feature to support for this shader.
|
||||
/// </summary>
|
||||
ShaderProfileFeatures MinFeatures = ShaderProfileFeatures::None;
|
||||
|
||||
/// <summary>
|
||||
/// All possible values for the permutations and it's values to generate different permutation of this function
|
||||
@@ -220,6 +225,11 @@ public:
|
||||
int32 ControlPointsCount;
|
||||
|
||||
public:
|
||||
HullShaderMeta()
|
||||
{
|
||||
MinFeatures = ShaderProfileFeatures::TessellationShaders;
|
||||
}
|
||||
|
||||
// [ShaderFunctionMeta]
|
||||
ShaderStage GetStage() const override
|
||||
{
|
||||
@@ -233,6 +243,11 @@ public:
|
||||
class DomainShaderMeta : public ShaderFunctionMeta
|
||||
{
|
||||
public:
|
||||
DomainShaderMeta()
|
||||
{
|
||||
MinFeatures = ShaderProfileFeatures::TessellationShaders;
|
||||
}
|
||||
|
||||
// [ShaderFunctionMeta]
|
||||
ShaderStage GetStage() const override
|
||||
{
|
||||
@@ -246,6 +261,11 @@ public:
|
||||
class GeometryShaderMeta : public ShaderFunctionMeta
|
||||
{
|
||||
public:
|
||||
GeometryShaderMeta()
|
||||
{
|
||||
MinFeatures = ShaderProfileFeatures::GeometryShaders;
|
||||
}
|
||||
|
||||
// [ShaderFunctionMeta]
|
||||
ShaderStage GetStage() const override
|
||||
{
|
||||
@@ -272,6 +292,11 @@ public:
|
||||
class ComputeShaderMeta : public ShaderFunctionMeta
|
||||
{
|
||||
public:
|
||||
ComputeShaderMeta()
|
||||
{
|
||||
MinFeatures = ShaderProfileFeatures::ComputeShaders;
|
||||
}
|
||||
|
||||
// [ShaderFunctionMeta]
|
||||
ShaderStage GetStage() const override
|
||||
{
|
||||
|
||||
@@ -4,10 +4,11 @@
|
||||
|
||||
#if COMPILE_WITH_SHADER_COMPILER
|
||||
|
||||
#include "Engine/Core/Log.h"
|
||||
#include "Engine/Core/Collections/Array.h"
|
||||
#include "Engine/Utilities/TextProcessing.h"
|
||||
#include "Engine/Profiler/ProfilerCPU.h"
|
||||
#include "Engine/Core/Log.h"
|
||||
#include "Engine/Graphics/RenderTools.h"
|
||||
#include "ShaderFunctionReader.CB.h"
|
||||
#include "ShaderFunctionReader.VS.h"
|
||||
#include "ShaderFunctionReader.HS.h"
|
||||
@@ -17,12 +18,13 @@
|
||||
#include "ShaderFunctionReader.CS.h"
|
||||
#include "Config.h"
|
||||
|
||||
ShaderProcessing::Parser::Parser(const String& targetName, const char* source, int32 sourceLength, ParserMacros macros, FeatureLevel featureLevel)
|
||||
ShaderProcessing::Parser::Parser(const String& targetName, const char* source, int32 sourceLength, ParserMacros macros, ShaderProfile profile)
|
||||
: failed(false)
|
||||
, targetName(targetName)
|
||||
, text(source, sourceLength)
|
||||
, _macros(macros)
|
||||
, _featureLevel(featureLevel)
|
||||
, _featureLevel(RenderTools::GetFeatureLevel(profile))
|
||||
, _features(RenderTools::GetShaderProfileFeatures(profile))
|
||||
{
|
||||
}
|
||||
|
||||
@@ -30,10 +32,10 @@ ShaderProcessing::Parser::~Parser()
|
||||
{
|
||||
}
|
||||
|
||||
bool ShaderProcessing::Parser::Process(const String& targetName, const char* source, int32 sourceLength, ParserMacros macros, FeatureLevel featureLevel, ShaderMeta* result)
|
||||
bool ShaderProcessing::Parser::Process(const String& targetName, const char* source, int32 sourceLength, ParserMacros macros, ShaderProfile profile, ShaderMeta* result)
|
||||
{
|
||||
PROFILE_CPU_NAMED("Shader.Parse");
|
||||
Parser parser(targetName, source, sourceLength, macros, featureLevel);
|
||||
Parser parser(targetName, source, sourceLength, macros, profile);
|
||||
parser.Process(result);
|
||||
return parser.Failed();
|
||||
}
|
||||
|
||||
@@ -22,20 +22,18 @@ namespace ShaderProcessing
|
||||
class Parser : public IShaderParser, public ITokenReadersContainerBase<IShaderFunctionReader>
|
||||
{
|
||||
private:
|
||||
|
||||
bool failed;
|
||||
String targetName;
|
||||
Reader text;
|
||||
ParserMacros _macros;
|
||||
FeatureLevel _featureLevel;
|
||||
ShaderProfileFeatures _features;
|
||||
|
||||
private:
|
||||
|
||||
Parser(const String& targetName, const char* source, int32 sourceLength, ParserMacros macros, FeatureLevel featureLevel);
|
||||
Parser(const String& targetName, const char* source, int32 sourceLength, ParserMacros macros, ShaderProfile profile);
|
||||
~Parser();
|
||||
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// Process shader source code and generate metadata
|
||||
/// </summary>
|
||||
@@ -43,13 +41,12 @@ namespace ShaderProcessing
|
||||
/// <param name="source">ANSI source code</param>
|
||||
/// <param name="sourceLength">Amount of characters in the source code</param>
|
||||
/// <param name="macros">The input macros.</param>
|
||||
/// <param name="featureLevel">The target feature level.</param>
|
||||
/// <param name="profile">The target shader profile.</param>
|
||||
/// <param name="result">Output result with metadata</param>
|
||||
/// <returns>True if cannot process the file (too many errors), otherwise false</returns>
|
||||
static bool Process(const String& targetName, const char* source, int32 sourceLength, ParserMacros macros, FeatureLevel featureLevel, ShaderMeta* result);
|
||||
static bool Process(const String& targetName, const char* source, int32 sourceLength, ParserMacros macros, ShaderProfile profile, ShaderMeta* result);
|
||||
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// Process shader source code and generate metadata
|
||||
/// </summary>
|
||||
@@ -57,34 +54,32 @@ namespace ShaderProcessing
|
||||
void Process(ShaderMeta* result);
|
||||
|
||||
private:
|
||||
|
||||
void init();
|
||||
bool process();
|
||||
bool collectResults(ShaderMeta* result);
|
||||
|
||||
public:
|
||||
|
||||
// [IShaderParser]
|
||||
FeatureLevel GetFeatureLevel() const override
|
||||
{
|
||||
return _featureLevel;
|
||||
}
|
||||
|
||||
ShaderProfileFeatures GetFeatures() const override
|
||||
{
|
||||
return _features;
|
||||
}
|
||||
bool Failed() const override
|
||||
{
|
||||
return failed;
|
||||
}
|
||||
|
||||
Reader& GetReader() override
|
||||
{
|
||||
return text;
|
||||
}
|
||||
|
||||
ParserMacros GetMacros() const override
|
||||
{
|
||||
return _macros;
|
||||
}
|
||||
|
||||
void OnError(const String& message) override;
|
||||
void OnWarning(const String& message) override;
|
||||
};
|
||||
|
||||
@@ -152,20 +152,14 @@ bool ShadersCompilation::Compile(ShaderCompilationOptions& options)
|
||||
options.SourceLength--;
|
||||
|
||||
const DateTime startTime = DateTime::NowUTC();
|
||||
const FeatureLevel featureLevel = RenderTools::GetFeatureLevel(options.Profile);
|
||||
|
||||
// Process shader source to collect metadata
|
||||
ShaderMeta meta;
|
||||
if (ShaderProcessing::Parser::Process(options.TargetName, options.Source, options.SourceLength, options.Macros, featureLevel, &meta))
|
||||
if (ShaderProcessing::Parser::Process(options.TargetName, options.Source, options.SourceLength, options.Macros, options.Profile, &meta))
|
||||
{
|
||||
LOG(Warning, "Failed to parse source code.");
|
||||
return true;
|
||||
}
|
||||
const int32 shadersCount = meta.GetShadersCount();
|
||||
if (shadersCount == 0 && featureLevel > FeatureLevel::ES2)
|
||||
{
|
||||
LOG(Warning, "Shader has no valid functions.");
|
||||
}
|
||||
|
||||
// Perform actual compilation
|
||||
bool result;
|
||||
|
||||
Reference in New Issue
Block a user