Files
UnrealEngineUWP/Engine/Source/Runtime/RenderCore/Private/ShaderSource.cpp
dan elksnitis 1d261111ce [shaders]
- modify the input hash debug dump mechanism to output an empty "debughash_<hash>" file instead of a txt file with the hash in contents, and always dump these files for the instance of the job that actually compiled
- the existing cvar will now just make it so these files are also dumped for jobs which hit in DDC or the job cache; we don't do this by default so there's only a single match for the debug hash for any given shader normally and it is inside the folder containing the full debug info, including those artifacts which are only output as a side effect of the compile step
- add the same hash as the first line in the stripped source code, so "debughash_<hash>" can be used as a search term in Everything to quickly find debug info associated with a shader (i.e. when looking at a capture in renderdoc or similar)

note: this is a resubmit with fixes for mac/linux issues (avoiding printfs and using string builders instead; since wchar_t and TCHAR are not the same size on these platforms using %ls does not work), and a further fix for problems encountered with source compression when using wide chars in preprocessing instead of ansi chars.

#rb Laura.Hermanns
#jira UE-209753

[CL 32542773 by dan elksnitis in ue5-main branch]
2024-03-27 10:15:04 -04:00

111 lines
3.4 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "ShaderSource.h"
#include "Containers/StringConv.h"
#include "Compression/OodleDataCompression.h"
#include "HAL/IConsoleManager.h"
#include "HAL/UnrealMemory.h"
static int32 GShaderSourceCompressionMethod = 2;
static FAutoConsoleVariableRef CVarShaderSourceCompressionMethod(
TEXT("r.ShaderSource.CompressionMethod"),
GShaderSourceCompressionMethod,
TEXT("Compression method for shader source stored in memory. See FOodleDataCompression::ECompressor enum for supported values; defaults to Mermaid."),
ECVF_Default);
static int32 GShaderSourceCompressionLevel = 1;
FAutoConsoleVariableRef CVarShaderSourceCompressionLevel(
TEXT("r.ShaderSource.CompressionLevel"),
GShaderSourceCompressionLevel,
TEXT("Compression level for shader source stored in memory. See FOodleDataCompression::ECompressionLevel enum for supported values; default is SuperFast."),
ECVF_Default);
FShaderSource::FShaderSource(FShaderSource::FViewType InSrc, int32 AdditionalSlack)
{
Set(InSrc, AdditionalSlack);
}
void FShaderSource::Set(FShaderSource::FViewType InSrc, int32 AdditionalSlack)
{
SetLen(InSrc.Len() + AdditionalSlack);
FShaderSource::CharType* SourceData = Source.GetData();
FMemory::Memcpy(SourceData, InSrc.GetData(), sizeof(FShaderSource::CharType) * InSrc.Len());
}
#if !SHADER_SOURCE_ANSI
void FShaderSource::Set(FAnsiStringView InSrc)
{
TStringConvert<ANSICHAR, TCHAR> Convert;
SetLen(InSrc.Len());
Convert.Convert(Source.GetData(), Source.Num(), InSrc.GetData(), InSrc.Len());
}
#endif
FShaderSource& FShaderSource::operator=(FShaderSource::FStringType&& InSrc)
{
SourceCompressed.Empty();
DecompressedCharCount = 0;
int32 InInitialLen = InSrc.Len();
// input char array already has a null terminator appended, so can add one less padding char
TArray<CharType>& InSrcArray = InSrc.GetCharArray();
InSrcArray.AddZeroed(ShaderSourceSimdPadding - 1);
Source = MoveTemp(InSrcArray);
return *this;
}
void FShaderSource::Compress()
{
FOodleDataCompression::ECompressor Compressor = static_cast<FOodleDataCompression::ECompressor>(GShaderSourceCompressionMethod);
if (Compressor == FOodleDataCompression::ECompressor::NotSet)
{
return;
}
checkf(!IsCompressed(), TEXT("FShaderSource is already compressed"));
FOodleDataCompression::ECompressionLevel CompressionLevel = static_cast<FOodleDataCompression::ECompressionLevel>(GShaderSourceCompressionLevel);
DecompressedCharCount = Source.Num();
int32 CompressionBufferSize = FOodleDataCompression::CompressedBufferSizeNeeded(GetDecompressedSize());
SourceCompressed.SetNumUninitialized(CompressionBufferSize);
int32 CompressedSize = FOodleDataCompression::Compress(
SourceCompressed.GetData(),
CompressionBufferSize,
Source.GetData(),
GetDecompressedSize(),
Compressor,
CompressionLevel);
SourceCompressed.SetNum(CompressedSize, EAllowShrinking::Yes);
Source.Empty();
}
void FShaderSource::Decompress()
{
if (IsCompressed())
{
Source.SetNumUninitialized(DecompressedCharCount);
FOodleDataCompression::Decompress(Source.GetData(), GetDecompressedSize(), SourceCompressed.GetData(), SourceCompressed.Num());
SourceCompressed.Empty();
DecompressedCharCount = 0;
}
}
FArchive& operator<<(FArchive& Ar, FShaderSource& Src)
{
Ar << Src.DecompressedCharCount;
if (Src.IsCompressed())
{
Ar << Src.SourceCompressed;
}
else
{
Ar << Src.Source;
}
return Ar;
}