mirror of
https://bitbucket.org/CPMADevs/cnq3
synced 2024-11-10 06:31:48 +00:00
added depth min/max generation pass
This commit is contained in:
parent
490617de7a
commit
c737a2833f
9 changed files with 186 additions and 1 deletions
|
@ -499,6 +499,7 @@ struct CRP : IRenderPipeline
|
|||
void BlitRenderTarget(HTexture destination, const char* passName);
|
||||
void DrawSceneView(const drawSceneViewCommand_t& cmd);
|
||||
void UploadSceneViewData();
|
||||
void BuildDepthPyramid();
|
||||
|
||||
HTexture GetReadRenderTarget();
|
||||
HTexture GetWriteRenderTarget();
|
||||
|
@ -508,6 +509,7 @@ struct CRP : IRenderPipeline
|
|||
float frameSeed;
|
||||
HTexture readbackRenderTarget;
|
||||
HTexture depthTexture;
|
||||
HTexture depthMinMaxTexture;
|
||||
HTexture normalTexture;
|
||||
HTexture motionVectorTexture; // raw, for TAA/denoisers/etc
|
||||
HTexture motionVectorMBTexture; // mangled, for motion blur only
|
||||
|
@ -523,6 +525,7 @@ struct CRP : IRenderPipeline
|
|||
HTexture blueNoise2D;
|
||||
FreezeFrame::Id freezeFrame;
|
||||
HTexture frozenTexture;
|
||||
HPipeline depthPyramidPipeline;
|
||||
|
||||
// blit
|
||||
HPipeline blitPipelineLDR;
|
||||
|
|
|
@ -33,6 +33,7 @@ along with Challenge Quake 3. If not, see <https://www.gnu.org/licenses/>.
|
|||
#include "compshaders/crp/mip_1.h"
|
||||
#include "compshaders/crp/mip_2.h"
|
||||
#include "compshaders/crp/mip_3.h"
|
||||
#include "compshaders/crp/depth_pyramid.h"
|
||||
|
||||
|
||||
struct SceneViewConst
|
||||
|
@ -47,6 +48,15 @@ struct SceneViewConst
|
|||
};
|
||||
};
|
||||
|
||||
#pragma pack(push, 4)
|
||||
struct DepthPyramidRC
|
||||
{
|
||||
uint32_t destTextureIndices[7];
|
||||
uint32_t depthTextureIndex;
|
||||
uint32_t depthSamplerIndex;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
|
||||
CRP crp;
|
||||
IRenderPipeline* crpp = &crp;
|
||||
|
@ -436,12 +446,21 @@ void CRP::Init()
|
|||
desc.committedResource = true;
|
||||
desc.shortLifeTime = true;
|
||||
desc.initialState = ResourceStates::DepthWriteBit;
|
||||
desc.allowedState = ResourceStates::DepthAccessBits | ResourceStates::PixelShaderAccessBit;
|
||||
desc.allowedState = ResourceStates::DepthAccessBits | ResourceStates::PixelShaderAccessBit | ResourceStates::ComputeShaderAccessBit;
|
||||
desc.format = TextureFormat::Depth32_Float;
|
||||
desc.SetClearDepthStencil(0.0f, 0);
|
||||
depthTexture = RHI::CreateTexture(desc);
|
||||
}
|
||||
|
||||
{
|
||||
TextureDesc desc("depth pyramid", glConfig.vidWidth, glConfig.vidHeight, 7);
|
||||
desc.shortLifeTime = true;
|
||||
desc.initialState = ResourceStates::UnorderedAccessBit;
|
||||
desc.allowedState = ResourceStates::UnorderedAccessBit | ResourceStates::PixelShaderAccessBit | ResourceStates::ComputeShaderAccessBit;
|
||||
desc.format = TextureFormat::R32G32_Float;
|
||||
depthMinMaxTexture = RHI::CreateTexture(desc);
|
||||
}
|
||||
|
||||
{
|
||||
TextureDesc desc("GBuffer normals", glConfig.vidWidth, glConfig.vidHeight);
|
||||
desc.committedResource = true;
|
||||
|
@ -509,6 +528,8 @@ void CRP::Init()
|
|||
blitPipelineHDR = CreateGraphicsPipeline(desc);
|
||||
}
|
||||
|
||||
depthPyramidPipeline = CreateComputePipeline("Depth Pyramid", ShaderByteCode(g_depth_pyramid_cs));
|
||||
|
||||
{
|
||||
BufferDesc desc("scene view upload #1", SceneViewConst::BufferBytes, ResourceStates::ShaderAccessBits);
|
||||
desc.shortLifeTime = true;
|
||||
|
@ -993,6 +1014,30 @@ void CRP::UploadSceneViewData()
|
|||
sceneViewIndex++;
|
||||
}
|
||||
|
||||
void CRP::BuildDepthPyramid()
|
||||
{
|
||||
SCOPED_RENDER_PASS("Depth Pyramid", 1.0f, 1.0f, 1.0f);
|
||||
|
||||
CmdBeginBarrier();
|
||||
CmdTextureBarrier(depthTexture, ResourceStates::ComputeShaderAccessBit);
|
||||
CmdTextureBarrier(depthMinMaxTexture, ResourceStates::UnorderedAccessBit);
|
||||
CmdEndBarrier();
|
||||
|
||||
DepthPyramidRC rc = {};
|
||||
for(uint32_t i = 0; i < ARRAY_LEN(rc.destTextureIndices); i++)
|
||||
{
|
||||
rc.destTextureIndices[i] = GetTextureIndexUAV(depthMinMaxTexture, i);
|
||||
}
|
||||
rc.depthTextureIndex = GetTextureIndexSRV(depthTexture);
|
||||
rc.depthSamplerIndex = GetSamplerIndex(TW_CLAMP_TO_EDGE, TextureFilter::Point);
|
||||
|
||||
const int w = glConfig.vidWidth / 2;
|
||||
const int h = glConfig.vidHeight / 2;
|
||||
CmdBindPipeline(depthPyramidPipeline);
|
||||
CmdSetComputeRootConstants(0, sizeof(rc), &rc);
|
||||
CmdDispatch((w + 7) / 8, (h + 7) / 8, 1);
|
||||
}
|
||||
|
||||
void CRP::ReadPixels(int w, int h, int alignment, colorSpace_t colorSpace, void* outPixels)
|
||||
{
|
||||
ReadTextureImage(outPixels, readbackRenderTarget, w, h, alignment, colorSpace);
|
||||
|
|
|
@ -396,3 +396,27 @@ float2 PolarToCartesian(float2 polar)
|
|||
|
||||
return cartesian;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T min3(T v0, T v1, T v2)
|
||||
{
|
||||
return min(v0, min(v1, v2));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T max3(T v0, T v1, T v2)
|
||||
{
|
||||
return max(v0, max(v1, v2));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T min4(T v0, T v1, T v2, T v3)
|
||||
{
|
||||
return min(min(v0, v1), min(v2, v3));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T max4(T v0, T v1, T v2, T v3)
|
||||
{
|
||||
return max(max(v0, v1), max(v2, v3));
|
||||
}
|
||||
|
|
100
code/renderer/shaders/crp/depth_pyramid.hlsl
Normal file
100
code/renderer/shaders/crp/depth_pyramid.hlsl
Normal file
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2024 Gian 'myT' Schellenbaum
|
||||
|
||||
This file is part of Challenge Quake 3 (CNQ3).
|
||||
|
||||
Challenge Quake 3 is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Challenge Quake 3 is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Challenge Quake 3. If not, see <https://www.gnu.org/licenses/>.
|
||||
===========================================================================
|
||||
*/
|
||||
// outputs min/max depth values for mip levels 0 to 7 in one go
|
||||
|
||||
|
||||
#include "common.hlsli"
|
||||
|
||||
|
||||
cbuffer RootConstants
|
||||
{
|
||||
uint destTextureIndex0;
|
||||
uint destTextureIndex1;
|
||||
uint destTextureIndex2;
|
||||
uint destTextureIndex3;
|
||||
uint destTextureIndex4;
|
||||
uint destTextureIndex5;
|
||||
uint destTextureIndex6;
|
||||
uint depthTextureIndex;
|
||||
uint depthSamplerIndex;
|
||||
}
|
||||
|
||||
groupshared float2 s_depth[32][32];
|
||||
|
||||
void ProcessMip(uint threadCount, uint scale, uint destTextureIndex, uint3 gtid, uint3 gid, bool writeToSM)
|
||||
{
|
||||
if(gtid.x < threadCount && gtid.y < threadCount)
|
||||
{
|
||||
uint2 baseCoords = gtid.xy * scale * 2;
|
||||
uint4 coords = uint4(baseCoords, baseCoords + scale.xx);
|
||||
float2 v0 = s_depth[coords.x][coords.y];
|
||||
float2 v1 = s_depth[coords.x][coords.w];
|
||||
float2 v2 = s_depth[coords.z][coords.y];
|
||||
float2 v3 = s_depth[coords.z][coords.w];
|
||||
float minZ = min4(v0.x, v1.x, v2.x, v3.x);
|
||||
float maxZ = max4(v0.y, v1.y, v2.y, v3.y);
|
||||
float2 minMaxZ = float2(minZ, maxZ);
|
||||
if(writeToSM)
|
||||
{
|
||||
s_depth[coords.x][coords.y] = minMaxZ;
|
||||
}
|
||||
RWTexture2D<float2> dst = ResourceDescriptorHeap[destTextureIndex];
|
||||
dst[gid.xy * threadCount + gtid.xy] = minMaxZ;
|
||||
}
|
||||
}
|
||||
|
||||
[numthreads(32, 32, 1)]
|
||||
void cs(uint3 dtid : SV_DispatchThreadID, uint3 gtid : SV_GroupThreadID, uint3 gid : SV_GroupID)
|
||||
{
|
||||
Texture2D<float> depthTexture = ResourceDescriptorHeap[depthTextureIndex];
|
||||
SamplerState depthSampler = SamplerDescriptorHeap[depthSamplerIndex];
|
||||
RWTexture2D<float2> dst0 = ResourceDescriptorHeap[destTextureIndex0];
|
||||
RWTexture2D<float2> dst1 = ResourceDescriptorHeap[destTextureIndex1];
|
||||
float2 depthTextureSize = float2(GetTextureSize(depthTexture));
|
||||
|
||||
// GatherRed order: x=(0, 1), y=(1, 1), z=(1, 0), w=(0, 0)
|
||||
float2 tc = (float2(dtid.xy * 2) + float2(0.5, 0.5)) / depthTextureSize;
|
||||
float4 mip0 = depthTexture.GatherRed(depthSampler, tc);
|
||||
float minZ = min4(mip0.x, mip0.y, mip0.z, mip0.w);
|
||||
float maxZ = max4(mip0.x, mip0.y, mip0.z, mip0.w);
|
||||
float2 minMaxZ = float2(minZ, maxZ);
|
||||
s_depth[gtid.x][gtid.y] = minMaxZ;
|
||||
dst0[dtid.xy * 2 + int2(0, 0)] = mip0.ww;
|
||||
dst0[dtid.xy * 2 + int2(0, 1)] = mip0.xx;
|
||||
dst0[dtid.xy * 2 + int2(1, 0)] = mip0.zz;
|
||||
dst0[dtid.xy * 2 + int2(1, 1)] = mip0.yy;
|
||||
dst1[dtid.xy] = minMaxZ;
|
||||
|
||||
GroupMemoryBarrierWithGroupSync();
|
||||
ProcessMip(16, 1, destTextureIndex2, gtid, gid, true);
|
||||
|
||||
GroupMemoryBarrierWithGroupSync();
|
||||
ProcessMip(8, 2, destTextureIndex3, gtid, gid, true);
|
||||
|
||||
GroupMemoryBarrierWithGroupSync();
|
||||
ProcessMip(4, 4, destTextureIndex4, gtid, gid, true);
|
||||
|
||||
GroupMemoryBarrierWithGroupSync();
|
||||
ProcessMip(2, 8, destTextureIndex5, gtid, gid, true);
|
||||
|
||||
GroupMemoryBarrierWithGroupSync();
|
||||
ProcessMip(1, 16, destTextureIndex6, gtid, gid, false);
|
||||
}
|
|
@ -440,6 +440,7 @@ void ProcessCRP()
|
|||
CompileCompute("mblur_tile_max.h", "mblur_tile_max.hlsl", "tile_max");
|
||||
CompilePixelShader("mblur_blur.h", "mblur_blur.hlsl", "blur");
|
||||
CompilePixelShader("mblur_pack.h", "mblur_pack.hlsl", "pack");
|
||||
CompileCompute("depth_pyramid.h", "depth_pyramid.hlsl", "depth_pyramid");
|
||||
}
|
||||
|
||||
int main(int /*argc*/, const char** argv)
|
||||
|
|
|
@ -193,6 +193,9 @@
|
|||
<FxCompile Include="..\..\code\renderer\shaders\crp\blit.hlsl">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</FxCompile>
|
||||
<FxCompile Include="..\..\code\renderer\shaders\crp\depth_pyramid.hlsl">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</FxCompile>
|
||||
<FxCompile Include="..\..\code\renderer\shaders\crp\dl_denoising.hlsl">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</FxCompile>
|
||||
|
|
|
@ -97,6 +97,9 @@
|
|||
<FxCompile Include="..\..\code\renderer\shaders\crp\blit.hlsl">
|
||||
<Filter>shaders\crp</Filter>
|
||||
</FxCompile>
|
||||
<FxCompile Include="..\..\code\renderer\shaders\crp\depth_pyramid.hlsl">
|
||||
<Filter>shaders\crp</Filter>
|
||||
</FxCompile>
|
||||
<FxCompile Include="..\..\code\renderer\shaders\crp\dl_denoising.hlsl">
|
||||
<Filter>shaders\crp</Filter>
|
||||
</FxCompile>
|
||||
|
|
|
@ -195,6 +195,9 @@
|
|||
<FxCompile Include="..\..\code\renderer\shaders\crp\blit.hlsl">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</FxCompile>
|
||||
<FxCompile Include="..\..\code\renderer\shaders\crp\depth_pyramid.hlsl">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</FxCompile>
|
||||
<FxCompile Include="..\..\code\renderer\shaders\crp\dl_denoising.hlsl">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</FxCompile>
|
||||
|
|
|
@ -97,6 +97,9 @@
|
|||
<FxCompile Include="..\..\code\renderer\shaders\crp\blit.hlsl">
|
||||
<Filter>shaders\crp</Filter>
|
||||
</FxCompile>
|
||||
<FxCompile Include="..\..\code\renderer\shaders\crp\depth_pyramid.hlsl">
|
||||
<Filter>shaders\crp</Filter>
|
||||
</FxCompile>
|
||||
<FxCompile Include="..\..\code\renderer\shaders\crp\dl_denoising.hlsl">
|
||||
<Filter>shaders\crp</Filter>
|
||||
</FxCompile>
|
||||
|
|
Loading…
Reference in a new issue