2019-12-26 14:45:42 -05:00
// Copyright Epic Games, Inc. All Rights Reserved.
Merging //UE4/Dev-Rendering-Graph@4492585 to Dev-Rendering (//UE4/Dev-Rendering)
This implements the framework to write the high level rendering code into passes organized in direct acyclic graph. It is also unifying the uniform buffer, shader parameters, and pass parameters to same single API: structures with run time meta data. This allow high level user code be extremely seamless, user code debugging, and render graph ease of implementation and debugging.
Issue of collaborative work of Arne Schnober, Brian Karis, Daniel Wright, Marcus Wassmer and Guillaume Abadie.
Names of the graph managed resources are not final.
#rb Arne.Schnober, Brian.Karis, Daniel.Wright, Marcus.Wassmer
[CL 4492694 by Guillaume Abadie in Dev-Rendering branch]
2018-10-19 17:36:35 -04:00
/*=============================================================================
ShaderParameterStruct . cpp : Shader parameter struct implementations .
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
# include "ShaderParameterStruct.h"
2024-04-23 17:02:48 -04:00
FRDGTextureAccess : : FRDGTextureAccess ( FRDGTexture * InTexture , ERHIAccess InAccess )
2024-04-23 17:29:27 -04:00
: FRDGTextureAccess ( InTexture , InTexture ? InTexture - > GetSubresourceRange ( ) : FRDGTextureSubresourceRange ( ) , InAccess )
2024-04-23 17:02:48 -04:00
{ }
FRDGTextureAccess : : FRDGTextureAccess ( FRDGTextureSRV * InTextureSRV , ERHIAccess InAccess )
2024-04-23 17:29:27 -04:00
: FRDGTextureAccess ( InTextureSRV ? InTextureSRV - > GetParent ( ) : nullptr , InTextureSRV ? InTextureSRV - > GetSubresourceRange ( ) : FRDGTextureSubresourceRange ( ) , InAccess )
2024-04-23 17:02:48 -04:00
{ }
FRDGTextureAccess : : FRDGTextureAccess ( FRDGTextureUAV * InTextureUAV , ERHIAccess InAccess )
2024-04-23 17:29:27 -04:00
: FRDGTextureAccess ( InTextureUAV ? InTextureUAV - > GetParent ( ) : nullptr , InTextureUAV ? InTextureUAV - > GetSubresourceRange ( ) : FRDGTextureSubresourceRange ( ) , InAccess )
2024-04-23 17:02:48 -04:00
{ }
Merging //UE4/Dev-Rendering-Graph@4492585 to Dev-Rendering (//UE4/Dev-Rendering)
This implements the framework to write the high level rendering code into passes organized in direct acyclic graph. It is also unifying the uniform buffer, shader parameters, and pass parameters to same single API: structures with run time meta data. This allow high level user code be extremely seamless, user code debugging, and render graph ease of implementation and debugging.
Issue of collaborative work of Arne Schnober, Brian Karis, Daniel Wright, Marcus Wassmer and Guillaume Abadie.
Names of the graph managed resources are not final.
#rb Arne.Schnober, Brian.Karis, Daniel.Wright, Marcus.Wassmer
[CL 4492694 by Guillaume Abadie in Dev-Rendering branch]
2018-10-19 17:36:35 -04:00
/** Context of binding a map. */
struct FShaderParameterStructBindingContext
{
2018-11-23 15:47:24 -05:00
// Shader having its parameter bound.
const FShader * Shader ;
Merging //UE4/Dev-Rendering-Graph@4492585 to Dev-Rendering (//UE4/Dev-Rendering)
This implements the framework to write the high level rendering code into passes organized in direct acyclic graph. It is also unifying the uniform buffer, shader parameters, and pass parameters to same single API: structures with run time meta data. This allow high level user code be extremely seamless, user code debugging, and render graph ease of implementation and debugging.
Issue of collaborative work of Arne Schnober, Brian Karis, Daniel Wright, Marcus Wassmer and Guillaume Abadie.
Names of the graph managed resources are not final.
#rb Arne.Schnober, Brian.Karis, Daniel.Wright, Marcus.Wassmer
[CL 4492694 by Guillaume Abadie in Dev-Rendering branch]
2018-10-19 17:36:35 -04:00
// Bindings to bind.
FShaderParameterBindings * Bindings ;
// The shader parameter map from the compilation.
const FShaderParameterMap * ParametersMap ;
// Map of global shader name that were bound to C++ members.
TMap < FString , FString > ShaderGlobalScopeBindings ;
// C++ name of the render target binding slot.
FString RenderTargetBindingSlotCppName ;
2020-04-06 21:12:18 -04:00
// Shader PermutationId
int32 PermutationId ;
2018-11-21 18:45:02 -05:00
// Whether this is for legacy shader parameter settings, or root shader parameter structures/
bool bUseRootShaderParameters ;
Merging //UE4/Dev-Rendering-Graph@4492585 to Dev-Rendering (//UE4/Dev-Rendering)
This implements the framework to write the high level rendering code into passes organized in direct acyclic graph. It is also unifying the uniform buffer, shader parameters, and pass parameters to same single API: structures with run time meta data. This allow high level user code be extremely seamless, user code debugging, and render graph ease of implementation and debugging.
Issue of collaborative work of Arne Schnober, Brian Karis, Daniel Wright, Marcus Wassmer and Guillaume Abadie.
Names of the graph managed resources are not final.
#rb Arne.Schnober, Brian.Karis, Daniel.Wright, Marcus.Wassmer
[CL 4492694 by Guillaume Abadie in Dev-Rendering branch]
2018-10-19 17:36:35 -04:00
void Bind (
const FShaderParametersMetadata & StructMetaData ,
const TCHAR * MemberPrefix ,
uint32 GeneralByteOffset )
{
const TArray < FShaderParametersMetadata : : FMember > & StructMembers = StructMetaData . GetMembers ( ) ;
for ( const FShaderParametersMetadata : : FMember & Member : StructMembers )
{
EUniformBufferBaseType BaseType = Member . GetBaseType ( ) ;
FString CppName = FString : : Printf ( TEXT ( " %s::%s " ) , StructMetaData . GetStructTypeName ( ) , Member . GetName ( ) ) ;
// Ignore rasterizer binding slots entirely since this actually have nothing to do with a shader.
if ( BaseType = = UBMT_RENDER_TARGET_BINDING_SLOTS )
{
if ( ! RenderTargetBindingSlotCppName . IsEmpty ( ) )
{
UE_LOG ( LogShaders , Fatal , TEXT ( " Render target binding slots collision: %s & %s " ) ,
* RenderTargetBindingSlotCppName , * CppName ) ;
}
RenderTargetBindingSlotCppName = CppName ;
continue ;
}
2021-05-25 12:18:27 -04:00
// Ignore RDG access types when binding to shaders.
if ( IsRDGResourceAccessType ( BaseType ) )
{
continue ;
}
Merging //UE4/Dev-Rendering-Graph@4492585 to Dev-Rendering (//UE4/Dev-Rendering)
This implements the framework to write the high level rendering code into passes organized in direct acyclic graph. It is also unifying the uniform buffer, shader parameters, and pass parameters to same single API: structures with run time meta data. This allow high level user code be extremely seamless, user code debugging, and render graph ease of implementation and debugging.
Issue of collaborative work of Arne Schnober, Brian Karis, Daniel Wright, Marcus Wassmer and Guillaume Abadie.
Names of the graph managed resources are not final.
#rb Arne.Schnober, Brian.Karis, Daniel.Wright, Marcus.Wassmer
[CL 4492694 by Guillaume Abadie in Dev-Rendering branch]
2018-10-19 17:36:35 -04:00
// Compute the shader member name to look for according to nesting.
FString ShaderBindingName = FString : : Printf ( TEXT ( " %s%s " ) , MemberPrefix , Member . GetName ( ) ) ;
uint16 ByteOffset = uint16 ( GeneralByteOffset + Member . GetOffset ( ) ) ;
check ( uint32 ( ByteOffset ) = = GeneralByteOffset + Member . GetOffset ( ) ) ;
2019-03-07 11:25:32 -05:00
const uint32 ArraySize = Member . GetNumElements ( ) ;
const bool bIsArray = ArraySize > 0 ;
const bool bIsRHIResource = (
BaseType = = UBMT_TEXTURE | |
BaseType = = UBMT_SRV | |
2019-06-11 18:27:07 -04:00
BaseType = = UBMT_UAV | |
2019-03-07 11:25:32 -05:00
BaseType = = UBMT_SAMPLER ) ;
2019-09-14 09:45:25 -04:00
const bool bIsRDGResource =
2021-05-25 12:18:27 -04:00
IsRDGResourceReferenceShaderParameterType ( BaseType ) ;
2019-09-14 09:45:25 -04:00
2023-04-18 10:06:12 -04:00
const bool bIsVariableNativeType = Member . IsVariableNativeType ( ) ;
2019-03-07 11:25:32 -05:00
2019-10-01 13:03:04 -04:00
checkf ( BaseType ! = UBMT_BOOL , TEXT ( " Should have failed in FShaderParametersMetadata::InitializeLayout() " ) ) ;
2019-06-11 18:27:07 -04:00
if ( BaseType = = UBMT_INCLUDED_STRUCT )
{
checkf ( ! bIsArray , TEXT ( " Array of included structure is impossible. " ) ) ;
Bind (
* Member . GetStructMetadata ( ) ,
/* MemberPrefix = */ MemberPrefix ,
/* GeneralByteOffset = */ ByteOffset ) ;
continue ;
}
else if ( BaseType = = UBMT_NESTED_STRUCT & & bIsArray )
{
const FShaderParametersMetadata * ChildStruct = Member . GetStructMetadata ( ) ;
uint32 StructSize = ChildStruct - > GetSize ( ) ;
for ( uint32 ArrayElementId = 0 ; ArrayElementId < ( bIsArray ? ArraySize : 1u ) ; ArrayElementId + + )
{
FString NewPrefix = FString : : Printf ( TEXT ( " %s%s_%d_ " ) , MemberPrefix , Member . GetName ( ) , ArrayElementId ) ;
Bind (
* ChildStruct ,
/* MemberPrefix = */ * NewPrefix ,
/* GeneralByteOffset = */ ByteOffset + ArrayElementId * StructSize ) ;
}
continue ;
}
else if ( BaseType = = UBMT_NESTED_STRUCT & & ! bIsArray )
Merging //UE4/Dev-Rendering-Graph@4492585 to Dev-Rendering (//UE4/Dev-Rendering)
This implements the framework to write the high level rendering code into passes organized in direct acyclic graph. It is also unifying the uniform buffer, shader parameters, and pass parameters to same single API: structures with run time meta data. This allow high level user code be extremely seamless, user code debugging, and render graph ease of implementation and debugging.
Issue of collaborative work of Arne Schnober, Brian Karis, Daniel Wright, Marcus Wassmer and Guillaume Abadie.
Names of the graph managed resources are not final.
#rb Arne.Schnober, Brian.Karis, Daniel.Wright, Marcus.Wassmer
[CL 4492694 by Guillaume Abadie in Dev-Rendering branch]
2018-10-19 17:36:35 -04:00
{
FString NewPrefix = FString : : Printf ( TEXT ( " %s%s_ " ) , MemberPrefix , Member . GetName ( ) ) ;
Bind (
* Member . GetStructMetadata ( ) ,
2019-06-11 18:27:07 -04:00
/* MemberPrefix = */ * NewPrefix ,
Merging //UE4/Dev-Rendering-Graph@4492585 to Dev-Rendering (//UE4/Dev-Rendering)
This implements the framework to write the high level rendering code into passes organized in direct acyclic graph. It is also unifying the uniform buffer, shader parameters, and pass parameters to same single API: structures with run time meta data. This allow high level user code be extremely seamless, user code debugging, and render graph ease of implementation and debugging.
Issue of collaborative work of Arne Schnober, Brian Karis, Daniel Wright, Marcus Wassmer and Guillaume Abadie.
Names of the graph managed resources are not final.
#rb Arne.Schnober, Brian.Karis, Daniel.Wright, Marcus.Wassmer
[CL 4492694 by Guillaume Abadie in Dev-Rendering branch]
2018-10-19 17:36:35 -04:00
/* GeneralByteOffset = */ ByteOffset ) ;
continue ;
}
2020-09-24 00:43:27 -04:00
else if ( BaseType = = UBMT_REFERENCED_STRUCT | | BaseType = = UBMT_RDG_UNIFORM_BUFFER )
Merging //UE4/Dev-Rendering-Graph@4492585 to Dev-Rendering (//UE4/Dev-Rendering)
This implements the framework to write the high level rendering code into passes organized in direct acyclic graph. It is also unifying the uniform buffer, shader parameters, and pass parameters to same single API: structures with run time meta data. This allow high level user code be extremely seamless, user code debugging, and render graph ease of implementation and debugging.
Issue of collaborative work of Arne Schnober, Brian Karis, Daniel Wright, Marcus Wassmer and Guillaume Abadie.
Names of the graph managed resources are not final.
#rb Arne.Schnober, Brian.Karis, Daniel.Wright, Marcus.Wassmer
[CL 4492694 by Guillaume Abadie in Dev-Rendering branch]
2018-10-19 17:36:35 -04:00
{
2020-09-24 00:43:27 -04:00
checkf ( ! bIsArray , TEXT ( " Array of referenced structure is not supported, because the structure is globally uniquely named. " ) ) ;
Merging //UE4/Dev-Rendering-Graph@4492585 to Dev-Rendering (//UE4/Dev-Rendering)
This implements the framework to write the high level rendering code into passes organized in direct acyclic graph. It is also unifying the uniform buffer, shader parameters, and pass parameters to same single API: structures with run time meta data. This allow high level user code be extremely seamless, user code debugging, and render graph ease of implementation and debugging.
Issue of collaborative work of Arne Schnober, Brian Karis, Daniel Wright, Marcus Wassmer and Guillaume Abadie.
Names of the graph managed resources are not final.
#rb Arne.Schnober, Brian.Karis, Daniel.Wright, Marcus.Wassmer
[CL 4492694 by Guillaume Abadie in Dev-Rendering branch]
2018-10-19 17:36:35 -04:00
// The member name of a globally referenced struct is the not name on the struct.
ShaderBindingName = Member . GetStructMetadata ( ) - > GetShaderVariableName ( ) ;
}
2019-03-07 11:25:32 -05:00
else if ( bUseRootShaderParameters & & bIsVariableNativeType )
2018-11-21 18:45:02 -05:00
{
// Constants are stored in the root shader parameter cbuffer when bUseRootShaderParameters == true.
continue ;
}
Merging //UE4/Dev-Rendering-Graph@4492585 to Dev-Rendering (//UE4/Dev-Rendering)
This implements the framework to write the high level rendering code into passes organized in direct acyclic graph. It is also unifying the uniform buffer, shader parameters, and pass parameters to same single API: structures with run time meta data. This allow high level user code be extremely seamless, user code debugging, and render graph ease of implementation and debugging.
Issue of collaborative work of Arne Schnober, Brian Karis, Daniel Wright, Marcus Wassmer and Guillaume Abadie.
Names of the graph managed resources are not final.
#rb Arne.Schnober, Brian.Karis, Daniel.Wright, Marcus.Wassmer
[CL 4492694 by Guillaume Abadie in Dev-Rendering branch]
2018-10-19 17:36:35 -04:00
2019-03-07 11:25:32 -05:00
const bool bIsResourceArray = bIsArray & & ( bIsRHIResource | | bIsRDGResource ) ;
for ( uint32 ArrayElementId = 0 ; ArrayElementId < ( bIsResourceArray ? ArraySize : 1u ) ; ArrayElementId + + )
Merging //UE4/Dev-Rendering-Graph@4492585 to Dev-Rendering (//UE4/Dev-Rendering)
This implements the framework to write the high level rendering code into passes organized in direct acyclic graph. It is also unifying the uniform buffer, shader parameters, and pass parameters to same single API: structures with run time meta data. This allow high level user code be extremely seamless, user code debugging, and render graph ease of implementation and debugging.
Issue of collaborative work of Arne Schnober, Brian Karis, Daniel Wright, Marcus Wassmer and Guillaume Abadie.
Names of the graph managed resources are not final.
#rb Arne.Schnober, Brian.Karis, Daniel.Wright, Marcus.Wassmer
[CL 4492694 by Guillaume Abadie in Dev-Rendering branch]
2018-10-19 17:36:35 -04:00
{
2019-03-07 11:25:32 -05:00
FString ElementShaderBindingName ;
if ( bIsResourceArray )
Merging //UE4/Dev-Rendering-Graph@4492585 to Dev-Rendering (//UE4/Dev-Rendering)
This implements the framework to write the high level rendering code into passes organized in direct acyclic graph. It is also unifying the uniform buffer, shader parameters, and pass parameters to same single API: structures with run time meta data. This allow high level user code be extremely seamless, user code debugging, and render graph ease of implementation and debugging.
Issue of collaborative work of Arne Schnober, Brian Karis, Daniel Wright, Marcus Wassmer and Guillaume Abadie.
Names of the graph managed resources are not final.
#rb Arne.Schnober, Brian.Karis, Daniel.Wright, Marcus.Wassmer
[CL 4492694 by Guillaume Abadie in Dev-Rendering branch]
2018-10-19 17:36:35 -04:00
{
2019-03-07 11:25:32 -05:00
if ( 0 ) // HLSLCC does not support array of resources.
ElementShaderBindingName = FString : : Printf ( TEXT ( " %s[%d] " ) , * ShaderBindingName , ArrayElementId ) ;
else
ElementShaderBindingName = FString : : Printf ( TEXT ( " %s_%d " ) , * ShaderBindingName , ArrayElementId ) ;
}
else
{
ElementShaderBindingName = ShaderBindingName ;
Merging //UE4/Dev-Rendering-Graph@4492585 to Dev-Rendering (//UE4/Dev-Rendering)
This implements the framework to write the high level rendering code into passes organized in direct acyclic graph. It is also unifying the uniform buffer, shader parameters, and pass parameters to same single API: structures with run time meta data. This allow high level user code be extremely seamless, user code debugging, and render graph ease of implementation and debugging.
Issue of collaborative work of Arne Schnober, Brian Karis, Daniel Wright, Marcus Wassmer and Guillaume Abadie.
Names of the graph managed resources are not final.
#rb Arne.Schnober, Brian.Karis, Daniel.Wright, Marcus.Wassmer
[CL 4492694 by Guillaume Abadie in Dev-Rendering branch]
2018-10-19 17:36:35 -04:00
}
2019-03-07 11:25:32 -05:00
if ( ShaderGlobalScopeBindings . Contains ( ElementShaderBindingName ) )
{
UE_LOG ( LogShaders , Fatal , TEXT ( " %s can't bind shader parameter %s, because it has already be bound by %s. " ) , * CppName , * ElementShaderBindingName , * * ShaderGlobalScopeBindings . Find ( ShaderBindingName ) ) ;
}
Merging //UE4/Dev-Rendering-Graph@4492585 to Dev-Rendering (//UE4/Dev-Rendering)
This implements the framework to write the high level rendering code into passes organized in direct acyclic graph. It is also unifying the uniform buffer, shader parameters, and pass parameters to same single API: structures with run time meta data. This allow high level user code be extremely seamless, user code debugging, and render graph ease of implementation and debugging.
Issue of collaborative work of Arne Schnober, Brian Karis, Daniel Wright, Marcus Wassmer and Guillaume Abadie.
Names of the graph managed resources are not final.
#rb Arne.Schnober, Brian.Karis, Daniel.Wright, Marcus.Wassmer
[CL 4492694 by Guillaume Abadie in Dev-Rendering branch]
2018-10-19 17:36:35 -04:00
2022-04-20 10:43:15 -04:00
TOptional < FParameterAllocation > ParameterAllocation = ParametersMap - > FindParameterAllocation ( ElementShaderBindingName ) ;
if ( ! ParameterAllocation . IsSet ( ) )
2019-03-07 11:25:32 -05:00
{
continue ;
}
2022-04-20 10:43:15 -04:00
2019-03-07 11:25:32 -05:00
ShaderGlobalScopeBindings . Add ( ElementShaderBindingName , CppName ) ;
Merging //UE4/Dev-Rendering-Graph@4492585 to Dev-Rendering (//UE4/Dev-Rendering)
This implements the framework to write the high level rendering code into passes organized in direct acyclic graph. It is also unifying the uniform buffer, shader parameters, and pass parameters to same single API: structures with run time meta data. This allow high level user code be extremely seamless, user code debugging, and render graph ease of implementation and debugging.
Issue of collaborative work of Arne Schnober, Brian Karis, Daniel Wright, Marcus Wassmer and Guillaume Abadie.
Names of the graph managed resources are not final.
#rb Arne.Schnober, Brian.Karis, Daniel.Wright, Marcus.Wassmer
[CL 4492694 by Guillaume Abadie in Dev-Rendering branch]
2018-10-19 17:36:35 -04:00
2019-03-07 11:25:32 -05:00
if ( bIsVariableNativeType )
{
checkf ( ArrayElementId = = 0 , TEXT ( " The entire array should be bound instead for RHI parameter submission performance. " ) ) ;
uint32 ByteSize = Member . GetMemberSize ( ) ;
Merging //UE4/Dev-Rendering-Graph@4492585 to Dev-Rendering (//UE4/Dev-Rendering)
This implements the framework to write the high level rendering code into passes organized in direct acyclic graph. It is also unifying the uniform buffer, shader parameters, and pass parameters to same single API: structures with run time meta data. This allow high level user code be extremely seamless, user code debugging, and render graph ease of implementation and debugging.
Issue of collaborative work of Arne Schnober, Brian Karis, Daniel Wright, Marcus Wassmer and Guillaume Abadie.
Names of the graph managed resources are not final.
#rb Arne.Schnober, Brian.Karis, Daniel.Wright, Marcus.Wassmer
[CL 4492694 by Guillaume Abadie in Dev-Rendering branch]
2018-10-19 17:36:35 -04:00
2019-03-07 11:25:32 -05:00
FShaderParameterBindings : : FParameter Parameter ;
2022-04-20 10:43:15 -04:00
Parameter . BufferIndex = ParameterAllocation - > BufferIndex ;
Parameter . BaseIndex = ParameterAllocation - > BaseIndex ;
2019-03-07 11:25:32 -05:00
Parameter . ByteOffset = ByteOffset ;
2022-04-20 10:43:15 -04:00
Parameter . ByteSize = ParameterAllocation - > Size ;
2019-03-07 11:25:32 -05:00
2022-04-20 10:43:15 -04:00
if ( uint32 ( ParameterAllocation - > Size ) > ByteSize )
2019-03-07 11:25:32 -05:00
{
UE_LOG ( LogShaders , Fatal , TEXT ( " The size required to bind shader %s's (Permutation Id %d) struct %s parameter %s is %i bytes, smaller than %s's %i bytes. " ) ,
2020-04-06 21:12:18 -04:00
Shader - > GetTypeUnfrozen ( ) - > GetName ( ) , PermutationId , StructMetaData . GetStructTypeName ( ) ,
2022-04-20 10:43:15 -04:00
* ElementShaderBindingName , ParameterAllocation - > Size , * CppName , ByteSize ) ;
2019-03-07 11:25:32 -05:00
}
Bindings - > Parameters . Add ( Parameter ) ;
}
2020-09-24 00:43:27 -04:00
else if ( BaseType = = UBMT_REFERENCED_STRUCT | | BaseType = = UBMT_RDG_UNIFORM_BUFFER )
2019-03-07 11:25:32 -05:00
{
check ( ! bIsArray ) ;
FShaderParameterBindings : : FParameterStructReference Parameter ;
2022-04-20 10:43:15 -04:00
Parameter . BufferIndex = ParameterAllocation - > BufferIndex ;
2019-03-07 11:25:32 -05:00
Parameter . ByteOffset = ByteOffset ;
2020-09-24 00:43:27 -04:00
if ( BaseType = = UBMT_REFERENCED_STRUCT )
{
Bindings - > ParameterReferences . Add ( Parameter ) ;
}
else
{
Bindings - > GraphUniformBuffers . Add ( Parameter ) ;
}
2019-03-07 11:25:32 -05:00
}
else if ( bIsRHIResource | | bIsRDGResource )
{
2023-10-20 23:12:44 -04:00
if ( IsParameterBindless ( ParameterAllocation - > Type ) )
2019-09-25 14:06:50 -04:00
{
2022-05-17 16:30:48 -04:00
FShaderParameterBindings : : FBindlessResourceParameter Parameter ;
Parameter . GlobalConstantOffset = ParameterAllocation - > BaseIndex ;
Parameter . ByteOffset = ByteOffset + ArrayElementId * SHADER_PARAMETER_POINTER_ALIGNMENT ;
Parameter . BaseType = BaseType ;
2019-03-07 11:25:32 -05:00
2022-05-17 16:30:48 -04:00
Bindings - > BindlessResourceParameters . Add ( Parameter ) ;
}
else
{
checkf ( ParameterAllocation - > BaseIndex < 256 , TEXT ( " BaseIndex does not fit into uint8. Change FResourceParameter::BaseIndex type to uint16 " ) ) ;
FShaderParameterBindings : : FResourceParameter Parameter ;
Parameter . BaseIndex = ( uint8 ) ParameterAllocation - > BaseIndex ;
Parameter . ByteOffset = ByteOffset + ArrayElementId * SHADER_PARAMETER_POINTER_ALIGNMENT ;
Parameter . BaseType = BaseType ;
if ( ParameterAllocation - > Size ! = 1 )
{
UE_LOG ( LogShaders , Fatal ,
TEXT ( " Error with shader %s's (Permutation Id %d) parameter %s is %i bytes, cpp name = %s. " )
TEXT ( " The shader compiler should give precisely which elements of an array did not get compiled out, " )
TEXT ( " for optimal automatic render graph pass dependency with ClearUnusedGraphResources(). " ) ,
Shader - > GetTypeUnfrozen ( ) - > GetName ( ) , PermutationId ,
* ElementShaderBindingName , ParameterAllocation - > Size , * CppName ) ;
}
Bindings - > ResourceParameters . Add ( Parameter ) ;
}
2019-03-07 11:25:32 -05:00
}
else
{
checkf ( 0 , TEXT ( " Unexpected base type for a shader parameter struct member. " ) ) ;
}
2020-09-24 00:43:27 -04:00
}
}
}
} ;
Merging //UE4/Dev-Rendering-Graph@4492585 to Dev-Rendering (//UE4/Dev-Rendering)
This implements the framework to write the high level rendering code into passes organized in direct acyclic graph. It is also unifying the uniform buffer, shader parameters, and pass parameters to same single API: structures with run time meta data. This allow high level user code be extremely seamless, user code debugging, and render graph ease of implementation and debugging.
Issue of collaborative work of Arne Schnober, Brian Karis, Daniel Wright, Marcus Wassmer and Guillaume Abadie.
Names of the graph managed resources are not final.
#rb Arne.Schnober, Brian.Karis, Daniel.Wright, Marcus.Wassmer
[CL 4492694 by Guillaume Abadie in Dev-Rendering branch]
2018-10-19 17:36:35 -04:00
2020-04-06 21:12:18 -04:00
void FShaderParameterBindings : : BindForLegacyShaderParameters ( const FShader * Shader , int32 PermutationId , const FShaderParameterMap & ParametersMap , const FShaderParametersMetadata & StructMetaData , bool bShouldBindEverything )
Merging //UE4/Dev-Rendering-Graph@4492585 to Dev-Rendering (//UE4/Dev-Rendering)
This implements the framework to write the high level rendering code into passes organized in direct acyclic graph. It is also unifying the uniform buffer, shader parameters, and pass parameters to same single API: structures with run time meta data. This allow high level user code be extremely seamless, user code debugging, and render graph ease of implementation and debugging.
Issue of collaborative work of Arne Schnober, Brian Karis, Daniel Wright, Marcus Wassmer and Guillaume Abadie.
Names of the graph managed resources are not final.
#rb Arne.Schnober, Brian.Karis, Daniel.Wright, Marcus.Wassmer
[CL 4492694 by Guillaume Abadie in Dev-Rendering branch]
2018-10-19 17:36:35 -04:00
{
2020-02-06 13:13:41 -05:00
const FShaderType * Type = Shader - > GetTypeUnfrozen ( ) ;
Merging //UE4/Dev-Rendering-Graph@4492585 to Dev-Rendering (//UE4/Dev-Rendering)
This implements the framework to write the high level rendering code into passes organized in direct acyclic graph. It is also unifying the uniform buffer, shader parameters, and pass parameters to same single API: structures with run time meta data. This allow high level user code be extremely seamless, user code debugging, and render graph ease of implementation and debugging.
Issue of collaborative work of Arne Schnober, Brian Karis, Daniel Wright, Marcus Wassmer and Guillaume Abadie.
Names of the graph managed resources are not final.
#rb Arne.Schnober, Brian.Karis, Daniel.Wright, Marcus.Wassmer
[CL 4492694 by Guillaume Abadie in Dev-Rendering branch]
2018-10-19 17:36:35 -04:00
checkf ( StructMetaData . GetSize ( ) < ( 1 < < ( sizeof ( uint16 ) * 8 ) ) , TEXT ( " Shader parameter structure can only have a size < 65536 bytes. " ) ) ;
2018-11-23 15:47:24 -05:00
check ( this = = & Shader - > Bindings ) ;
2019-06-11 18:27:07 -04:00
2020-02-06 13:13:41 -05:00
switch ( Type - > GetFrequency ( ) )
2019-06-11 18:27:07 -04:00
{
2021-08-09 16:36:09 -04:00
# if PLATFORM_SUPPORTS_MESH_SHADERS
case SF_Mesh :
case SF_Amplification :
# endif
2019-06-11 18:27:07 -04:00
case SF_Vertex :
case SF_Pixel :
case SF_Geometry :
case SF_Compute :
2024-05-23 10:28:09 -04:00
case SF_WorkGraphComputeNode :
2019-06-11 18:27:07 -04:00
break ;
default :
checkf ( 0 , TEXT ( " Invalid shader frequency for this shader binding technique. " ) ) ;
break ;
}
Merging //UE4/Dev-Rendering-Graph@4492585 to Dev-Rendering (//UE4/Dev-Rendering)
This implements the framework to write the high level rendering code into passes organized in direct acyclic graph. It is also unifying the uniform buffer, shader parameters, and pass parameters to same single API: structures with run time meta data. This allow high level user code be extremely seamless, user code debugging, and render graph ease of implementation and debugging.
Issue of collaborative work of Arne Schnober, Brian Karis, Daniel Wright, Marcus Wassmer and Guillaume Abadie.
Names of the graph managed resources are not final.
#rb Arne.Schnober, Brian.Karis, Daniel.Wright, Marcus.Wassmer
[CL 4492694 by Guillaume Abadie in Dev-Rendering branch]
2018-10-19 17:36:35 -04:00
FShaderParameterStructBindingContext BindingContext ;
2018-11-23 15:47:24 -05:00
BindingContext . Shader = Shader ;
2020-04-06 21:12:18 -04:00
BindingContext . PermutationId = PermutationId ;
Merging //UE4/Dev-Rendering-Graph@4492585 to Dev-Rendering (//UE4/Dev-Rendering)
This implements the framework to write the high level rendering code into passes organized in direct acyclic graph. It is also unifying the uniform buffer, shader parameters, and pass parameters to same single API: structures with run time meta data. This allow high level user code be extremely seamless, user code debugging, and render graph ease of implementation and debugging.
Issue of collaborative work of Arne Schnober, Brian Karis, Daniel Wright, Marcus Wassmer and Guillaume Abadie.
Names of the graph managed resources are not final.
#rb Arne.Schnober, Brian.Karis, Daniel.Wright, Marcus.Wassmer
[CL 4492694 by Guillaume Abadie in Dev-Rendering branch]
2018-10-19 17:36:35 -04:00
BindingContext . Bindings = this ;
BindingContext . ParametersMap = & ParametersMap ;
2021-08-18 16:55:41 -04:00
// When using a stable root constant buffer, can submit all shader parameters in one RHISetShaderParameter()
{
const TCHAR * ShaderBindingName = FShaderParametersMetadata : : kRootUniformBufferBindingName ;
BindingContext . bUseRootShaderParameters = ParametersMap . ContainsParameterAllocation ( ShaderBindingName ) ;
if ( BindingContext . bUseRootShaderParameters )
{
const FParameterAllocation & Allocation = ParametersMap . ParameterMap . FindChecked ( ShaderBindingName ) ;
check ( int32 ( Allocation . BufferIndex ) = = FShaderParametersMetadata : : kRootCBufferBindingIndex ) ;
check ( uint32 ( Allocation . BaseIndex + Allocation . Size ) < = StructMetaData . GetSize ( ) ) ;
check ( Allocation . Type = = EShaderParameterType : : LooseData ) ;
FShaderParameterBindings : : FParameter Parameter ;
Parameter . BufferIndex = Allocation . BufferIndex ;
Parameter . BaseIndex = Allocation . BaseIndex ;
Parameter . ByteOffset = Allocation . BaseIndex ;
Parameter . ByteSize = Allocation . Size ;
Parameters . Add ( Parameter ) ;
BindingContext . ShaderGlobalScopeBindings . Add ( ShaderBindingName , StructMetaData . GetStructTypeName ( ) ) ;
Allocation . bBound = true ;
}
}
Merging //UE4/Dev-Rendering-Graph@4492585 to Dev-Rendering (//UE4/Dev-Rendering)
This implements the framework to write the high level rendering code into passes organized in direct acyclic graph. It is also unifying the uniform buffer, shader parameters, and pass parameters to same single API: structures with run time meta data. This allow high level user code be extremely seamless, user code debugging, and render graph ease of implementation and debugging.
Issue of collaborative work of Arne Schnober, Brian Karis, Daniel Wright, Marcus Wassmer and Guillaume Abadie.
Names of the graph managed resources are not final.
#rb Arne.Schnober, Brian.Karis, Daniel.Wright, Marcus.Wassmer
[CL 4492694 by Guillaume Abadie in Dev-Rendering branch]
2018-10-19 17:36:35 -04:00
BindingContext . Bind (
StructMetaData ,
/* MemberPrefix = */ TEXT ( " " ) ,
/* ByteOffset = */ 0 ) ;
2019-11-14 19:25:20 -05:00
StructureLayoutHash = StructMetaData . GetLayoutHash ( ) ;
2018-11-21 18:45:02 -05:00
RootParameterBufferIndex = kInvalidBufferIndex ;
Merging //UE4/Dev-Rendering-Graph@4492585 to Dev-Rendering (//UE4/Dev-Rendering)
This implements the framework to write the high level rendering code into passes organized in direct acyclic graph. It is also unifying the uniform buffer, shader parameters, and pass parameters to same single API: structures with run time meta data. This allow high level user code be extremely seamless, user code debugging, and render graph ease of implementation and debugging.
Issue of collaborative work of Arne Schnober, Brian Karis, Daniel Wright, Marcus Wassmer and Guillaume Abadie.
Names of the graph managed resources are not final.
#rb Arne.Schnober, Brian.Karis, Daniel.Wright, Marcus.Wassmer
[CL 4492694 by Guillaume Abadie in Dev-Rendering branch]
2018-10-19 17:36:35 -04:00
TArray < FString > AllParameterNames ;
ParametersMap . GetAllParameterNames ( AllParameterNames ) ;
2018-11-21 20:49:28 -05:00
if ( bShouldBindEverything & & BindingContext . ShaderGlobalScopeBindings . Num ( ) ! = AllParameterNames . Num ( ) )
Merging //UE4/Dev-Rendering-Graph@4492585 to Dev-Rendering (//UE4/Dev-Rendering)
This implements the framework to write the high level rendering code into passes organized in direct acyclic graph. It is also unifying the uniform buffer, shader parameters, and pass parameters to same single API: structures with run time meta data. This allow high level user code be extremely seamless, user code debugging, and render graph ease of implementation and debugging.
Issue of collaborative work of Arne Schnober, Brian Karis, Daniel Wright, Marcus Wassmer and Guillaume Abadie.
Names of the graph managed resources are not final.
#rb Arne.Schnober, Brian.Karis, Daniel.Wright, Marcus.Wassmer
[CL 4492694 by Guillaume Abadie in Dev-Rendering branch]
2018-10-19 17:36:35 -04:00
{
2019-06-11 18:27:07 -04:00
FString ErrorString = FString : : Printf (
2020-06-23 18:40:00 -04:00
TEXT ( " Shader %s, permutation %d has unbound parameters not represented in the parameter struct: " ) , Type - > GetName ( ) , PermutationId ) ;
2018-11-23 15:47:24 -05:00
2018-11-21 18:45:02 -05:00
for ( const FString & GlobalParameterName : AllParameterNames )
{
if ( ! BindingContext . ShaderGlobalScopeBindings . Contains ( GlobalParameterName ) )
{
2019-06-11 18:27:07 -04:00
ErrorString + = FString : : Printf ( TEXT ( " \n %s " ) , * GlobalParameterName ) ;
2018-11-21 18:45:02 -05:00
}
}
2020-09-24 19:46:43 -04:00
ensureMsgf ( false , TEXT ( " %s " ) , * ErrorString ) ;
2018-11-21 18:45:02 -05:00
}
}
2020-04-06 21:12:18 -04:00
void FShaderParameterBindings : : BindForRootShaderParameters ( const FShader * Shader , int32 PermutationId , const FShaderParameterMap & ParametersMap )
2018-11-21 18:45:02 -05:00
{
2020-02-06 13:13:41 -05:00
const FShaderType * Type = Shader - > GetTypeUnfrozen ( ) ;
2018-11-23 15:47:24 -05:00
check ( this = = & Shader - > Bindings ) ;
2020-02-06 13:13:41 -05:00
check ( Type - > GetRootParametersMetadata ( ) ) ;
2018-11-23 15:47:24 -05:00
2020-02-06 13:13:41 -05:00
const FShaderParametersMetadata & StructMetaData = * Type - > GetRootParametersMetadata ( ) ;
2018-11-21 18:45:02 -05:00
checkf ( StructMetaData . GetSize ( ) < ( 1 < < ( sizeof ( uint16 ) * 8 ) ) , TEXT ( " Shader parameter structure can only have a size < 65536 bytes. " ) ) ;
2020-02-06 13:13:41 -05:00
switch ( Type - > GetFrequency ( ) )
2019-06-11 18:27:07 -04:00
{
case SF_RayGen :
case SF_RayMiss :
case SF_RayHitGroup :
case SF_RayCallable :
break ;
default :
checkf ( 0 , TEXT ( " Invalid shader frequency for this shader binding technic. " ) ) ;
break ;
}
2018-11-21 18:45:02 -05:00
FShaderParameterStructBindingContext BindingContext ;
2018-11-23 15:47:24 -05:00
BindingContext . Shader = Shader ;
2020-04-06 21:12:18 -04:00
BindingContext . PermutationId = PermutationId ;
2018-11-21 18:45:02 -05:00
BindingContext . Bindings = this ;
BindingContext . ParametersMap = & ParametersMap ;
BindingContext . bUseRootShaderParameters = true ;
BindingContext . Bind (
StructMetaData ,
/* MemberPrefix = */ TEXT ( " " ) ,
/* ByteOffset = */ 0 ) ;
2019-11-14 19:25:20 -05:00
StructureLayoutHash = StructMetaData . GetLayoutHash ( ) ;
2018-11-21 18:45:02 -05:00
// Binds the uniform buffer that contains the root shader parameters.
{
const TCHAR * ShaderBindingName = FShaderParametersMetadata : : kRootUniformBufferBindingName ;
2024-06-03 10:21:45 -04:00
if ( TOptional < FParameterAllocation > Parameter = ParametersMap . FindParameterAllocation ( ShaderBindingName ) )
2018-11-21 18:45:02 -05:00
{
BindingContext . ShaderGlobalScopeBindings . Add ( ShaderBindingName , ShaderBindingName ) ;
2024-06-03 10:21:45 -04:00
RootParameterBufferIndex = Parameter - > BufferIndex ;
2018-11-21 18:45:02 -05:00
}
2018-11-21 18:50:51 -05:00
else
{
check ( RootParameterBufferIndex = = FShaderParameterBindings : : kInvalidBufferIndex ) ;
}
2018-11-21 18:45:02 -05:00
}
TArray < FString > AllParameterNames ;
ParametersMap . GetAllParameterNames ( AllParameterNames ) ;
if ( BindingContext . ShaderGlobalScopeBindings . Num ( ) ! = AllParameterNames . Num ( ) )
{
2019-06-11 18:27:07 -04:00
FString ErrorString = FString : : Printf (
2020-06-23 18:40:00 -04:00
TEXT ( " Shader %s, permutation %d has unbound parameters not represented in the parameter struct: " ) ,
Type - > GetName ( ) , PermutationId ) ;
2018-11-23 15:47:24 -05:00
Merging //UE4/Dev-Rendering-Graph@4492585 to Dev-Rendering (//UE4/Dev-Rendering)
This implements the framework to write the high level rendering code into passes organized in direct acyclic graph. It is also unifying the uniform buffer, shader parameters, and pass parameters to same single API: structures with run time meta data. This allow high level user code be extremely seamless, user code debugging, and render graph ease of implementation and debugging.
Issue of collaborative work of Arne Schnober, Brian Karis, Daniel Wright, Marcus Wassmer and Guillaume Abadie.
Names of the graph managed resources are not final.
#rb Arne.Schnober, Brian.Karis, Daniel.Wright, Marcus.Wassmer
[CL 4492694 by Guillaume Abadie in Dev-Rendering branch]
2018-10-19 17:36:35 -04:00
for ( const FString & GlobalParameterName : AllParameterNames )
{
if ( ! BindingContext . ShaderGlobalScopeBindings . Contains ( GlobalParameterName ) )
{
2019-06-11 18:27:07 -04:00
ErrorString + = FString : : Printf ( TEXT ( " \n %s " ) , * GlobalParameterName ) ;
Merging //UE4/Dev-Rendering-Graph@4492585 to Dev-Rendering (//UE4/Dev-Rendering)
This implements the framework to write the high level rendering code into passes organized in direct acyclic graph. It is also unifying the uniform buffer, shader parameters, and pass parameters to same single API: structures with run time meta data. This allow high level user code be extremely seamless, user code debugging, and render graph ease of implementation and debugging.
Issue of collaborative work of Arne Schnober, Brian Karis, Daniel Wright, Marcus Wassmer and Guillaume Abadie.
Names of the graph managed resources are not final.
#rb Arne.Schnober, Brian.Karis, Daniel.Wright, Marcus.Wassmer
[CL 4492694 by Guillaume Abadie in Dev-Rendering branch]
2018-10-19 17:36:35 -04:00
}
}
2019-06-11 18:27:07 -04:00
UE_LOG ( LogShaders , Fatal , TEXT ( " %s " ) , * ErrorString ) ;
Merging //UE4/Dev-Rendering-Graph@4492585 to Dev-Rendering (//UE4/Dev-Rendering)
This implements the framework to write the high level rendering code into passes organized in direct acyclic graph. It is also unifying the uniform buffer, shader parameters, and pass parameters to same single API: structures with run time meta data. This allow high level user code be extremely seamless, user code debugging, and render graph ease of implementation and debugging.
Issue of collaborative work of Arne Schnober, Brian Karis, Daniel Wright, Marcus Wassmer and Guillaume Abadie.
Names of the graph managed resources are not final.
#rb Arne.Schnober, Brian.Karis, Daniel.Wright, Marcus.Wassmer
[CL 4492694 by Guillaume Abadie in Dev-Rendering branch]
2018-10-19 17:36:35 -04:00
}
}
2019-06-11 18:27:07 -04:00
bool FRenderTargetBinding : : Validate ( ) const
{
2019-09-14 09:45:25 -04:00
if ( ! Texture )
2019-06-11 18:27:07 -04:00
{
2019-09-14 09:45:25 -04:00
checkf ( LoadAction = = ERenderTargetLoadAction : : ENoAction ,
TEXT ( " Can't have a load action when no texture is bound. " ) ) ;
2020-09-24 00:43:27 -04:00
checkf ( ! ResolveTexture , TEXT ( " Can't have a resolve texture when no render target texture is bound. " ) ) ;
2019-06-11 18:27:07 -04:00
}
return true ;
}
bool FDepthStencilBinding : : Validate ( ) const
{
if ( Texture )
{
EPixelFormat PixelFormat = Texture - > Desc . Format ;
const TCHAR * FormatString = GetPixelFormatString ( PixelFormat ) ;
2021-05-14 11:17:41 -04:00
bool bIsDepthFormat = PixelFormat = = PF_DepthStencil | | PixelFormat = = PF_ShadowDepth | | PixelFormat = = PF_D24 | | PixelFormat = = PF_R32_FLOAT ;
2019-06-11 18:27:07 -04:00
checkf ( bIsDepthFormat ,
TEXT ( " Can't bind texture %s as a depth stencil because its pixel format is %s. " ) ,
Texture - > Name , FormatString ) ;
checkf ( DepthStencilAccess ! = FExclusiveDepthStencil : : DepthNop_StencilNop ,
2020-09-24 00:43:27 -04:00
TEXT ( " Texture %s is bound but both depth / stencil are set to no-op. " ) ,
2019-06-11 18:27:07 -04:00
Texture - > Name ) ;
bool bHasStencil = PixelFormat = = PF_DepthStencil ;
if ( ! bHasStencil )
{
2019-09-14 09:45:25 -04:00
checkf ( StencilLoadAction = = ERenderTargetLoadAction : : ENoAction ,
2019-06-11 18:27:07 -04:00
TEXT ( " Unable to load stencil of texture %s that have a pixel format %s that does not support stencil. " ) ,
Texture - > Name , FormatString ) ;
checkf ( ! DepthStencilAccess . IsUsingStencil ( ) ,
TEXT ( " Unable to have stencil access on texture %s that have a pixel format %s that does not support stencil. " ) ,
Texture - > Name , FormatString ) ;
}
2019-09-14 09:45:25 -04:00
bool bReadDepth = DepthStencilAccess . IsUsingDepth ( ) & & ! DepthStencilAccess . IsDepthWrite ( ) ;
bool bReadStencil = DepthStencilAccess . IsUsingStencil ( ) & & ! DepthStencilAccess . IsStencilWrite ( ) ;
checkf ( ! ( bReadDepth & & DepthLoadAction ! = ERenderTargetLoadAction : : ELoad ) ,
2020-09-24 00:43:27 -04:00
TEXT ( " Depth read access without depth load action on texture %s. " ) ,
2019-09-14 09:45:25 -04:00
Texture - > Name ) ;
checkf ( ! ( bReadStencil & & StencilLoadAction ! = ERenderTargetLoadAction : : ELoad ) ,
2020-09-24 00:43:27 -04:00
TEXT ( " Stencil read access without stencil load action on texture %s. " ) ,
2019-09-14 09:45:25 -04:00
Texture - > Name ) ;
2019-06-11 18:27:07 -04:00
}
else
{
2024-04-24 06:43:38 -04:00
checkf ( ! ResolveTexture ,
TEXT ( " Can't have a depth stencil resolve texture when no depth stencil target texture is bound. " ) ) ;
2019-09-14 09:45:25 -04:00
checkf ( DepthLoadAction = = ERenderTargetLoadAction : : ENoAction ,
2020-09-24 00:43:27 -04:00
TEXT ( " Can't have a depth load action when no texture is bound. " ) ) ;
2019-09-14 09:45:25 -04:00
checkf ( StencilLoadAction = = ERenderTargetLoadAction : : ENoAction ,
2020-09-24 00:43:27 -04:00
TEXT ( " Can't have a stencil load action when no texture is bound. " ) ) ;
2019-06-11 18:27:07 -04:00
checkf ( DepthStencilAccess = = FExclusiveDepthStencil : : DepthNop_StencilNop ,
2020-09-24 00:43:27 -04:00
TEXT ( " Can't have a depth stencil access when no texture is bound. " ) ) ;
2019-06-11 18:27:07 -04:00
}
return true ;
}
2020-02-06 13:13:41 -05:00
void EmitNullShaderParameterFatalError ( const TShaderRef < FShader > & Shader , const FShaderParametersMetadata * ParametersMetadata , uint16 MemberOffset )
Merging //UE4/Dev-Rendering-Graph@4492585 to Dev-Rendering (//UE4/Dev-Rendering)
This implements the framework to write the high level rendering code into passes organized in direct acyclic graph. It is also unifying the uniform buffer, shader parameters, and pass parameters to same single API: structures with run time meta data. This allow high level user code be extremely seamless, user code debugging, and render graph ease of implementation and debugging.
Issue of collaborative work of Arne Schnober, Brian Karis, Daniel Wright, Marcus Wassmer and Guillaume Abadie.
Names of the graph managed resources are not final.
#rb Arne.Schnober, Brian.Karis, Daniel.Wright, Marcus.Wassmer
[CL 4492694 by Guillaume Abadie in Dev-Rendering branch]
2018-10-19 17:36:35 -04:00
{
2019-10-01 13:03:04 -04:00
FString MemberName = ParametersMetadata - > GetFullMemberCodeName ( MemberOffset ) ;
Merging //UE4/Dev-Rendering-Graph@4492585 to Dev-Rendering (//UE4/Dev-Rendering)
This implements the framework to write the high level rendering code into passes organized in direct acyclic graph. It is also unifying the uniform buffer, shader parameters, and pass parameters to same single API: structures with run time meta data. This allow high level user code be extremely seamless, user code debugging, and render graph ease of implementation and debugging.
Issue of collaborative work of Arne Schnober, Brian Karis, Daniel Wright, Marcus Wassmer and Guillaume Abadie.
Names of the graph managed resources are not final.
#rb Arne.Schnober, Brian.Karis, Daniel.Wright, Marcus.Wassmer
[CL 4492694 by Guillaume Abadie in Dev-Rendering branch]
2018-10-19 17:36:35 -04:00
2020-02-06 13:13:41 -05:00
const TCHAR * ShaderClassName = Shader . GetType ( ) - > GetName ( ) ;
Merging //UE4/Dev-Rendering-Graph@4492585 to Dev-Rendering (//UE4/Dev-Rendering)
This implements the framework to write the high level rendering code into passes organized in direct acyclic graph. It is also unifying the uniform buffer, shader parameters, and pass parameters to same single API: structures with run time meta data. This allow high level user code be extremely seamless, user code debugging, and render graph ease of implementation and debugging.
Issue of collaborative work of Arne Schnober, Brian Karis, Daniel Wright, Marcus Wassmer and Guillaume Abadie.
Names of the graph managed resources are not final.
#rb Arne.Schnober, Brian.Karis, Daniel.Wright, Marcus.Wassmer
[CL 4492694 by Guillaume Abadie in Dev-Rendering branch]
2018-10-19 17:36:35 -04:00
UE_LOG ( LogShaders , Fatal ,
TEXT ( " %s's required shader parameter %s::%s was not set. " ) ,
ShaderClassName ,
2019-03-07 11:25:32 -05:00
ParametersMetadata - > GetStructTypeName ( ) ,
* MemberName ) ;
Merging //UE4/Dev-Rendering-Graph@4492585 to Dev-Rendering (//UE4/Dev-Rendering)
This implements the framework to write the high level rendering code into passes organized in direct acyclic graph. It is also unifying the uniform buffer, shader parameters, and pass parameters to same single API: structures with run time meta data. This allow high level user code be extremely seamless, user code debugging, and render graph ease of implementation and debugging.
Issue of collaborative work of Arne Schnober, Brian Karis, Daniel Wright, Marcus Wassmer and Guillaume Abadie.
Names of the graph managed resources are not final.
#rb Arne.Schnober, Brian.Karis, Daniel.Wright, Marcus.Wassmer
[CL 4492694 by Guillaume Abadie in Dev-Rendering branch]
2018-10-19 17:36:35 -04:00
}
2018-11-21 20:49:28 -05:00
2022-04-20 10:43:15 -04:00
/// Utility class for reading shader parameters out of the data blob passed in.
struct FShaderParameterReader
{
FShaderParameterReader ( ) = delete ;
2022-11-04 16:00:20 -04:00
FShaderParameterReader ( const void * InData , uint64 InDataSize ) : Data ( reinterpret_cast < const uint8 * > ( InData ) ) , DataSize ( InDataSize ) { }
2022-11-15 19:41:53 -05:00
FShaderParameterReader ( TConstArrayView < uint8 > InData ) : Data ( reinterpret_cast < const uint8 * > ( InData . GetData ( ) ) ) , DataSize ( InData . Num ( ) ) { }
2022-04-20 10:43:15 -04:00
template < typename TParameterIn >
const void * GetRawPointer ( const TParameterIn & InParameter ) const
{
2022-11-04 16:00:20 -04:00
checkSlow ( InParameter . ByteOffset < = DataSize ) ;
2022-04-20 10:43:15 -04:00
return ( Data + InParameter . ByteOffset ) ;
}
template < typename TParameterOut , typename TParameterIn >
const TParameterOut & Read ( const TParameterIn & InParameter ) const
{
2022-11-04 16:00:20 -04:00
checkSlow ( InParameter . ByteOffset + sizeof ( TParameterOut ) < = DataSize ) ;
2022-04-20 10:43:15 -04:00
return * reinterpret_cast < const TParameterOut * > ( Data + InParameter . ByteOffset ) ;
}
const uint8 * Data ;
2022-11-04 16:00:20 -04:00
const uint64 DataSize ;
2022-04-20 10:43:15 -04:00
} ;
2018-11-21 20:49:28 -05:00
# if DO_CHECK
2023-09-05 10:12:00 -04:00
void ValidateShaderParameters ( const TShaderRef < FShader > & Shader , const FShaderParametersMetadata * ParametersMetadata , const void * ParametersData )
2018-11-21 20:49:28 -05:00
{
const FShaderParameterBindings & Bindings = Shader - > Bindings ;
2019-11-14 19:25:20 -05:00
checkf (
Bindings . StructureLayoutHash = = ParametersMetadata - > GetLayoutHash ( ) ,
2020-09-24 00:43:27 -04:00
TEXT ( " Shader %s's parameter structure has changed without recompilation of the shader " ) ,
2020-10-20 20:31:31 -04:00
Shader . GetType ( ) - > GetName ( ) ) ;
2019-11-14 19:25:20 -05:00
2022-11-07 16:32:05 -05:00
const FShaderParameterReader Reader ( ParametersData , ParametersMetadata - > GetSize ( ) ) ;
2018-11-21 20:49:28 -05:00
2020-02-06 13:13:41 -05:00
const TCHAR * ShaderClassName = Shader . GetType ( ) - > GetName ( ) ;
2020-06-23 18:40:00 -04:00
const TCHAR * ShaderParameterStructName = ParametersMetadata - > GetStructTypeName ( ) ;
2019-10-01 13:03:04 -04:00
2023-08-25 22:19:10 -04:00
FRHIShader * RHIShader = Shader . GetRHIShaderBase ( Shader - > GetFrequency ( ) ) ;
2022-04-20 10:43:15 -04:00
for ( const FShaderParameterBindings : : FResourceParameter & Parameter : Bindings . ResourceParameters )
2018-11-21 20:49:28 -05:00
{
2022-04-20 10:43:15 -04:00
const EUniformBufferBaseType BaseType = static_cast < EUniformBufferBaseType > ( Parameter . BaseType ) ;
2020-03-10 08:04:05 -04:00
switch ( BaseType )
2018-11-21 20:49:28 -05:00
{
2020-03-10 08:04:05 -04:00
case UBMT_TEXTURE :
case UBMT_SRV :
case UBMT_UAV :
case UBMT_SAMPLER :
{
2022-04-20 10:43:15 -04:00
const FRHIResource * Resource = Reader . Read < const FRHIResource * > ( Parameter ) ;
if ( ! Resource )
2020-03-10 08:04:05 -04:00
{
2022-04-20 10:43:15 -04:00
EmitNullShaderParameterFatalError ( Shader , ParametersMetadata , Parameter . ByteOffset ) ;
2020-03-10 08:04:05 -04:00
}
2023-08-25 22:19:10 -04:00
break ;
2020-03-10 08:04:05 -04:00
}
case UBMT_RDG_TEXTURE :
{
2022-04-20 10:43:15 -04:00
const FRDGTexture * GraphTexture = Reader . Read < const FRDGTexture * > ( Parameter ) ;
2020-03-10 08:04:05 -04:00
if ( ! GraphTexture )
{
2022-04-20 10:43:15 -04:00
EmitNullShaderParameterFatalError ( Shader , ParametersMetadata , Parameter . ByteOffset ) ;
2020-03-10 08:04:05 -04:00
}
2023-08-25 22:19:10 -04:00
break ;
2020-03-10 08:04:05 -04:00
}
case UBMT_RDG_TEXTURE_SRV :
2024-04-23 17:02:48 -04:00
case UBMT_RDG_TEXTURE_NON_PIXEL_SRV :
2020-03-10 08:04:05 -04:00
case UBMT_RDG_BUFFER_SRV :
2023-08-25 22:19:10 -04:00
case UBMT_RDG_TEXTURE_UAV :
2020-03-10 08:04:05 -04:00
case UBMT_RDG_BUFFER_UAV :
{
2022-04-20 10:43:15 -04:00
const FRDGResource * GraphResource = Reader . Read < const FRDGResource * > ( Parameter ) ;
2023-08-25 22:19:10 -04:00
2020-03-10 08:04:05 -04:00
if ( ! GraphResource )
{
2022-04-20 10:43:15 -04:00
EmitNullShaderParameterFatalError ( Shader , ParametersMetadata , Parameter . ByteOffset ) ;
2020-03-10 08:04:05 -04:00
}
2023-08-25 22:19:10 -04:00
break ;
2020-03-10 08:04:05 -04:00
}
default :
break ;
2018-11-21 20:49:28 -05:00
}
}
2020-09-24 00:43:27 -04:00
// Graph Uniform Buffers
2022-04-20 10:43:15 -04:00
for ( const FShaderParameterBindings : : FParameterStructReference & Parameter : Bindings . GraphUniformBuffers )
2020-09-24 00:43:27 -04:00
{
2022-04-20 10:43:15 -04:00
const FRDGUniformBufferBinding & UniformBufferBinding = Reader . Read < FRDGUniformBufferBinding > ( Parameter ) ;
2020-12-07 17:42:32 -04:00
if ( ! UniformBufferBinding )
2020-09-24 00:43:27 -04:00
{
2022-04-20 10:43:15 -04:00
EmitNullShaderParameterFatalError ( Shader , ParametersMetadata , Parameter . ByteOffset ) ;
2020-09-24 00:43:27 -04:00
}
}
2018-11-21 20:49:28 -05:00
// Reference structures
2022-04-20 10:43:15 -04:00
for ( const FShaderParameterBindings : : FParameterStructReference & Parameter : Bindings . ParameterReferences )
2018-11-21 20:49:28 -05:00
{
2022-04-20 10:43:15 -04:00
const FUniformBufferBinding & UniformBufferBinding = Reader . Read < FUniformBufferBinding > ( Parameter ) ;
2020-12-07 17:42:32 -04:00
if ( ! UniformBufferBinding )
2018-11-21 20:49:28 -05:00
{
2022-04-20 10:43:15 -04:00
EmitNullShaderParameterFatalError ( Shader , ParametersMetadata , Parameter . ByteOffset ) ;
2018-11-21 20:49:28 -05:00
}
}
}
2020-09-24 00:43:27 -04:00
void ValidateShaderParameterResourcesRHI ( const void * Contents , const FRHIUniformBufferLayout & Layout )
{
for ( int32 Index = 0 , Count = Layout . Resources . Num ( ) ; Index < Count ; + + Index )
{
const auto Parameter = Layout . Resources [ Index ] ;
FRHIResource * Resource = GetShaderParameterResourceRHI ( Contents , Parameter . MemberOffset , Parameter . MemberType ) ;
const bool bSRV =
Parameter . MemberType = = UBMT_SRV | |
2023-11-03 22:27:11 -04:00
Parameter . MemberType = = UBMT_RDG_TEXTURE_SRV | |
2024-04-23 17:02:48 -04:00
Parameter . MemberType = = UBMT_RDG_TEXTURE_NON_PIXEL_SRV | |
2023-11-03 22:27:11 -04:00
Parameter . MemberType = = UBMT_RDG_BUFFER_SRV ;
2020-09-24 00:43:27 -04:00
// Allow null SRV's in uniform buffers for feature levels that don't support SRV's in shaders
if ( GMaxRHIFeatureLevel < = ERHIFeatureLevel : : ES3_1 & & bSRV )
{
continue ;
}
checkf ( Resource , TEXT ( " Null resource entry in uniform buffer parameters: %s.Resources[%u], ResourceType 0x%x. " ) , * Layout . GetDebugName ( ) , Index , Parameter . MemberType ) ;
}
}
2018-11-21 20:49:28 -05:00
# endif // DO_CHECK
2022-04-13 13:29:15 -04:00
2022-11-15 19:41:53 -05:00
template < typename BindingParameterType >
FRHIShaderParameterResource ExtractShaderParameterResource ( FShaderParameterReader Reader , const BindingParameterType & Parameter )
2022-05-17 16:30:48 -04:00
{
const EUniformBufferBaseType BaseType = static_cast < EUniformBufferBaseType > ( Parameter . BaseType ) ;
2022-11-15 19:41:53 -05:00
2022-05-17 16:30:48 -04:00
switch ( BaseType )
{
case UBMT_TEXTURE :
{
FRHITexture * Texture = Reader . Read < FRHITexture * > ( Parameter ) ;
checkSlow ( Texture ) ;
2022-11-18 12:10:55 -05:00
return FRHIShaderParameterResource ( Texture , GetParameterIndex ( Parameter ) ) ;
2022-05-17 16:30:48 -04:00
}
case UBMT_SRV :
{
FRHIShaderResourceView * ShaderResourceView = Reader . Read < FRHIShaderResourceView * > ( Parameter ) ;
checkSlow ( ShaderResourceView ) ;
2022-11-18 12:10:55 -05:00
return FRHIShaderParameterResource ( ShaderResourceView , GetParameterIndex ( Parameter ) ) ;
2022-11-15 19:41:53 -05:00
}
case UBMT_UAV :
{
FRHIUnorderedAccessView * UnorderedAccessView = Reader . Read < FRHIUnorderedAccessView * > ( Parameter ) ;
checkSlow ( UnorderedAccessView ) ;
2022-11-18 12:10:55 -05:00
return FRHIShaderParameterResource ( UnorderedAccessView , GetParameterIndex ( Parameter ) ) ;
2022-05-17 16:30:48 -04:00
}
case UBMT_SAMPLER :
{
FRHISamplerState * SamplerState = Reader . Read < FRHISamplerState * > ( Parameter ) ;
checkSlow ( SamplerState ) ;
2022-11-18 12:10:55 -05:00
return FRHIShaderParameterResource ( SamplerState , GetParameterIndex ( Parameter ) ) ;
2022-05-17 16:30:48 -04:00
}
case UBMT_RDG_TEXTURE :
{
FRDGTexture * RDGTexture = Reader . Read < FRDGTexture * > ( Parameter ) ;
checkSlow ( RDGTexture ) ;
2022-11-15 19:41:53 -05:00
RDGTexture - > MarkResourceAsUsed ( ) ;
2022-11-18 12:10:55 -05:00
return FRHIShaderParameterResource ( RDGTexture - > GetRHI ( ) , GetParameterIndex ( Parameter ) ) ;
2022-05-17 16:30:48 -04:00
}
case UBMT_RDG_TEXTURE_SRV :
2024-04-23 17:02:48 -04:00
case UBMT_RDG_TEXTURE_NON_PIXEL_SRV :
2022-05-17 16:30:48 -04:00
case UBMT_RDG_BUFFER_SRV :
{
FRDGShaderResourceView * RDGShaderResourceView = Reader . Read < FRDGShaderResourceView * > ( Parameter ) ;
checkSlow ( RDGShaderResourceView ) ;
RDGShaderResourceView - > MarkResourceAsUsed ( ) ;
2022-11-18 12:10:55 -05:00
return FRHIShaderParameterResource ( RDGShaderResourceView - > GetRHI ( ) , GetParameterIndex ( Parameter ) ) ;
2022-05-17 16:30:48 -04:00
}
case UBMT_RDG_TEXTURE_UAV :
case UBMT_RDG_BUFFER_UAV :
{
FRDGUnorderedAccessView * RDGUnorderedAccessView = Reader . Read < FRDGUnorderedAccessView * > ( Parameter ) ;
checkSlow ( RDGUnorderedAccessView ) ;
2022-11-15 19:41:53 -05:00
RDGUnorderedAccessView - > MarkResourceAsUsed ( ) ;
2022-11-18 12:10:55 -05:00
return FRHIShaderParameterResource ( RDGUnorderedAccessView - > GetRHI ( ) , GetParameterIndex ( Parameter ) ) ;
2022-05-17 16:30:48 -04:00
}
default :
checkf ( false , TEXT ( " Unhandled resource type? " ) ) ;
2022-11-18 12:10:55 -05:00
return FRHIShaderParameterResource ( ) ;
2022-04-13 13:29:15 -04:00
}
}
2024-06-26 10:46:46 -04:00
template < typename TParameterFunction >
static void IterateShaderParameterMembersInternal (
const FShaderParametersMetadata & ParametersMetadata ,
uint16 ByteOffset ,
TParameterFunction Lambda )
{
for ( const FShaderParametersMetadata : : FMember & Member : ParametersMetadata . GetMembers ( ) )
{
EUniformBufferBaseType BaseType = Member . GetBaseType ( ) ;
const uint16 MemberOffset = ByteOffset + uint16 ( Member . GetOffset ( ) ) ;
const uint32 NumElements = Member . GetNumElements ( ) ;
if ( BaseType = = UBMT_INCLUDED_STRUCT )
{
check ( NumElements = = 0 ) ;
IterateShaderParameterMembersInternal ( * Member . GetStructMetadata ( ) , MemberOffset , Lambda ) ;
}
else if ( BaseType = = UBMT_NESTED_STRUCT & & NumElements = = 0 )
{
IterateShaderParameterMembersInternal ( * Member . GetStructMetadata ( ) , MemberOffset , Lambda ) ;
}
else if ( BaseType = = UBMT_NESTED_STRUCT & & NumElements > 0 )
{
const FShaderParametersMetadata & NewParametersMetadata = * Member . GetStructMetadata ( ) ;
for ( uint32 ArrayElementId = 0 ; ArrayElementId < NumElements ; ArrayElementId + + )
{
uint16 NewStructOffset = MemberOffset + ArrayElementId * NewParametersMetadata . GetSize ( ) ;
IterateShaderParameterMembersInternal ( NewParametersMetadata , NewStructOffset , Lambda ) ;
}
}
else
{
const bool bParametersAreExpanded = NumElements > 0 & & ( IsShaderParameterTypeRHIResource ( BaseType ) | | IsRDGResourceReferenceShaderParameterType ( BaseType ) ) ;
if ( bParametersAreExpanded )
{
const uint16 ElementSize = SHADER_PARAMETER_POINTER_ALIGNMENT ;
for ( uint32 Index = 0 ; Index < NumElements ; Index + + )
{
Lambda ( BaseType , MemberOffset + Index * ElementSize ) ;
}
}
else
{
Lambda ( BaseType , MemberOffset ) ;
}
}
}
}
static bool DoesBaseTypeSupportBindless ( EUniformBufferBaseType Type )
{
switch ( Type )
{
case UBMT_TEXTURE :
case UBMT_SRV :
case UBMT_UAV :
case UBMT_SAMPLER :
case UBMT_RDG_TEXTURE :
case UBMT_RDG_TEXTURE_SRV :
case UBMT_RDG_TEXTURE_NON_PIXEL_SRV :
case UBMT_RDG_TEXTURE_UAV :
case UBMT_RDG_BUFFER_SRV :
case UBMT_RDG_BUFFER_UAV :
case UBMT_RESOURCE_COLLECTION :
return true ;
}
return false ;
}
void SetAllShaderParametersAsBindless (
FRHIBatchedShaderParameters & BatchedParameters ,
const FShaderParametersMetadata * ParametersMetadata ,
const void * InParametersData )
{
TConstArrayView < uint8 > ParametersData ( ( const uint8 * ) InParametersData , ParametersMetadata - > GetSize ( ) ) ;
const FShaderParameterReader Reader ( ParametersData ) ;
uint16 ByteOffset = 0 ;
IterateShaderParameterMembersInternal ( * ParametersMetadata , ByteOffset , [ & BatchedParameters , Reader ] ( EUniformBufferBaseType BaseType , uint16 ByteOffset )
{
if ( DoesBaseTypeSupportBindless ( BaseType ) )
{
FShaderParameterBindings : : FBindlessResourceParameter Parameter { } ;
Parameter . GlobalConstantOffset = ByteOffset ;
Parameter . ByteOffset = ByteOffset ;
Parameter . BaseType = BaseType ;
// Make sure the resource wasn't set to null
if ( Reader . Read < void * > ( Parameter ) )
{
const FRHIShaderParameterResource ShaderParameterResource = ExtractShaderParameterResource ( Reader , Parameter ) ;
BatchedParameters . AddBindlessParameter ( ShaderParameterResource ) ;
}
}
} ) ;
}
2022-11-15 19:41:53 -05:00
static void ExtractShaderParameterResources (
TArray < FRHIShaderParameterResource > & OutResourceParameters ,
TArray < FRHIShaderParameterResource > & OutBindlessParameters ,
const FShaderParameterBindings & Bindings ,
2024-05-30 16:07:45 -04:00
TConstArrayView < uint8 > ParametersData ,
EUniformBufferBindingFlags UniformBufferBindingFlags )
2022-04-13 13:29:15 -04:00
{
2022-11-15 19:41:53 -05:00
const FShaderParameterReader Reader ( ParametersData ) ;
2022-04-20 10:43:15 -04:00
2022-11-15 19:41:53 -05:00
# if PLATFORM_SUPPORTS_BINDLESS_RENDERING
if ( int32 NumBindings = Bindings . BindlessResourceParameters . Num ( ) )
{
OutBindlessParameters . Reserve ( NumBindings ) ;
for ( const FShaderParameterBindings : : FBindlessResourceParameter & Parameter : Bindings . BindlessResourceParameters )
{
const FRHIShaderParameterResource ShaderParameterResource = ExtractShaderParameterResource ( Reader , Parameter ) ;
OutBindlessParameters . Emplace ( ShaderParameterResource ) ;
}
}
# endif
2023-02-07 16:19:47 -05:00
const int32 NumBindings = Bindings . ResourceParameters . Num ( ) + Bindings . GraphUniformBuffers . Num ( ) + Bindings . ParameterReferences . Num ( ) ;
2022-11-15 19:41:53 -05:00
if ( NumBindings )
{
OutResourceParameters . Reserve ( NumBindings ) ;
for ( const FShaderParameterBindings : : FResourceParameter & Parameter : Bindings . ResourceParameters )
{
const FRHIShaderParameterResource ShaderParameterResource = ExtractShaderParameterResource ( Reader , Parameter ) ;
OutResourceParameters . Emplace ( ShaderParameterResource ) ;
}
for ( const FShaderParameterBindings : : FParameterStructReference & Parameter : Bindings . GraphUniformBuffers )
{
const FRDGUniformBufferBinding & UniformBufferBinding = Reader . Read < FRDGUniformBufferBinding > ( Parameter ) ;
2024-05-30 16:07:45 -04:00
if ( EnumHasAnyFlags ( UniformBufferBinding . GetBindingFlags ( ) , UniformBufferBindingFlags ) )
2022-11-15 19:41:53 -05:00
{
UniformBufferBinding - > MarkResourceAsUsed ( ) ;
2022-11-18 12:10:55 -05:00
OutResourceParameters . Emplace ( UniformBufferBinding - > GetRHI ( ) , GetParameterIndex ( Parameter ) ) ;
2022-11-15 19:41:53 -05:00
}
}
for ( const FShaderParameterBindings : : FParameterStructReference & Parameter : Bindings . ParameterReferences )
{
const FUniformBufferBinding & UniformBufferBinding = Reader . Read < FUniformBufferBinding > ( Parameter ) ;
2024-05-30 16:07:45 -04:00
if ( EnumHasAnyFlags ( UniformBufferBinding . GetBindingFlags ( ) , UniformBufferBindingFlags ) )
2022-11-15 19:41:53 -05:00
{
2022-11-18 12:10:55 -05:00
OutResourceParameters . Emplace ( UniformBufferBinding . GetUniformBuffer ( ) , GetParameterIndex ( Parameter ) ) ;
2022-11-15 19:41:53 -05:00
}
}
2022-04-13 13:29:15 -04:00
}
}
2024-05-20 17:14:34 -04:00
static void ExtractShaderParameterResources (
FRHIBatchedShaderParameters & BatchedParameters ,
const FShaderParameterBindings & Bindings ,
2024-05-30 16:07:45 -04:00
TConstArrayView < uint8 > ParametersData ,
EUniformBufferBindingFlags UniformBufferBindingFlags )
2024-05-20 17:14:34 -04:00
{
const FShaderParameterReader Reader ( ParametersData ) ;
# if PLATFORM_SUPPORTS_BINDLESS_RENDERING
if ( int32 NumBindings = Bindings . BindlessResourceParameters . Num ( ) )
{
for ( const FShaderParameterBindings : : FBindlessResourceParameter & Parameter : Bindings . BindlessResourceParameters )
{
const FRHIShaderParameterResource ShaderParameterResource = ExtractShaderParameterResource ( Reader , Parameter ) ;
BatchedParameters . AddBindlessParameter ( ShaderParameterResource ) ;
}
}
# endif
const int32 NumBindings = Bindings . ResourceParameters . Num ( ) + Bindings . GraphUniformBuffers . Num ( ) + Bindings . ParameterReferences . Num ( ) ;
if ( NumBindings )
{
for ( const FShaderParameterBindings : : FResourceParameter & Parameter : Bindings . ResourceParameters )
{
const FRHIShaderParameterResource ShaderParameterResource = ExtractShaderParameterResource ( Reader , Parameter ) ;
BatchedParameters . AddResourceParameter ( ShaderParameterResource ) ;
}
for ( const FShaderParameterBindings : : FParameterStructReference & Parameter : Bindings . GraphUniformBuffers )
{
const FRDGUniformBufferBinding & UniformBufferBinding = Reader . Read < FRDGUniformBufferBinding > ( Parameter ) ;
2024-05-30 16:07:45 -04:00
if ( EnumHasAnyFlags ( UniformBufferBinding . GetBindingFlags ( ) , UniformBufferBindingFlags ) )
2024-05-20 17:14:34 -04:00
{
UniformBufferBinding - > MarkResourceAsUsed ( ) ;
BatchedParameters . AddResourceParameter ( UniformBufferBinding - > GetRHI ( ) , GetParameterIndex ( Parameter ) ) ;
}
}
for ( const FShaderParameterBindings : : FParameterStructReference & Parameter : Bindings . ParameterReferences )
{
const FUniformBufferBinding & UniformBufferBinding = Reader . Read < FUniformBufferBinding > ( Parameter ) ;
2024-05-30 16:07:45 -04:00
if ( EnumHasAnyFlags ( UniformBufferBinding . GetBindingFlags ( ) , UniformBufferBindingFlags ) )
2024-05-20 17:14:34 -04:00
{
BatchedParameters . AddResourceParameter ( UniformBufferBinding . GetUniformBuffer ( ) , GetParameterIndex ( Parameter ) ) ;
}
}
}
}
2023-02-07 16:19:47 -05:00
/** Set batched parameters from a parameters struct. */
void SetShaderParameters (
FRHIBatchedShaderParameters & BatchedParameters ,
const FShaderParameterBindings & Bindings ,
const FShaderParametersMetadata * ParametersMetadata ,
const void * InParametersData )
{
TConstArrayView < uint8 > FullParametersData ( ( const uint8 * ) InParametersData , ParametersMetadata - > GetSize ( ) ) ;
for ( const FShaderParameterBindings : : FParameter & Parameter : Bindings . Parameters )
{
BatchedParameters . SetShaderParameter ( Parameter . BufferIndex , Parameter . BaseIndex , Parameter . ByteSize , FullParametersData . GetData ( ) + Parameter . ByteOffset ) ;
}
2024-05-30 16:07:45 -04:00
ExtractShaderParameterResources ( BatchedParameters , Bindings , FullParametersData , EUniformBufferBindingFlags : : Shader ) ;
2023-02-07 16:19:47 -05:00
}
2022-04-13 13:29:15 -04:00
/** Set shader's parameters from its parameters struct. */
template < typename TRHICmdList , typename TShaderRHI >
inline void SetShaderParametersInternal (
TRHICmdList & RHICmdList ,
TShaderRHI * ShaderRHI ,
const FShaderParameterBindings & Bindings ,
2022-11-07 16:32:05 -05:00
const FShaderParametersMetadata * ParametersMetadata ,
2022-11-15 19:41:53 -05:00
const void * InParametersData )
2022-04-13 13:29:15 -04:00
{
checkf ( Bindings . RootParameterBufferIndex = = FShaderParameterBindings : : kInvalidBufferIndex , TEXT ( " Can't use SetShaderParameters() for root parameter buffer index. " ) ) ;
2024-05-30 16:07:45 -04:00
checkf ( ! IsRayTracingShaderFrequency ( ShaderRHI - > GetFrequency ( ) ) , TEXT ( " Can't use SetShaderParameters() with RHICmdList parameter for ray tracing shaders. " ) ) ;
2024-05-20 17:14:34 -04:00
FRHIBatchedShaderParameters & ShaderParameters = RHICmdList . GetScratchShaderParameters ( ) ;
SetShaderParameters ( ShaderParameters , Bindings , ParametersMetadata , InParametersData ) ;
RHICmdList . SetBatchedShaderParameters ( ShaderRHI , ShaderParameters ) ;
2022-04-13 13:29:15 -04:00
}
void SetShaderParameters (
FRHIComputeCommandList & RHICmdList ,
FRHIComputeShader * ShaderRHI ,
const FShaderParameterBindings & Bindings ,
2022-11-07 16:32:05 -05:00
const FShaderParametersMetadata * ParametersMetadata ,
const void * ParametersData )
2022-04-13 13:29:15 -04:00
{
2022-11-07 16:32:05 -05:00
SetShaderParametersInternal ( RHICmdList , ShaderRHI , Bindings , ParametersMetadata , ParametersData ) ;
2022-04-13 13:29:15 -04:00
}
void SetShaderParameters (
FRHICommandList & RHICmdList ,
FRHIGraphicsShader * ShaderRHI ,
const FShaderParameterBindings & Bindings ,
2022-11-07 16:32:05 -05:00
const FShaderParametersMetadata * ParametersMetadata ,
const void * ParametersData )
2022-04-13 13:29:15 -04:00
{
2022-11-07 16:32:05 -05:00
SetShaderParametersInternal ( RHICmdList , ShaderRHI , Bindings , ParametersMetadata , ParametersData ) ;
2022-04-13 13:29:15 -04:00
}
void SetShaderParameters (
FRHICommandList & RHICmdList ,
FRHIComputeShader * ShaderRHI ,
const FShaderParameterBindings & Bindings ,
2022-11-07 16:32:05 -05:00
const FShaderParametersMetadata * ParametersMetadata ,
const void * ParametersData )
2022-04-13 13:29:15 -04:00
{
2022-11-07 16:32:05 -05:00
SetShaderParametersInternal ( RHICmdList , ShaderRHI , Bindings , ParametersMetadata , ParametersData ) ;
2022-04-13 13:29:15 -04:00
}
# if RHI_RAYTRACING
2024-05-31 16:55:53 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS // Allow FRayTracingShaderBindingsWriter
2022-04-13 13:29:15 -04:00
void SetShaderParameters (
FRayTracingShaderBindingsWriter & RTBindingsWriter ,
const FShaderParameterBindings & Bindings ,
2022-11-07 16:32:05 -05:00
const FShaderParametersMetadata * ParametersMetadata ,
const void * ParametersData )
2022-04-13 13:29:15 -04:00
{
2022-11-07 16:32:05 -05:00
const FShaderParameterReader Reader ( ParametersData , ParametersMetadata - > GetSize ( ) ) ;
2022-04-20 10:43:15 -04:00
2024-05-31 02:49:31 -04:00
# if PLATFORM_SUPPORTS_BINDLESS_RENDERING
if ( int32 NumBindings = Bindings . BindlessResourceParameters . Num ( ) )
{
for ( const FShaderParameterBindings : : FBindlessResourceParameter & Parameter : Bindings . BindlessResourceParameters )
{
const FRHIShaderParameterResource ShaderParameterResource = ExtractShaderParameterResource ( Reader , Parameter ) ;
RTBindingsWriter . AddBindlessParameter ( ShaderParameterResource ) ;
}
}
# endif // PLATFORM_SUPPORTS_BINDLESS_RENDERING
2022-04-20 10:43:15 -04:00
for ( const FShaderParameterBindings : : FResourceParameter & Parameter : Bindings . ResourceParameters )
2022-04-13 13:29:15 -04:00
{
2022-04-20 10:43:15 -04:00
const EUniformBufferBaseType BaseType = static_cast < EUniformBufferBaseType > ( Parameter . BaseType ) ;
2022-04-13 13:29:15 -04:00
switch ( BaseType )
{
case UBMT_TEXTURE :
{
2022-04-20 10:43:15 -04:00
FRHITexture * Texture = Reader . Read < FRHITexture * > ( Parameter ) ;
RTBindingsWriter . SetTexture ( Parameter . BaseIndex , Texture ) ;
2022-04-13 13:29:15 -04:00
}
break ;
case UBMT_SRV :
{
2022-04-20 10:43:15 -04:00
FRHIShaderResourceView * ShaderResourceView = Reader . Read < FRHIShaderResourceView * > ( Parameter ) ;
RTBindingsWriter . SetSRV ( Parameter . BaseIndex , ShaderResourceView ) ;
2022-04-13 13:29:15 -04:00
}
break ;
case UBMT_UAV :
{
2022-04-20 10:43:15 -04:00
FRHIUnorderedAccessView * UnorderedAccessView = Reader . Read < FRHIUnorderedAccessView * > ( Parameter ) ;
RTBindingsWriter . SetUAV ( Parameter . BaseIndex , UnorderedAccessView ) ;
2022-04-13 13:29:15 -04:00
}
break ;
case UBMT_SAMPLER :
{
2022-04-20 10:43:15 -04:00
FRHISamplerState * SamplerState = Reader . Read < FRHISamplerState * > ( Parameter ) ;
RTBindingsWriter . SetSampler ( Parameter . BaseIndex , SamplerState ) ;
2022-04-13 13:29:15 -04:00
}
break ;
case UBMT_RDG_TEXTURE :
{
2022-04-20 10:43:15 -04:00
FRDGTexture * RDGTexture = Reader . Read < FRDGTexture * > ( Parameter ) ;
checkSlow ( RDGTexture ) ;
RDGTexture - > MarkResourceAsUsed ( ) ;
RTBindingsWriter . SetTexture ( Parameter . BaseIndex , RDGTexture - > GetRHI ( ) ) ;
2022-04-13 13:29:15 -04:00
}
break ;
case UBMT_RDG_TEXTURE_SRV :
2024-04-23 17:02:48 -04:00
case UBMT_RDG_TEXTURE_NON_PIXEL_SRV :
2022-04-13 13:29:15 -04:00
case UBMT_RDG_BUFFER_SRV :
{
2022-04-20 10:43:15 -04:00
FRDGShaderResourceView * RDGShaderResourceView = Reader . Read < FRDGShaderResourceView * > ( Parameter ) ;
checkSlow ( RDGShaderResourceView ) ;
RDGShaderResourceView - > MarkResourceAsUsed ( ) ;
RTBindingsWriter . SetSRV ( Parameter . BaseIndex , RDGShaderResourceView - > GetRHI ( ) ) ;
2022-04-13 13:29:15 -04:00
}
break ;
case UBMT_RDG_TEXTURE_UAV :
case UBMT_RDG_BUFFER_UAV :
{
2022-04-20 10:43:15 -04:00
FRDGUnorderedAccessView * RDGUnorderedAccessView = Reader . Read < FRDGUnorderedAccessView * > ( Parameter ) ;
checkSlow ( RDGUnorderedAccessView ) ;
RDGUnorderedAccessView - > MarkResourceAsUsed ( ) ;
RTBindingsWriter . SetUAV ( Parameter . BaseIndex , RDGUnorderedAccessView - > GetRHI ( ) ) ;
2022-04-13 13:29:15 -04:00
}
break ;
default :
checkf ( false , TEXT ( " Unhandled resource type? " ) ) ;
break ;
}
}
// Graph Uniform Buffers
2022-04-20 10:43:15 -04:00
for ( const FShaderParameterBindings : : FParameterStructReference & Parameter : Bindings . GraphUniformBuffers )
2022-04-13 13:29:15 -04:00
{
2022-04-20 10:43:15 -04:00
const FRDGUniformBufferBinding & UniformBufferBinding = Reader . Read < FRDGUniformBufferBinding > ( Parameter ) ;
2022-04-13 13:29:15 -04:00
checkSlow ( UniformBufferBinding ) ;
UniformBufferBinding - > MarkResourceAsUsed ( ) ;
2022-04-20 10:43:15 -04:00
RTBindingsWriter . SetUniformBuffer ( Parameter . BufferIndex , UniformBufferBinding - > GetRHI ( ) ) ;
2022-04-13 13:29:15 -04:00
}
// Referenced uniform buffers
2022-04-20 10:43:15 -04:00
for ( const FShaderParameterBindings : : FParameterStructReference & Parameter : Bindings . ParameterReferences )
2022-04-13 13:29:15 -04:00
{
2022-04-20 10:43:15 -04:00
const FUniformBufferBinding & UniformBufferBinding = Reader . Read < FUniformBufferBinding > ( Parameter ) ;
RTBindingsWriter . SetUniformBuffer ( Parameter . BufferIndex , UniformBufferBinding . GetUniformBuffer ( ) ) ;
2022-04-13 13:29:15 -04:00
}
// Root uniform buffer.
if ( Bindings . RootParameterBufferIndex ! = FShaderParameterBindings : : kInvalidBufferIndex )
{
// Do not do any validation at some resources may have been removed from the structure because known to not be used by the shader.
EUniformBufferValidation Validation = EUniformBufferValidation : : None ;
2022-11-07 16:32:05 -05:00
RTBindingsWriter . RootUniformBuffer = RHICreateUniformBuffer ( ParametersData , ParametersMetadata - > GetLayoutPtr ( ) , UniformBuffer_SingleDraw , Validation ) ;
2022-04-13 13:29:15 -04:00
RTBindingsWriter . SetUniformBuffer ( Bindings . RootParameterBufferIndex , RTBindingsWriter . RootUniformBuffer ) ;
}
}
2024-05-31 16:55:53 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2024-05-30 16:07:45 -04:00
FRayTracingShaderBindings ConvertRayTracingShaderBindings ( const FRHIBatchedShaderParameters & BatchedParameters )
{
FRayTracingShaderBindings Result ;
// Use array views for bounds checking
TArrayView < FRHITexture * > Textures = Result . Textures ;
TArrayView < FRHIShaderResourceView * > SRVs = Result . SRVs ;
TArrayView < FRHIUniformBuffer * > UniformBuffers = Result . UniformBuffers ;
TArrayView < FRHISamplerState * > Samplers = Result . Samplers ;
TArrayView < FRHIUnorderedAccessView * > UAVs = Result . UAVs ;
checkf ( BatchedParameters . Parameters . IsEmpty ( ) , TEXT ( " FRHIShaderParameter is not supported by FRayTracingShaderBindings " ) ) ;
for ( const FRHIShaderParameterResource & It : BatchedParameters . ResourceParameters )
{
using EType = FRHIShaderParameterResource : : EType ;
switch ( It . Type )
{
case EType : : Texture :
Textures [ It . Index ] = static_cast < FRHITexture * > ( It . Resource ) ;
break ;
case EType : : ResourceView :
SRVs [ It . Index ] = static_cast < FRHIShaderResourceView * > ( It . Resource ) ;
break ;
case EType : : UnorderedAccessView :
UAVs [ It . Index ] = static_cast < FRHIUnorderedAccessView * > ( It . Resource ) ;
break ;
case EType : : Sampler :
Samplers [ It . Index ] = static_cast < FRHISamplerState * > ( It . Resource ) ;
break ;
case EType : : UniformBuffer :
UniformBuffers [ It . Index ] = static_cast < FRHIUniformBuffer * > ( It . Resource ) ;
break ;
case EType : : ResourceCollection :
checkNoEntry ( ) ; // not supported
break ;
default :
checkNoEntry ( ) ;
}
}
2024-05-31 16:55:53 -04:00
Result . BindlessParameters = BatchedParameters . BindlessParameters ;
2024-05-30 16:07:45 -04:00
return Result ;
}
void SetRayTracingShaderParameters (
FRHIBatchedShaderParameters & BatchedParameters ,
const FShaderParameterBindings & Bindings ,
const FShaderParametersMetadata * ParametersMetadata ,
const void * InParametersData )
{
TConstArrayView < uint8 > FullParametersData ( ( const uint8 * ) InParametersData , ParametersMetadata - > GetSize ( ) ) ;
#if 0 // Loose parameter binding could be supported if the need arises, but we currently don't support it.
for ( const FShaderParameterBindings : : FParameter & Parameter : Bindings . Parameters )
{
BatchedParameters . SetShaderParameter ( Parameter . BufferIndex , Parameter . BaseIndex , Parameter . ByteSize , FullParametersData . GetData ( ) + Parameter . ByteOffset ) ;
}
# else
checkf ( Bindings . Parameters . Num ( ) = = 0 , TEXT ( " Ray tracing shader should use SHADER_USE_ROOT_PARAMETER_STRUCT() to passdown the cbuffer layout to the shader compiler. " ) ) ;
# endif
ExtractShaderParameterResources ( BatchedParameters , Bindings , FullParametersData , EUniformBufferBindingFlags : : StaticAndShader ) ;
// Root uniform buffer.
if ( Bindings . RootParameterBufferIndex ! = FShaderParameterBindings : : kInvalidBufferIndex )
{
// Do not do any validation at some resources may have been removed from the structure because known to not be used by the shader.
EUniformBufferValidation Validation = EUniformBufferValidation : : None ;
FUniformBufferRHIRef RootUniformBuffer = RHICreateUniformBuffer ( InParametersData , ParametersMetadata - > GetLayoutPtr ( ) , UniformBuffer_SingleDraw , Validation ) ;
BatchedParameters . AddResourceParameter ( RootUniformBuffer , Bindings . RootParameterBufferIndex ) ;
}
# if DO_CHECK
{
2024-05-31 16:55:53 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS // Allow FRayTracingShaderBindingsWriter
2024-05-30 16:07:45 -04:00
FRayTracingShaderBindingsWriter RTBindingsWriter ;
2024-05-31 16:55:53 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2024-05-30 16:07:45 -04:00
SetShaderParameters ( RTBindingsWriter , Bindings , ParametersMetadata , InParametersData ) ;
FRayTracingShaderBindings ConvertedBindings = ConvertRayTracingShaderBindings ( BatchedParameters ) ;
{
for ( int32 i = 0 ; i < UE_ARRAY_COUNT ( ConvertedBindings . Textures ) ; + + i )
{
check ( RTBindingsWriter . Textures [ i ] = = ConvertedBindings . Textures [ i ] ) ;
}
for ( int32 i = 0 ; i < UE_ARRAY_COUNT ( ConvertedBindings . SRVs ) ; + + i )
{
check ( RTBindingsWriter . SRVs [ i ] = = ConvertedBindings . SRVs [ i ] ) ;
}
for ( int32 i = 0 ; i < UE_ARRAY_COUNT ( ConvertedBindings . UniformBuffers ) ; + + i )
{
if ( RTBindingsWriter . UniformBuffers [ i ] )
{
check ( ConvertedBindings . UniformBuffers [ i ] ) ;
check ( RTBindingsWriter . UniformBuffers [ i ] - > GetLayout ( ) = = ConvertedBindings . UniformBuffers [ i ] - > GetLayout ( ) ) ;
}
else
{
check ( ConvertedBindings . UniformBuffers [ i ] = = nullptr ) ;
}
}
for ( int32 i = 0 ; i < UE_ARRAY_COUNT ( ConvertedBindings . Samplers ) ; + + i )
{
check ( RTBindingsWriter . Samplers [ i ] = = ConvertedBindings . Samplers [ i ] ) ;
}
for ( int32 i = 0 ; i < UE_ARRAY_COUNT ( ConvertedBindings . UAVs ) ; + + i )
{
check ( RTBindingsWriter . UAVs [ i ] = = ConvertedBindings . UAVs [ i ] ) ;
}
2024-05-31 16:55:53 -04:00
check ( RTBindingsWriter . BindlessParameters . Num ( ) = = ConvertedBindings . BindlessParameters . Num ( ) ) ;
for ( int32 i = 0 ; i < ConvertedBindings . BindlessParameters . Num ( ) ; + + i )
{
2024-06-10 18:20:23 -04:00
check ( RTBindingsWriter . BindlessParameters [ i ] = = ConvertedBindings . BindlessParameters [ i ] ) ;
2024-05-31 16:55:53 -04:00
}
2024-05-30 16:07:45 -04:00
}
}
# endif // DO_CHECK
}
2022-04-13 13:29:15 -04:00
# endif // RHI_RAYTRACING