Files
UnrealEngine/Engine/Source/Developer/TargetPlatform/Public/Interfaces/IShaderFormat.h
Brandyn / Techy fcc1b09210 init
2026-04-04 15:40:51 -05:00

220 lines
10 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
/** Wildcard string used to search for shader format modules. */
#define SHADERFORMAT_MODULE_WILDCARD TEXT("*ShaderFormat*")
class FSerializedShaderArchive;
class FShaderPreprocessOutput;
class FCompressedBuffer;
class FSharedBuffer;
struct FShaderCompilerEnvironment;
struct FShaderCompilerInput;
struct FShaderCompilerOutput;
struct FShaderDebugDataContext;
/**
* IShaderFormat, shader pre-compilation abstraction
*/
class IShaderFormat
{
public:
/**
* Gets the current version of the specified shader format.
*
* @param Format The format to get the version for.
* @return Version number.
*/
virtual uint32 GetVersion(FName Format) const = 0;
/**
* Gets the list of supported formats.
*
* @param OutFormats Will hold the list of formats.
*/
virtual void GetSupportedFormats(TArray<FName>& OutFormats) const = 0;
/**
* Can this shader format strip shader code for packaging in a shader library?
* @param bNative Whether the final shader library uses a native format which may determine if the shader is stripped.
* @returns True if and only if the format can strip extraneous data from shaders to be included in a shared library, otherwise false.
*/
virtual bool CanStripShaderCode(bool const bNativeFormat) const { return false; }
/**
* Strips the shader bytecode provided of any unnecessary optional data elements when archiving shaders into the shared library.
*
* @param Code The byte code to strip (must be uncompressed).
* @param DebugOutputDir The output directory to write the debug symbol file for this shader.
* @param bNative Whether the final shader library uses a native format which may determine how the shader is stripped.
* @return True if the format has successfully stripped the extraneous data from shaders, otherwise false
*/
virtual bool StripShaderCode(TArray<uint8>& Code, FString const& DebugOutputDir, bool const bNative) const { return false; }
/**
* Whether this shader format supports a format-specific archive for precompiled shader code.
*
* @returns true if shader archives are supported, false otherwise.
*/
virtual bool SupportsShaderArchives() const { return false; }
/**
* Create a format specific archive for precompiled shader code.
*
* @param LibraryName The name of this shader library.
* @param Format The format of shaders to cache.
* @param WorkingDirectory The working directory.
* @param The output directory for the archive.
* @param The directory for the debug data previously generated.
* @param Optional pointer to a TArray that on success will be filled with a list of the written file paths.
* @returns true if the archive was created
*/
virtual bool CreateShaderArchive(FString const& LibraryName,
FName ShaderFormatAndShaderPlatformName,
const FString& WorkingDirectory,
const FString& OutputDir,
const FString& DebugOutputDir,
const FSerializedShaderArchive& SerializedShaders,
const TArray<FSharedBuffer>& ShaderCode,
TArray<FString>* OutputFiles) const
{
return false;
}
/**
* Can the shader format compile shaders to the native binary format for the platform.
* @returns True if the native compiler is available and configured, otherwise false.
*/
virtual bool CanCompileBinaryShaders() const { return true; }
/**
* Returns name of directory with platform specific shaders.
*
* @returns Name of directory with platform specific shaders.
*/
virtual const TCHAR* GetPlatformIncludeDirectory() const = 0;
/**
* Called before a shader is compiled to allow the platform shader format to modify the shader compiler input,
* e.g. by adding console variable values relevant to shader compilation on that platform.
*/
virtual void ModifyShaderCompilerInput(FShaderCompilerInput& Input) const { }
UE_DEPRECATED(5.6, "Use overload accepting a const FCompressedBuffer& for symbol data")
virtual void NotifyShaderCompiled(const TConstArrayView<uint8>& SymbolData, FName Format, const FString& DebugInfo = FString()) const { }
/**
* Called when a shader resource is cooked, so the shader format can perform platform-specific operations on the debug data.
* Does nothing on platforms that make no use of the symbol data.
*/
virtual void NotifyShaderCompiled(const FCompressedBuffer& SymbolData, FName Format, const FString& DebugInfo = FString()) const { }
/** Called at the end of a cook to free resources and finalize artifacts created during the cook. */
virtual void NotifyShaderCompilersShutdown(FName Format) const { }
/**
* Appends shader key text to the provided key string for use in DDC unique key construction.
* @param KeyString String that will get shader key text appended to.
*/
virtual void AppendToKeyString(FString& KeyString) const { }
/**
* Execute all shader preprocessing steps, storing the output in the PreprocessOutput struct
*/
virtual bool PreprocessShader(const FShaderCompilerInput& Input, const FShaderCompilerEnvironment& Environment, FShaderPreprocessOutput& PreprocessOutput) const { return false; };
/**
* Compile the specified preprocessed shader.
*/
virtual void CompilePreprocessedShader(
const FShaderCompilerInput& Input,
const FShaderPreprocessOutput& PreprocessOutput,
FShaderCompilerOutput& Output,
const FString& WorkingDirectory) const {}
/**
* Compile the specified preprocessed shaders; only called if the call to RequiresSecondaryCompile given the first preprocess
* output returns true. The shader system will pack these outputs together in the following format:
* [int32 key][uint32 primary length][uint32 secondary length][full primary shader code][full secondary shader code]
* where "key" is the return value of the GetPackedShaderKey function (this should also be implemented by any backends which
* require secondary compilation and is used by the RHI to differentiate packed shader code from single shaders)
*/
virtual void CompilePreprocessedShader(
const FShaderCompilerInput& Input,
const FShaderPreprocessOutput& PrimaryPreprocessOutput,
const FShaderPreprocessOutput& SecondaryPreprocessOutput,
FShaderCompilerOutput& PrimaryOutput,
FShaderCompilerOutput& SecondaryOutput,
const FString& WorkingDirectory) const {}
/**
* Predicate which should return true if a second preprocess & compilation is required given the initial preprocess output.
* This is generally be determined by analyzing the directives on the given preprocess output (which are set by the presence
* of UESHADERMETADATA directives in the original source), though other conditions are possible and up to the implementation.
* In the event this returns true, PreprocessShader will be called an additional time, with the bIsSecondary field on the
* FShaderPreprocessOutput set to true, and the overload of CompilePreprocessedShader taking two FShaderPreprocessOutput and
* two FShaderCompilerOutput objects will be called instead of the single object variants. Note that this is done instead of
* calling the single object variant twice so shader formats can statically distinguish primary compilation in a dual-compile
* case from the single-compile case.
*/
virtual bool RequiresSecondaryCompile(
const FShaderCompilerInput& Input,
const FShaderCompilerEnvironment& Environment,
const FShaderPreprocessOutput& PreprocessOutput) const { return false; }
/**
* For shader formats which support secondary compilation, this can optionally return a name that is appended to diagnostic messages
* to distinguish errors in the secondary compile from the primary.
*/
virtual FStringView GetSecondaryCompileName() const { return TEXTVIEW(""); }
/**
* Virtual function that can be implemented by backends which require secondary compilation to specify a unique "key" identifier
* for the packing scheme (for validation in the runtime at load). see RequiresSecondaryCompile and the overloads of
* CompilePreprocessedShader for additional details.
*/
virtual int32 GetPackedShaderKey() const { return 0; }
/*
* Implement to output debug info for a single compile job.
* This will be called for all jobs (including those found in the job cache) but only if debug info is enabled for the job.
* Note that any debug info output in CompilePreprocessedShader will only be done for the job that actually executes the
* compile step, as such any debug outputs that are desirable for all jobs should be written by this function.
* A BaseShaderFormat implementation is provided in ShaderCompilerCommon which dumps preprocessed and stripped USFs along
* with the hash of the shader code in an OutputHash.txt file; if no additional custom debug output is required the shader
* format can inherit from FBaseShaderFormat instead of IShaderFormat.
*/
virtual void OutputDebugData(
const FShaderCompilerInput& Input,
const FShaderPreprocessOutput& PreprocessOutput,
const FShaderCompilerOutput& Output,
FShaderDebugDataContext& Ctx) const {};
/*
* Implement to output debug info for the case where a secondary preprocessed shader was created. As with the dual-output version
* of CompilePreprocessedShader this is provided so shader formats can statically distinguish the single and dual output cases.
* Note that BaseShaderFormat does not provide an implementation of this so it needs to be explicitly implemented by backends
* which require secondary compilation, even if inheriting from FBaseShaderFormat.
*/
virtual void OutputDebugData(
const FShaderCompilerInput& Input,
const FShaderPreprocessOutput& PreprocessOutput,
const FShaderPreprocessOutput& SecondaryPreprocessOutput,
const FShaderCompilerOutput& Output,
const FShaderCompilerOutput& SecondaryOutput,
FShaderDebugDataContext& Ctx) const {};
/* Implement to output a minimal set of debug info based solely on the compile input. This is invoked when preprocessing fails. */
virtual void OutputDebugDataMinimal(const FShaderCompilerInput& Input, FShaderDebugDataContext& Ctx) const {};
public:
/** Virtual destructor. */
virtual ~IShaderFormat() { }
};