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

Commit 5f75c37

Browse files
Update tiles oldest-first, improves visual quality. convert.bat includes .xet files e.g. for updating the older hubble files.
1 parent 9bbec41 commit 5f75c37

File tree

3 files changed

+118
-98
lines changed

3 files changed

+118
-98
lines changed

TileUpdateManager/TileUpdateManagerBase.cpp

Lines changed: 108 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ Streaming::TileUpdateManagerBase::~TileUpdateManagerBase()
9999

100100

101101
//-----------------------------------------------------------------------------
102-
// kick off thread that continuously streams tiles
102+
// kick off threads that continuously streams tiles
103103
// gives StreamingResources opportunities to update feedback
104104
//-----------------------------------------------------------------------------
105105
void Streaming::TileUpdateManagerBase::StartThreads()
@@ -115,127 +115,138 @@ void Streaming::TileUpdateManagerBase::StartThreads()
115115
{
116116
DebugPrint(L"Created Feedback Thread\n");
117117

118-
// NOTE: expects the streaming resource array size to be unchanged during thread lifetime
118+
ProcessFeedbackThread();
119119

120-
// array of indices to resources that need tiles loaded/evicted
121-
std::vector<UINT> staleResources;
122-
staleResources.reserve(m_streamingResources.size());
120+
DebugPrint(L"Destroyed ProcessFeedback Thread\n");
121+
});
123122

124-
// flags to prevent duplicates in the staleResources array
125-
std::vector<BYTE> pending(m_streamingResources.size(), 0);
123+
m_updateResidencyThread = std::thread([&]
124+
{
125+
DebugPrint(L"Created UpdateResidency Thread\n");
126126

127-
UINT64 previousFrameFenceValue = m_frameFenceValue;
127+
// continuously modify residency maps as a result of gpu completion events
128+
// FIXME? probably not enough work to deserve it's own thread
129+
// Note that UpdateMinMipMap() exits quickly if nothing to do
128130
while (m_threadsRunning)
129131
{
130-
// prioritize loading packed mips, as objects shouldn't be displayed until packed mips load
131-
bool expected = true;
132-
if (m_havePackedMipsToLoad.compare_exchange_weak(expected, false))
132+
m_residencyChangedFlag.Wait();
133+
134+
for (auto p : m_streamingResources)
133135
{
134-
for (auto p : m_streamingResources)
135-
{
136-
if (!p->InitPackedMips())
137-
{
138-
m_havePackedMipsToLoad = true;
139-
}
140-
}
141-
if (m_havePackedMipsToLoad)
142-
{
143-
continue; // still working on loading packed mips. don't move on to other streaming tasks yet.
144-
}
136+
p->UpdateMinMipMap();
145137
}
138+
}
139+
DebugPrint(L"Destroyed UpdateResidency Thread\n");
140+
});
141+
}
146142

147-
// DEBUG: verify that no streaming resources have been added/removed during thread lifetime
148-
ASSERT(m_streamingResources.size() == pending.size());
143+
//-----------------------------------------------------------------------------
144+
// per frame, call StreamingResource::ProcessFeedback()
145+
// expects the no change in # of streaming resources during thread lifetime
146+
//-----------------------------------------------------------------------------
147+
void Streaming::TileUpdateManagerBase::ProcessFeedbackThread()
148+
{
149+
// array of indices to resources that need tiles loaded/evicted
150+
std::vector<UINT> staleResources;
151+
staleResources.reserve(m_streamingResources.size());
149152

150-
UINT64 frameFenceValue = m_frameFence->GetCompletedValue();
153+
// flags to prevent duplicates in the staleResources array
154+
std::vector<BYTE> pending(m_streamingResources.size(), 0);
151155

152-
// Only process feedback buffers once per frame
153-
if (previousFrameFenceValue != frameFenceValue)
156+
UINT64 previousFrameFenceValue = m_frameFenceValue;
157+
while (m_threadsRunning)
158+
{
159+
// prioritize loading packed mips, as objects shouldn't be displayed until packed mips load
160+
bool expected = true;
161+
if (m_havePackedMipsToLoad.compare_exchange_weak(expected, false))
162+
{
163+
for (auto p : m_streamingResources)
164+
{
165+
if (!p->InitPackedMips())
154166
{
155-
previousFrameFenceValue = frameFenceValue;
156-
157-
auto startTime = m_cpuTimer.GetTime();
158-
UINT j = 0;
159-
for (auto p : m_streamingResources)
160-
{
161-
// early exit, important for application exit or TUM::Finish() when adding/deleting objects
162-
if (!m_threadsRunning)
163-
{
164-
break;
165-
}
166-
167-
p->ProcessFeedback(frameFenceValue);
168-
if (p->IsStale() && !pending[j])
169-
{
170-
staleResources.push_back(j);
171-
pending[j] = 1;
172-
}
173-
j++;
174-
}
175-
m_processFeedbackTime += UINT64(m_cpuTimer.GetTime() - startTime);
167+
m_havePackedMipsToLoad = true;
176168
}
169+
}
170+
if (m_havePackedMipsToLoad)
171+
{
172+
Sleep(2);
173+
continue; // still working on loading packed mips. don't move on to other streaming tasks yet.
174+
}
175+
}
177176

178-
// continuously push uploads and evictions
179-
bool uploadRequested = false;
180-
for (UINT i = 0; i < staleResources.size(); )
181-
{
182-
// exit loop if we ran out of UpdateLists or application exiting
183-
if ((!m_pDataUploader->UpdateListAvailable()) || (!m_threadsRunning))
184-
{
185-
break;
186-
}
187-
188-
UINT resourceIndex = staleResources[i];
189-
auto p = m_streamingResources[resourceIndex];
190-
bool tilesQueued = p->QueueTiles();
191-
uploadRequested = uploadRequested || tilesQueued;
192-
193-
// if all loads/evictions handled, remove from staleResource list
194-
if (!p->IsStale())
195-
{
196-
pending[resourceIndex] = 0; // clear the flag that prevents duplicates
197-
// compact the array by swapping this entry with the last
198-
staleResources[i] = staleResources.back();
199-
staleResources.resize(staleResources.size() - 1);
200-
}
201-
else
202-
{
203-
i++;
204-
}
205-
}
177+
// DEBUG: verify that no streaming resources have been added/removed during thread lifetime
178+
ASSERT(m_streamingResources.size() == pending.size());
206179

207-
// if uploads were queued, tell the file streamer to signal the corresponding fence
208-
if (uploadRequested)
180+
UINT64 frameFenceValue = m_frameFence->GetCompletedValue();
181+
182+
// Only process feedback buffers once per frame
183+
if (previousFrameFenceValue != frameFenceValue)
184+
{
185+
previousFrameFenceValue = frameFenceValue;
186+
187+
auto startTime = m_cpuTimer.GetTime();
188+
UINT j = 0;
189+
for (auto p : m_streamingResources)
190+
{
191+
// early exit, important for application exit or TUM::Finish() when adding/deleting objects
192+
if (!m_threadsRunning)
209193
{
210-
m_pDataUploader->SignalFileStreamer();
194+
break;
211195
}
212196

213-
// nothing to do? wait for next frame
214-
if ((0 == staleResources.size()) && m_threadsRunning)
197+
p->ProcessFeedback(frameFenceValue);
198+
if (p->IsStale() && !pending[j])
215199
{
216-
m_processFeedbackFlag.Wait();
200+
staleResources.push_back(j);
201+
pending[j] = 1;
217202
}
203+
j++;
218204
}
219-
DebugPrint(L"Destroyed ProcessFeedback Thread\n");
220-
});
205+
// add the amount of time we just spent processing feedback for a single frame
206+
m_processFeedbackTime += UINT64(m_cpuTimer.GetTime() - startTime);
207+
}
221208

222-
m_updateResidencyThread = std::thread([&]
209+
// push uploads and evictions for stale resources
210+
bool uploadRequested = false; // remember if any work was queued so we can signal afterwards
211+
UINT newStaleSize = 0; // track number of stale resources, then resize the array to the updated number
212+
for (UINT i = 0; i < staleResources.size(); i++)
223213
{
224-
DebugPrint(L"Created UpdateResidency Thread\n");
225-
// continuously modify residency maps as a result of gpu completion events
226-
// FIXME? probably not enough work to deserve it's own thread
227-
// Note that UpdateMinMipMap() exits quickly if nothing to do
228-
while (m_threadsRunning)
214+
215+
UINT resourceIndex = staleResources[i];
216+
auto p = m_streamingResources[resourceIndex];
217+
218+
if (m_pDataUploader->UpdateListAvailable() && m_threadsRunning)
229219
{
230-
m_residencyChangedFlag.Wait();
220+
uploadRequested = p->QueueTiles() || uploadRequested;
221+
}
231222

232-
for (auto p : m_streamingResources)
233-
{
234-
p->UpdateMinMipMap();
235-
}
223+
// if all loads/evictions handled, remove from staleResource list
224+
if (p->IsStale())
225+
{
226+
// compact, removing non-stale resource indices while retaining oldest-first ordering
227+
staleResources[newStaleSize] = resourceIndex;
228+
newStaleSize++;
236229
}
237-
DebugPrint(L"Destroyed UpdateResidency Thread\n");
238-
});
230+
else
231+
{
232+
pending[resourceIndex] = 0; // clear the flag that prevents duplicates
233+
}
234+
}
235+
236+
staleResources.resize(newStaleSize);
237+
238+
// if uploads were queued, tell the file streamer to signal the corresponding fence
239+
if (uploadRequested)
240+
{
241+
m_pDataUploader->SignalFileStreamer();
242+
}
243+
244+
// nothing to do? wait for next frame
245+
if ((0 == staleResources.size()) && m_threadsRunning)
246+
{
247+
m_processFeedbackFlag.Wait();
248+
}
249+
}
239250
}
240251

241252
//-----------------------------------------------------------------------------

TileUpdateManager/TileUpdateManagerBase.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ namespace Streaming
134134
std::atomic<bool> m_havePackedMipsToLoad{ false };
135135

136136
void StartThreads();
137+
void ProcessFeedbackThread();
137138

138139
//---------------------------------------------------------------------------
139140
// TUM creates 2 command lists to be executed Before & After application draw

scripts/convert.bat

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,16 @@ set outdir=%cd%
99
popd
1010
pushd %1
1111

12+
SHIFT
13+
SHIFT
14+
1215
for /R %%f in (*.dds) do (
1316
echo %%~nf.dds
14-
%exedir%\DdsToXet.exe -in %%~nf.dds -out %outdir%\%%~nf.xet %3
17+
%exedir%\DdsToXet.exe -in %%~nf.dds -out %outdir%\%%~nf.xet %*
18+
)
19+
20+
for /R %%f in (*.xet) do (
21+
echo %%~nf.xet
22+
%exedir%\DdsToXet.exe -in %%~nf.xet -out %outdir%\%%~nf.xet %*
1523
)
1624
popd

0 commit comments

Comments
 (0)