Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

revert: "feat: allow adjustment of compiler threads (#99)" #100

Merged
merged 1 commit into from
Sep 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 5 additions & 51 deletions src/Menu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
#include "Features/WaterBlending.h"

#define SETTING_MENU_TOGGLEKEY "Toggle Key"
#define SETTING_MENU_SKIPKEY "Skip Compilation Key"
#define SETTING_MENU_FONTSCALE "Font Scale"

void SetupImGuiStyle()
Expand Down Expand Up @@ -78,9 +77,6 @@ void Menu::Load(json& o_json)
if (o_json[SETTING_MENU_TOGGLEKEY].is_number_unsigned()) {
toggleKey = o_json[SETTING_MENU_TOGGLEKEY];
}
if (o_json[SETTING_MENU_SKIPKEY].is_number_unsigned()) {
skipCompilationKey = o_json[SETTING_MENU_SKIPKEY];
}
if (o_json[SETTING_MENU_FONTSCALE].is_number_float()) {
fontScale = o_json[SETTING_MENU_FONTSCALE];
}
Expand All @@ -90,7 +86,6 @@ void Menu::Save(json& o_json)
{
json menu;
menu[SETTING_MENU_TOGGLEKEY] = toggleKey;
menu[SETTING_MENU_SKIPKEY] = skipCompilationKey;
menu[SETTING_MENU_FONTSCALE] = fontScale;

o_json["Menu"] = menu;
Expand Down Expand Up @@ -216,18 +211,11 @@ RE::BSEventNotifyControl Menu::ProcessEvent(RE::InputEvent* const* a_event, RE::
switch (button->device.get()) {
case RE::INPUT_DEVICE::kKeyboard:
if (!button->IsPressed()) {
logger::trace("Detected key code {} ({})", KeyIdToString(key), key);
if (settingToggleKey) {
toggleKey = key;
settingToggleKey = false;
} else if (settingSkipCompilationKey) {
skipCompilationKey = key;
settingSkipCompilationKey = false;
} else if (key == toggleKey) {
IsEnabled = !IsEnabled;
} else if (key == skipCompilationKey) {
auto& shaderCache = SIE::ShaderCache::Instance();
shaderCache.backgroundCompilation = true;
}
}

Expand Down Expand Up @@ -424,25 +412,10 @@ void Menu::DrawSettings()

ImGui::AlignTextToFramePadding();
ImGui::SameLine();
if (ImGui::Button("Change##toggle")) {
if (ImGui::Button("Change")) {
settingToggleKey = true;
}
}
if (settingSkipCompilationKey) {
ImGui::Text("Press any key to set as Skip Compilation Key...");
} else {
ImGui::AlignTextToFramePadding();
ImGui::Text("Skip Compilation Key:");
ImGui::SameLine();
ImGui::AlignTextToFramePadding();
ImGui::TextColored(ImVec4(1, 1, 0, 1), "%s", KeyIdToString(skipCompilationKey));

ImGui::AlignTextToFramePadding();
ImGui::SameLine();
if (ImGui::Button("Change##skip")) {
settingSkipCompilationKey = true;
}
}

if (ImGui::SliderFloat("Font Scale", &fontScale, -2.f, 2.f, "%.2f")) {
float trueScale = exp2(fontScale);
Expand Down Expand Up @@ -506,19 +479,9 @@ void Menu::DrawSettings()
ImGui::BeginTooltip();
ImGui::PushTextWrapPos(ImGui::GetFontSize() * 35.0f);
ImGui::Text(
"Number of threads to use to compile shaders. "
"The more threads the faster compilation will finish but may make the system unresponsive. ");
ImGui::PopTextWrapPos();
ImGui::EndTooltip();
}
ImGui::SliderInt("Background Compiler Threads", &shaderCache.backgroundCompilationThreadCount, 1, static_cast<int32_t>(std::thread::hardware_concurrency()));
if (ImGui::IsItemHovered()) {
ImGui::BeginTooltip();
ImGui::PushTextWrapPos(ImGui::GetFontSize() * 35.0f);
ImGui::Text(
"Number of threads to use to compile shaders while playing game. "
"This is activated if the startup compilation is skipped. "
"The more threads the faster compilation will finish but may make the system unresponsive. ");
"Number of threads to compile shaders with. "
"The more threads the faster compilation will finish but may make the system unresponsive. "
"This should only be changed between restarts. ");
ImGui::PopTextWrapPos();
ImGui::EndTooltip();
}
Expand Down Expand Up @@ -612,9 +575,7 @@ void Menu::DrawOverlay()

auto failed = shaderCache.GetFailedTasks();
auto hide = shaderCache.IsHideErrors();
auto progressTitle = fmt::format("{}Compiling Shaders: {}",
shaderCache.backgroundCompilation ? "Background " : "",
shaderCache.GetShaderStatsString(!state->IsDeveloperMode()).c_str());
auto progressTitle = fmt::format("Compiling Shaders: {}", shaderCache.GetShaderStatsString(!state->IsDeveloperMode()).c_str());
auto percent = (float)compiledShaders / (float)totalShaders;
auto progressOverlay = fmt::format("{}/{} ({:2.1f}%)", compiledShaders, totalShaders, 100 * percent);
if (shaderCache.IsCompiling()) {
Expand All @@ -626,13 +587,6 @@ void Menu::DrawOverlay()
}
ImGui::TextUnformatted(progressTitle.c_str());
ImGui::ProgressBar(percent, ImVec2(0.0f, 0.0f), progressOverlay.c_str());
if (!shaderCache.backgroundCompilation && shaderCache.menuLoaded) {
auto skipShadersText = fmt::format(
"Press {} to proceed without completing shader compilation. "
"WARNING: Uncompiled shaders will have visual errors or cause stuttering when loading.",
KeyIdToString(skipCompilationKey));
ImGui::TextUnformatted(skipShadersText.c_str());
}

ImGui::End();
} else if (failed && !hide) {
Expand Down
3 changes: 1 addition & 2 deletions src/Menu.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,8 @@ class Menu : public RE::BSTEventSink<RE::InputEvent*>

private:
uint32_t toggleKey = VK_END;
uint32_t skipCompilationKey = VK_ESCAPE;
bool settingToggleKey = false;
bool settingSkipCompilationKey = false;

float fontScale = 0.f; // exponential

Menu() {}
Expand Down
58 changes: 13 additions & 45 deletions src/ShaderCache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

#include <d3d11.h>
#include <d3dcompiler.h>
#include <fmt/std.h>
#include <wrl/client.h>

#include "Features/ExtendedMaterials.h"
Expand Down Expand Up @@ -1387,27 +1386,6 @@ namespace SIE
Clear();
}

void ShaderCache::AdjustThreadCount()
{
auto size = compilationThreads.size();
if (size == compilationThreadCount)
return;
if (size && std::this_thread::get_id() != compilationThreads.front().get_id())
// only allow first thread to adjust threads
return;
logger::debug("Adjusting active threads {}/{}", (int)size, (int)compilationThreadCount);
if (size && size > compilationThreadCount) {
auto& thread = compilationThreads.back();
logger::debug("Stopping thread {}: active {}/{}", thread.get_id(), (int)size - 1, (int)compilationThreadCount);
thread.request_stop();
compilationThreads.pop_back();
} else if (size < compilationThreadCount) {
compilationThreads.push_back(std::jthread(&ShaderCache::ProcessCompilationSet, this, ssource.get_token()));
auto& thread = compilationThreads.back();
logger::debug("Starting new thread {}: active {}/{}", thread.get_id(), (int)size + 1, (int)compilationThreadCount);
}
}

void ShaderCache::Clear()
{
for (auto& shaders : vertexShaders) {
Expand All @@ -1423,7 +1401,6 @@ namespace SIE
shaders.clear();
}

ssource.request_stop();
compilationSet.Clear();
std::unique_lock lock{ mapMutex };
shaderMap.clear();
Expand Down Expand Up @@ -1569,8 +1546,10 @@ namespace SIE

ShaderCache::ShaderCache()
{
logger::debug("ShaderCache initialized with {} compiler threads", (int)compilationThreadCount);
AdjustThreadCount();
logger::debug("ShaderCache initialized with {} compiler threads", compilationThreadCount);
for (size_t threadIndex = 0; threadIndex < compilationThreadCount; ++threadIndex) {
compilationThreads.push_back(std::jthread(&ShaderCache::ProcessCompilationSet, this));
}
}

RE::BSGraphics::VertexShader* ShaderCache::MakeAndAddVertexShader(const RE::BSShader& shader,
Expand Down Expand Up @@ -1663,16 +1642,13 @@ namespace SIE
hideError = !hideError;
}

void ShaderCache::ProcessCompilationSet(std::stop_token stoken)
void ShaderCache::ProcessCompilationSet()
{
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_BELOW_NORMAL);
while (!stoken.stop_requested()) {
const auto& task = compilationSet.WaitTake(stoken);
if (!task.has_value())
break; // exit because thread told to end
task.value().Perform();
compilationSet.Complete(task.value());
AdjustThreadCount();
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL);
while (true) {
const auto& task = compilationSet.WaitTake();
task.Perform();
compilationSet.Complete(task);
}
}

Expand Down Expand Up @@ -1708,23 +1684,15 @@ namespace SIE
return GetId() == other.GetId();
}

std::optional<ShaderCompilationTask> CompilationSet::WaitTake(std::stop_token stoken)
ShaderCompilationTask CompilationSet::WaitTake()
{
std::unique_lock lock(compilationMutex);
if (!conditionVariable.wait(
lock, stoken,
[this, &shaderCache]() { return !availableTasks.empty() &&
// check against all tasks in queue to trickle the work. It cannot be the active tasks count because the thread pool itself is maximum.
(int)shaderCache.compilationPool.get_tasks_total() <=
(!shaderCache.backgroundCompilation ? shaderCache.compilationThreadCount : shaderCache.backgroundCompilationThreadCount); })) {
/*Woke up because of a stop request. */
return std::nullopt;
}
conditionVariable.wait(lock, [this]() { return !availableTasks.empty(); });
if (!ShaderCache::Instance().IsCompiling()) { // we just got woken up because there's a task, start clock
lastCalculation = lastReset = high_resolution_clock::now();
}
auto node = availableTasks.extract(availableTasks.begin());
auto& task = node.value();
auto task = node.value();
tasksInProgress.insert(std::move(node));
return task;
}
Expand Down
17 changes: 4 additions & 13 deletions src/ShaderCache.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ namespace SIE
class CompilationSet
{
public:
std::optional<ShaderCompilationTask> WaitTake(std::stop_token stoken);
ShaderCompilationTask WaitTake();
void Add(const ShaderCompilationTask& task);
void Complete(const ShaderCompilationTask& task);
void Clear();
Expand All @@ -77,7 +77,7 @@ namespace SIE
std::unordered_set<ShaderCompilationTask> availableTasks;
std::unordered_set<ShaderCompilationTask> tasksInProgress;
std::unordered_set<ShaderCompilationTask> processedTasks; // completed or failed
std::condition_variable_any conditionVariable;
std::condition_variable conditionVariable;
std::chrono::steady_clock::time_point lastReset = high_resolution_clock::now();
std::chrono::steady_clock::time_point lastCalculation = high_resolution_clock::now();
double totalMs = (double)duration_cast<std::chrono::milliseconds>(lastReset - lastReset).count();
Expand Down Expand Up @@ -124,11 +124,7 @@ namespace SIE
void DeleteDiskCache();
void ValidateDiskCache();
void WriteDiskCacheInfo();
/// <summary>
/// Adjust the compiler threads based on the compileThreadCount.
/// </summary>
/// This will terminate or generate threads as required to match compileThreadCount.
void AdjustThreadCount();

void Clear();

bool AddCompletedShader(ShaderClass shaderClass, const RE::BSShader& shader, uint32_t descriptor, ID3DBlob* a_blob);
Expand Down Expand Up @@ -156,14 +152,10 @@ namespace SIE
bool IsHideErrors();

int32_t compilationThreadCount = std::max(static_cast<int32_t>(std::thread::hardware_concurrency()) - 1, 1);
int32_t backgroundCompilationThreadCount = std::max(static_cast<int32_t>(std::thread::hardware_concurrency()) / 2, 1);
BS::thread_pool compilationPool{};
bool backgroundCompilation = false;
bool menuLoaded = false;

private:
ShaderCache();
void ProcessCompilationSet(std::stop_token stoken);
void ProcessCompilationSet();

~ShaderCache();

Expand All @@ -181,7 +173,6 @@ namespace SIE
bool hideError = false;

eastl::vector<std::jthread> compilationThreads;
std::stop_source ssource;
std::mutex vertexShadersMutex;
std::mutex pixelShadersMutex;
CompilationSet compilationSet;
Expand Down
3 changes: 0 additions & 3 deletions src/State.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,6 @@ void State::Load()
SetDefines(advanced["Shader Defines"]);
if (advanced["Compiler Threads"].is_number_integer())
shaderCache.compilationThreadCount = std::clamp(advanced["Compiler Threads"].get<int32_t>(), 1, static_cast<int32_t>(std::thread::hardware_concurrency()));
if (advanced["Background Compiler Threads"].is_number_integer())
shaderCache.backgroundCompilationThreadCount = std::clamp(advanced["Compiler Threads"].get<int32_t>(), 1, static_cast<int32_t>(std::thread::hardware_concurrency()));
}

if (settings["General"].is_object()) {
Expand Down Expand Up @@ -147,7 +145,6 @@ void State::Save()
advanced["Log Level"] = logLevel;
advanced["Shader Defines"] = shaderDefinesString;
advanced["Compiler Threads"] = shaderCache.compilationThreadCount;
advanced["Background Compiler Threads"] = shaderCache.backgroundCompilationThreadCount;
settings["Advanced"] = advanced;

json general;
Expand Down
4 changes: 2 additions & 2 deletions src/XSEPlugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,8 @@ void MessageHandler(SKSE::MessagingInterface::Message* message)
RE::BSInputDeviceManager::GetSingleton()->AddEventSink(Menu::GetSingleton());

auto& shaderCache = SIE::ShaderCache::Instance();
shaderCache.menuLoaded = true;
while (shaderCache.IsCompiling() && !shaderCache.backgroundCompilation) {

while (shaderCache.IsCompiling()) {
std::this_thread::sleep_for(100ms);
}

Expand Down