You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
- add new IShaderFormat API for separate preprocessing and compilation; backends can implement one or the other depending on the return value of SupportsIndependentPreprocessing - add support for executing preprocessing in the cook process prior to job submission and constructing job input hashes based on preprocessed source (and a subset of the environment used as compile inputs). controlled by a cvar for now and disabled by default - add a BaseShaderFormat class in ShaderCompilerCommon which implements common behaviour for output of debug data - note this function is only called for formats which support independent preprocessing, so is expected to be used only by formats which have been converted to use this API - add new cvars for output of some additional shader debug data - 1. a txt file containing the input hash a.k.a. job cache key 2. a text file containing all diagnostic messages (errors and warnings) for the job - minor change to how input hashes are constructed for pipeline jobs - sum hashes as 256-bit ints instead of adding to a buffer and re-hashing. faster and simpler, and also more collision resistant (sum of two well distributed hashes equally well distributed) #rb Jason.Nadro #rb Yuriy.ODonnell #preflight 64512c88c86798f650b953d3 [CL 25317218 by dan elksnitis in ue5-main branch]
133 lines
3.7 KiB
C
133 lines
3.7 KiB
C
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#pragma once
|
|
|
|
#include "CoreMinimal.h"
|
|
#include "ShaderCore.h"
|
|
#include "mcpp.h"
|
|
#include "ShaderCompilerCore.h"
|
|
#include "ShaderPreprocessTypes.h"
|
|
|
|
enum class EMessageType
|
|
{
|
|
Error = 0,
|
|
Warn = 1,
|
|
ShaderMetaData = 2,
|
|
};
|
|
|
|
/**
|
|
* Filter preprocessor errors.
|
|
* @param ErrorMsg - The error message.
|
|
* @returns true if the message is valid and has not been filtered out.
|
|
*/
|
|
inline EMessageType FilterPreprocessorError(const FString& ErrorMsg)
|
|
{
|
|
const TCHAR* SubstringsToFilter[] =
|
|
{
|
|
TEXT("Unknown encoding:"),
|
|
TEXT("with no newline, supplemented newline"),
|
|
TEXT("Converted [CR+LF] to [LF]")
|
|
};
|
|
const int32 FilteredSubstringCount = UE_ARRAY_COUNT(SubstringsToFilter);
|
|
|
|
if (ErrorMsg.Contains(TEXT("UESHADERMETADATA")))
|
|
{
|
|
return EMessageType::ShaderMetaData;
|
|
}
|
|
|
|
for (int32 SubstringIndex = 0; SubstringIndex < FilteredSubstringCount; ++SubstringIndex)
|
|
{
|
|
if (ErrorMsg.Contains(SubstringsToFilter[SubstringIndex]))
|
|
{
|
|
return EMessageType::Warn;
|
|
}
|
|
}
|
|
return EMessageType::Error;
|
|
}
|
|
|
|
static void ExtractDirective(FString& OutString, FString WarningString)
|
|
{
|
|
static const FString PrefixString = TEXT("UESHADERMETADATA_");
|
|
uint32 DirectiveStartPosition = WarningString.Find(PrefixString) + PrefixString.Len();
|
|
uint32 DirectiveEndPosition = WarningString.Find(TEXT("\n"));
|
|
if (DirectiveEndPosition == INDEX_NONE)
|
|
{
|
|
DirectiveEndPosition = WarningString.Len();
|
|
}
|
|
OutString = WarningString.Mid(DirectiveStartPosition, (DirectiveEndPosition - DirectiveStartPosition));
|
|
}
|
|
|
|
/**
|
|
* Parses MCPP error output.
|
|
* @param ShaderOutput - Shader output to which to add errors.
|
|
* @param McppErrors - MCPP error output.
|
|
*/
|
|
static bool ParseMcppErrors(FShaderPreprocessOutput& Output, const FString& McppErrors)
|
|
{
|
|
bool bSuccess = true;
|
|
if (McppErrors.Len() > 0)
|
|
{
|
|
TArray<FString> Lines;
|
|
McppErrors.ParseIntoArray(Lines, TEXT("\n"), true);
|
|
for (int32 LineIndex = 0; LineIndex < Lines.Num(); ++LineIndex)
|
|
{
|
|
FString& Line = Lines[LineIndex];
|
|
int32 SepIndex1 = Line.Find(TEXT(":"), ESearchCase::CaseSensitive, ESearchDir::FromStart, 2);
|
|
int32 SepIndex2 = Line.Find(TEXT(":"), ESearchCase::CaseSensitive, ESearchDir::FromStart, SepIndex1 + 1);
|
|
if (SepIndex1 != INDEX_NONE && SepIndex2 != INDEX_NONE && SepIndex1 < SepIndex2)
|
|
{
|
|
FString Filename = Line.Left(SepIndex1);
|
|
FString LineNumStr = Line.Mid(SepIndex1 + 1, SepIndex2 - SepIndex1 - 1);
|
|
FString Message = Line.Mid(SepIndex2 + 1, Line.Len() - SepIndex2 - 1);
|
|
if (Filename.Len() && LineNumStr.Len() && LineNumStr.IsNumeric() && Message.Len())
|
|
{
|
|
while (++LineIndex < Lines.Num() && Lines[LineIndex].Len() && Lines[LineIndex].StartsWith(TEXT(" "),ESearchCase::CaseSensitive))
|
|
{
|
|
Message += FString(TEXT("\n")) + Lines[LineIndex];
|
|
}
|
|
--LineIndex;
|
|
Message.TrimStartAndEndInline();
|
|
|
|
// Ignore the warning about files that don't end with a newline.
|
|
switch (FilterPreprocessorError(Message))
|
|
{
|
|
case EMessageType::Error:
|
|
{
|
|
Output.LogError(MoveTemp(Filename), MoveTemp(Message), MoveTemp(LineNumStr));
|
|
bSuccess = false;
|
|
}
|
|
break;
|
|
case EMessageType::Warn:
|
|
{
|
|
// Warnings are ignored.
|
|
}
|
|
break;
|
|
case EMessageType::ShaderMetaData:
|
|
{
|
|
FString Directive;
|
|
ExtractDirective(Directive, Message);
|
|
Output.AddDirective(MoveTemp(Directive));
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Presume message is an error
|
|
Output.LogError(MoveTemp(Line));
|
|
bSuccess = false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Presume message is an error
|
|
Output.LogError(MoveTemp(Line));
|
|
bSuccess = false;
|
|
}
|
|
}
|
|
}
|
|
return bSuccess;
|
|
}
|