Skip to content

Commit f4e25b4

Browse files
committed
Fix incorrect resource release from DynamicUploadHeap when using QueueID::Both
1 parent 241adc2 commit f4e25b4

9 files changed

+34
-20
lines changed

Modules/Graphics.Heaps/DynamicUploadHeap.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,10 @@ namespace EduEngine
3030
return dynAlloc;
3131
}
3232

33-
void DynamicUploadHeap::FinishFrame(uint64_t fenceValue, uint64_t lastCompletedFenceValue)
33+
void DynamicUploadHeap::FinishFrame(FenceValues fenceValue, FenceValues lastCompletedFenceValue)
3434
{
3535
size_t numBuffsToDelete = 0;
36+
3637
for (size_t ind = 0; ind < m_RingBuffers.size(); ++ind)
3738
{
3839
auto& ringBuff = m_RingBuffers[ind];

Modules/Graphics.Heaps/DynamicUploadHeap.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ namespace EduEngine
1919

2020
DynamicAllocation Allocate(size_t sizeInBytes, size_t alignment = DEFAULT_ALIGN);
2121

22-
void FinishFrame(uint64_t fenceValue, uint64_t lastCompletedFenceValue);
22+
void FinishFrame(FenceValues fenceValue, FenceValues lastCompletedFenceValue);
2323

2424
private:
2525
const bool m_bIsCPUAccessible;

Modules/Graphics.Heaps/QueueID.h

+14
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,18 @@ namespace EduEngine
99
Compute = 1,
1010
Both = 2,
1111
};
12+
13+
struct GRAPHICS_HEAPS_API FenceValues
14+
{
15+
uint64_t DirectFence;
16+
uint64_t ComputeFence;
17+
18+
bool operator<=(const FenceValues& other) const {
19+
return (DirectFence <= other.DirectFence) && (ComputeFence <= other.ComputeFence);
20+
}
21+
22+
bool operator<(const FenceValues& other) const {
23+
return (DirectFence < other.DirectFence) && (ComputeFence <= other.ComputeFence);
24+
}
25+
};
1226
}

Modules/Graphics.Heaps/RingBuffer.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ namespace EduEngine
9393
return InvalidOffset;
9494
}
9595

96-
void RingBuffer::FinishCurrentFrame(uint64_t fenceValue)
96+
void RingBuffer::FinishCurrentFrame(FenceValues fenceValue)
9797
{
9898
if (m_CurrFrameSize != 0)
9999
{
@@ -102,7 +102,7 @@ namespace EduEngine
102102
}
103103
}
104104

105-
void RingBuffer::ReleaseCompletedFrames(uint64_t completedFenceValue)
105+
void RingBuffer::ReleaseCompletedFrames(FenceValues completedFenceValue)
106106
{
107107
// We can release all tails whose associated fence value is less than or equal to CompletedFenceValue
108108
while (!m_CompletedFrameTails.empty() && m_CompletedFrameTails.front().FenceValue <= completedFenceValue)

Modules/Graphics.Heaps/RingBuffer.h

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#pragma once
22
#include "pch.h"
3+
#include "QueueID.h"
34

45
namespace EduEngine
56
{
@@ -8,14 +9,14 @@ namespace EduEngine
89
public:
910
struct GRAPHICS_HEAPS_API FrameTailAttribs
1011
{
11-
FrameTailAttribs(uint64_t fv, size_t off, size_t sz) :
12+
FrameTailAttribs(FenceValues fv, size_t off, size_t sz) :
1213
FenceValue(fv),
1314
Offset(off),
1415
Size(sz)
1516
{}
1617
// Fence value associated with the command list in which
1718
// the allocation could have been referenced last time
18-
uint64_t FenceValue;
19+
FenceValues FenceValue;
1920
size_t Offset;
2021
size_t Size;
2122
};
@@ -32,8 +33,8 @@ namespace EduEngine
3233

3334
size_t Allocate(size_t size);
3435

35-
void FinishCurrentFrame(uint64_t fenceValue);
36-
void ReleaseCompletedFrames(uint64_t completedFenceValue);
36+
void FinishCurrentFrame(FenceValues fenceValue);
37+
void ReleaseCompletedFrames(FenceValues completedFenceValue);
3738

3839
size_t GetMaxSize()const { return m_MaxSize; }
3940
bool IsFull()const { return m_UsedSize == m_MaxSize; };

Modules/Graphics/BufferD3D12.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,11 @@ namespace EduEngine
6363

6464
memcpy(reinterpret_cast<char*>(uploadBuff.CPUAddress), data, uploadBufferSize);
6565

66-
auto& cmdContext = m_QueueId == QueueID::Compute
66+
auto& cmdContext = m_QueueId != QueueID::Direct
6767
? m_Device->GetCommandContext(D3D12_COMMAND_LIST_TYPE_COMPUTE)
6868
: m_Device->GetCommandContext(D3D12_COMMAND_LIST_TYPE_DIRECT);
6969

70-
auto beforeState = m_QueueId == QueueID::Compute ? D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE : D3D12_RESOURCE_STATE_GENERIC_READ;
70+
auto beforeState = m_QueueId != QueueID::Direct ? D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE : D3D12_RESOURCE_STATE_GENERIC_READ;
7171

7272
cmdContext.ResourceBarrier(CD3DX12_RESOURCE_BARRIER::Transition(m_d3d12Resource.Get(),
7373
beforeState, D3D12_RESOURCE_STATE_COPY_DEST));

Modules/Graphics/CommandQueueD3D12.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,8 @@ namespace EduEngine
7171
break;
7272
}
7373

74-
m_DynUploadHeap->FinishFrame(m_NextCmdList.load(), numCompletedCmdLists);
74+
auto nextCmdList = m_NextCmdList.load();
75+
m_DynUploadHeap->FinishFrame({ nextCmdList , nextCmdList }, { numCompletedCmdLists , numCompletedCmdLists });
7576
}
7677

7778
void CommandQueueD3D12::Flush()

Modules/Graphics/RenderDeviceD3D12.cpp

+5-8
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ namespace EduEngine
3434
{ m_GPUDescriptorHeaps[0], 2048, "CBV_SRV_UAV_DynSuballocationMgr" },
3535
{ m_GPUDescriptorHeaps[1], 2048, "SAMPLER_DynSuballocationMgr" }
3636
},
37-
m_DynUploadHeap { true, this, 2048 }
37+
m_DynUploadHeap{ true, this, 2048 }
3838
{
3939
}
4040

@@ -114,14 +114,13 @@ namespace EduEngine
114114
auto numDirectNextCmdLists = m_CommandQueues[0].GetNextCmdListNum();
115115
auto numComputeNextCmdLists = m_CommandQueues[1].GetNextCmdListNum();
116116

117-
auto minCompletedCmdList = std::min(numDirectCompletedCmdLists, numComputeCompletedCmdLists);
118-
auto maxNextCmdList = std::max(numDirectNextCmdLists, numComputeNextCmdLists);
117+
FenceValues completedFences = { numDirectCompletedCmdLists, numComputeCompletedCmdLists };
119118

120119
while (!m_ReleaseObjectsQueue.empty())
121120
{
122121
auto& firstObj = m_ReleaseObjectsQueue.front();
123122
// GPU must have been idled when ForceRelease == true
124-
if (firstObj.first < minCompletedCmdList || forceRelease)
123+
if (firstObj.first < completedFences || forceRelease)
125124
m_ReleaseObjectsQueue.pop_front();
126125
else
127126
break;
@@ -130,7 +129,7 @@ namespace EduEngine
130129
for (size_t i = 0; i < 2; i++)
131130
m_DynamicSuballocationMgr[i].DiscardAllocations();
132131

133-
m_DynUploadHeap.FinishFrame(maxNextCmdList, minCompletedCmdList);
132+
m_DynUploadHeap.FinishFrame({ numDirectNextCmdLists, numComputeNextCmdLists }, { numDirectCompletedCmdLists, numComputeCompletedCmdLists });
134133
}
135134

136135
void RenderDeviceD3D12::FlushQueues()
@@ -144,8 +143,6 @@ namespace EduEngine
144143
uint64_t directNum = m_CommandQueues[0].GetNextCmdListNum();
145144
uint64_t computeNum = m_CommandQueues[1].GetNextCmdListNum();
146145

147-
uint64_t max = directNum > computeNum ? directNum : computeNum;
148-
149-
m_ReleaseObjectsQueue.emplace_back(max, std::move(wrapper));
146+
m_ReleaseObjectsQueue.emplace_back(FenceValues{ directNum, computeNum }, std::move(wrapper));
150147
}
151148
}

Modules/Graphics/RenderDeviceD3D12.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ namespace EduEngine
4747
GPUDescriptorHeap m_GPUDescriptorHeaps[2];
4848
DynamicSuballocationsManager m_DynamicSuballocationMgr[2];
4949

50-
typedef std::pair<uint64_t, ReleaseResourceWrapper> ReleaseObject;
50+
typedef std::pair<FenceValues, ReleaseResourceWrapper> ReleaseObject;
5151

5252
std::mutex m_ReleasedObjectsMutex;
5353
DynamicUploadHeap m_DynUploadHeap; // must be before m_ReleaseObjectsQueue

0 commit comments

Comments
 (0)