diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 18b6e20a4..f3159f1da 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -204,20 +204,20 @@ namespace dxvk { void DxvkContext::bindShader( VkShaderStageFlagBits stage, const Rc& shader) { - DxvkShaderStage* shaderStage = nullptr; + Rc* shaderStage; switch (stage) { - case VK_SHADER_STAGE_VERTEX_BIT: shaderStage = &m_state.gp.vs; break; - case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT: shaderStage = &m_state.gp.tcs; break; - case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT: shaderStage = &m_state.gp.tes; break; - case VK_SHADER_STAGE_GEOMETRY_BIT: shaderStage = &m_state.gp.gs; break; - case VK_SHADER_STAGE_FRAGMENT_BIT: shaderStage = &m_state.gp.fs; break; - case VK_SHADER_STAGE_COMPUTE_BIT: shaderStage = &m_state.cp.cs; 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.shaders.tcs; 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.shaders.gs; break; + case VK_SHADER_STAGE_FRAGMENT_BIT: shaderStage = &m_state.gp.shaders.fs; break; + case VK_SHADER_STAGE_COMPUTE_BIT: shaderStage = &m_state.cp.shaders.cs; break; default: return; } - shaderStage->shader = shader; - + *shaderStage = shader; + if (stage == VK_SHADER_STAGE_COMPUTE_BIT) { m_flags.set( DxvkContextFlag::CpDirtyPipeline, @@ -3410,7 +3410,7 @@ namespace dxvk { m_flags.clr(DxvkContextFlag::CpDirtyPipeline); 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 && m_state.cp.pipeline->layout()->pushConstRange().size) @@ -3460,11 +3460,8 @@ namespace dxvk { m_flags.clr(DxvkContextFlag::GpDirtyPipeline); m_state.gp.state.bsBindingMask.clear(); - m_state.gp.pipeline = m_pipeMgr->createGraphicsPipeline( - m_state.gp.vs.shader, - 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(); + m_state.gp.pipeline = m_pipeMgr->createGraphicsPipeline(m_state.gp.shaders); + m_state.gp.flags = DxvkGraphicsPipelineFlags(); if (m_state.gp.pipeline != nullptr) { m_state.gp.flags = m_state.gp.pipeline->flags(); @@ -3869,7 +3866,7 @@ namespace dxvk { void DxvkContext::updateTransformFeedbackBuffers() { - auto gsOptions = m_state.gp.gs.shader->shaderOptions(); + auto gsOptions = m_state.gp.shaders.gs->shaderOptions(); VkBuffer xfbBuffers[MaxNumXfbBuffers]; VkDeviceSize xfbOffsets[MaxNumXfbBuffers]; diff --git a/src/dxvk/dxvk_context_state.h b/src/dxvk/dxvk_context_state.h index 002bebeeb..c27050af1 100644 --- a/src/dxvk/dxvk_context_state.h +++ b/src/dxvk/dxvk_context_state.h @@ -113,18 +113,8 @@ namespace dxvk { }; - struct DxvkShaderStage { - Rc shader; - }; - - struct DxvkGraphicsPipelineState { - DxvkShaderStage vs; - DxvkShaderStage tcs; - DxvkShaderStage tes; - DxvkShaderStage gs; - DxvkShaderStage fs; - + DxvkGraphicsPipelineShaders shaders; DxvkGraphicsPipelineStateInfo state; DxvkGraphicsPipelineFlags flags; Rc pipeline; @@ -132,8 +122,7 @@ namespace dxvk { struct DxvkComputePipelineState { - DxvkShaderStage cs; - + DxvkComputePipelineShaders shaders; DxvkComputePipelineStateInfo state; Rc pipeline; }; diff --git a/src/dxvk/dxvk_pipemanager.cpp b/src/dxvk/dxvk_pipemanager.cpp index b6447e834..c13e91a2e 100644 --- a/src/dxvk/dxvk_pipemanager.cpp +++ b/src/dxvk/dxvk_pipemanager.cpp @@ -57,51 +57,37 @@ namespace dxvk { Rc DxvkPipelineManager::createComputePipeline( - const Rc& cs) { - if (cs == nullptr) + const DxvkComputePipelineShaders& shaders) { + if (shaders.cs == nullptr) return nullptr; std::lock_guard lock(m_mutex); - DxvkComputePipelineShaders key; - key.cs = cs; - - auto pair = m_computePipelines.find(key); + auto pair = m_computePipelines.find(shaders); if (pair != m_computePipelines.end()) return pair->second; - Rc pipeline = new DxvkComputePipeline(this, key); + Rc pipeline = new DxvkComputePipeline(this, shaders); - m_computePipelines.insert(std::make_pair(key, pipeline)); + m_computePipelines.insert(std::make_pair(shaders, pipeline)); return pipeline; } Rc DxvkPipelineManager::createGraphicsPipeline( - const Rc& vs, - const Rc& tcs, - const Rc& tes, - const Rc& gs, - const Rc& fs) { - if (vs == nullptr) + const DxvkGraphicsPipelineShaders& shaders) { + if (shaders.vs == nullptr) return nullptr; std::lock_guard lock(m_mutex); - DxvkGraphicsPipelineShaders key; - key.vs = vs; - key.tcs = tcs; - key.tes = tes; - key.gs = gs; - key.fs = fs; - - auto pair = m_graphicsPipelines.find(key); + auto pair = m_graphicsPipelines.find(shaders); if (pair != m_graphicsPipelines.end()) return pair->second; - Rc pipeline = new DxvkGraphicsPipeline(this, key); + Rc pipeline = new DxvkGraphicsPipeline(this, shaders); - m_graphicsPipelines.insert(std::make_pair(key, pipeline)); + m_graphicsPipelines.insert(std::make_pair(shaders, pipeline)); return pipeline; } diff --git a/src/dxvk/dxvk_pipemanager.h b/src/dxvk/dxvk_pipemanager.h index 9bcb279e5..05280565f 100644 --- a/src/dxvk/dxvk_pipemanager.h +++ b/src/dxvk/dxvk_pipemanager.h @@ -60,11 +60,11 @@ namespace dxvk { * If a pipeline for the given shader stage object * already exists, it will be returned. Otherwise, * a new pipeline will be created. - * \param [in] cs Compute shader + * \param [in] shaders Shaders for the pipeline * \returns Compute pipeline object */ Rc createComputePipeline( - const Rc& cs); + const DxvkComputePipelineShaders& shaders); /** * \brief Retrieves a graphics pipeline object @@ -72,19 +72,11 @@ namespace dxvk { * If a pipeline for the given shader stage objects * already exists, it will be returned. Otherwise, * a new pipeline will be created. - * \param [in] vs Vertex shader - * \param [in] tcs Tessellation control shader - * \param [in] tes Tessellation evaluation shader - * \param [in] gs Geometry shader - * \param [in] fs Fragment shader + * \param [in] shaders Shaders for the pipeline * \returns Graphics pipeline object */ Rc createGraphicsPipeline( - const Rc& vs, - const Rc& tcs, - const Rc& tes, - const Rc& gs, - const Rc& fs); + const DxvkGraphicsPipelineShaders& shaders); /* * \brief Registers a shader diff --git a/src/dxvk/dxvk_state_cache.cpp b/src/dxvk/dxvk_state_cache.cpp index a9249a3a2..0b310062f 100644 --- a/src/dxvk/dxvk_state_cache.cpp +++ b/src/dxvk/dxvk_state_cache.cpp @@ -191,12 +191,12 @@ namespace dxvk { for (auto p = pipelines.first; p != pipelines.second; p++) { WorkerItem item; - if (!getShaderByKey(p->second.vs, item.vs) - || !getShaderByKey(p->second.tcs, item.tcs) - || !getShaderByKey(p->second.tes, item.tes) - || !getShaderByKey(p->second.gs, item.gs) - || !getShaderByKey(p->second.fs, item.fs) - || !getShaderByKey(p->second.cs, item.cs)) + if (!getShaderByKey(p->second.vs, item.gp.vs) + || !getShaderByKey(p->second.tcs, item.gp.tcs) + || !getShaderByKey(p->second.tes, item.gp.tes) + || !getShaderByKey(p->second.gs, item.gp.gs) + || !getShaderByKey(p->second.fs, item.gp.fs) + || !getShaderByKey(p->second.cs, item.cp.cs)) continue; if (!workerLock) @@ -247,16 +247,15 @@ namespace dxvk { void DxvkStateCache::compilePipelines(const WorkerItem& item) { DxvkStateCacheKey key; - key.vs = getShaderKey(item.vs); - key.tcs = getShaderKey(item.tcs); - key.tes = getShaderKey(item.tes); - key.gs = getShaderKey(item.gs); - key.fs = getShaderKey(item.fs); - key.cs = getShaderKey(item.cs); + key.vs = getShaderKey(item.gp.vs); + key.tcs = getShaderKey(item.gp.tcs); + key.tes = getShaderKey(item.gp.tes); + key.gs = getShaderKey(item.gp.gs); + key.fs = getShaderKey(item.gp.fs); + key.cs = getShaderKey(item.cp.cs); - if (item.cs == nullptr) { - auto pipeline = m_pipeManager->createGraphicsPipeline( - item.vs, item.tcs, item.tes, item.gs, item.fs); + if (item.cp.cs == nullptr) { + auto pipeline = m_pipeManager->createGraphicsPipeline(item.gp); auto entries = m_entryMap.equal_range(key); for (auto e = entries.first; e != entries.second; e++) { @@ -266,7 +265,7 @@ namespace dxvk { pipeline->getPipelineHandle(entry.gpState, *rp); } } else { - auto pipeline = m_pipeManager->createComputePipeline(item.cs); + auto pipeline = m_pipeManager->createComputePipeline(item.cp); auto entries = m_entryMap.equal_range(key); for (auto e = entries.first; e != entries.second; e++) { diff --git a/src/dxvk/dxvk_state_cache.h b/src/dxvk/dxvk_state_cache.h index 599e6df00..f764d25ce 100644 --- a/src/dxvk/dxvk_state_cache.h +++ b/src/dxvk/dxvk_state_cache.h @@ -84,12 +84,8 @@ namespace dxvk { using WriterItem = DxvkStateCacheEntry; struct WorkerItem { - Rc vs; - Rc tcs; - Rc tes; - Rc gs; - Rc fs; - Rc cs; + DxvkGraphicsPipelineShaders gp; + DxvkComputePipelineShaders cp; }; DxvkPipelineManager* m_pipeManager;