// Copyright Epic Games, Inc. All Rights Reserved. /*============================================================================= ShaderParameters.h: Shader parameter inline definitions. =============================================================================*/ #pragma once #include "CoreMinimal.h" #include "RHI.h" #include "RHIUtilities.h" #include "ShaderParameters.h" #include "ShaderCore.h" #include "Misc/App.h" class FShaderMapPointerTable; template class TUniformBuffer; template class TUniformBufferRef; template class TShaderRefBase; template using TShaderRef = TShaderRefBase; template void SetShaderValue( FRHIBatchedShaderParameters& BatchedParameters , const FShaderParameter& Parameter , const ParameterType& Value , uint32 ElementIndex = 0 ) { // This will trigger if the parameter was not serialized checkSlow(Parameter.IsInitialized()); static_assert(!TIsPointer::Value, "Passing by value is not valid."); const uint32 AlignedTypeSize = Align(sizeof(ParameterType), SHADER_PARAMETER_ARRAY_ELEMENT_ALIGNMENT); const uint32 ElementByteOffset = ElementIndex * AlignedTypeSize; const int32 NumBytesToSet = FMath::Min(sizeof(ParameterType), static_cast(Parameter.GetNumBytes()) - ElementByteOffset); if (NumBytesToSet > 0) { BatchedParameters.SetShaderParameter( Parameter.GetBufferIndex(), Parameter.GetBaseIndex() + ElementByteOffset, (uint32)NumBytesToSet, &Value); } } template void SetShaderValueArray( FRHIBatchedShaderParameters& BatchedParameters , const FShaderParameter& Parameter , const ParameterType* Values , uint32 NumElements , uint32 ElementIndex = 0 ) { const uint32 AlignedTypeSize = Align(sizeof(ParameterType), SHADER_PARAMETER_ARRAY_ELEMENT_ALIGNMENT); const uint32 ElementByteOffset = ElementIndex * AlignedTypeSize; const int32 NumBytesToSet = FMath::Min(NumElements * AlignedTypeSize, Parameter.GetNumBytes() - ElementByteOffset); // This will trigger if the parameter was not serialized checkSlow(Parameter.IsInitialized()); if (NumBytesToSet > 0) { BatchedParameters.SetShaderParameter( Parameter.GetBufferIndex(), Parameter.GetBaseIndex() + ElementByteOffset, (uint32)NumBytesToSet, Values ); } } inline void SetTextureParameter(FRHIBatchedShaderParameters& BatchedParameters, const FShaderResourceParameter& Parameter, FRHITexture* TextureRHI) { if (Parameter.IsBound()) { #if PLATFORM_SUPPORTS_BINDLESS_RENDERING if (Parameter.GetType() == EShaderParameterType::BindlessResourceIndex) { BatchedParameters.SetBindlessTexture(Parameter.GetBaseIndex(), TextureRHI); } else #endif { BatchedParameters.SetShaderTexture(Parameter.GetBaseIndex(), TextureRHI); } } } inline void SetSamplerParameter(FRHIBatchedShaderParameters& BatchedParameters, const FShaderResourceParameter& Parameter, FRHISamplerState* SamplerStateRHI) { if (Parameter.IsBound()) { #if PLATFORM_SUPPORTS_BINDLESS_RENDERING if (Parameter.GetType() == EShaderParameterType::BindlessSamplerIndex) { BatchedParameters.SetBindlessSampler(Parameter.GetBaseIndex(), SamplerStateRHI); } else #endif { BatchedParameters.SetShaderSampler(Parameter.GetBaseIndex(), SamplerStateRHI); } } } inline void SetTextureParameter( FRHIBatchedShaderParameters& BatchedParameters, const FShaderResourceParameter& TextureParameter, const FShaderResourceParameter& SamplerParameter, FRHISamplerState* SamplerStateRHI, FRHITexture* TextureRHI ) { SetTextureParameter(BatchedParameters, TextureParameter, TextureRHI); SetSamplerParameter(BatchedParameters, SamplerParameter, SamplerStateRHI); } inline void SetTextureParameter( FRHIBatchedShaderParameters& BatchedParameters, const FShaderResourceParameter& TextureParameter, const FShaderResourceParameter& SamplerParameter, const FTexture* Texture ) { if (TextureParameter.IsBound()) { Texture->LastRenderTime = FApp::GetCurrentTime(); } SetTextureParameter(BatchedParameters, TextureParameter, Texture->TextureRHI); SetSamplerParameter(BatchedParameters, SamplerParameter, Texture->SamplerStateRHI); } inline void SetSRVParameter(FRHIBatchedShaderParameters& BatchedParameters, const FShaderResourceParameter& Parameter, FRHIShaderResourceView* SRV) { if (Parameter.IsBound()) { #if PLATFORM_SUPPORTS_BINDLESS_RENDERING if (Parameter.GetType() == EShaderParameterType::BindlessResourceIndex) { BatchedParameters.SetBindlessResourceView(Parameter.GetBaseIndex(), SRV); } else #endif { BatchedParameters.SetShaderResourceViewParameter(Parameter.GetBaseIndex(), SRV); } } } inline void SetUAVParameter(FRHIBatchedShaderParameters& BatchedParameters, const FShaderResourceParameter& Parameter, FRHIUnorderedAccessView* UAV) { if (Parameter.IsBound()) { #if PLATFORM_SUPPORTS_BINDLESS_RENDERING if (Parameter.GetType() == EShaderParameterType::BindlessResourceIndex) { BatchedParameters.SetBindlessUAV(Parameter.GetBaseIndex(), UAV); } else #endif { BatchedParameters.SetUAVParameter(Parameter.GetBaseIndex(), UAV); } } } inline void SetUniformBufferParameter(FRHIBatchedShaderParameters& BatchedParameters, const FShaderUniformBufferParameter& Parameter, FRHIUniformBuffer* UniformBufferRHI) { // This will trigger if the parameter was not serialized checkSlow(Parameter.IsInitialized()); // If it is bound, we must set it so something valid checkSlow(!Parameter.IsBound() || UniformBufferRHI); if (Parameter.IsBound()) { BatchedParameters.SetShaderUniformBuffer(Parameter.GetBaseIndex(), UniformBufferRHI); } } template inline void SetUniformBufferParameter(FRHIBatchedShaderParameters& BatchedParameters, const TShaderUniformBufferParameter& Parameter, const TUniformBufferRef& UniformBufferRef) { // This will trigger if the parameter was not serialized checkSlow(Parameter.IsInitialized()); // If it is bound, we must set it so something valid checkSlow(!Parameter.IsBound() || IsValidRef(UniformBufferRef)); if (Parameter.IsBound()) { SetUniformBufferParameter(BatchedParameters, Parameter, UniformBufferRef.GetReference()); } } template inline void SetUniformBufferParameter(FRHIBatchedShaderParameters& BatchedParameters, const TShaderUniformBufferParameter& Parameter, const TUniformBuffer& UniformBuffer) { // This will trigger if the parameter was not serialized checkSlow(Parameter.IsInitialized()); // If it is bound, we must set it so something valid checkSlow(!Parameter.IsBound() || UniformBuffer.GetUniformBufferRHI()); if (Parameter.IsBound()) { SetUniformBufferParameter(BatchedParameters, Parameter, UniformBuffer.GetUniformBufferRHI()); } } template inline void SetUniformBufferParameterImmediate(FRHIBatchedShaderParameters& BatchedParameters, const TShaderUniformBufferParameter& Parameter, const TBufferStruct& UniformBufferValue) { // This will trigger if the parameter was not serialized checkSlow(Parameter.IsInitialized()); if (Parameter.IsBound()) { FUniformBufferRHIRef UniformBufferRef = RHICreateUniformBuffer(&UniformBufferValue, &TBufferStruct::FTypeInfo::GetStructMetadata()->GetLayout(), UniformBuffer_SingleDraw); SetUniformBufferParameter(BatchedParameters, Parameter, UniformBufferRef.GetReference()); } } // Utility to set a single shader value on a shader. Should only be used if a shader requires only a single value. template void SetSingleShaderValue( TRHICmdList& RHICmdList , TShaderTypeRHI* InShaderRHI , const FShaderParameter& Parameter , const ParameterType& Value ) { FRHIBatchedShaderParameters& BatchedParameters = RHICmdList.GetScratchShaderParameters(); SetShaderValue(BatchedParameters, Parameter, Value); RHICmdList.SetBatchedShaderParameters(InShaderRHI, BatchedParameters); } // Mixed mode binding utilities /// Utility to set all legacy and non-legacy parameters for a shader. Requires the shader type to implement SetParameters(FRHIBatchedShaderParameters& BatchedParameters, ...) template inline void SetShaderParametersMixed( TRHICmdList& RHICmdList, const TShaderRef& InShader, TShaderTypeRHI* InShaderRHI, const typename TShaderType::FParameters& Parameters, TArguments&&... InArguments) { FRHIBatchedShaderParameters& BatchedParameters = RHICmdList.GetScratchShaderParameters(); // New Style first SetShaderParameters(BatchedParameters, InShader, Parameters); // Legacy second InShader->SetParameters(BatchedParameters, Forward(InArguments)...); RHICmdList.SetBatchedShaderParameters(InShaderRHI, BatchedParameters); } /// Utility to set all legacy and non-legacy parameters for a Vertex shader. Requires the shader type to implement SetParameters(FRHIBatchedShaderParameters& BatchedParameters, ...) template inline void SetShaderParametersMixedVS(TRHICmdList& RHICmdList, const TShaderRef& InShader, const typename TShaderType::FParameters& Parameters, TArguments&&... InArguments) { SetShaderParametersMixed(RHICmdList, InShader, InShader.GetVertexShader(), Parameters, Forward(InArguments)...); } /// Utility to set all legacy and non-legacy parameters for a Mesh shader. Requires the shader type to implement SetParameters(FRHIBatchedShaderParameters& BatchedParameters, ...) template inline void SetShaderParametersMixedMS(TRHICmdList& RHICmdList, const TShaderRef& InShader, const typename TShaderType::FParameters& Parameters, TArguments&&... InArguments) { SetShaderParametersMixed(RHICmdList, InShader, InShader.GetMeshShader(), Parameters, Forward(InArguments)...); } /// Utility to set all legacy and non-legacy parameters for an Amplification shader. Requires the shader type to implement SetParameters(FRHIBatchedShaderParameters& BatchedParameters, ...) template inline void SetShaderParametersMixedAS(TRHICmdList& RHICmdList, const TShaderRef& InShader, const typename TShaderType::FParameters& Parameters, TArguments&&... InArguments) { SetShaderParametersMixed(RHICmdList, InShader, InShader.GetAmplificationShader(), Parameters, Forward(InArguments)...); } /// Utility to set all legacy and non-legacy parameters for a Pixel shader. Requires the shader type to implement SetParameters(FRHIBatchedShaderParameters& BatchedParameters, ...) template inline void SetShaderParametersMixedPS(TRHICmdList& RHICmdList, const TShaderRef& InShader, const typename TShaderType::FParameters& Parameters, TArguments&&... InArguments) { SetShaderParametersMixed(RHICmdList, InShader, InShader.GetPixelShader(), Parameters, Forward(InArguments)...); } /// Utility to set all legacy and non-legacy parameters for a Geometry shader. Requires the shader type to implement SetParameters(FRHIBatchedShaderParameters& BatchedParameters, ...) template inline void SetShaderParametersMixedGS(TRHICmdList& RHICmdList, const TShaderRef& InShader, const typename TShaderType::FParameters& Parameters, TArguments&&... InArguments) { SetShaderParametersMixed(RHICmdList, InShader, InShader.GetGeometryShader(), Parameters, Forward(InArguments)...); } /// Utility to set all legacy and non-legacy parameters for a Compute shader. Requires the shader type to implement SetParameters(FRHIBatchedShaderParameters& BatchedParameters, ...) template inline void SetShaderParametersMixedCS(TRHICmdList& RHICmdList, const TShaderRef& InShader, const typename TShaderType::FParameters& Parameters, TArguments&&... InArguments) { SetShaderParametersMixed(RHICmdList, InShader, InShader.GetComputeShader(), Parameters, Forward(InArguments)...); } // Legacy binding utilities /// Utility to set all legacy parameters for a shader. Requires the shader type to implement SetParameters(FRHIBatchedShaderParameters& BatchedParameters, ...) template inline void SetShaderParametersLegacy(TRHICmdList& RHICmdList, const TShaderRef& InShader, TShaderTypeRHI* InShaderRHI, TArguments&&... InArguments) { FRHIBatchedShaderParameters& BatchedParameters = RHICmdList.GetScratchShaderParameters(); InShader->SetParameters(BatchedParameters, Forward(InArguments)...); RHICmdList.SetBatchedShaderParameters(InShaderRHI, BatchedParameters); } /// Utility to set all legacy parameters for a Vertex shader. Requires the shader type to implement SetParameters(FRHIBatchedShaderParameters& BatchedParameters, ...) template inline void SetShaderParametersLegacyVS(TRHICmdList& RHICmdList, const TShaderRef& InShader, TArguments&&... InArguments) { SetShaderParametersLegacy(RHICmdList, InShader, InShader.GetVertexShader(), Forward(InArguments)...); } /// Utility to set all legacy parameters for a Mesh shader. Requires the shader type to implement SetParameters(FRHIBatchedShaderParameters& BatchedParameters, ...) template inline void SetShaderParametersLegacyMS(TRHICmdList& RHICmdList, const TShaderRef& InShader, TArguments&&... InArguments) { SetShaderParametersLegacy(RHICmdList, InShader, InShader.GetMeshShader(), Forward(InArguments)...); } /// Utility to set all legacy parameters for an Amplification shader. Requires the shader type to implement SetParameters(FRHIBatchedShaderParameters& BatchedParameters, ...) template inline void SetShaderParametersLegacyAS(TRHICmdList& RHICmdList, const TShaderRef& InShader, TArguments&&... InArguments) { SetShaderParametersLegacy(RHICmdList, InShader, InShader.GetAmplificationShader(), Forward(InArguments)...); } /// Utility to set all legacy parameters for a Pixel shader. Requires the shader type to implement SetParameters(FRHIBatchedShaderParameters& BatchedParameters, ...) template inline void SetShaderParametersLegacyPS(TRHICmdList& RHICmdList, const TShaderRef& InShader, TArguments&&... InArguments) { SetShaderParametersLegacy(RHICmdList, InShader, InShader.GetPixelShader(), Forward(InArguments)...); } /// Utility to set all legacy parameters for a Geometry shader. Requires the shader type to implement SetParameters(FRHIBatchedShaderParameters& BatchedParameters, ...) template inline void SetShaderParametersLegacyGS(TRHICmdList& RHICmdList, const TShaderRef& InShader, TArguments&&... InArguments) { SetShaderParametersLegacy(RHICmdList, InShader, InShader.GetGeometryShader(), Forward(InArguments)...); } /// Utility to set all legacy parameters for a Compute shader. Requires the shader type to implement SetParameters(FRHIBatchedShaderParameters& BatchedParameters, ...) template inline void SetShaderParametersLegacyCS(TRHICmdList& RHICmdList, const TShaderRef& InShader, TArguments&&... InArguments) { SetShaderParametersLegacy(RHICmdList, InShader, InShader.GetComputeShader(), Forward(InArguments)...); } /// Utility to unset all legacy parameters for a Pixel shader. Requires the shader type to implement UnsetParameters(FRHIBatchedShaderParameters& BatchedParameters) template inline void UnsetShaderParametersLegacyPS(TRHICmdList& RHICmdList, const TShaderRef& InShader) { FRHIBatchedShaderParameters& BatchedParameters = RHICmdList.GetScratchShaderParameters(); InShader->UnsetParameters(BatchedParameters); RHICmdList.SetBatchedShaderParameters(InShader.GetPixelShader(), BatchedParameters); } /// Utility to unset all legacy parameters for a Compute shader. Requires the shader type to implement UnsetParameters(FRHIBatchedShaderParameters& BatchedParameters) template inline void UnsetShaderParametersLegacyCS(TRHICmdList& RHICmdList, const TShaderRef& InShader) { FRHIBatchedShaderParameters& BatchedParameters = RHICmdList.GetScratchShaderParameters(); InShader->UnsetParameters(BatchedParameters); RHICmdList.SetBatchedShaderParameters(InShader.GetComputeShader(), BatchedParameters); } /** * Sets the value of a shader parameter. Template'd on shader type * A template parameter specified the type of the parameter value. * NOTE: Shader should be the param ref type, NOT the param type, since Shader is passed by value. * Otherwise AddRef/ReleaseRef will be called many times. */ template UE_DEPRECATED(5.3, "SetShaderValue with FRHIBatchedShaderParameters should be used.") void SetShaderValue( TRHICmdList& RHICmdList, const ShaderRHIParamRef& Shader, const FShaderParameter& Parameter, const ParameterType& Value, uint32 ElementIndex = 0 ) { FRHIBatchedShaderParameters& BatchedParameters = RHICmdList.GetScratchShaderParameters(); SetShaderValue(BatchedParameters, Parameter, Value, ElementIndex); RHICmdList.SetBatchedShaderParameters(Shader, BatchedParameters); } template UE_DEPRECATED(5.3, "SetShaderValue with FRHIBatchedShaderParameters should be used.") void SetShaderValueOnContext( IRHICommandContext& RHICmdListContext, const ShaderRHIParamRef& Shader, const FShaderParameter& Parameter, const ParameterType& Value, uint32 ElementIndex = 0 ) { FRHIBatchedShaderParameters BatchedParameters; SetShaderValue(BatchedParameters, Parameter, Value, ElementIndex); RHICmdListContext.RHISetBatchedShaderParameters(Shader, BatchedParameters); } /** * Sets the value of a shader parameter array. Template'd on shader type * A template parameter specified the type of the parameter value. * NOTE: Shader should be the param ref type, NOT the param type, since Shader is passed by value. * Otherwise AddRef/ReleaseRef will be called many times. */ template UE_DEPRECATED(5.3, "SetShaderValueArray with FRHIBatchedShaderParameters should be used.") void SetShaderValueArray( TRHICmdList& RHICmdList, const ShaderRHIParamRef& Shader, const FShaderParameter& Parameter, const ParameterType* Values, uint32 NumElements, uint32 BaseElementIndex = 0 ) { FRHIBatchedShaderParameters& BatchedParameters = RHICmdList.GetScratchShaderParameters(); SetShaderValueArray(BatchedParameters, Parameter, Values, NumElements, BaseElementIndex); RHICmdList.SetBatchedShaderParameters(Shader, BatchedParameters); } /** Specialization of the above for C++ bool type. */ template UE_DEPRECATED(5.3, "SetShaderValueArray with FRHIBatchedShaderParameters should be used.") void SetShaderValueArray( TRHICmdList& RHICmdList, const ShaderRHIParamRef& Shader, const FShaderParameter& Parameter, const bool* Values, uint32 NumElements, uint32 BaseElementIndex = 0 ) { UE_LOG(LogShaders, Fatal, TEXT("SetShaderValueArray does not support bool arrays.")); } // LWC_TODO: Setting guards to catch attempts to pass a type with double components. Could just convert these to the correct type internally, but would prefer to catch potential issues + optimize where possible. #define GUARD_SETSHADERVALUE(_TYPE) \ template \ void SetShaderValue( TRHICmdList& RHICmdList, const ShaderRHIParamRef& Shader, const FShaderParameter& Parameter, \ const _TYPE##d& Value, uint32 ElementIndex = 0) { static_assert(sizeof(ShaderRHIParamRef) == 0, "Passing unsupported "#_TYPE"d. Requires "#_TYPE"f"); } \ template \ void SetShaderValueOnContext(IRHICommandContext& RHICmdListContext, const ShaderRHIParamRef& Shader, const FShaderParameter& Parameter, \ const _TYPE##d& Value, uint32 ElementIndex = 0) { static_assert(sizeof(ShaderRHIParamRef) == 0, "Passing unsupported "#_TYPE"d. Requires "#_TYPE"f"); } \ template \ void SetShaderValueArray(TRHICmdList& RHICmdList, const ShaderRHIParamRef& Shader, const FShaderParameter& Parameter, \ const _TYPE##d* Values, uint32 NumElements, uint32 BaseElementIndex = 0) { static_assert(sizeof(ShaderRHIParamRef) == 0, "Passing unsupported "#_TYPE"d*. Requires "#_TYPE"f*"); } \ // Primary GUARD_SETSHADERVALUE(FMatrix44) GUARD_SETSHADERVALUE(FVector2) GUARD_SETSHADERVALUE(FVector3) GUARD_SETSHADERVALUE(FVector4) GUARD_SETSHADERVALUE(FPlane4) GUARD_SETSHADERVALUE(FQuat4) // Secondary GUARD_SETSHADERVALUE(FSphere3) GUARD_SETSHADERVALUE(FBox3) /** * Sets the value of a shader surface parameter (e.g. to access MSAA samples). * Template'd on shader type (e.g. pixel shader or compute shader). */ template UE_DEPRECATED(5.2, "SetTextureParameter with an index can't be supported anymore. Your code should be changed to use shader parameter structs to utilize resource arrays.") FORCEINLINE void SetTextureParameter(TRHICmdList& RHICmdList, TRHIShader* Shader, const FShaderResourceParameter& Parameter, FRHITexture* TextureRHI, uint32 ElementIndex) { if (Parameter.IsBound() && ElementIndex < Parameter.GetNumResources()) { FRHIBatchedShaderParameters& BatchedParameters = RHICmdList.GetScratchShaderParameters(); #if PLATFORM_SUPPORTS_BINDLESS_RENDERING if (Parameter.GetType() == EShaderParameterType::BindlessResourceIndex) { checkf(ElementIndex == 0, TEXT("Bindless resources don't support element offsets")); BatchedParameters.SetBindlessTexture(Parameter.GetBaseIndex(), TextureRHI); } else #endif { BatchedParameters.SetShaderTexture(Parameter.GetBaseIndex() + ElementIndex, TextureRHI); } RHICmdList.SetBatchedShaderParameters(Shader, BatchedParameters); } } template UE_DEPRECATED(5.3, "SetTextureParameter with FRHIBatchedShaderParameters should be used.") FORCEINLINE void SetTextureParameter(TRHICmdList& RHICmdList, TRHIShader* Shader, const FShaderResourceParameter& Parameter, FRHITexture* TextureRHI) { FRHIBatchedShaderParameters& BatchedParameters = RHICmdList.GetScratchShaderParameters(); SetTextureParameter(BatchedParameters, Parameter, TextureRHI); RHICmdList.SetBatchedShaderParameters(Shader, BatchedParameters); } /** * Sets the value of a shader sampler parameter. Template'd on shader type. */ template UE_DEPRECATED(5.2, "SetSamplerParameter with an index can't be supported anymore. Your code should be changed to use shader parameter structs to utilize resource arrays.") FORCEINLINE void SetSamplerParameter(TRHICmdList& RHICmdList, TRHIShader* Shader, const FShaderResourceParameter& Parameter, FRHISamplerState* SamplerStateRHI, uint32 ElementIndex) { if (Parameter.IsBound() && ElementIndex < Parameter.GetNumResources()) { FRHIBatchedShaderParameters& BatchedParameters = RHICmdList.GetScratchShaderParameters(); #if PLATFORM_SUPPORTS_BINDLESS_RENDERING if (Parameter.GetType() == EShaderParameterType::BindlessSamplerIndex) { checkf(ElementIndex == 0, TEXT("Bindless resources don't support element offsets")); BatchedParameters.SetBindlessSampler(Parameter.GetBaseIndex(), SamplerStateRHI); } else #endif { BatchedParameters.SetShaderSampler(Parameter.GetBaseIndex() + ElementIndex, SamplerStateRHI); } RHICmdList.SetBatchedShaderParameters(Shader, BatchedParameters); } } template UE_DEPRECATED(5.3, "SetSamplerParameter with FRHIBatchedShaderParameters should be used.") FORCEINLINE void SetSamplerParameter(TRHICmdList& RHICmdList, TRHIShader* Shader, const FShaderResourceParameter& Parameter, FRHISamplerState* SamplerStateRHI) { FRHIBatchedShaderParameters& BatchedParameters = RHICmdList.GetScratchShaderParameters(); SetSamplerParameter(BatchedParameters, Parameter, SamplerStateRHI); RHICmdList.SetBatchedShaderParameters(Shader, BatchedParameters); } /** * Sets the value of a shader texture parameter. Template'd on shader type. */ template UE_DEPRECATED(5.2, "SetTextureParameter with an index can't be supported anymore. Your code should be changed to use shader parameter structs to utilize resource arrays.") FORCEINLINE void SetTextureParameter( TRHICmdList& RHICmdList, TRHIShader* Shader, const FShaderResourceParameter& TextureParameter, const FShaderResourceParameter& SamplerParameter, FRHISamplerState* SamplerStateRHI, FRHITexture* TextureRHI, uint32 ElementIndex ) { PRAGMA_DISABLE_DEPRECATION_WARNINGS SetTextureParameter(RHICmdList, Shader, TextureParameter, TextureRHI, ElementIndex); // @todo UE samplerstate Should we maybe pass in two separate values? SamplerElement and TextureElement? Or never allow an array of samplers? Unsure best // if there is a matching sampler for this texture array index (ElementIndex), then set it. This will help with this case: // Texture2D LightMapTextures[NUM_LIGHTMAP_COEFFICIENTS]; // SamplerState LightMapTexturesSampler; // In this case, we only set LightMapTexturesSampler when ElementIndex is 0, we don't set the sampler state for all 4 textures // This assumes that the all textures want to use the same sampler state SetSamplerParameter(RHICmdList, Shader, SamplerParameter, SamplerStateRHI, ElementIndex); PRAGMA_ENABLE_DEPRECATION_WARNINGS } template FORCEINLINE void SetTextureParameter(TRHICmdList& RHICmdList, TRHIShader* Shader, const FShaderResourceParameter& TextureParameter, const FShaderResourceParameter& SamplerParameter, FRHISamplerState* SamplerStateRHI, FRHITexture* TextureRHI) { FRHIBatchedShaderParameters& BatchedParameters = RHICmdList.GetScratchShaderParameters(); SetTextureParameter(BatchedParameters, TextureParameter, SamplerParameter, SamplerStateRHI, TextureRHI); RHICmdList.SetBatchedShaderParameters(Shader, BatchedParameters); } /** * Sets the value of a shader texture parameter. Template'd on shader type */ template UE_DEPRECATED(5.2, "SetTextureParameter with an index can't be supported anymore. Your code should be changed to use shader parameter structs to utilize resource arrays.") FORCEINLINE void SetTextureParameter( TRHICmdList& RHICmdList, TRHIShader* Shader, const FShaderResourceParameter& TextureParameter, const FShaderResourceParameter& SamplerParameter, const FTexture* Texture, uint32 ElementIndex ) { if (TextureParameter.IsBound()) { Texture->LastRenderTime = FApp::GetCurrentTime(); } PRAGMA_DISABLE_DEPRECATION_WARNINGS SetTextureParameter(RHICmdList, Shader, TextureParameter, Texture->TextureRHI, ElementIndex); SetSamplerParameter(RHICmdList, Shader, SamplerParameter, Texture->SamplerStateRHI, ElementIndex); PRAGMA_ENABLE_DEPRECATION_WARNINGS } template UE_DEPRECATED(5.3, "SetTextureParameter with FRHIBatchedShaderParameters should be used.") FORCEINLINE void SetTextureParameter(TRHICmdList& RHICmdList, TRHIShader* Shader, const FShaderResourceParameter& TextureParameter, const FShaderResourceParameter& SamplerParameter, const FTexture* Texture) { FRHIBatchedShaderParameters& BatchedParameters = RHICmdList.GetScratchShaderParameters(); SetTextureParameter(BatchedParameters, TextureParameter, SamplerParameter, Texture); RHICmdList.SetBatchedShaderParameters(Shader, BatchedParameters); } /** * Sets the value of a shader resource view parameter * Template'd on shader type (e.g. pixel shader or compute shader). */ template UE_DEPRECATED(5.3, "SetSRVParameter with FRHIBatchedShaderParameters should be used.") FORCEINLINE void SetSRVParameter(TRHICmdList& RHICmdList, TRHIShader* Shader, const FShaderResourceParameter& Parameter, FRHIShaderResourceView* SRV) { FRHIBatchedShaderParameters& BatchedParameters = RHICmdList.GetScratchShaderParameters(); SetSRVParameter(BatchedParameters, Parameter, SRV); RHICmdList.SetBatchedShaderParameters(Shader, BatchedParameters); } template UE_DEPRECATED(5.3, "SetSRVParameter with FRHIBatchedShaderParameters should be used.") FORCEINLINE void SetSRVParameter(TRHICmdList& RHICmdList, const TRefCountPtr& Shader, const FShaderResourceParameter& Parameter, FRHIShaderResourceView* SRV) { FRHIBatchedShaderParameters& BatchedParameters = RHICmdList.GetScratchShaderParameters(); SetSRVParameter(BatchedParameters, Parameter, SRV); RHICmdList.SetBatchedShaderParameters(Shader.GetReference(), BatchedParameters); } template UE_DEPRECATED(5.3, "SetUAVParameter with FRHIBatchedShaderParameters should be used.") FORCEINLINE void SetUAVParameterSafeShader(TRHICmdList& RHICmdList, TRHIShader* Shader, const FShaderResourceParameter& Parameter, FRHIUnorderedAccessView* UAV) { FRHIBatchedShaderParameters& BatchedParameters = RHICmdList.GetScratchShaderParameters(); SetUAVParameter(BatchedParameters, Parameter, UAV); RHICmdList.SetBatchedShaderParameters(Shader, BatchedParameters); } UE_DEPRECATED(5.3, "SetUAVParameter with FRHIBatchedShaderParameters should be used.") FORCEINLINE void SetUAVParameter(FRHIComputeCommandList& RHICmdList, FRHIComputeShader* Shader, const FShaderResourceParameter& Parameter, FRHIUnorderedAccessView* UAV) { FRHIBatchedShaderParameters& BatchedParameters = RHICmdList.GetScratchShaderParameters(); SetUAVParameter(BatchedParameters, Parameter, UAV); RHICmdList.SetBatchedShaderParameters(Shader, BatchedParameters); } UE_DEPRECATED(5.3, "SetUAVParameter with FRHIBatchedShaderParameters should be used.") FORCEINLINE void SetUAVParameter(FRHICommandList& RHICmdList, FRHIPixelShader* Shader, const FShaderResourceParameter& Parameter, FRHIUnorderedAccessView* UAV) { FRHIBatchedShaderParameters& BatchedParameters = RHICmdList.GetScratchShaderParameters(); SetUAVParameter(BatchedParameters, Parameter, UAV); RHICmdList.SetBatchedShaderParameters(Shader, BatchedParameters); } template UE_DEPRECATED(5.3, "SetUAVParameter with FRHIBatchedShaderParameters should be used.") inline bool SetUAVParameterIfCS(TRHICmdList& RHICmdList, FRHIVertexShader* Shader, const FShaderResourceParameter& UAVParameter, FRHIUnorderedAccessView* UAV) { return false; } template UE_DEPRECATED(5.3, "SetUAVParameter with FRHIBatchedShaderParameters should be used.") inline bool SetUAVParameterIfCS(TRHICmdList& RHICmdList, FRHIPixelShader* Shader, const FShaderResourceParameter& UAVParameter, FRHIUnorderedAccessView* UAV) { PRAGMA_DISABLE_DEPRECATION_WARNINGS SetUAVParameter(RHICmdList, Shader, UAVParameter, UAV); PRAGMA_ENABLE_DEPRECATION_WARNINGS return UAVParameter.IsBound(); } template UE_DEPRECATED(5.3, "SetUAVParameter with FRHIBatchedShaderParameters should be used.") inline bool SetUAVParameterIfCS(TRHICmdList& RHICmdList, FRHIGeometryShader* Shader, const FShaderResourceParameter& UAVParameter, FRHIUnorderedAccessView* UAV) { return false; } template UE_DEPRECATED(5.3, "SetUAVParameter with FRHIBatchedShaderParameters should be used.") inline bool SetUAVParameterIfCS(TRHICmdList& RHICmdList, FRHIComputeShader* Shader, const FShaderResourceParameter& UAVParameter, FRHIUnorderedAccessView* UAV) { PRAGMA_DISABLE_DEPRECATION_WARNINGS SetUAVParameter(RHICmdList, Shader, UAVParameter, UAV); PRAGMA_ENABLE_DEPRECATION_WARNINGS return UAVParameter.IsBound(); } PRAGMA_DISABLE_DEPRECATION_WARNINGS template inline void FRWShaderParameter::SetBuffer(TRHICmdList& RHICmdList, const TShaderRHIRef& Shader, const FRWBuffer& RWBuffer) const { if (!SetUAVParameterIfCS(RHICmdList, Shader, UAVParameter, RWBuffer.UAV)) { SetSRVParameter(RHICmdList, Shader, SRVParameter, RWBuffer.SRV); } } template inline void FRWShaderParameter::SetBuffer(TRHICmdList& RHICmdList, const TShaderRHIRef& Shader, const FRWBufferStructured& RWBuffer) const { if (!SetUAVParameterIfCS(RHICmdList, Shader, UAVParameter, RWBuffer.UAV)) { SetSRVParameter(RHICmdList, Shader, SRVParameter, RWBuffer.SRV); } } template inline void FRWShaderParameter::SetTexture(TRHICmdList& RHICmdList, const TShaderRHIRef& Shader, FRHITexture* Texture, FRHIUnorderedAccessView* UAV) const { if (!SetUAVParameterIfCS(RHICmdList, Shader, UAVParameter, UAV)) { SetTextureParameter(RHICmdList, Shader, SRVParameter, Texture); } } template inline void FRWShaderParameter::SetUAV(TRHICmdList& RHICmdList, FRHIComputeShader* ComputeShader, FRHIUnorderedAccessView* UAV) const { SetUAVParameter(RHICmdList, ComputeShader, UAVParameter, UAV); } template inline void FRWShaderParameter::UnsetUAV(TRHICmdList& RHICmdList, FRHIComputeShader* ComputeShader) const { SetUAVParameter(RHICmdList, ComputeShader,UAVParameter,FUnorderedAccessViewRHIRef()); } PRAGMA_ENABLE_DEPRECATION_WARNINGS /** Sets the value of a shader uniform buffer parameter to a uniform buffer containing the struct. */ template UE_DEPRECATED(5.3, "SetUniformBufferParameter with FRHIBatchedShaderParameters should be used.") inline void SetUniformBufferParameter( TRHICmdList& RHICmdList, const TShaderRHIRef& Shader, const FShaderUniformBufferParameter& Parameter, FRHIUniformBuffer* UniformBufferRHI ) { FRHIBatchedShaderParameters& BatchedParameters = RHICmdList.GetScratchShaderParameters(); SetUniformBufferParameter(BatchedParameters, Parameter, UniformBufferRHI); RHICmdList.SetBatchedShaderParameters(Shader, BatchedParameters); } /** Sets the value of a shader uniform buffer parameter to a uniform buffer containing the struct. */ template UE_DEPRECATED(5.3, "SetUniformBufferParameter with FRHIBatchedShaderParameters should be used.") inline void SetUniformBufferParameter( TRHICmdList& RHICmdList, const TShaderRHIRef& Shader, const TShaderUniformBufferParameter& Parameter, const TUniformBufferRef& UniformBufferRef ) { FRHIBatchedShaderParameters& BatchedParameters = RHICmdList.GetScratchShaderParameters(); SetUniformBufferParameter(BatchedParameters, Parameter, UniformBufferRef); RHICmdList.SetBatchedShaderParameters(Shader, BatchedParameters); } /** Sets the value of a shader uniform buffer parameter to a uniform buffer containing the struct. */ template UE_DEPRECATED(5.3, "SetUniformBufferParameter with FRHIBatchedShaderParameters should be used.") inline void SetUniformBufferParameter( TRHICmdList& RHICmdList, const TShaderRHIRef& Shader, const TShaderUniformBufferParameter& Parameter, const TUniformBuffer& UniformBuffer ) { FRHIBatchedShaderParameters& BatchedParameters = RHICmdList.GetScratchShaderParameters(); SetUniformBufferParameter(BatchedParameters, Parameter, UniformBuffer); RHICmdList.SetBatchedShaderParameters(Shader, BatchedParameters); } /** Sets the value of a shader uniform buffer parameter to a value of the struct. */ template UE_DEPRECATED(5.3, "SetUniformBufferParameterImmediate with FRHIBatchedShaderParameters should be used.") inline void SetUniformBufferParameterImmediate( FRHICommandList& RHICmdList, const TShaderRHIRef& Shader, const TShaderUniformBufferParameter& Parameter, const TBufferStruct& UniformBufferValue ) { FRHIBatchedShaderParameters& BatchedParameters = RHICmdList.GetScratchShaderParameters(); SetUniformBufferParameterImmediate(BatchedParameters, Parameter, UniformBufferValue); RHICmdList.SetBatchedShaderParameters(Shader, BatchedParameters); } /** Sets the value of a shader uniform buffer parameter to a value of the struct. */ template UE_DEPRECATED(5.3, "SetUniformBufferParameterImmediate with FRHIBatchedShaderParameters should be used.") inline void SetUniformBufferParameterImmediate( TRHICmdList& RHICmdList, const TShaderRHIRef& Shader, const TShaderUniformBufferParameter& Parameter, const TBufferStruct& UniformBufferValue ) { FRHIBatchedShaderParameters& BatchedParameters = RHICmdList.GetScratchShaderParameters(); SetUniformBufferParameterImmediate(BatchedParameters, Parameter, UniformBufferValue); RHICmdList.SetBatchedShaderParameters(Shader, BatchedParameters); }