136 lines
2.6 KiB
HLSL
136 lines
2.6 KiB
HLSL
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "BloomCommon.ush"
|
|
|
|
|
|
//------------------------------------------------------- CONSTANTS
|
|
|
|
#define TILE_SIZE 8
|
|
|
|
|
|
//------------------------------------------------------- PARAMETERS
|
|
|
|
/*
|
|
uint
|
|
uint
|
|
float
|
|
uint
|
|
* */
|
|
uint2 KernelSpatialTextureSize;
|
|
Texture2D KernelSpatialTexture;
|
|
|
|
RWCoherentStructuredBuffer(uint) KernelCenterCoordOutput;
|
|
|
|
|
|
//------------------------------------------------------- LDS
|
|
|
|
groupshared uint MaxLuminance;
|
|
groupshared uint2 MaxLuminancePixelPos;
|
|
groupshared uint CurrentMaxLuminance;
|
|
groupshared uint bDone;
|
|
groupshared uint PrevLock;
|
|
|
|
|
|
//------------------------------------------------------- ENTRY POINT
|
|
|
|
[numthreads(TILE_SIZE, TILE_SIZE, 1)]
|
|
void MainCS(
|
|
uint2 GroupId : SV_GroupID,
|
|
uint GroupThreadIndex : SV_GroupIndex)
|
|
{
|
|
// Init LDS
|
|
if (GroupThreadIndex == 0)
|
|
{
|
|
MaxLuminance = 0;
|
|
bDone = 0;
|
|
}
|
|
|
|
GroupMemoryBarrierWithGroupSync();
|
|
|
|
uint2 InputPixelPos = TILE_SIZE * GroupId + uint2(GroupThreadIndex % TILE_SIZE, GroupThreadIndex / TILE_SIZE);
|
|
|
|
float4 TexelColor = KernelSpatialTexture[InputPixelPos];
|
|
|
|
bool bValidPixel = all(InputPixelPos < KernelSpatialTextureSize);
|
|
|
|
if (!bValidPixel)
|
|
{
|
|
TexelColor = 0.0;
|
|
}
|
|
|
|
// Locate the position of the brightest pixel
|
|
{
|
|
float TexelLuminance = Luminance(TexelColor.rgb);
|
|
|
|
InterlockedMax(MaxLuminance, asuint(TexelLuminance));
|
|
|
|
GroupMemoryBarrierWithGroupSync();
|
|
|
|
if (MaxLuminance == asuint(TexelLuminance))
|
|
{
|
|
MaxLuminancePixelPos = InputPixelPos;
|
|
}
|
|
}
|
|
|
|
GroupMemoryBarrierWithGroupSync();
|
|
|
|
if (MaxLuminance == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
while (bDone == 0)
|
|
{
|
|
if (GroupThreadIndex == 0)
|
|
{
|
|
CurrentMaxLuminance = KernelCenterCoordOutput[2];
|
|
}
|
|
|
|
GroupMemoryBarrierWithGroupSync();
|
|
|
|
if (MaxLuminance > CurrentMaxLuminance)
|
|
{
|
|
if (GroupThreadIndex == 0)
|
|
{
|
|
uint LocalPrevLock;
|
|
InterlockedCompareExchange(
|
|
KernelCenterCoordOutput[3],
|
|
uint(0),
|
|
uint(1),
|
|
/* out */ LocalPrevLock);
|
|
|
|
PrevLock = LocalPrevLock;
|
|
}
|
|
|
|
GroupMemoryBarrierWithGroupSync();
|
|
|
|
if (PrevLock == 0)
|
|
{
|
|
AllMemoryBarrier();
|
|
|
|
if (GroupThreadIndex == 0 && MaxLuminance > KernelCenterCoordOutput[2])
|
|
{
|
|
KernelCenterCoordOutput[0] = MaxLuminancePixelPos.x;
|
|
KernelCenterCoordOutput[1] = MaxLuminancePixelPos.y;
|
|
KernelCenterCoordOutput[2] = MaxLuminance;
|
|
}
|
|
|
|
AllMemoryBarrier();
|
|
|
|
if (GroupThreadIndex == 0)
|
|
{
|
|
uint Unused;
|
|
InterlockedExchange(KernelCenterCoordOutput[3], 0, Unused);
|
|
}
|
|
bDone += 1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bDone += 1;
|
|
}
|
|
|
|
GroupMemoryBarrierWithGroupSync();
|
|
}
|
|
}
|