mirror of
https://github.com/EduApps-CDG/OpenDX
synced 2024-12-30 09:45:37 +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(
|
VkPipeline DxvkComputePipeline::getPipelineHandle(
|
||||||
const DxvkComputePipelineStateInfo& state,
|
const DxvkComputePipelineStateInfo& state,
|
||||||
DxvkStatCounters& stats) {
|
DxvkStatCounters& stats) {
|
||||||
for (const PipelineStruct& pair : m_pipelines) {
|
VkPipeline pipeline = VK_NULL_HANDLE;
|
||||||
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->compilePipeline(state, m_basePipeline);
|
// If no pipeline exists with the given state vector,
|
||||||
m_pipelines.push_back({ state, pipeline });
|
// create a new one and add it to the pipeline set.
|
||||||
|
VkPipeline newPipeline = this->compilePipeline(state, m_basePipeline);
|
||||||
|
|
||||||
if (m_basePipeline == VK_NULL_HANDLE)
|
{ std::lock_guard<sync::Spinlock> lock(m_mutex);
|
||||||
m_basePipeline = pipeline;
|
|
||||||
|
// 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 false;
|
||||||
return pipeline;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "dxvk_binding.h"
|
#include "dxvk_binding.h"
|
||||||
#include "dxvk_pipecache.h"
|
#include "dxvk_pipecache.h"
|
||||||
#include "dxvk_pipelayout.h"
|
#include "dxvk_pipelayout.h"
|
||||||
@ -76,10 +78,15 @@ namespace dxvk {
|
|||||||
Rc<DxvkPipelineLayout> m_layout;
|
Rc<DxvkPipelineLayout> m_layout;
|
||||||
Rc<DxvkShaderModule> m_cs;
|
Rc<DxvkShaderModule> m_cs;
|
||||||
|
|
||||||
|
sync::Spinlock m_mutex;
|
||||||
std::vector<PipelineStruct> m_pipelines;
|
std::vector<PipelineStruct> m_pipelines;
|
||||||
|
|
||||||
VkPipeline m_basePipeline = VK_NULL_HANDLE;
|
VkPipeline m_basePipeline = VK_NULL_HANDLE;
|
||||||
|
|
||||||
|
bool findPipeline(
|
||||||
|
const DxvkComputePipelineStateInfo& state,
|
||||||
|
VkPipeline& pipeline) const;
|
||||||
|
|
||||||
VkPipeline compilePipeline(
|
VkPipeline compilePipeline(
|
||||||
const DxvkComputePipelineStateInfo& state,
|
const DxvkComputePipelineStateInfo& state,
|
||||||
VkPipeline baseHandle) const;
|
VkPipeline baseHandle) const;
|
||||||
|
@ -78,23 +78,52 @@ namespace dxvk {
|
|||||||
VkPipeline DxvkGraphicsPipeline::getPipelineHandle(
|
VkPipeline DxvkGraphicsPipeline::getPipelineHandle(
|
||||||
const DxvkGraphicsPipelineStateInfo& state,
|
const DxvkGraphicsPipelineStateInfo& state,
|
||||||
DxvkStatCounters& stats) {
|
DxvkStatCounters& stats) {
|
||||||
|
VkPipeline pipeline = VK_NULL_HANDLE;
|
||||||
|
|
||||||
for (const PipelineStruct& pair : m_pipelines) {
|
{ std::lock_guard<sync::Spinlock> lock(m_mutex);
|
||||||
if (pair.stateVector == state)
|
|
||||||
return pair.pipeline;
|
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)
|
? this->compilePipeline(state, m_basePipeline)
|
||||||
: VK_NULL_HANDLE;
|
: 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)
|
return false;
|
||||||
m_basePipeline = pipeline;
|
|
||||||
|
|
||||||
stats.addCtr(DxvkStatCounter::PipeCountGraphics, 1);
|
|
||||||
return pipeline;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <vector>
|
#include <mutex>
|
||||||
|
|
||||||
#include "dxvk_binding.h"
|
#include "dxvk_binding.h"
|
||||||
#include "dxvk_constant_state.h"
|
#include "dxvk_constant_state.h"
|
||||||
@ -160,10 +160,15 @@ namespace dxvk {
|
|||||||
|
|
||||||
DxvkGraphicsCommonPipelineStateInfo m_common;
|
DxvkGraphicsCommonPipelineStateInfo m_common;
|
||||||
|
|
||||||
|
sync::Spinlock m_mutex;
|
||||||
std::vector<PipelineStruct> m_pipelines;
|
std::vector<PipelineStruct> m_pipelines;
|
||||||
|
|
||||||
VkPipeline m_basePipeline = VK_NULL_HANDLE;
|
VkPipeline m_basePipeline = VK_NULL_HANDLE;
|
||||||
|
|
||||||
|
bool findPipeline(
|
||||||
|
const DxvkGraphicsPipelineStateInfo& state,
|
||||||
|
VkPipeline& pipeline) const;
|
||||||
|
|
||||||
VkPipeline compilePipeline(
|
VkPipeline compilePipeline(
|
||||||
const DxvkGraphicsPipelineStateInfo& state,
|
const DxvkGraphicsPipelineStateInfo& state,
|
||||||
VkPipeline baseHandle) const;
|
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;
|
return a.cs == b.cs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool DxvkPipelineKeyEq::operator () (const DxvkGraphicsPipelineKey& a, const DxvkGraphicsPipelineKey& b) const {
|
bool DxvkPipelineKeyEq::operator () (
|
||||||
return a.vs == b.vs
|
const DxvkGraphicsPipelineKey& a,
|
||||||
&& a.tcs == b.tcs
|
const DxvkGraphicsPipelineKey& b) const {
|
||||||
&& a.tes == b.tes
|
return a.vs == b.vs && a.tcs == b.tcs
|
||||||
&& a.gs == b.gs
|
&& a.tes == b.tes && a.gs == b.gs
|
||||||
&& a.fs == b.fs;
|
&& a.fs == b.fs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -52,6 +54,8 @@ namespace dxvk {
|
|||||||
if (cs == nullptr)
|
if (cs == nullptr)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
|
std::lock_guard<std::mutex> lock(m_mutex);
|
||||||
|
|
||||||
DxvkComputePipelineKey key;
|
DxvkComputePipelineKey key;
|
||||||
key.cs = cs;
|
key.cs = cs;
|
||||||
|
|
||||||
@ -77,6 +81,8 @@ namespace dxvk {
|
|||||||
if (vs == nullptr)
|
if (vs == nullptr)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
|
std::lock_guard<std::mutex> lock(m_mutex);
|
||||||
|
|
||||||
DxvkGraphicsPipelineKey key;
|
DxvkGraphicsPipelineKey key;
|
||||||
key.vs = vs;
|
key.vs = vs;
|
||||||
key.tcs = tcs;
|
key.tcs = tcs;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <mutex>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
#include "dxvk_compute.h"
|
#include "dxvk_compute.h"
|
||||||
@ -99,6 +100,8 @@ namespace dxvk {
|
|||||||
|
|
||||||
const DxvkDevice* m_device;
|
const DxvkDevice* m_device;
|
||||||
|
|
||||||
|
std::mutex m_mutex;
|
||||||
|
|
||||||
std::unordered_map<
|
std::unordered_map<
|
||||||
DxvkComputePipelineKey,
|
DxvkComputePipelineKey,
|
||||||
Rc<DxvkComputePipeline>,
|
Rc<DxvkComputePipeline>,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user