Skip to content

Commit

Permalink
Fix another shutdown race condition in the Vulkan backend
Browse files Browse the repository at this point in the history
  • Loading branch information
hrydgard committed Jan 15, 2024
1 parent d0faf25 commit c1a7235
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 2 deletions.
22 changes: 20 additions & 2 deletions Common/GPU/Vulkan/VulkanRenderManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,9 @@ struct SinglePipelineTask {

class CreateMultiPipelinesTask : public Task {
public:
CreateMultiPipelinesTask(VulkanContext *vulkan, std::vector<SinglePipelineTask> tasks) : vulkan_(vulkan), tasks_(tasks) {}
CreateMultiPipelinesTask(VulkanContext *vulkan, std::vector<SinglePipelineTask> tasks) : vulkan_(vulkan), tasks_(tasks) {
tasksInFlight_.fetch_add(1);
}
~CreateMultiPipelinesTask() {}

TaskType Type() const override {
Expand All @@ -426,12 +428,25 @@ class CreateMultiPipelinesTask : public Task {
for (auto &task : tasks_) {
task.pipeline->Create(vulkan_, task.compatibleRenderPass, task.rpType, task.sampleCount, task.scheduleTime, task.countToCompile);
}
tasksInFlight_.fetch_sub(1);
}

VulkanContext *vulkan_;
std::vector<SinglePipelineTask> tasks_;

// Use during shutdown to make sure there aren't any leftover tasks sitting queued.
// Could probably be done more elegantly. Like waiting for all tasks of a type, or saving pointers to them, or something...
static void WaitForAll() {
while (tasksInFlight_.load() > 0) {
sleep_ms(2);
}
}

static std::atomic<int> tasksInFlight_;
};

std::atomic<int> CreateMultiPipelinesTask::tasksInFlight_;

void VulkanRenderManager::CompileThreadFunc() {
SetCurrentThreadName("ShaderCompile");
while (true) {
Expand Down Expand Up @@ -465,7 +480,8 @@ void VulkanRenderManager::CompileThreadFunc() {
for (auto &entry : toCompile) {
switch (entry.type) {
case CompileQueueEntry::Type::GRAPHICS:
map[std::pair< Promise<VkShaderModule> *, Promise<VkShaderModule> *>(entry.graphics->desc->vertexShader, entry.graphics->desc->fragmentShader)].push_back(
{
map[std::make_pair(entry.graphics->desc->vertexShader, entry.graphics->desc->fragmentShader)].push_back(
SinglePipelineTask{
entry.graphics,
entry.compatibleRenderPass,
Expand All @@ -477,6 +493,7 @@ void VulkanRenderManager::CompileThreadFunc() {
);
break;
}
}
}

for (auto iter : map) {
Expand All @@ -500,6 +517,7 @@ void VulkanRenderManager::DrainAndBlockCompileQueue() {
while (!compileQueue_.empty()) {
queueRunner_.WaitForCompileNotification();
}
CreateMultiPipelinesTask::WaitForAll();
}

void VulkanRenderManager::ReleaseCompileQueue() {
Expand Down
2 changes: 2 additions & 0 deletions Common/GPU/Vulkan/thin3d_vulkan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -191,9 +191,11 @@ class VKShaderModule : public ShaderModule {
const std::string &GetSource() const { return source_; }
~VKShaderModule() {
if (module_) {
INFO_LOG(G3D, "~VKShaderModule");
VkShaderModule shaderModule = module_->BlockUntilReady();
vulkan_->Delete().QueueDeleteShaderModule(shaderModule);
vulkan_->Delete().QueueCallback([](VulkanContext *context, void *m) {
INFO_LOG(G3D, "destroying shader module promise");
auto module = (Promise<VkShaderModule> *)m;
delete module;
}, module_);
Expand Down
1 change: 1 addition & 0 deletions Common/Thread/ThreadManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class Task {
virtual void Cancel() {}
virtual uint64_t id() { return 0; }
virtual void Release() { delete this; }
virtual const char *Kind() const { return nullptr; } // Useful for selecting task by some qualifier, like, waiting for them all.
};

class Waitable {
Expand Down

0 comments on commit c1a7235

Please sign in to comment.