2018-05-09 14:26:45 +02:00
|
|
|
#include "dxvk_device.h"
|
2017-12-07 09:38:31 +01:00
|
|
|
#include "dxvk_pipemanager.h"
|
2018-09-21 23:23:43 +02:00
|
|
|
#include "dxvk_state_cache.h"
|
2017-12-07 09:38:31 +01:00
|
|
|
|
|
|
|
namespace dxvk {
|
|
|
|
|
2019-07-23 12:41:09 +02:00
|
|
|
size_t DxvkPipelineKeyHash::operator () (const DxvkComputePipelineShaders& key) const {
|
2017-12-07 09:38:31 +01:00
|
|
|
std::hash<DxvkShader*> hash;
|
|
|
|
return hash(key.cs.ptr());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-07-23 12:41:09 +02:00
|
|
|
size_t DxvkPipelineKeyHash::operator () (const DxvkGraphicsPipelineShaders& key) const {
|
2017-12-07 09:38:31 +01:00
|
|
|
DxvkHashState state;
|
|
|
|
|
|
|
|
std::hash<DxvkShader*> hash;
|
|
|
|
state.add(hash(key.vs.ptr()));
|
|
|
|
state.add(hash(key.tcs.ptr()));
|
|
|
|
state.add(hash(key.tes.ptr()));
|
|
|
|
state.add(hash(key.gs.ptr()));
|
|
|
|
state.add(hash(key.fs.ptr()));
|
|
|
|
return state;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-05-01 16:45:28 +02:00
|
|
|
bool DxvkPipelineKeyEq::operator () (
|
2019-07-23 12:41:09 +02:00
|
|
|
const DxvkComputePipelineShaders& a,
|
|
|
|
const DxvkComputePipelineShaders& b) const {
|
2017-12-07 09:38:31 +01:00
|
|
|
return a.cs == b.cs;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-05-01 16:45:28 +02:00
|
|
|
bool DxvkPipelineKeyEq::operator () (
|
2019-07-23 12:41:09 +02:00
|
|
|
const DxvkGraphicsPipelineShaders& a,
|
|
|
|
const DxvkGraphicsPipelineShaders& b) const {
|
2018-05-01 16:45:28 +02:00
|
|
|
return a.vs == b.vs && a.tcs == b.tcs
|
|
|
|
&& a.tes == b.tes && a.gs == b.gs
|
|
|
|
&& a.fs == b.fs;
|
2017-12-07 09:38:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-09-21 23:23:43 +02:00
|
|
|
DxvkPipelineManager::DxvkPipelineManager(
|
|
|
|
const DxvkDevice* device,
|
|
|
|
DxvkRenderPassPool* passManager)
|
|
|
|
: m_device (device),
|
|
|
|
m_cache (new DxvkPipelineCache(device->vkd())) {
|
2018-11-15 17:12:09 -05:00
|
|
|
std::string useStateCache = env::getEnvVar("DXVK_STATE_CACHE");
|
2018-09-13 21:39:56 +02:00
|
|
|
|
2018-11-24 20:04:21 +01:00
|
|
|
if (useStateCache != "0" && device->config().enableStateCache)
|
2018-11-15 09:24:11 +01:00
|
|
|
m_stateCache = new DxvkStateCache(device, this, passManager);
|
2018-01-13 22:18:32 +01:00
|
|
|
}
|
2017-12-07 09:38:31 +01:00
|
|
|
|
|
|
|
|
|
|
|
DxvkPipelineManager::~DxvkPipelineManager() {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Rc<DxvkComputePipeline> DxvkPipelineManager::createComputePipeline(
|
2018-01-13 22:18:32 +01:00
|
|
|
const Rc<DxvkShader>& cs) {
|
2017-12-07 09:38:31 +01:00
|
|
|
if (cs == nullptr)
|
|
|
|
return nullptr;
|
|
|
|
|
2018-05-01 16:45:28 +02:00
|
|
|
std::lock_guard<std::mutex> lock(m_mutex);
|
|
|
|
|
2019-07-23 12:41:09 +02:00
|
|
|
DxvkComputePipelineShaders key;
|
2017-12-07 09:38:31 +01:00
|
|
|
key.cs = cs;
|
|
|
|
|
|
|
|
auto pair = m_computePipelines.find(key);
|
|
|
|
if (pair != m_computePipelines.end())
|
|
|
|
return pair->second;
|
|
|
|
|
2019-07-23 12:48:11 +02:00
|
|
|
Rc<DxvkComputePipeline> pipeline = new DxvkComputePipeline(this, key);
|
2018-03-29 12:32:20 +02:00
|
|
|
|
2017-12-07 09:38:31 +01:00
|
|
|
m_computePipelines.insert(std::make_pair(key, pipeline));
|
|
|
|
return pipeline;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Rc<DxvkGraphicsPipeline> DxvkPipelineManager::createGraphicsPipeline(
|
2018-01-13 22:18:32 +01:00
|
|
|
const Rc<DxvkShader>& vs,
|
|
|
|
const Rc<DxvkShader>& tcs,
|
|
|
|
const Rc<DxvkShader>& tes,
|
|
|
|
const Rc<DxvkShader>& gs,
|
|
|
|
const Rc<DxvkShader>& fs) {
|
2017-12-07 09:38:31 +01:00
|
|
|
if (vs == nullptr)
|
|
|
|
return nullptr;
|
|
|
|
|
2018-05-01 16:45:28 +02:00
|
|
|
std::lock_guard<std::mutex> lock(m_mutex);
|
|
|
|
|
2019-07-23 12:41:09 +02:00
|
|
|
DxvkGraphicsPipelineShaders key;
|
2017-12-07 09:38:31 +01:00
|
|
|
key.vs = vs;
|
|
|
|
key.tcs = tcs;
|
|
|
|
key.tes = tes;
|
|
|
|
key.gs = gs;
|
|
|
|
key.fs = fs;
|
|
|
|
|
|
|
|
auto pair = m_graphicsPipelines.find(key);
|
|
|
|
if (pair != m_graphicsPipelines.end())
|
|
|
|
return pair->second;
|
|
|
|
|
2019-07-23 12:48:11 +02:00
|
|
|
Rc<DxvkGraphicsPipeline> pipeline = new DxvkGraphicsPipeline(this, key);
|
2018-03-29 12:32:20 +02:00
|
|
|
|
2017-12-07 09:38:31 +01:00
|
|
|
m_graphicsPipelines.insert(std::make_pair(key, pipeline));
|
|
|
|
return pipeline;
|
|
|
|
}
|
2018-09-21 22:28:06 +02:00
|
|
|
|
2018-09-21 23:23:43 +02:00
|
|
|
|
|
|
|
void DxvkPipelineManager::registerShader(
|
|
|
|
const Rc<DxvkShader>& shader) {
|
|
|
|
if (m_stateCache != nullptr)
|
|
|
|
m_stateCache->registerShader(shader);
|
|
|
|
}
|
|
|
|
|
2018-09-21 22:28:06 +02:00
|
|
|
|
|
|
|
DxvkPipelineCount DxvkPipelineManager::getPipelineCount() const {
|
|
|
|
DxvkPipelineCount result;
|
|
|
|
result.numComputePipelines = m_numComputePipelines.load();
|
|
|
|
result.numGraphicsPipelines = m_numGraphicsPipelines.load();
|
|
|
|
return result;
|
|
|
|
}
|
2019-04-14 12:15:43 +02:00
|
|
|
|
|
|
|
|
|
|
|
bool DxvkPipelineManager::isCompilingShaders() const {
|
|
|
|
return m_stateCache != nullptr
|
|
|
|
&& m_stateCache->isCompilingShaders();
|
|
|
|
}
|
2017-12-07 09:38:31 +01:00
|
|
|
|
2018-11-15 17:12:09 -05:00
|
|
|
}
|