Skip to content
This repository was archived by the owner on Dec 25, 2023. It is now read-only.

Commit c378b3a

Browse files
misc. improvements. heuristic change can result in substantial bandwidth & latency improvements under heavy load (benchmark).
1 parent 461a8c3 commit c378b3a

19 files changed

+89
-99
lines changed

TileUpdateManager/DataUploader.cpp

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -239,12 +239,15 @@ void Streaming::DataUploader::StopThreads()
239239
//-----------------------------------------------------------------------------
240240
void Streaming::DataUploader::FlushCommands()
241241
{
242-
DebugPrint("DataUploader waiting on ", m_updateListAllocator.GetAllocated(), " tasks to complete\n");
243-
while (m_updateListAllocator.GetAllocated()) // wait so long as there is outstanding work
242+
if (m_updateListAllocator.GetAllocated())
244243
{
245-
m_submitFlag.Set(); // (paranoia)
246-
m_fenceMonitorFlag.Set(); // (paranoia)
247-
_mm_pause();
244+
DebugPrint("DataUploader waiting on ", m_updateListAllocator.GetAllocated(), " tasks to complete\n");
245+
while (m_updateListAllocator.GetAllocated()) // wait so long as there is outstanding work
246+
{
247+
m_submitFlag.Set(); // (paranoia)
248+
m_fenceMonitorFlag.Set(); // (paranoia)
249+
_mm_pause();
250+
}
248251
}
249252
// if this loop doesn't exit, then a race condition occurred while allocating/freeing updatelists
250253

@@ -276,7 +279,7 @@ Streaming::UpdateList* Streaming::DataUploader::AllocateUpdateList(Streaming::St
276279

277280
// start fence polling thread now
278281
{
279-
m_monitorTasks[m_monitorTaskAlloc.GetWriteIndex()] = index;
282+
m_monitorTasks[m_monitorTaskAlloc.GetWriteIndex()] = pUpdateList;
280283
m_monitorTaskAlloc.Allocate();
281284
m_fenceMonitorFlag.Set();
282285
}
@@ -316,7 +319,7 @@ void Streaming::DataUploader::SubmitUpdateList(Streaming::UpdateList& in_updateL
316319

317320
// add to submit task queue
318321
{
319-
m_submitTasks[m_submitTaskAlloc.GetWriteIndex()] = UINT(&in_updateList - m_updateLists.data());
322+
m_submitTasks[m_submitTaskAlloc.GetWriteIndex()] = &in_updateList;
320323
m_submitTaskAlloc.Allocate();
321324
m_submitFlag.Set();
322325
}
@@ -345,7 +348,7 @@ void Streaming::DataUploader::FenceMonitorThread()
345348
for (UINT i = startIndex; i < (startIndex + numTasks); i++)
346349
{
347350
ASSERT(numTasks != 0);
348-
auto& updateList = m_updateLists[m_monitorTasks[i % m_monitorTasks.size()]];
351+
auto& updateList = *m_monitorTasks[i % m_monitorTasks.size()];
349352

350353
bool freeUpdateList = false;
351354

@@ -461,11 +464,9 @@ void Streaming::DataUploader::SubmitThread()
461464
{
462465
signalMap = true;
463466

464-
UINT index = m_submitTasks[m_submitTaskAlloc.GetReadIndex()]; // get the next task
467+
auto& updateList = *m_submitTasks[m_submitTaskAlloc.GetReadIndex()]; // get the next task
465468
m_submitTaskAlloc.Free(); // consume this task
466469

467-
auto& updateList = m_updateLists[index];
468-
469470
ASSERT(UpdateList::State::STATE_SUBMITTED == updateList.m_executionState);
470471

471472
// set to the fence value to be signaled next

TileUpdateManager/DataUploader.h

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,6 @@ namespace Streaming
109109
ComPtr<ID3D12CommandQueue> m_mappingCommandQueue;
110110

111111
// pool of all updatelists
112-
// copy thread loops over these
113112
std::vector<UpdateList> m_updateLists;
114113
Streaming::AllocatorMT m_updateListAllocator;
115114

@@ -125,18 +124,18 @@ namespace Streaming
125124
// thread to handle UpdateList submissions
126125
void SubmitThread();
127126
std::thread m_submitThread;
128-
Streaming::SynchronizationFlag m_submitFlag;
129-
std::vector<UINT> m_submitTasks;
127+
Streaming::SynchronizationFlag m_submitFlag; // sleeps until flag set
128+
std::vector<UpdateList*> m_submitTasks;
130129
RingBuffer m_submitTaskAlloc;
131130

132131
// thread to poll copy and mapping fences
133132
// this thread could have been designed using WaitForMultipleObjects, but it was found that SetEventOnCompletion() was expensive in a tight thread loop
134133
// compromise solution is to keep this thread awake so long as there are live UpdateLists.
135134
void FenceMonitorThread();
136135
std::thread m_fenceMonitorThread;
137-
Streaming::SynchronizationFlag m_fenceMonitorFlag;
136+
Streaming::SynchronizationFlag m_fenceMonitorFlag; // sleeps until flag set
138137
RawCpuTimer* m_pFenceThreadTimer{ nullptr }; // init timer on the thread that uses it. can't really worry about thread migration.
139-
std::vector<UINT> m_monitorTasks;
138+
std::vector<UpdateList*> m_monitorTasks;
140139
RingBuffer m_monitorTaskAlloc;
141140

142141
void StartThreads();

TileUpdateManager/FileStreamerDS.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,9 @@ void Streaming::FileStreamerDS::StreamTexture(Streaming::UpdateList& in_updateLi
9999
UINT numCoords = (UINT)in_updateList.m_coords.size();
100100
for (UINT i = 0; i < numCoords; i++)
101101
{
102-
request.Source.File.Offset = pTextureFileInfo->GetFileOffset(in_updateList.m_coords[i], request.Source.File.Size);
102+
auto fileOffset = pTextureFileInfo->GetFileOffset(in_updateList.m_coords[i]);
103+
request.Source.File.Offset = fileOffset.offset;
104+
request.Source.File.Size = fileOffset.numBytes;
103105

104106
D3D12_TILED_RESOURCE_COORDINATE coord{};
105107
ID3D12Resource* pAtlas = pDstHeap->ComputeCoordFromTileIndex(coord, in_updateList.m_heapIndices[i], textureFormat);

TileUpdateManager/FileStreamerReference.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -189,8 +189,7 @@ void Streaming::FileStreamerReference::LoadTexture(Streaming::FileStreamerRefere
189189
for (UINT i = startIndex; i < endIndex; i++)
190190
{
191191
// get file offset to tile
192-
UINT32 numBytes = 0;
193-
UINT fileOffset = pTextureFileInfo->GetFileOffset(pUpdateList->m_coords[i], numBytes);
192+
auto fileOffset = pTextureFileInfo->GetFileOffset(pUpdateList->m_coords[i]);
194193

195194
// convert tile index into byte offset
196195
UINT byteOffset = D3D12_TILED_RESOURCE_TILE_SIZE_IN_BYTES * in_copyBatch.m_uploadIndices[i];
@@ -204,11 +203,11 @@ void Streaming::FileStreamerReference::LoadTexture(Streaming::FileStreamerRefere
204203
o.Internal = 0;
205204
o.InternalHigh = 0;
206205
o.OffsetHigh = 0;
207-
o.Offset = fileOffset;
206+
o.Offset = fileOffset.offset;
208207

209208
// align # bytes read
210209
UINT alignment = FileStreamerReference::MEDIA_SECTOR_SIZE - 1;
211-
numBytes = (numBytes + alignment) & ~(alignment);
210+
UINT numBytes = (fileOffset.numBytes + alignment) & ~(alignment);
212211
o.Offset &= ~alignment; // rewind the offset to alignment
213212

214213
::ReadFile(pFileHandle, pDst, numBytes, nullptr, &o);

TileUpdateManager/InternalResources.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,18 +33,18 @@
3333
//-----------------------------------------------------------------------------
3434
Streaming::InternalResources::InternalResources(
3535
ID3D12Device8* in_pDevice,
36-
XeTexture* m_pTextureFileInfo,
36+
const XeTexture& m_textureFileInfo,
3737
// need the swap chain count so we can create per-frame upload buffers
3838
UINT in_swapChainBufferCount) :
3939
m_packedMipInfo{}, m_tileShape{}, m_numTilesTotal(0)
4040
{
4141
// create reserved resource
4242
{
4343
D3D12_RESOURCE_DESC rd = CD3DX12_RESOURCE_DESC::Tex2D(
44-
m_pTextureFileInfo->GetFormat(),
45-
m_pTextureFileInfo->GetImageWidth(),
46-
m_pTextureFileInfo->GetImageHeight(), 1,
47-
(UINT16)m_pTextureFileInfo->GetMipCount()
44+
m_textureFileInfo.GetFormat(),
45+
m_textureFileInfo.GetImageWidth(),
46+
m_textureFileInfo.GetImageHeight(), 1,
47+
(UINT16)m_textureFileInfo.GetMipCount()
4848
);
4949

5050
// Layout must be D3D12_TEXTURE_LAYOUT_64KB_UNDEFINED_SWIZZLE when creating reserved resources

TileUpdateManager/InternalResources.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ namespace Streaming
3737
class InternalResources
3838
{
3939
public:
40-
InternalResources(ID3D12Device8* in_pDevice, class XeTexture* m_pTextureFileInfo,
40+
InternalResources(ID3D12Device8* in_pDevice, const class XeTexture& m_textureFileInfo,
4141
// need the swap chain count so we can create per-frame upload buffers
4242
UINT in_swapChainBufferCount);
4343

TileUpdateManager/StreamingResourceBase.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828

2929
#include "StreamingResourceBase.h"
3030
#include "TileUpdateManagerSR.h"
31-
#include "XeTexture.h"
3231

3332
#include "UpdateList.h"
3433

@@ -61,9 +60,9 @@ Streaming::StreamingResourceBase::StreamingResourceBase(
6160
, m_pHeap(in_pHeap)
6261
, m_pFileHandle(in_pFileHandle)
6362
, m_filename(in_filename)
63+
, m_textureFileInfo(in_filename)
6464
{
65-
m_pTextureFileInfo = std::make_unique<Streaming::XeTexture>(in_filename);
66-
m_resources = std::make_unique<Streaming::InternalResources>(in_pTileUpdateManager->GetDevice(), m_pTextureFileInfo.get(), (UINT)m_queuedFeedback.size());
65+
m_resources = std::make_unique<Streaming::InternalResources>(in_pTileUpdateManager->GetDevice(), m_textureFileInfo, (UINT)m_queuedFeedback.size());
6766
m_tileMappingState.Init(m_resources->GetPackedMipInfo().NumStandardMips, m_resources->GetTiling());
6867

6968
// no packed mips. odd, but possible. no need to check/update this variable again.
@@ -85,7 +84,7 @@ Streaming::StreamingResourceBase::StreamingResourceBase(
8584
m_minMipMap.resize(m_tileReferences.size(), m_maxMip);
8685

8786
// make sure my heap has an atlas corresponding to my format
88-
m_pHeap->AllocateAtlas(in_pTileUpdateManager->GetMappingQueue(), m_pTextureFileInfo->GetFormat());
87+
m_pHeap->AllocateAtlas(in_pTileUpdateManager->GetMappingQueue(), m_textureFileInfo.GetFormat());
8988

9089
// Load packed mips. packed mips are not streamed or evicted.
9190
LoadPackedMips();
@@ -837,7 +836,7 @@ void Streaming::StreamingResourceBase::EvictionDelay::Rescue(const Streaming::St
837836
void Streaming::StreamingResourceBase::LoadPackedMips()
838837
{
839838
UINT numBytes = 0;
840-
UINT offset = m_pTextureFileInfo->GetPackedMipFileOffset(&numBytes, &m_packedMipsUncompressedSize);
839+
UINT offset = m_textureFileInfo.GetPackedMipFileOffset(&numBytes, &m_packedMipsUncompressedSize);
841840
m_packedMips.resize(numBytes);
842841
std::ifstream inFile(m_filename.c_str(), std::ios::binary);
843842
inFile.seekg(offset);

TileUpdateManager/StreamingResourceBase.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,12 @@ Base class for StreamingResource
3737

3838
#include "SamplerFeedbackStreaming.h"
3939
#include "InternalResources.h"
40+
#include "XeTexture.h"
4041

4142
namespace Streaming
4243
{
4344
class TileUpdateManagerSR;
4445
struct UpdateList;
45-
class XeTexture;
4646
class Heap;
4747
class FileHandle;
4848

@@ -161,7 +161,7 @@ namespace Streaming
161161
const std::wstring m_filename;
162162

163163
// object that streams data from a file
164-
std::unique_ptr<Streaming::XeTexture> m_pTextureFileInfo;
164+
const Streaming::XeTexture m_textureFileInfo;
165165
std::unique_ptr<Streaming::InternalResources> m_resources;
166166
std::unique_ptr<Streaming::FileHandle> m_pFileHandle;
167167
Streaming::Heap* m_pHeap{ nullptr };

TileUpdateManager/StreamingResourceDU.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ namespace Streaming
3737
class StreamingResourceDU : private StreamingResourceBase
3838
{
3939
public:
40-
XeTexture* GetTextureFileInfo() const { return m_pTextureFileInfo.get(); }
40+
const XeTexture* GetTextureFileInfo() const { return &m_textureFileInfo; }
4141
Streaming::Heap* GetHeap() const { return m_pHeap; }
4242

4343
// just for packed mips

TileUpdateManager/TileUpdateManager.cpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ void Streaming::TileUpdateManagerBase::Destroy()
5757
//--------------------------------------------
5858
StreamingHeap* Streaming::TileUpdateManagerBase::CreateStreamingHeap(UINT in_maxNumTilesHeap)
5959
{
60-
auto pStreamingHeap = new Streaming::Heap(m_pDataUploader->GetMappingQueue(), in_maxNumTilesHeap);
60+
auto pStreamingHeap = new Streaming::Heap(m_dataUploader.GetMappingQueue(), in_maxNumTilesHeap);
6161
return (StreamingHeap*)pStreamingHeap;
6262
}
6363

@@ -69,7 +69,7 @@ StreamingResource* Streaming::TileUpdateManagerBase::CreateStreamingResource(con
6969
// if threads are running, stop them. they have state that depends on knowing the # of StreamingResources
7070
Finish();
7171

72-
Streaming::FileHandle* pFileHandle = m_pDataUploader->OpenFile(in_filename);
72+
Streaming::FileHandle* pFileHandle = m_dataUploader.OpenFile(in_filename);
7373
auto pRsrc = new Streaming::StreamingResourceBase(in_filename, pFileHandle, (Streaming::TileUpdateManagerSR*)this, (Streaming::Heap*)in_pHeap);
7474
m_streamingResources.push_back(pRsrc);
7575
m_numStreamingResourcesChanged = true;
@@ -92,11 +92,11 @@ void Streaming::TileUpdateManagerBase::UseDirectStorage(bool in_useDS)
9292
streamerType = Streaming::DataUploader::StreamerType::DirectStorage;
9393
}
9494

95-
auto pOldStreamer = m_pDataUploader->SetStreamer(streamerType);
95+
auto pOldStreamer = m_dataUploader.SetStreamer(streamerType);
9696

9797
for (auto& s : m_streamingResources)
9898
{
99-
s->SetFileHandle(m_pDataUploader.get());
99+
s->SetFileHandle(&m_dataUploader);
100100
}
101101

102102
delete pOldStreamer;
@@ -142,13 +142,13 @@ float Streaming::TileUpdateManagerBase::GetCpuProcessFeedbackTime()
142142
//-----------------------------------------------------------------------------
143143
// performance and visualization
144144
//-----------------------------------------------------------------------------
145-
float Streaming::TileUpdateManagerBase::GetGpuStreamingTime() const { return m_pDataUploader->GetGpuStreamingTime(); }
146-
float Streaming::TileUpdateManagerBase::GetTotalTileCopyLatency() const { return m_pDataUploader->GetApproximateTileCopyLatency(); }
145+
float Streaming::TileUpdateManagerBase::GetGpuStreamingTime() const { return m_dataUploader.GetGpuStreamingTime(); }
146+
float Streaming::TileUpdateManagerBase::GetTotalTileCopyLatency() const { return m_dataUploader.GetApproximateTileCopyLatency(); }
147147

148148
// the total time the GPU spent resolving feedback during the previous frame
149149
float Streaming::TileUpdateManagerBase::GetGpuTime() const { return m_gpuTimerResolve.GetTimes()[m_renderFrameIndex].first; }
150-
UINT Streaming::TileUpdateManagerBase::GetTotalNumUploads() const { return m_pDataUploader->GetTotalNumUploads(); }
151-
UINT Streaming::TileUpdateManagerBase::GetTotalNumEvictions() const { return m_pDataUploader->GetTotalNumEvictions(); }
150+
UINT Streaming::TileUpdateManagerBase::GetTotalNumUploads() const { return m_dataUploader.GetTotalNumUploads(); }
151+
UINT Streaming::TileUpdateManagerBase::GetTotalNumEvictions() const { return m_dataUploader.GetTotalNumEvictions(); }
152152
UINT Streaming::TileUpdateManagerBase::GetTotalNumSubmits() const { return m_numTotalSubmits; }
153153

154154
void Streaming::TileUpdateManagerBase::SetVisualizationMode(UINT in_mode)
@@ -160,12 +160,12 @@ void Streaming::TileUpdateManagerBase::SetVisualizationMode(UINT in_mode)
160160
o->ClearAllocations();
161161
}
162162

163-
m_pDataUploader->SetVisualizationMode(in_mode);
163+
m_dataUploader.SetVisualizationMode(in_mode);
164164
}
165165

166166
void Streaming::TileUpdateManagerBase::CaptureTraceFile(bool in_captureTrace)
167167
{
168-
m_pDataUploader->CaptureTraceFile(in_captureTrace);
168+
m_dataUploader.CaptureTraceFile(in_captureTrace);
169169
}
170170

171171
//-----------------------------------------------------------------------------

0 commit comments

Comments
 (0)