1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-02-28 07:54:14 +01:00

[dxvk] Use shader key structs directly for pipeline lookups

Removes some overhead and unnecessary ref count changes on shaders.
This commit is contained in:
Philip Rebohle 2019-07-23 12:54:25 +02:00
parent 8d4996bcda
commit 8cd13cc5bd
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
6 changed files with 46 additions and 87 deletions

View File

@ -204,19 +204,19 @@ namespace dxvk {
void DxvkContext::bindShader( void DxvkContext::bindShader(
VkShaderStageFlagBits stage, VkShaderStageFlagBits stage,
const Rc<DxvkShader>& shader) { const Rc<DxvkShader>& shader) {
DxvkShaderStage* shaderStage = nullptr; Rc<DxvkShader>* shaderStage;
switch (stage) { switch (stage) {
case VK_SHADER_STAGE_VERTEX_BIT: shaderStage = &m_state.gp.vs; break; case VK_SHADER_STAGE_VERTEX_BIT: shaderStage = &m_state.gp.shaders.vs; break;
case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT: shaderStage = &m_state.gp.tcs; break; case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT: shaderStage = &m_state.gp.shaders.tcs; break;
case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT: shaderStage = &m_state.gp.tes; break; case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT: shaderStage = &m_state.gp.shaders.tes; break;
case VK_SHADER_STAGE_GEOMETRY_BIT: shaderStage = &m_state.gp.gs; break; case VK_SHADER_STAGE_GEOMETRY_BIT: shaderStage = &m_state.gp.shaders.gs; break;
case VK_SHADER_STAGE_FRAGMENT_BIT: shaderStage = &m_state.gp.fs; break; case VK_SHADER_STAGE_FRAGMENT_BIT: shaderStage = &m_state.gp.shaders.fs; break;
case VK_SHADER_STAGE_COMPUTE_BIT: shaderStage = &m_state.cp.cs; break; case VK_SHADER_STAGE_COMPUTE_BIT: shaderStage = &m_state.cp.shaders.cs; break;
default: return; default: return;
} }
shaderStage->shader = shader; *shaderStage = shader;
if (stage == VK_SHADER_STAGE_COMPUTE_BIT) { if (stage == VK_SHADER_STAGE_COMPUTE_BIT) {
m_flags.set( m_flags.set(
@ -3410,7 +3410,7 @@ namespace dxvk {
m_flags.clr(DxvkContextFlag::CpDirtyPipeline); m_flags.clr(DxvkContextFlag::CpDirtyPipeline);
m_state.cp.state.bsBindingMask.clear(); m_state.cp.state.bsBindingMask.clear();
m_state.cp.pipeline = m_pipeMgr->createComputePipeline(m_state.cp.cs.shader); m_state.cp.pipeline = m_pipeMgr->createComputePipeline(m_state.cp.shaders);
if (m_state.cp.pipeline != nullptr if (m_state.cp.pipeline != nullptr
&& m_state.cp.pipeline->layout()->pushConstRange().size) && m_state.cp.pipeline->layout()->pushConstRange().size)
@ -3460,11 +3460,8 @@ namespace dxvk {
m_flags.clr(DxvkContextFlag::GpDirtyPipeline); m_flags.clr(DxvkContextFlag::GpDirtyPipeline);
m_state.gp.state.bsBindingMask.clear(); m_state.gp.state.bsBindingMask.clear();
m_state.gp.pipeline = m_pipeMgr->createGraphicsPipeline( m_state.gp.pipeline = m_pipeMgr->createGraphicsPipeline(m_state.gp.shaders);
m_state.gp.vs.shader, m_state.gp.flags = DxvkGraphicsPipelineFlags();
m_state.gp.tcs.shader, m_state.gp.tes.shader,
m_state.gp.gs.shader, m_state.gp.fs.shader);
m_state.gp.flags = DxvkGraphicsPipelineFlags();
if (m_state.gp.pipeline != nullptr) { if (m_state.gp.pipeline != nullptr) {
m_state.gp.flags = m_state.gp.pipeline->flags(); m_state.gp.flags = m_state.gp.pipeline->flags();
@ -3869,7 +3866,7 @@ namespace dxvk {
void DxvkContext::updateTransformFeedbackBuffers() { void DxvkContext::updateTransformFeedbackBuffers() {
auto gsOptions = m_state.gp.gs.shader->shaderOptions(); auto gsOptions = m_state.gp.shaders.gs->shaderOptions();
VkBuffer xfbBuffers[MaxNumXfbBuffers]; VkBuffer xfbBuffers[MaxNumXfbBuffers];
VkDeviceSize xfbOffsets[MaxNumXfbBuffers]; VkDeviceSize xfbOffsets[MaxNumXfbBuffers];

View File

@ -113,18 +113,8 @@ namespace dxvk {
}; };
struct DxvkShaderStage {
Rc<DxvkShader> shader;
};
struct DxvkGraphicsPipelineState { struct DxvkGraphicsPipelineState {
DxvkShaderStage vs; DxvkGraphicsPipelineShaders shaders;
DxvkShaderStage tcs;
DxvkShaderStage tes;
DxvkShaderStage gs;
DxvkShaderStage fs;
DxvkGraphicsPipelineStateInfo state; DxvkGraphicsPipelineStateInfo state;
DxvkGraphicsPipelineFlags flags; DxvkGraphicsPipelineFlags flags;
Rc<DxvkGraphicsPipeline> pipeline; Rc<DxvkGraphicsPipeline> pipeline;
@ -132,8 +122,7 @@ namespace dxvk {
struct DxvkComputePipelineState { struct DxvkComputePipelineState {
DxvkShaderStage cs; DxvkComputePipelineShaders shaders;
DxvkComputePipelineStateInfo state; DxvkComputePipelineStateInfo state;
Rc<DxvkComputePipeline> pipeline; Rc<DxvkComputePipeline> pipeline;
}; };

View File

@ -57,51 +57,37 @@ namespace dxvk {
Rc<DxvkComputePipeline> DxvkPipelineManager::createComputePipeline( Rc<DxvkComputePipeline> DxvkPipelineManager::createComputePipeline(
const Rc<DxvkShader>& cs) { const DxvkComputePipelineShaders& shaders) {
if (cs == nullptr) if (shaders.cs == nullptr)
return nullptr; return nullptr;
std::lock_guard<std::mutex> lock(m_mutex); std::lock_guard<std::mutex> lock(m_mutex);
DxvkComputePipelineShaders key; auto pair = m_computePipelines.find(shaders);
key.cs = cs;
auto pair = m_computePipelines.find(key);
if (pair != m_computePipelines.end()) if (pair != m_computePipelines.end())
return pair->second; return pair->second;
Rc<DxvkComputePipeline> pipeline = new DxvkComputePipeline(this, key); Rc<DxvkComputePipeline> pipeline = new DxvkComputePipeline(this, shaders);
m_computePipelines.insert(std::make_pair(key, pipeline)); m_computePipelines.insert(std::make_pair(shaders, pipeline));
return pipeline; return pipeline;
} }
Rc<DxvkGraphicsPipeline> DxvkPipelineManager::createGraphicsPipeline( Rc<DxvkGraphicsPipeline> DxvkPipelineManager::createGraphicsPipeline(
const Rc<DxvkShader>& vs, const DxvkGraphicsPipelineShaders& shaders) {
const Rc<DxvkShader>& tcs, if (shaders.vs == nullptr)
const Rc<DxvkShader>& tes,
const Rc<DxvkShader>& gs,
const Rc<DxvkShader>& fs) {
if (vs == nullptr)
return nullptr; return nullptr;
std::lock_guard<std::mutex> lock(m_mutex); std::lock_guard<std::mutex> lock(m_mutex);
DxvkGraphicsPipelineShaders key; auto pair = m_graphicsPipelines.find(shaders);
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()) if (pair != m_graphicsPipelines.end())
return pair->second; return pair->second;
Rc<DxvkGraphicsPipeline> pipeline = new DxvkGraphicsPipeline(this, key); Rc<DxvkGraphicsPipeline> pipeline = new DxvkGraphicsPipeline(this, shaders);
m_graphicsPipelines.insert(std::make_pair(key, pipeline)); m_graphicsPipelines.insert(std::make_pair(shaders, pipeline));
return pipeline; return pipeline;
} }

View File

@ -60,11 +60,11 @@ namespace dxvk {
* If a pipeline for the given shader stage object * If a pipeline for the given shader stage object
* already exists, it will be returned. Otherwise, * already exists, it will be returned. Otherwise,
* a new pipeline will be created. * a new pipeline will be created.
* \param [in] cs Compute shader * \param [in] shaders Shaders for the pipeline
* \returns Compute pipeline object * \returns Compute pipeline object
*/ */
Rc<DxvkComputePipeline> createComputePipeline( Rc<DxvkComputePipeline> createComputePipeline(
const Rc<DxvkShader>& cs); const DxvkComputePipelineShaders& shaders);
/** /**
* \brief Retrieves a graphics pipeline object * \brief Retrieves a graphics pipeline object
@ -72,19 +72,11 @@ namespace dxvk {
* If a pipeline for the given shader stage objects * If a pipeline for the given shader stage objects
* already exists, it will be returned. Otherwise, * already exists, it will be returned. Otherwise,
* a new pipeline will be created. * a new pipeline will be created.
* \param [in] vs Vertex shader * \param [in] shaders Shaders for the pipeline
* \param [in] tcs Tessellation control shader
* \param [in] tes Tessellation evaluation shader
* \param [in] gs Geometry shader
* \param [in] fs Fragment shader
* \returns Graphics pipeline object * \returns Graphics pipeline object
*/ */
Rc<DxvkGraphicsPipeline> createGraphicsPipeline( Rc<DxvkGraphicsPipeline> createGraphicsPipeline(
const Rc<DxvkShader>& vs, const DxvkGraphicsPipelineShaders& shaders);
const Rc<DxvkShader>& tcs,
const Rc<DxvkShader>& tes,
const Rc<DxvkShader>& gs,
const Rc<DxvkShader>& fs);
/* /*
* \brief Registers a shader * \brief Registers a shader

View File

@ -191,12 +191,12 @@ namespace dxvk {
for (auto p = pipelines.first; p != pipelines.second; p++) { for (auto p = pipelines.first; p != pipelines.second; p++) {
WorkerItem item; WorkerItem item;
if (!getShaderByKey(p->second.vs, item.vs) if (!getShaderByKey(p->second.vs, item.gp.vs)
|| !getShaderByKey(p->second.tcs, item.tcs) || !getShaderByKey(p->second.tcs, item.gp.tcs)
|| !getShaderByKey(p->second.tes, item.tes) || !getShaderByKey(p->second.tes, item.gp.tes)
|| !getShaderByKey(p->second.gs, item.gs) || !getShaderByKey(p->second.gs, item.gp.gs)
|| !getShaderByKey(p->second.fs, item.fs) || !getShaderByKey(p->second.fs, item.gp.fs)
|| !getShaderByKey(p->second.cs, item.cs)) || !getShaderByKey(p->second.cs, item.cp.cs))
continue; continue;
if (!workerLock) if (!workerLock)
@ -247,16 +247,15 @@ namespace dxvk {
void DxvkStateCache::compilePipelines(const WorkerItem& item) { void DxvkStateCache::compilePipelines(const WorkerItem& item) {
DxvkStateCacheKey key; DxvkStateCacheKey key;
key.vs = getShaderKey(item.vs); key.vs = getShaderKey(item.gp.vs);
key.tcs = getShaderKey(item.tcs); key.tcs = getShaderKey(item.gp.tcs);
key.tes = getShaderKey(item.tes); key.tes = getShaderKey(item.gp.tes);
key.gs = getShaderKey(item.gs); key.gs = getShaderKey(item.gp.gs);
key.fs = getShaderKey(item.fs); key.fs = getShaderKey(item.gp.fs);
key.cs = getShaderKey(item.cs); key.cs = getShaderKey(item.cp.cs);
if (item.cs == nullptr) { if (item.cp.cs == nullptr) {
auto pipeline = m_pipeManager->createGraphicsPipeline( auto pipeline = m_pipeManager->createGraphicsPipeline(item.gp);
item.vs, item.tcs, item.tes, item.gs, item.fs);
auto entries = m_entryMap.equal_range(key); auto entries = m_entryMap.equal_range(key);
for (auto e = entries.first; e != entries.second; e++) { for (auto e = entries.first; e != entries.second; e++) {
@ -266,7 +265,7 @@ namespace dxvk {
pipeline->getPipelineHandle(entry.gpState, *rp); pipeline->getPipelineHandle(entry.gpState, *rp);
} }
} else { } else {
auto pipeline = m_pipeManager->createComputePipeline(item.cs); auto pipeline = m_pipeManager->createComputePipeline(item.cp);
auto entries = m_entryMap.equal_range(key); auto entries = m_entryMap.equal_range(key);
for (auto e = entries.first; e != entries.second; e++) { for (auto e = entries.first; e != entries.second; e++) {

View File

@ -84,12 +84,8 @@ namespace dxvk {
using WriterItem = DxvkStateCacheEntry; using WriterItem = DxvkStateCacheEntry;
struct WorkerItem { struct WorkerItem {
Rc<DxvkShader> vs; DxvkGraphicsPipelineShaders gp;
Rc<DxvkShader> tcs; DxvkComputePipelineShaders cp;
Rc<DxvkShader> tes;
Rc<DxvkShader> gs;
Rc<DxvkShader> fs;
Rc<DxvkShader> cs;
}; };
DxvkPipelineManager* m_pipeManager; DxvkPipelineManager* m_pipeManager;