Skip to content

Commit 824f5e8

Browse files
committed
Refactor command list flushing with proper mutex locking and cleanup
1 parent b353330 commit 824f5e8

3 files changed

Lines changed: 31 additions & 29 deletions

File tree

src/vrhi_backend.cpp

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@
2525
#include <komihash/komihash.h>
2626

2727
vhCmdBackendState g_vhCmdBackendState;
28+
void vhCmdListFlushAll_DeviceStateLocked();
2829

29-
// Static member definitions
3030
std::unordered_map< nvrhi::BindingLayoutHandle, vhBackendShader* > vhCmdBackendState::s_layoutToShader;
3131
vhStateResolveCache vhCmdBackendState::s_resolveCache;
3232
std::unordered_map< uint32_t, vhShaderReflectionResource* > vhCmdBackendState::s_slotToReflection;
@@ -1886,33 +1886,27 @@ void vhCmdBackendState::Handle_vhCmdSetStateAttachments( VIDL_vhCmdSetStateAttac
18861886
void vhCmdBackendState::Handle_vhFlushInternal( VIDL_vhFlushInternal* cmd )
18871887
{
18881888
BE_CmdRAII cmdRAII( cmd );
1889+
std::lock_guard< std::mutex > lock( g_nvRHIStateMutex );
18891890

1890-
// TODO: Flush all transient buffer maps here.
1891-
{
1892-
std::lock_guard<std::mutex> lock( g_nvRHIStateMutex );
1893-
m_globalUniformBuffer.Unmap_DeviceStateLocked();
1894-
}
1891+
// Flush and step transient buffer maps here.
1892+
// This needs to be done *before* we flush the command lists to GPU!!
1893+
m_globalUniformBuffer.Unmap_DeviceStateLocked();
1894+
m_globalUniformBuffer.Step();
1895+
m_globalUniformBufferLastHash = 0;
18951896

1897+
// Send it!!
1898+
vhCmdListFlushAll_DeviceStateLocked();
18961899

18971900
// Free all cmd memory allocations, because hitting this flush means all previous commands have been processed.
18981901
{
1899-
std::lock_guard<std::mutex> lock( g_vhMemListMutex );
1902+
std::lock_guard< std::mutex > lock( g_vhMemListMutex );
19001903
g_vhMemList.clear();
19011904
}
1902-
1903-
// This uses g_nvRHIStateMutex then gives it up, we need to avoid double-locking.
1904-
vhCmdListFlushAll();
1905-
1905+
if ( cmd->waitForGPU )
19061906
{
1907-
std::lock_guard< std::mutex > lock( g_nvRHIStateMutex );
1908-
if ( cmd->waitForGPU )
1909-
{
1910-
g_vhDevice->waitForIdle();
1911-
}
1912-
g_vhDevice->runGarbageCollection();
1913-
m_globalUniformBuffer.Step();
1914-
m_globalUniformBufferLastHash = 0;
1907+
g_vhDevice->waitForIdle();
19151908
}
1909+
g_vhDevice->runGarbageCollection();
19161910

19171911
// Notify caller that we're done.
19181912
// Safety warning : fence is probably from stack of caller

src/vrhi_internal.cpp

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -126,14 +126,14 @@ nvrhi::CommandListHandle vhCmdListGet( nvrhi::CommandQueue type )
126126
// - Copy feeds Compute and Graphics
127127
// - Compute feeds Graphics
128128
//
129-
void vhCmdListFlush_SingleQueueInternal( nvrhi::CommandQueue type )
129+
void vhCmdListFlush_SingleQueueInternal_DeviceStateLocked( nvrhi::CommandQueue type )
130130
{
131+
// WARNING: Lock g_nvRHIStateMutex before calling this.
131132
auto typeIdx = ( uint64_t ) type;
132133
uint64_t instance = 0;
133134

134135
if ( g_vhCmdLists[typeIdx] )
135136
{
136-
std::lock_guard<std::mutex> lock( g_nvRHIStateMutex );
137137
g_vhCmdLists[typeIdx]->close();
138138

139139
// Execute and get the instance ID for synchronisation
@@ -160,20 +160,22 @@ void vhCmdListFlush_SingleQueueInternal( nvrhi::CommandQueue type )
160160

161161
void vhCmdListFlush( nvrhi::CommandQueue type )
162162
{
163+
std::lock_guard< std::mutex > lock( g_nvRHIStateMutex );
164+
163165
// Both queues depend on copy; flush copy first
164166
if ( type == nvrhi::CommandQueue::Graphics || type == nvrhi::CommandQueue::Compute )
165167
{
166-
vhCmdListFlush_SingleQueueInternal( nvrhi::CommandQueue::Copy );
168+
vhCmdListFlush_SingleQueueInternal_DeviceStateLocked( nvrhi::CommandQueue::Copy );
167169
}
168170

169171
// Graphics depends on compute; flush compute first
170172
if ( type == nvrhi::CommandQueue::Graphics )
171173
{
172-
vhCmdListFlush_SingleQueueInternal( nvrhi::CommandQueue::Compute );
174+
vhCmdListFlush_SingleQueueInternal_DeviceStateLocked( nvrhi::CommandQueue::Compute );
173175
}
174176

175177
// Flush the requested queue
176-
vhCmdListFlush_SingleQueueInternal( type );
178+
vhCmdListFlush_SingleQueueInternal_DeviceStateLocked( type );
177179
}
178180

179181
void vhCmdListFlushTransferIfNeeded()
@@ -186,13 +188,20 @@ void vhCmdListFlushTransferIfNeeded()
186188
}
187189
}
188190

189-
void vhCmdListFlushAll()
191+
void vhCmdListFlushAll_DeviceStateLocked()
190192
{
193+
// WARNING: Lock g_nvRHIStateMutex before calling this.
191194
// The order here matters slightly for efficiency ( Flush upsteam first ),
192195
// but the actual dependency correctness is handled by the waits inserted inside vhCmdListFlush.
193-
vhCmdListFlush_SingleQueueInternal( nvrhi::CommandQueue::Copy );
194-
vhCmdListFlush_SingleQueueInternal( nvrhi::CommandQueue::Compute );
195-
vhCmdListFlush_SingleQueueInternal( nvrhi::CommandQueue::Graphics );
196+
vhCmdListFlush_SingleQueueInternal_DeviceStateLocked( nvrhi::CommandQueue::Copy );
197+
vhCmdListFlush_SingleQueueInternal_DeviceStateLocked( nvrhi::CommandQueue::Compute );
198+
vhCmdListFlush_SingleQueueInternal_DeviceStateLocked( nvrhi::CommandQueue::Graphics );
199+
}
200+
201+
void vhCmdListFlushAll()
202+
{
203+
std::lock_guard< std::mutex > lock( g_nvRHIStateMutex );
204+
vhCmdListFlushAll_DeviceStateLocked();
196205
}
197206

198207
// Global states for user convenience.

src/vrhi_state.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -506,7 +506,6 @@ bool vhDebugLayoutDiffCheck( const nvrhi::BindingLayoutVector& layouts, const nv
506506

507507
void vhWriteStateToGlobalUniform( const vhState& state, vhGlobalUniform& out )
508508
{
509-
// Clear
510509
memset( &out, 0, sizeof( vhGlobalUniform ) );
511510

512511
// Viewport / Camera

0 commit comments

Comments
 (0)