Files
UnrealEngine/Engine/Source/Runtime/RenderCore/Private/ShaderSource.cpp
2025-05-18 13:04:45 +08:00

102 lines
3.1 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());
}
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;
}