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"
/** 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
2019-03-07 11:25:32 -05:00
const bool bIsVariableNativeType = (
BaseType = = UBMT_INT32 | |
BaseType = = UBMT_UINT32 | |
BaseType = = UBMT_FLOAT32 ) ;
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 )
{
2022-04-20 10:43:15 -04:00
checkf ( ParameterAllocation - > BaseIndex < 256 , TEXT ( " BaseIndex does not fit into uint8. Change FResourceParameter::BaseIndex type to uint16 " ) ) ;
2019-03-07 11:25:32 -05:00
FShaderParameterBindings : : FResourceParameter Parameter ;
2022-04-20 10:43:15 -04:00
Parameter . BaseIndex = ( uint8 ) ParameterAllocation - > BaseIndex ;
2019-03-07 11:25:32 -05:00
Parameter . ByteOffset = ByteOffset + ArrayElementId * SHADER_PARAMETER_POINTER_ALIGNMENT ;
2020-03-10 08:04:05 -04:00
Parameter . BaseType = BaseType ;
2019-03-07 11:25:32 -05:00
2022-04-20 10:43:15 -04:00
if ( ParameterAllocation - > Size ! = 1 )
2019-09-25 14:06:50 -04:00
{
2020-06-23 18:40:00 -04:00
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 ,
2022-04-20 10:43:15 -04:00
* ElementShaderBindingName , ParameterAllocation - > Size , * CppName ) ;
2019-09-25 14:06:50 -04:00
}
2019-03-07 11:25:32 -05:00
2020-03-10 08:04:05 -04:00
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 :
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 ;
uint16 BufferIndex , BaseIndex , BoundSize ;
if ( ParametersMap . FindParameterAllocation ( ShaderBindingName , BufferIndex , BaseIndex , BoundSize ) )
{
BindingContext . ShaderGlobalScopeBindings . Add ( ShaderBindingName , ShaderBindingName ) ;
RootParameterBufferIndex = BufferIndex ;
}
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
{
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 ;
FShaderParameterReader ( const void * InData ) : Data ( reinterpret_cast < const uint8 * > ( InData ) ) { }
template < typename TParameterIn >
const void * GetRawPointer ( const TParameterIn & InParameter ) const
{
return ( Data + InParameter . ByteOffset ) ;
}
template < typename TParameterOut , typename TParameterIn >
const TParameterOut & Read ( const TParameterIn & InParameter ) const
{
return * reinterpret_cast < const TParameterOut * > ( Data + InParameter . ByteOffset ) ;
}
const uint8 * Data ;
} ;
2018-11-21 20:49:28 -05:00
# if DO_CHECK
2020-02-06 13:13:41 -05:00
void ValidateShaderParameters ( const TShaderRef < FShader > & Shader , const FShaderParametersMetadata * ParametersMetadata , const void * Parameters )
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-04-20 10:43:15 -04:00
const FShaderParameterReader Reader ( Parameters ) ;
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
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
}
}
break ;
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
}
}
break ;
case UBMT_RDG_TEXTURE_SRV :
case UBMT_RDG_TEXTURE_UAV :
case UBMT_RDG_BUFFER_SRV :
case UBMT_RDG_BUFFER_UAV :
{
2022-04-20 10:43:15 -04:00
const FRDGResource * GraphResource = Reader . Read < const FRDGResource * > ( Parameter ) ;
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
}
}
break ;
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 | |
Parameter . MemberType = = UBMT_RDG_TEXTURE_SRV | |
Parameter . MemberType = = UBMT_RDG_BUFFER_SRV ;
// 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
template < typename TRHICmdList >
2022-04-20 10:43:15 -04:00
inline void SetShaderUAV ( TRHICmdList & RHICmdList , FRHIGraphicsShader * ShaderRHI , FShaderParameterReader Reader , const FShaderParameterBindings : : FResourceParameter & ParameterBinding )
2022-04-13 13:29:15 -04:00
{
if ( ShaderRHI - > GetType ( ) = = RRT_PixelShader )
{
FRHIPixelShader * PixelShaderRHI = static_cast < FRHIPixelShader * > ( ShaderRHI ) ;
if ( ParameterBinding . BaseType = = UBMT_UAV )
{
2022-04-20 10:43:15 -04:00
FRHIUnorderedAccessView * ShaderParameterRef = Reader . Read < FRHIUnorderedAccessView * > ( ParameterBinding ) ;
2022-04-13 13:29:15 -04:00
RHICmdList . SetUAVParameter ( PixelShaderRHI , ParameterBinding . BaseIndex , ShaderParameterRef ) ;
}
else if ( ParameterBinding . BaseType = = UBMT_RDG_TEXTURE_UAV | | ParameterBinding . BaseType = = UBMT_RDG_BUFFER_UAV )
{
2022-04-20 10:43:15 -04:00
FRDGUnorderedAccessView * GraphUAV = Reader . Read < FRDGUnorderedAccessView * > ( ParameterBinding ) ;
2022-04-13 13:29:15 -04:00
checkSlow ( GraphUAV ) ;
2022-04-20 10:43:15 -04:00
2022-04-13 13:29:15 -04:00
GraphUAV - > MarkResourceAsUsed ( ) ;
RHICmdList . SetUAVParameter ( PixelShaderRHI , ParameterBinding . BaseIndex , GraphUAV - > GetRHI ( ) ) ;
}
}
else
{
checkf ( false , TEXT ( " TShaderRHI Can't have compute shader to be set. UAVs are not supported on vertex, tessellation and geometry shaders. " ) ) ;
}
}
template < typename TRHICmdList >
2022-04-20 10:43:15 -04:00
inline void SetShaderUAV ( TRHICmdList & RHICmdList , FRHIComputeShader * ShaderRHI , FShaderParameterReader Reader , const FShaderParameterBindings : : FResourceParameter & ParameterBinding )
2022-04-13 13:29:15 -04:00
{
if ( ParameterBinding . BaseType = = UBMT_UAV )
{
2022-04-20 10:43:15 -04:00
FRHIUnorderedAccessView * ShaderParameterRef = Reader . Read < FRHIUnorderedAccessView * > ( ParameterBinding ) ;
2022-04-13 13:29:15 -04:00
RHICmdList . SetUAVParameter ( ShaderRHI , ParameterBinding . BaseIndex , ShaderParameterRef ) ;
}
else if ( ParameterBinding . BaseType = = UBMT_RDG_TEXTURE_UAV | | ParameterBinding . BaseType = = UBMT_RDG_BUFFER_UAV )
{
2022-04-20 10:43:15 -04:00
FRDGUnorderedAccessView * GraphUAV = Reader . Read < FRDGUnorderedAccessView * > ( ParameterBinding ) ;
2022-04-13 13:29:15 -04:00
checkSlow ( GraphUAV ) ;
2022-04-20 10:43:15 -04:00
2022-04-13 13:29:15 -04:00
GraphUAV - > MarkResourceAsUsed ( ) ;
RHICmdList . SetUAVParameter ( ShaderRHI , ParameterBinding . BaseIndex , GraphUAV - > GetRHI ( ) ) ;
}
}
/** Set shader's parameters from its parameters struct. */
template < typename TRHICmdList , typename TShaderRHI >
inline void SetShaderParametersInternal (
TRHICmdList & RHICmdList ,
TShaderRHI * ShaderRHI ,
const FShaderParameterBindings & Bindings ,
const FShaderParametersMetadata * ParametersMetadata ,
const uint8 * Base )
{
checkf ( Bindings . RootParameterBufferIndex = = FShaderParameterBindings : : kInvalidBufferIndex , TEXT ( " Can't use SetShaderParameters() for root parameter buffer index. " ) ) ;
2022-04-20 10:43:15 -04:00
FShaderParameterReader Reader ( Base ) ;
2022-04-13 13:29:15 -04:00
// Parameters
2022-04-20 10:43:15 -04:00
for ( const FShaderParameterBindings : : FParameter & Parameter : Bindings . Parameters )
2022-04-13 13:29:15 -04:00
{
2022-04-20 10:43:15 -04:00
const void * DataPtr = Reader . GetRawPointer ( Parameter ) ;
RHICmdList . SetShaderParameter ( ShaderRHI , Parameter . BufferIndex , Parameter . BaseIndex , Parameter . ByteSize , DataPtr ) ;
2022-04-13 13:29:15 -04:00
}
TArray < FShaderParameterBindings : : FResourceParameter , TInlineAllocator < 16 > > GraphSRVs ;
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 * RHITexture = Reader . Read < FRHITexture * > ( Parameter ) ;
RHICmdList . SetShaderTexture ( ShaderRHI , Parameter . BaseIndex , RHITexture ) ;
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 ) ;
RHICmdList . SetShaderResourceViewParameter ( ShaderRHI , Parameter . BaseIndex , ShaderResourceView ) ;
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 ) ;
RHICmdList . SetShaderSampler ( ShaderRHI , 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 ( ) ;
RHICmdList . SetShaderTexture ( ShaderRHI , Parameter . BaseIndex , RDGTexture - > GetRHI ( ) ) ;
2022-04-13 13:29:15 -04:00
}
break ;
case UBMT_RDG_TEXTURE_SRV :
case UBMT_RDG_BUFFER_SRV :
{
//HACKHACK: defer SRVs binding after UAVs
2022-04-20 10:43:15 -04:00
GraphSRVs . Add ( Parameter ) ;
2022-04-13 13:29:15 -04:00
}
break ;
case UBMT_UAV :
case UBMT_RDG_TEXTURE_UAV :
case UBMT_RDG_BUFFER_UAV :
{
2022-04-20 10:43:15 -04:00
SetShaderUAV ( RHICmdList , ShaderRHI , Reader , Parameter ) ;
2022-04-13 13:29:15 -04:00
}
break ;
default :
checkf ( false , TEXT ( " Unhandled resource type? " ) ) ;
break ;
}
}
//HACKHACK: Bind SRVs after UAVs as a workaround for D3D11 RHI unbinding SRVs when binding a UAV on the same resource even when the views don't overlap.
2022-04-20 10:43:15 -04:00
for ( const FShaderParameterBindings : : FResourceParameter & Parameter : GraphSRVs )
2022-04-13 13:29:15 -04:00
{
2022-04-20 10:43:15 -04:00
FRDGShaderResourceView * RDGShaderResourceView = Reader . Read < FRDGShaderResourceView * > ( Parameter ) ;
checkSlow ( RDGShaderResourceView ) ;
RDGShaderResourceView - > MarkResourceAsUsed ( ) ;
2022-04-13 13:29:15 -04:00
2022-04-20 10:43:15 -04:00
RHICmdList . SetShaderResourceViewParameter ( ShaderRHI , Parameter . BaseIndex , RDGShaderResourceView - > GetRHI ( ) ) ;
2022-04-13 13:29:15 -04:00
}
// 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
if ( UniformBufferBinding . IsShader ( ) )
{
UniformBufferBinding - > MarkResourceAsUsed ( ) ;
2022-04-20 10:43:15 -04:00
RHICmdList . SetShaderUniformBuffer ( ShaderRHI , Parameter . BufferIndex , UniformBufferBinding - > GetRHI ( ) ) ;
2022-04-13 13:29:15 -04:00
}
}
// Reference structures
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 ) ;
2022-04-13 13:29:15 -04:00
if ( UniformBufferBinding . IsShader ( ) )
{
2022-04-20 10:43:15 -04:00
RHICmdList . SetShaderUniformBuffer ( ShaderRHI , Parameter . BufferIndex , UniformBufferBinding . GetUniformBuffer ( ) ) ;
2022-04-13 13:29:15 -04:00
}
}
}
void SetShaderParameters (
FRHIComputeCommandList & RHICmdList ,
FRHIComputeShader * ShaderRHI ,
const FShaderParameterBindings & Bindings ,
const FShaderParametersMetadata * ParametersMetadata ,
const uint8 * Base )
{
SetShaderParametersInternal ( RHICmdList , ShaderRHI , Bindings , ParametersMetadata , Base ) ;
}
void SetShaderParameters (
FRHICommandList & RHICmdList ,
FRHIGraphicsShader * ShaderRHI ,
const FShaderParameterBindings & Bindings ,
const FShaderParametersMetadata * ParametersMetadata ,
const uint8 * Base )
{
SetShaderParametersInternal ( RHICmdList , ShaderRHI , Bindings , ParametersMetadata , Base ) ;
}
void SetShaderParameters (
FRHICommandList & RHICmdList ,
FRHIComputeShader * ShaderRHI ,
const FShaderParameterBindings & Bindings ,
const FShaderParametersMetadata * ParametersMetadata ,
const uint8 * Base )
{
SetShaderParametersInternal ( RHICmdList , ShaderRHI , Bindings , ParametersMetadata , Base ) ;
}
# if RHI_RAYTRACING
void SetShaderParameters (
FRayTracingShaderBindingsWriter & RTBindingsWriter ,
const FShaderParameterBindings & Bindings ,
const FRHIUniformBufferLayout * RootUniformBufferLayout ,
const uint8 * Base )
{
2022-04-20 10:43:15 -04:00
const FShaderParameterReader Reader ( Base ) ;
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 :
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 ;
RTBindingsWriter . RootUniformBuffer = RHICreateUniformBuffer ( Base , RootUniformBufferLayout , UniformBuffer_SingleDraw , Validation ) ;
RTBindingsWriter . SetUniformBuffer ( Bindings . RootParameterBufferIndex , RTBindingsWriter . RootUniformBuffer ) ;
}
}
# endif // RHI_RAYTRACING