91 lines
4.0 KiB
HLSL
91 lines
4.0 KiB
HLSL
#ifndef PROBE_VOLUME_LIGHT_LOOP_DEF
|
|
#define PROBE_VOLUME_LIGHT_LOOP_DEF
|
|
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/LightLoop.cs.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/ProbeVolume/ProbeVolumeShaderVariables.hlsl"
|
|
|
|
#ifndef SCALARIZE_LIGHT_LOOP
|
|
// We perform scalarization only for forward rendering as for deferred loads will already be scalar since tiles will match waves and therefore all threads will read from the same tile.
|
|
// More info on scalarization: https://flashypixels.wordpress.com/2018/11/10/intro-to-gpu-scalarization-part-2-scalarize-all-the-lights/
|
|
#define SCALARIZE_LIGHT_LOOP (defined(PLATFORM_SUPPORTS_WAVE_INTRINSICS) && !defined(LIGHTLOOP_DISABLE_TILE_AND_CLUSTER) && SHADERPASS == SHADERPASS_FORWARD)
|
|
#endif
|
|
|
|
void ProbeVolumeGetCountAndStart(PositionInputs posInput, out uint probeVolumeStart, out uint probeVolumeCount)
|
|
{
|
|
#ifndef LIGHTLOOP_DISABLE_TILE_AND_CLUSTER
|
|
// Access probe volume data from standard lightloop light list data structure.
|
|
GetCountAndStart(posInput, LIGHTCATEGORY_PROBE_VOLUME, probeVolumeStart, probeVolumeCount);
|
|
#else // LIGHTLOOP_DISABLE_TILE_AND_CLUSTER
|
|
probeVolumeCount = _ProbeVolumeCount;
|
|
probeVolumeStart = 0;
|
|
#endif
|
|
}
|
|
|
|
void ProbeVolumeGetCountAndStartAndFastPath(PositionInputs posInput, out uint probeVolumeStart, out uint probeVolumeCount, out bool fastPath)
|
|
{
|
|
fastPath = false;
|
|
|
|
#if SCALARIZE_LIGHT_LOOP
|
|
// Fast path is when we all pixels in a wave is accessing same tile or cluster.
|
|
uint probeVolumeStartFirstLane = WaveReadLaneFirst(probeVolumeStart);
|
|
fastPath = WaveActiveAllTrue(probeVolumeStart == probeVolumeStartFirstLane);
|
|
if (fastPath)
|
|
{
|
|
probeVolumeStart = probeVolumeStartFirstLane;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
uint ProbeVolumeFetchIndex(uint probeVolumeStart, uint probeVolumeOffset)
|
|
{
|
|
// Access probe volume data from standard lightloop light list data structure.
|
|
return FetchIndex(probeVolumeStart, probeVolumeOffset);
|
|
}
|
|
|
|
// This function scalarize an index accross all lanes. To be effecient it must be used in the context
|
|
// of the scalarization of a loop. It is to use with IsFastPath so it can optimize the number of
|
|
// element to load, which is optimal when all the lanes are contained into a tile.
|
|
uint ProbeVolumeScalarizeElementIndex(uint v_elementIdx, bool fastPath)
|
|
{
|
|
uint s_elementIdx = v_elementIdx;
|
|
#if SCALARIZE_LIGHT_LOOP
|
|
if (!fastPath)
|
|
{
|
|
// If we are not in fast path, v_elementIdx is not scalar, so we need to query the Min value across the wave.
|
|
s_elementIdx = WaveActiveMin(v_elementIdx);
|
|
// If WaveActiveMin returns 0xffffffff it means that all lanes are actually dead, so we can safely ignore the loop and move forward.
|
|
// This could happen as an helper lane could reach this point, hence having a valid v_elementIdx, but their values will be ignored by the WaveActiveMin
|
|
if (s_elementIdx == -1)
|
|
{
|
|
return -1;
|
|
}
|
|
}
|
|
// Note that the WaveReadLaneFirst should not be needed, but the compiler might insist in putting the result in VGPR.
|
|
// However, we are certain at this point that the index is scalar.
|
|
s_elementIdx = WaveReadLaneFirst(s_elementIdx);
|
|
#endif
|
|
return s_elementIdx;
|
|
}
|
|
|
|
bool ProbeVolumeIsAllWavesComplete(float weightHierarchy, int volumeBlendMode)
|
|
{
|
|
// Probe volumes are sorted primarily by blend mode, and secondarily by size.
|
|
// This means we will evaluate all Additive and Subtractive blending volumes first, and finally our Normal (over) blending volumes.
|
|
// This allows us to early out if our weightHierarchy reaches 1.0, since we know we will only ever process more VOLUMEBLENDMODE_NORMAL volumes,
|
|
// whos weight will always evaluate to zero.
|
|
#if defined(PLATFORM_SUPPORTS_WAVE_INTRINSICS)
|
|
if (WaveActiveMin(weightHierarchy) >= 1.0
|
|
#if SHADEROPTIONS_PROBE_VOLUMES_ADDITIVE_BLENDING
|
|
&& WaveActiveAllTrue(volumeBlendMode == VOLUMEBLENDMODE_NORMAL)
|
|
#endif
|
|
)
|
|
{
|
|
return true;
|
|
}
|
|
#endif
|
|
|
|
return false;
|
|
}
|
|
|
|
#endif // endof PROBE_VOLUME_LIGHT_LOOP_DEF
|