Skip to content

Commit ea64570

Browse files
Added DepthRangeCalculator class
1 parent 19cbfe6 commit ea64570

File tree

6 files changed

+569
-0
lines changed

6 files changed

+569
-0
lines changed

Components/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ set(SOURCE
88
"${CMAKE_CURRENT_SOURCE_DIR}/src/VectorFieldRenderer.cpp"
99
"${CMAKE_CURRENT_SOURCE_DIR}/src/ToneMapping.cpp"
1010
"${CMAKE_CURRENT_SOURCE_DIR}/src/CoordinateGridRenderer.cpp"
11+
"${CMAKE_CURRENT_SOURCE_DIR}/src/DepthRangeCalculator.cpp"
1112
)
1213

1314
set(INCLUDE
@@ -18,6 +19,7 @@ set(INCLUDE
1819
"${CMAKE_CURRENT_SOURCE_DIR}/interface/VectorFieldRenderer.hpp"
1920
"${CMAKE_CURRENT_SOURCE_DIR}/interface/ToneMapping.hpp"
2021
"${CMAKE_CURRENT_SOURCE_DIR}/interface/CoordinateGridRenderer.hpp"
22+
"${CMAKE_CURRENT_SOURCE_DIR}/interface/DepthRangeCalculator.hpp"
2123
)
2224

2325
target_sources(DiligentFX PRIVATE ${SOURCE} ${INCLUDE})
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
/*
2+
* Copyright 2025 Diligent Graphics LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
* In no event and under no legal theory, whether in tort (including negligence),
17+
* contract, or otherwise, unless required by applicable law (such as deliberate
18+
* and grossly negligent acts) or agreed to in writing, shall any Contributor be
19+
* liable for any damages, including any direct, indirect, special, incidental,
20+
* or consequential damages of any character arising as a result of this License or
21+
* out of the use or inability to use the software (including but not limited to damages
22+
* for loss of goodwill, work stoppage, computer failure or malfunction, or any and
23+
* all other commercial damages or losses), even if such Contributor has been advised
24+
* of the possibility of such damages.
25+
*/
26+
27+
#include "../../../DiligentCore/Graphics/GraphicsEngine/interface/RenderDevice.h"
28+
#include "../../../DiligentCore/Graphics/GraphicsEngine/interface/DeviceContext.h"
29+
#include "../../../DiligentCore/Graphics/GraphicsTools/interface/RenderStateCache.h"
30+
#include "../../../DiligentCore/Graphics/GraphicsTools/interface/GPUCompletionAwaitQueue.hpp"
31+
#include "../../../DiligentCore/Common/interface/RefCntAutoPtr.hpp"
32+
33+
namespace Diligent
34+
{
35+
36+
/// Computes depth range from the scene depth buffer.
37+
///
38+
/// The class uses a compute shader to read the depth buffer and compute the near and far
39+
/// depth values. It writes the results to a buffer with the following layout:
40+
///
41+
/// struct DepthRange
42+
/// {
43+
/// float SceneNearZ;
44+
/// float SceneFarZ;
45+
/// float SceneNearDepth;
46+
/// float SceneFarDepth;
47+
/// };
48+
///
49+
/// SceneNearZ is always less than SceneFarZ.
50+
/// SceneNearDepth is the depth value corresponding to SceneNearZ.
51+
/// SceneFarDepth is the depth value corresponding to SceneFarZ.
52+
/// Note that if reverse depth is used, SceneNearDepth will be greater than SceneFarDepth.
53+
///
54+
/// \remarks SceneNearZ and SceneFarZ must be positive values.
55+
class DepthRangeCalculator
56+
{
57+
public:
58+
/// Depth range calculator create info.
59+
struct CreateInfo
60+
{
61+
/// Render device.
62+
IRenderDevice* pDevice = nullptr;
63+
64+
/// An optional render state cache.
65+
IRenderStateCache* pStateCache = nullptr;
66+
67+
/// Whether shader matrices are laid out in row-major order in GPU memory.
68+
///
69+
/// \remarks By default, shader matrices are laid out in column-major order
70+
/// in GPU memory. If this option is set to true, shaders will be compiled
71+
/// with the SHADER_COMPILE_FLAG_PACK_MATRIX_ROW_MAJOR flag and
72+
/// use the row-major layout.
73+
bool PackMatrixRowMajor = false;
74+
75+
/// Whether to compile shaders asynchronously.
76+
bool AsyncShaders = false;
77+
78+
/// Whether to read back the depth range data to the CPU.
79+
bool ReadBackData = false;
80+
};
81+
82+
/// Constructs a depth range calculator object.
83+
///
84+
/// \param [in] CI Create info.
85+
///
86+
/// In case of failure, an exception is thrown.
87+
DepthRangeCalculator(const CreateInfo& CI) noexcept(false);
88+
89+
/// Returns true if the depth range calculator is ready to be used.
90+
bool IsReady() const
91+
{
92+
return m_ComputeDepthRangePSO && m_ComputeDepthRangePSO->GetStatus() == PIPELINE_STATE_STATUS_READY;
93+
}
94+
95+
/// Creates a shader resource binding object to use in ComputeRange() method.
96+
RefCntAutoPtr<IShaderResourceBinding> CreateSRB(ITextureView* pDepthBufferSRV,
97+
IBuffer* pCameraAttribs);
98+
99+
/// Attributes for ComputeRange() method.
100+
struct ComputeRangeAttribs
101+
{
102+
/// Device context to use for command recording.
103+
IDeviceContext* pContext = nullptr;
104+
105+
/// Shader resource binding object.
106+
///
107+
/// The SRB must be created using the CreateSRB() method.
108+
IShaderResourceBinding* pSRB = nullptr;
109+
110+
/// Depth buffer width.
111+
Uint32 Width = 0;
112+
113+
/// Depth buffer height.
114+
Uint32 Height = 0;
115+
};
116+
117+
/// Computes the depth range.
118+
///
119+
/// \param [in] Attribs Method attributes.
120+
///
121+
/// The near/far depth values are written to the depth range buffer.
122+
/// If the ReadBackData option was set to true in the CreateInfo structure,
123+
/// the depth range will also be read back to the CPU and can be accessed using
124+
/// the GetDepthRange() method.
125+
///
126+
/// Note that the data read back to the CPU is typically a few frames behind the GPU.
127+
void ComputeRange(const ComputeRangeAttribs& Attribs);
128+
129+
/// Returns the depth range buffer.
130+
IBuffer* GetDepthRangeBuffer() const
131+
{
132+
return m_DepthRangeBuff;
133+
}
134+
135+
struct DepthRange
136+
{
137+
float fSceneNearZ = 0;
138+
float fSceneFarZ = 0;
139+
float fSceneNearDepth = 0;
140+
float fSceneFarDepth = 0;
141+
};
142+
143+
/// Returns the depth range read back to the CPU.
144+
///
145+
/// \param [in] pCtx If not null, the function will poll the read back queue for the latest data.
146+
/// \return The depth range read back to the CPU.
147+
const DepthRange& GetDepthRange(IDeviceContext* pCtx = nullptr);
148+
149+
private:
150+
void PollReadBackQueue(IDeviceContext* pCtx);
151+
152+
private:
153+
RefCntAutoPtr<IRenderDevice> m_pDevice;
154+
RefCntAutoPtr<IPipelineResourceSignature> m_Signature;
155+
RefCntAutoPtr<IPipelineState> m_ClearDepthRangePSO;
156+
RefCntAutoPtr<IPipelineState> m_ComputeDepthRangePSO;
157+
158+
using DepthRangeReadBackQueueType = GPUCompletionAwaitQueue<RefCntAutoPtr<IBuffer>>;
159+
std::unique_ptr<DepthRangeReadBackQueueType> m_DepthRangeReadBackQueue;
160+
161+
RefCntAutoPtr<IBuffer> m_DepthRangeBuff;
162+
163+
DepthRange m_DepthRange;
164+
};
165+
166+
} // namespace Diligent

0 commit comments

Comments
 (0)