Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/doitsujin/dxvk.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Rebohle <philip.rebohle@tu-dortmund.de>2023-01-13 17:09:32 +0300
committerPhilip Rebohle <philip.rebohle@tu-dortmund.de>2023-01-13 18:27:22 +0300
commitee66ede841ae5e29b6c0142c9a64b1b07c4fb216 (patch)
tree4de9f09abeb17af69ce025f8e23d7b0a6346e825
parent80ff2f9ed4a6ec3df76be2816fe1f634110af337 (diff)
[hud] Display approximate progress when compiling shadersworker-priority
-rw-r--r--src/dxvk/dxvk_device.cpp4
-rw-r--r--src/dxvk/dxvk_pipemanager.cpp13
-rw-r--r--src/dxvk/dxvk_pipemanager.h31
-rw-r--r--src/dxvk/dxvk_stats.h3
-rw-r--r--src/dxvk/hud/dxvk_hud_item.cpp49
-rw-r--r--src/dxvk/hud/dxvk_hud_item.h13
6 files changed, 83 insertions, 30 deletions
diff --git a/src/dxvk/dxvk_device.cpp b/src/dxvk/dxvk_device.cpp
index e059f901..54ef2821 100644
--- a/src/dxvk/dxvk_device.cpp
+++ b/src/dxvk/dxvk_device.cpp
@@ -188,12 +188,14 @@ namespace dxvk {
DxvkStatCounters DxvkDevice::getStatCounters() {
DxvkPipelineCount pipe = m_objects.pipelineManager().getPipelineCount();
+ DxvkPipelineWorkerStats workers = m_objects.pipelineManager().getWorkerStats();
DxvkStatCounters result;
result.setCtr(DxvkStatCounter::PipeCountGraphics, pipe.numGraphicsPipelines);
result.setCtr(DxvkStatCounter::PipeCountLibrary, pipe.numGraphicsLibraries);
result.setCtr(DxvkStatCounter::PipeCountCompute, pipe.numComputePipelines);
- result.setCtr(DxvkStatCounter::PipeCompilerBusy, m_objects.pipelineManager().isCompilingShaders());
+ result.setCtr(DxvkStatCounter::PipeTasksDone, workers.tasksCompleted);
+ result.setCtr(DxvkStatCounter::PipeTasksTotal, workers.tasksTotal);
result.setCtr(DxvkStatCounter::GpuIdleTicks, m_submissionQueue.gpuIdleTicks());
std::lock_guard<sync::Spinlock> lock(m_statLock);
diff --git a/src/dxvk/dxvk_pipemanager.cpp b/src/dxvk/dxvk_pipemanager.cpp
index b6443975..40c20cf8 100644
--- a/src/dxvk/dxvk_pipemanager.cpp
+++ b/src/dxvk/dxvk_pipemanager.cpp
@@ -24,7 +24,7 @@ namespace dxvk {
std::unique_lock lock(m_lock);
this->startWorkers();
- m_pendingTasks += 1;
+ m_tasksTotal += 1;
m_buckets[uint32_t(priority)].queue.emplace(library);
notifyWorkers(priority);
@@ -39,18 +39,13 @@ namespace dxvk {
this->startWorkers();
pipeline->acquirePipeline();
- m_pendingTasks += 1;
+ m_tasksTotal += 1;
m_buckets[uint32_t(priority)].queue.emplace(pipeline, state);
notifyWorkers(priority);
}
- bool DxvkPipelineWorkers::isBusy() const {
- return m_pendingTasks.load() != 0ull;
- }
-
-
void DxvkPipelineWorkers::stopWorkers() {
{ std::unique_lock lock(m_lock);
@@ -164,12 +159,12 @@ namespace dxvk {
if (entry.pipelineLibrary) {
entry.pipelineLibrary->compilePipeline();
- m_pendingTasks -= 1;
} else if (entry.graphicsPipeline) {
entry.graphicsPipeline->compilePipeline(entry.graphicsState);
entry.graphicsPipeline->releasePipeline();
- m_pendingTasks -= 1;
}
+
+ m_tasksCompleted += 1;
}
}
diff --git a/src/dxvk/dxvk_pipemanager.h b/src/dxvk/dxvk_pipemanager.h
index 033e37ee..36801aef 100644
--- a/src/dxvk/dxvk_pipemanager.h
+++ b/src/dxvk/dxvk_pipemanager.h
@@ -34,6 +34,11 @@ namespace dxvk {
std::atomic<uint32_t> numComputePipelines = { 0u };
};
+ struct DxvkPipelineWorkerStats {
+ uint64_t tasksCompleted;
+ uint64_t tasksTotal;
+ };
+
/**
* \brief Pipeline priority
*/
@@ -59,6 +64,19 @@ namespace dxvk {
~DxvkPipelineWorkers();
/**
+ * \brief Queries worker statistics
+ *
+ * The returned result may be immediately out of date.
+ * \returns Worker statistics
+ */
+ DxvkPipelineWorkerStats getStats() const {
+ DxvkPipelineWorkerStats result;
+ result.tasksCompleted = m_tasksCompleted.load(std::memory_order_acquire);
+ result.tasksTotal = m_tasksTotal.load(std::memory_order_relaxed);
+ return result;
+ }
+
+ /**
* \brief Compiles a pipeline library
*
* Asynchronously compiles a basic variant of
@@ -83,12 +101,6 @@ namespace dxvk {
DxvkPipelinePriority priority);
/**
- * \brief Checks whether workers are busy
- * \returns \c true if there is unfinished work
- */
- bool isBusy() const;
-
- /**
* \brief Stops all worker threads
*
* Stops threads and waits for their current work
@@ -121,7 +133,8 @@ namespace dxvk {
DxvkDevice* m_device;
- std::atomic<uint64_t> m_pendingTasks = { 0ull };
+ std::atomic<uint64_t> m_tasksTotal = { 0ull };
+ std::atomic<uint64_t> m_tasksCompleted = { 0ull };
dxvk::mutex m_lock;
std::array<PipelineBucket, 3> m_buckets;
@@ -242,8 +255,8 @@ namespace dxvk {
* \brief Checks whether async compiler is busy
* \returns \c true if shaders are being compiled
*/
- bool isCompilingShaders() const {
- return m_workers.isBusy();
+ DxvkPipelineWorkerStats getWorkerStats() const {
+ return m_workers.getStats();
}
/**
diff --git a/src/dxvk/dxvk_stats.h b/src/dxvk/dxvk_stats.h
index 211570f5..91c83701 100644
--- a/src/dxvk/dxvk_stats.h
+++ b/src/dxvk/dxvk_stats.h
@@ -18,7 +18,8 @@ namespace dxvk {
PipeCountGraphics, ///< Number of graphics pipelines
PipeCountLibrary, ///< Number of graphics shader libraries
PipeCountCompute, ///< Number of compute pipelines
- PipeCompilerBusy, ///< Boolean indicating compiler activity
+ PipeTasksDone, ///< Boolean indicating compiler activity
+ PipeTasksTotal, ///< Boolean indicating compiler activity
QueueSubmitCount, ///< Number of command buffer submissions
QueuePresentCount, ///< Number of present calls / frames
GpuSyncCount, ///< Number of GPU synchronizations
diff --git a/src/dxvk/hud/dxvk_hud_item.cpp b/src/dxvk/hud/dxvk_hud_item.cpp
index 4b7b0ea5..40707d64 100644
--- a/src/dxvk/hud/dxvk_hud_item.cpp
+++ b/src/dxvk/hud/dxvk_hud_item.cpp
@@ -755,15 +755,36 @@ namespace dxvk::hud {
void HudCompilerActivityItem::update(dxvk::high_resolution_clock::time_point time) {
DxvkStatCounters counters = m_device->getStatCounters();
- bool doShow = counters.getCtr(DxvkStatCounter::PipeCompilerBusy);
- if (!doShow) {
- auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(time - m_timeShown);
- doShow = elapsed.count() <= MinShowDuration;
- }
+ m_tasksDone = counters.getCtr(DxvkStatCounter::PipeTasksDone);
+ m_tasksTotal = counters.getCtr(DxvkStatCounter::PipeTasksTotal);
+
+ bool doShow = m_tasksDone < m_tasksTotal;
- if (doShow && !m_show)
+ if (!doShow)
+ m_timeDone = time;
+
+ if (!m_show) {
m_timeShown = time;
+ m_showPercentage = false;
+ } else {
+ auto durationShown = std::chrono::duration_cast<std::chrono::milliseconds>(time - m_timeShown);
+ auto durationWorking = std::chrono::duration_cast<std::chrono::milliseconds>(time - m_timeDone);
+
+ if (!doShow) {
+ m_offset = m_tasksTotal;
+
+ // Ensure the item stays up long enough to be legible
+ doShow = durationShown.count() <= MinShowDuration;
+ }
+
+ if (!m_showPercentage) {
+ // Don't show percentage if it's just going to be stuck at 99%
+ // because the workers are not being fed tasks fast enough
+ m_showPercentage = durationWorking.count() >= (MinShowDuration / 5)
+ && (computePercentage() < 50);
+ }
+ }
m_show = doShow;
}
@@ -773,13 +794,27 @@ namespace dxvk::hud {
HudRenderer& renderer,
HudPos position) {
if (m_show) {
+ std::string string = "Compiling shaders...";
+
+ if (m_showPercentage)
+ string = str::format(string, " (", computePercentage(), "%)");
+
renderer.drawText(16.0f,
{ position.x, renderer.surfaceSize().height / renderer.scale() - 20.0f },
{ 1.0f, 1.0f, 1.0f, 1.0f },
- "Compiling shaders...");
+ string);
}
return position;
}
+
+ uint32_t HudCompilerActivityItem::computePercentage() const {
+ if (m_offset == m_tasksTotal)
+ return 100;
+
+ return (uint32_t(m_tasksDone - m_offset) * 100)
+ / (uint32_t(m_tasksTotal - m_offset));
+ }
+
}
diff --git a/src/dxvk/hud/dxvk_hud_item.h b/src/dxvk/hud/dxvk_hud_item.h
index b91f4d71..18f75054 100644
--- a/src/dxvk/hud/dxvk_hud_item.h
+++ b/src/dxvk/hud/dxvk_hud_item.h
@@ -482,10 +482,17 @@ namespace dxvk::hud {
Rc<DxvkDevice> m_device;
- bool m_show = false;
+ bool m_show = false;
+ bool m_showPercentage = false;
- dxvk::high_resolution_clock::time_point m_timeShown
- = dxvk::high_resolution_clock::now();
+ uint64_t m_tasksDone = 0ull;
+ uint64_t m_tasksTotal = 0ull;
+ uint64_t m_offset = 0ull;
+
+ dxvk::high_resolution_clock::time_point m_timeShown = dxvk::high_resolution_clock::now();
+ dxvk::high_resolution_clock::time_point m_timeDone = dxvk::high_resolution_clock::now();
+
+ uint32_t computePercentage() const;
};