You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

129 lines
4.6 KiB

#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureXR.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/DepthPyramidConstants.cs.hlsl"
#pragma only_renderers d3d11 playstation xboxone xboxseries vulkan metal switch switch2
#pragma multi_compile_local _ ENABLE_CHECKERBOARD
#pragma kernel KDepthDownsample8DualUav KERNEL_NAME=KDepthDownsample8DualUav
RW_TEXTURE2D_X(float, _DepthMipChain);
#if UNITY_REVERSED_Z
#define MIN_DEPTH(A, B) max((A), (B))
#define MIN3_DEPTH(A, B, C) Max3((A), (B), (C))
#define MAX_DEPTH(A, B) min((A), (B))
#define MAX3_DEPTH(A, B, C) Min3((A), (B), (C))
#else
#define MIN_DEPTH(A, B) min((A), (B))
#define MIN3_DEPTH(A, B, C) Min3((A), (B), (C))
#define MAX_DEPTH(A, B) max((A), (B))
#define MAX3_DEPTH(A, B, C) Max3((A), (B), (C))
#endif
uint2 CoordInTileByIndex(uint i)
{
// decode i = [yxxyyx] (we want each pair of bits to have an x and a y)
return uint2(
(i & 1) | ((i >> 2) & 6),
((i >> 1) & 3) | ((i >> 3) & 4));
}
groupshared float s_minDepth[32];
#ifdef ENABLE_CHECKERBOARD
groupshared float s_maxDepth[32];
#endif
void SubgroupMergeDepths(uint threadID, uint bitIndex, inout float minDepth, inout float maxDepth)
{
uint highIndex = threadID >> (bitIndex + 1);
uint lowIndex = threadID & ((1 << (bitIndex + 1)) - 1);
if (lowIndex == (1 << bitIndex))
{
s_minDepth[highIndex] = minDepth;
#ifdef ENABLE_CHECKERBOARD
s_maxDepth[highIndex] = maxDepth;
#endif
}
GroupMemoryBarrierWithGroupSync();
if (lowIndex == 0)
{
minDepth = MIN_DEPTH(minDepth, s_minDepth[highIndex]);
#ifdef ENABLE_CHECKERBOARD
maxDepth = MAX_DEPTH(maxDepth, s_maxDepth[highIndex]);
#endif
}
GroupMemoryBarrierWithGroupSync();
}
float CheckerboardDepth(uint2 coord, float minDepth, float maxDepth)
{
return ((coord.x ^ coord.y) & 1) ? minDepth : maxDepth;
}
// Downsample a depth texture by taking the min value of sampled pixels
[numthreads(64, 1, 1)]
void KERNEL_NAME(uint threadID : SV_GroupThreadID, uint3 groupID : SV_GroupID)
{
UNITY_XR_ASSIGN_VIEW_INDEX(groupID.z);
// assign threads to pixels in a swizzle-like pattern
int2 dstCoord0 = (groupID.xy << 3) | CoordInTileByIndex(threadID);
int2 readOffsetUL = dstCoord0 << 1;
float p00 = _DepthMipChain[COORD_TEXTURE2D_X(_SrcOffset + min(readOffsetUL + int2(0, 0), _SrcLimit))];
float p10 = _DepthMipChain[COORD_TEXTURE2D_X(_SrcOffset + min(readOffsetUL + int2(1, 0), _SrcLimit))];
float p01 = _DepthMipChain[COORD_TEXTURE2D_X(_SrcOffset + min(readOffsetUL + int2(0, 1), _SrcLimit))];
float p11 = _DepthMipChain[COORD_TEXTURE2D_X(_SrcOffset + min(readOffsetUL + int2(1, 1), _SrcLimit))];
float minDepth = MIN3_DEPTH(p00, p10, MIN_DEPTH(p01, p11));
float maxDepth = MAX3_DEPTH(p00, p10, MAX_DEPTH(p01, p11));
// write dst0
if (all(dstCoord0 < _DstSize0))
{
_DepthMipChain[COORD_TEXTURE2D_X(_MinDstOffset0 + dstCoord0)] = minDepth;
#ifdef ENABLE_CHECKERBOARD
if (_CbDstCount >= 1)
_DepthMipChain[COORD_TEXTURE2D_X(_CbDstOffset0 + dstCoord0)] = CheckerboardDepth(dstCoord0, minDepth, maxDepth);
#endif
}
// merge to thread 0 in subgroup size 4
SubgroupMergeDepths(threadID, 0, minDepth, maxDepth);
SubgroupMergeDepths(threadID, 1, minDepth, maxDepth);
if (_MinDstCount >= 2 && (threadID & 0x3) == 0)
{
int2 dstCoord1 = dstCoord0 >> 1;
if (all(dstCoord1 < _DstSize1))
{
_DepthMipChain[COORD_TEXTURE2D_X(_MinDstOffset1 + dstCoord1)] = minDepth;
#ifdef ENABLE_CHECKERBOARD
if (_CbDstCount >= 2)
_DepthMipChain[COORD_TEXTURE2D_X(_CbDstOffset1 + dstCoord1)] = CheckerboardDepth(dstCoord1, minDepth, maxDepth);
#endif
}
}
// merge to thread 0 in subgroup size 16
SubgroupMergeDepths(threadID, 2, minDepth, maxDepth);
SubgroupMergeDepths(threadID, 3, minDepth, maxDepth);
if (_MinDstCount >= 3 && (threadID & 0xf) == 0)
{
int2 dstCoord2 = dstCoord0 >> 2;
if (all(dstCoord2 < _DstSize2))
_DepthMipChain[COORD_TEXTURE2D_X(_MinDstOffset2 + dstCoord2)] = minDepth;
}
// merge to thread 0
SubgroupMergeDepths(threadID, 4, minDepth, maxDepth);
SubgroupMergeDepths(threadID, 5, minDepth, maxDepth);
if (_MinDstCount >= 4 && (threadID & 0x3f) == 0)
{
int2 dstCoord3 = dstCoord0 >> 3;
if (all(dstCoord3 < _DstSize3))
_DepthMipChain[COORD_TEXTURE2D_X(_MinDstOffset3 + dstCoord3)] = minDepth;
}
}