Skip to content

Commit 7efa78a

Browse files
Scope: Added feature to wait a fence to be triggered (o3de#17569)
* Optionally use timeline semaphores for Vulkan Fences * Scope: Added fences to wait for Signed-off-by: Martin Sattlecker <[email protected]> Co-authored-by: Martin Winter <[email protected]>
1 parent ee2edcb commit 7efa78a

29 files changed

+398
-85
lines changed

Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/DeviceFeatures.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,10 @@ namespace AZ::RHI
9696
//! Whether swapchain scaling support is available.
9797
RHI::ScalingFlags m_swapchainScalingFlags = RHI::ScalingFlags::None;
9898

99+
//! Whether fences can be signalled from the CPU
100+
//! If this is false, the Fence::SignalOnCpu inserts the signal command into a queue
101+
bool m_signalFenceFromCPU = false;
102+
99103
/// Additional features here.
100104
};
101105
}

Gems/Atom/RHI/Code/Include/Atom/RHI/FrameGraph.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ namespace AZ::RHI
110110
void ExecuteAfter(const ScopeId& scopeId);
111111
void ExecuteBefore(const ScopeId& scopeId);
112112
void SignalFence(Fence& fence);
113+
void WaitFence(Fence& fence);
113114
void SetEstimatedItemCount(uint32_t itemCount);
114115
void SetHardwareQueueClass(HardwareQueueClass hardwareQueueClass);
115116

Gems/Atom/RHI/Code/Include/Atom/RHI/FrameGraphInterface.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,13 @@ namespace AZ::RHI
208208
{
209209
m_frameGraph.SignalFence(fence);
210210
}
211-
211+
212+
//! Requests that the provided fence be waited for before the scope has started.
213+
void WaitFence(Fence& fence)
214+
{
215+
m_frameGraph.WaitFence(fence);
216+
}
217+
212218
//! Sets the number of work items (Draw / Dispatch / etc) that will be processed by
213219
//! this scope. This value is used to load-balance the scope across command lists. A small
214220
//! value may result in the scope being merged onto a single command list, whereas a large

Gems/Atom/RHI/Code/Include/Atom/RHI/Scope.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,9 @@ namespace AZ::RHI
117117
//! Returns a list of fences to signal on completion of the scope.
118118
const AZStd::vector<Ptr<Fence>>& GetFencesToSignal() const;
119119

120+
//! Returns a list of fences to wait for before start of the scope.
121+
const AZStd::vector<Ptr<Fence>>& GetFencesToWaitFor() const;
122+
120123
//! Initializes the scope.
121124
void Init(const ScopeId& scopeId, HardwareQueueClass hardwareQueueClass = HardwareQueueClass::Graphics);
122125

@@ -240,6 +243,9 @@ namespace AZ::RHI
240243
/// The set of fences to signal on scope completion.
241244
AZStd::vector<Ptr<Fence>> m_fencesToSignal;
242245

246+
/// The set of fences to wait for before scope has started.
247+
AZStd::vector<Ptr<Fence>> m_fencesToWaitFor;
248+
243249
/// The set query pools.
244250
AZStd::vector<Ptr<QueryPool>> m_queryPools;
245251
};

Gems/Atom/RHI/Code/Source/RHI/FrameGraph.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,11 @@ namespace AZ::RHI
429429
m_currentScope->m_fencesToSignal.push_back(&fence);
430430
}
431431

432+
void FrameGraph::WaitFence(Fence& fence)
433+
{
434+
m_currentScope->m_fencesToWaitFor.push_back(&fence);
435+
}
436+
432437
ResultCode FrameGraph::TopologicalSort()
433438
{
434439
struct NodeId

Gems/Atom/RHI/Code/Source/RHI/Scope.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ namespace AZ::RHI
9191
m_bufferAttachments.clear();
9292
m_swapChainsToPresent.clear();
9393
m_fencesToSignal.clear();
94+
m_fencesToWaitFor.clear();
9495
m_resourcePoolResolves.clear();
9596
m_queryPools.clear();
9697
}
@@ -222,6 +223,11 @@ namespace AZ::RHI
222223
return m_fencesToSignal;
223224
}
224225

226+
const AZStd::vector<Ptr<Fence>>& Scope::GetFencesToWaitFor() const
227+
{
228+
return m_fencesToWaitFor;
229+
}
230+
225231
Scope* Scope::GetProducerByQueue(HardwareQueueClass hardwareQueueClass) const
226232
{
227233
return m_producersByQueue[static_cast<size_t>(hardwareQueueClass)];

Gems/Atom/RHI/DX12/Code/Source/RHI/CommandQueue.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,11 @@ namespace AZ
144144
static const uint32_t CommandListCountMax = 128;
145145
ID3D12CommandQueue* dx12CommandQueue = static_cast<ID3D12CommandQueue*>(commandQueue);
146146

147+
for (Fence* fence : request.m_userFencesToWaitFor)
148+
{
149+
dx12CommandQueue->Wait(fence->Get(), fence->GetPendingValue());
150+
}
151+
147152
for (size_t producerQueueIdx = 0; producerQueueIdx < request.m_waitFences.size(); ++producerQueueIdx)
148153
{
149154
if (const uint64_t fenceValue = request.m_waitFences[producerQueueIdx])

Gems/Atom/RHI/DX12/Code/Source/RHI/CommandQueue.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ namespace AZ
3434

3535
/// A set of user fences to signal after executing the command lists.
3636
AZStd::vector<Fence*> m_userFencesToSignal;
37+
38+
/// A set of user fences to wait for before executing the command lists.
39+
AZStd::vector<Fence*> m_userFencesToWaitFor;
3740
};
3841

3942
enum class HardwareQueueSubclass

Gems/Atom/RHI/DX12/Code/Source/RHI/Device.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,8 @@ namespace AZ
298298
RHI::ShadingRateFlags::Rate4x4;
299299
}
300300

301+
m_features.m_signalFenceFromCPU = true;
302+
301303
m_limits.m_shadingRateTileSize = RHI::Size(options6.ShadingRateImageTileSize, options6.ShadingRateImageTileSize, 1);
302304
#endif
303305

Gems/Atom/RHI/DX12/Code/Source/RHI/FrameGraphExecuteGroupMerged.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,16 @@ namespace AZ
5454
fencesToSignal.push_back(&static_cast<FenceImpl&>(*fence).Get());
5555
}
5656
}
57+
58+
{
59+
auto& fencesToWaitFor = m_workRequest.m_userFencesToWaitFor;
60+
61+
fencesToWaitFor.reserve(fencesToWaitFor.size() + scope->GetFencesToWaitFor().size());
62+
for (const RHI::Ptr<RHI::Fence>& fence : scope->GetFencesToWaitFor())
63+
{
64+
fencesToWaitFor.push_back(&static_cast<FenceImpl&>(*fence).Get());
65+
}
66+
}
5767
}
5868

5969
InitMergedRequest request;

0 commit comments

Comments
 (0)