mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-01-18 20:52:10 +01:00
[dxvk] Made pipe manager and pipeline classes thread-safe
This commit is contained in:
parent
cf1358b2f4
commit
d201a1f7c6
@ -42,19 +42,50 @@ namespace dxvk {
|
||||
VkPipeline DxvkComputePipeline::getPipelineHandle(
|
||||
const DxvkComputePipelineStateInfo& state,
|
||||
DxvkStatCounters& stats) {
|
||||
for (const PipelineStruct& pair : m_pipelines) {
|
||||
if (pair.stateVector == state)
|
||||
return pair.pipeline;
|
||||
VkPipeline pipeline = VK_NULL_HANDLE;
|
||||
|
||||
{ std::lock_guard<sync::Spinlock> lock(m_mutex);
|
||||
|
||||
if (this->findPipeline(state, pipeline))
|
||||
return pipeline;
|
||||
}
|
||||
|
||||
VkPipeline pipeline = this->compilePipeline(state, m_basePipeline);
|
||||
m_pipelines.push_back({ state, pipeline });
|
||||
// If no pipeline exists with the given state vector,
|
||||
// create a new one and add it to the pipeline set.
|
||||
VkPipeline newPipeline = this->compilePipeline(state, m_basePipeline);
|
||||
|
||||
if (m_basePipeline == VK_NULL_HANDLE)
|
||||
m_basePipeline = pipeline;
|
||||
{ std::lock_guard<sync::Spinlock> lock(m_mutex);
|
||||
|
||||
// Discard the pipeline if another thread
|
||||
// was faster compiling the same pipeline
|
||||
if (this->findPipeline(state, pipeline)) {
|
||||
m_vkd->vkDestroyPipeline(m_vkd->device(), newPipeline, nullptr);
|
||||
return pipeline;
|
||||
}
|
||||
|
||||
// Add new pipeline to the set
|
||||
m_pipelines.push_back({ state, newPipeline });
|
||||
|
||||
if (m_basePipeline == VK_NULL_HANDLE)
|
||||
m_basePipeline = newPipeline;
|
||||
|
||||
stats.addCtr(DxvkStatCounter::PipeCountCompute, 1);
|
||||
return newPipeline;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool DxvkComputePipeline::findPipeline(
|
||||
const DxvkComputePipelineStateInfo& state,
|
||||
VkPipeline& pipeline) const {
|
||||
for (const PipelineStruct& pair : m_pipelines) {
|
||||
if (pair.stateVector == state) {
|
||||
pipeline = pair.pipeline;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
stats.addCtr(DxvkStatCounter::PipeCountCompute, 1);
|
||||
return pipeline;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "dxvk_binding.h"
|
||||
#include "dxvk_pipecache.h"
|
||||
#include "dxvk_pipelayout.h"
|
||||
@ -76,10 +78,15 @@ namespace dxvk {
|
||||
Rc<DxvkPipelineLayout> m_layout;
|
||||
Rc<DxvkShaderModule> m_cs;
|
||||
|
||||
sync::Spinlock m_mutex;
|
||||
std::vector<PipelineStruct> m_pipelines;
|
||||
|
||||
VkPipeline m_basePipeline = VK_NULL_HANDLE;
|
||||
|
||||
bool findPipeline(
|
||||
const DxvkComputePipelineStateInfo& state,
|
||||
VkPipeline& pipeline) const;
|
||||
|
||||
VkPipeline compilePipeline(
|
||||
const DxvkComputePipelineStateInfo& state,
|
||||
VkPipeline baseHandle) const;
|
||||
|
@ -78,23 +78,52 @@ namespace dxvk {
|
||||
VkPipeline DxvkGraphicsPipeline::getPipelineHandle(
|
||||
const DxvkGraphicsPipelineStateInfo& state,
|
||||
DxvkStatCounters& stats) {
|
||||
VkPipeline pipeline = VK_NULL_HANDLE;
|
||||
|
||||
for (const PipelineStruct& pair : m_pipelines) {
|
||||
if (pair.stateVector == state)
|
||||
return pair.pipeline;
|
||||
{ std::lock_guard<sync::Spinlock> lock(m_mutex);
|
||||
|
||||
if (this->findPipeline(state, pipeline))
|
||||
return pipeline;
|
||||
}
|
||||
|
||||
VkPipeline pipeline = this->validatePipelineState(state)
|
||||
// If no pipeline exists with the given state vector,
|
||||
// create a new one and add it to the pipeline set.
|
||||
VkPipeline newPipeline = this->validatePipelineState(state)
|
||||
? this->compilePipeline(state, m_basePipeline)
|
||||
: VK_NULL_HANDLE;
|
||||
|
||||
m_pipelines.push_back({ state, pipeline });
|
||||
{ std::lock_guard<sync::Spinlock> lock(m_mutex);
|
||||
|
||||
// Discard the pipeline if another thread
|
||||
// was faster compiling the same pipeline
|
||||
if (this->findPipeline(state, pipeline)) {
|
||||
m_vkd->vkDestroyPipeline(m_vkd->device(), newPipeline, nullptr);
|
||||
return pipeline;
|
||||
}
|
||||
|
||||
// Add new pipeline to the set
|
||||
m_pipelines.push_back({ state, newPipeline });
|
||||
|
||||
if (m_basePipeline == VK_NULL_HANDLE)
|
||||
m_basePipeline = newPipeline;
|
||||
|
||||
stats.addCtr(DxvkStatCounter::PipeCountGraphics, 1);
|
||||
return newPipeline;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool DxvkGraphicsPipeline::findPipeline(
|
||||
const DxvkGraphicsPipelineStateInfo& state,
|
||||
VkPipeline& pipeline) const {
|
||||
for (const PipelineStruct& pair : m_pipelines) {
|
||||
if (pair.stateVector == state) {
|
||||
pipeline = pair.pipeline;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_basePipeline == VK_NULL_HANDLE)
|
||||
m_basePipeline = pipeline;
|
||||
|
||||
stats.addCtr(DxvkStatCounter::PipeCountGraphics, 1);
|
||||
return pipeline;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <mutex>
|
||||
|
||||
#include "dxvk_binding.h"
|
||||
#include "dxvk_constant_state.h"
|
||||
@ -160,10 +160,15 @@ namespace dxvk {
|
||||
|
||||
DxvkGraphicsCommonPipelineStateInfo m_common;
|
||||
|
||||
sync::Spinlock m_mutex;
|
||||
std::vector<PipelineStruct> m_pipelines;
|
||||
|
||||
VkPipeline m_basePipeline = VK_NULL_HANDLE;
|
||||
|
||||
bool findPipeline(
|
||||
const DxvkGraphicsPipelineStateInfo& state,
|
||||
VkPipeline& pipeline) const;
|
||||
|
||||
VkPipeline compilePipeline(
|
||||
const DxvkGraphicsPipelineStateInfo& state,
|
||||
VkPipeline baseHandle) const;
|
||||
|
@ -21,17 +21,19 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
bool DxvkPipelineKeyEq::operator () (const DxvkComputePipelineKey& a, const DxvkComputePipelineKey& b) const {
|
||||
bool DxvkPipelineKeyEq::operator () (
|
||||
const DxvkComputePipelineKey& a,
|
||||
const DxvkComputePipelineKey& b) const {
|
||||
return a.cs == b.cs;
|
||||
}
|
||||
|
||||
|
||||
bool DxvkPipelineKeyEq::operator () (const DxvkGraphicsPipelineKey& a, const DxvkGraphicsPipelineKey& b) const {
|
||||
return a.vs == b.vs
|
||||
&& a.tcs == b.tcs
|
||||
&& a.tes == b.tes
|
||||
&& a.gs == b.gs
|
||||
&& a.fs == b.fs;
|
||||
bool DxvkPipelineKeyEq::operator () (
|
||||
const DxvkGraphicsPipelineKey& a,
|
||||
const DxvkGraphicsPipelineKey& b) const {
|
||||
return a.vs == b.vs && a.tcs == b.tcs
|
||||
&& a.tes == b.tes && a.gs == b.gs
|
||||
&& a.fs == b.fs;
|
||||
}
|
||||
|
||||
|
||||
@ -52,6 +54,8 @@ namespace dxvk {
|
||||
if (cs == nullptr)
|
||||
return nullptr;
|
||||
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
|
||||
DxvkComputePipelineKey key;
|
||||
key.cs = cs;
|
||||
|
||||
@ -77,6 +81,8 @@ namespace dxvk {
|
||||
if (vs == nullptr)
|
||||
return nullptr;
|
||||
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
|
||||
DxvkGraphicsPipelineKey key;
|
||||
key.vs = vs;
|
||||
key.tcs = tcs;
|
||||
|
@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <mutex>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "dxvk_compute.h"
|
||||
@ -99,6 +100,8 @@ namespace dxvk {
|
||||
|
||||
const DxvkDevice* m_device;
|
||||
|
||||
std::mutex m_mutex;
|
||||
|
||||
std::unordered_map<
|
||||
DxvkComputePipelineKey,
|
||||
Rc<DxvkComputePipeline>,
|
||||
|
Loading…
x
Reference in New Issue
Block a user