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
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
|
|
|
|
#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;
|
|
}
|
|
}
|