diff --git a/src/dxvk/dxvk_compute.cpp b/src/dxvk/dxvk_compute.cpp index ebd86f12e..355b01b12 100644 --- a/src/dxvk/dxvk_compute.cpp +++ b/src/dxvk/dxvk_compute.cpp @@ -20,11 +20,11 @@ namespace dxvk { DxvkComputePipeline::DxvkComputePipeline( - DxvkPipelineManager* pipeMgr, - const Rc& cs) - : m_vkd(pipeMgr->m_device->vkd()), - m_pipeMgr(pipeMgr), m_cs(cs) { - cs->defineResourceSlots(m_slotMapping); + DxvkPipelineManager* pipeMgr, + DxvkComputePipelineShaders shaders) + : m_vkd(pipeMgr->m_device->vkd()), m_pipeMgr(pipeMgr), + m_shaders(std::move(shaders)) { + m_shaders.cs->defineResourceSlots(m_slotMapping); m_slotMapping.makeDescriptorsDynamic( m_pipeMgr->m_device->options().maxNumDynamicUniformBuffers, @@ -86,7 +86,7 @@ namespace dxvk { if (Logger::logLevel() <= LogLevel::Debug) { Logger::debug("Compiling compute pipeline..."); - Logger::debug(str::format(" cs : ", m_cs->debugName())); + Logger::debug(str::format(" cs : ", m_shaders.cs->debugName())); } DxvkSpecConstants specData; @@ -98,7 +98,7 @@ namespace dxvk { DxvkShaderModuleCreateInfo moduleInfo; moduleInfo.fsDualSrcBlend = false; - auto csm = m_cs->createShaderModule(m_vkd, m_slotMapping, moduleInfo); + auto csm = m_shaders.cs->createShaderModule(m_vkd, m_slotMapping, moduleInfo); VkComputePipelineCreateInfo info; info.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO; @@ -116,7 +116,7 @@ namespace dxvk { if (m_vkd->vkCreateComputePipelines(m_vkd->device(), m_pipeMgr->m_cache->handle(), 1, &info, nullptr, &pipeline) != VK_SUCCESS) { Logger::err("DxvkComputePipeline: Failed to compile pipeline"); - Logger::err(str::format(" cs : ", m_cs->debugName())); + Logger::err(str::format(" cs : ", m_shaders.cs->debugName())); return VK_NULL_HANDLE; } @@ -139,8 +139,8 @@ namespace dxvk { DxvkStateCacheKey key; - if (m_cs != nullptr) - key.cs = m_cs->getShaderKey(); + if (m_shaders.cs != nullptr) + key.cs = m_shaders.cs->getShaderKey(); m_pipeMgr->m_stateCache->addComputePipeline(key, state); } diff --git a/src/dxvk/dxvk_compute.h b/src/dxvk/dxvk_compute.h index 60a03450c..933698c10 100644 --- a/src/dxvk/dxvk_compute.h +++ b/src/dxvk/dxvk_compute.h @@ -47,8 +47,9 @@ namespace dxvk { public: DxvkComputePipeline( - DxvkPipelineManager* pipeMgr, - const Rc& cs); + DxvkPipelineManager* pipeMgr, + DxvkComputePipelineShaders shaders); + ~DxvkComputePipeline(); /** @@ -79,13 +80,13 @@ namespace dxvk { VkPipeline pipeline; }; - Rc m_vkd; - DxvkPipelineManager* m_pipeMgr; + Rc m_vkd; + DxvkPipelineManager* m_pipeMgr; - DxvkDescriptorSlotMapping m_slotMapping; + DxvkComputePipelineShaders m_shaders; + DxvkDescriptorSlotMapping m_slotMapping; - Rc m_cs; - Rc m_layout; + Rc m_layout; sync::Spinlock m_mutex; std::vector m_pipelines; diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index 924031993..a80515847 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -38,19 +38,15 @@ namespace dxvk { DxvkGraphicsPipeline::DxvkGraphicsPipeline( - DxvkPipelineManager* pipeMgr, - const Rc& vs, - const Rc& tcs, - const Rc& tes, - const Rc& gs, - const Rc& fs) + DxvkPipelineManager* pipeMgr, + DxvkGraphicsPipelineShaders shaders) : m_vkd(pipeMgr->m_device->vkd()), m_pipeMgr(pipeMgr), - m_vs(vs), m_tcs(tcs), m_tes(tes), m_gs(gs), m_fs(fs) { - if (vs != nullptr) vs ->defineResourceSlots(m_slotMapping); - if (tcs != nullptr) tcs->defineResourceSlots(m_slotMapping); - if (tes != nullptr) tes->defineResourceSlots(m_slotMapping); - if (gs != nullptr) gs ->defineResourceSlots(m_slotMapping); - if (fs != nullptr) fs ->defineResourceSlots(m_slotMapping); + m_shaders(std::move(shaders)) { + if (m_shaders.vs != nullptr) m_shaders.vs ->defineResourceSlots(m_slotMapping); + if (m_shaders.tcs != nullptr) m_shaders.tcs->defineResourceSlots(m_slotMapping); + if (m_shaders.tes != nullptr) m_shaders.tes->defineResourceSlots(m_slotMapping); + if (m_shaders.gs != nullptr) m_shaders.gs ->defineResourceSlots(m_slotMapping); + if (m_shaders.fs != nullptr) m_shaders.fs ->defineResourceSlots(m_slotMapping); m_slotMapping.makeDescriptorsDynamic( pipeMgr->m_device->options().maxNumDynamicUniformBuffers, @@ -59,10 +55,10 @@ namespace dxvk { m_layout = new DxvkPipelineLayout(m_vkd, m_slotMapping, VK_PIPELINE_BIND_POINT_GRAPHICS); - m_vsIn = vs != nullptr ? vs->interfaceSlots().inputSlots : 0; - m_fsOut = fs != nullptr ? fs->interfaceSlots().outputSlots : 0; + m_vsIn = m_shaders.vs != nullptr ? m_shaders.vs->interfaceSlots().inputSlots : 0; + m_fsOut = m_shaders.fs != nullptr ? m_shaders.fs->interfaceSlots().outputSlots : 0; - if (gs != nullptr && gs->hasCapability(spv::CapabilityTransformFeedback)) + if (m_shaders.gs != nullptr && m_shaders.gs->hasCapability(spv::CapabilityTransformFeedback)) m_flags.set(DxvkGraphicsPipelineFlag::HasTransformFeedback); VkShaderStageFlags stoStages = m_layout->getStorageDescriptorStages(); @@ -73,7 +69,7 @@ namespace dxvk { if (stoStages & ~VK_SHADER_STAGE_FRAGMENT_BIT) m_flags.set(DxvkGraphicsPipelineFlag::HasVsStorageDescriptors); - m_common.msSampleShadingEnable = fs != nullptr && fs->hasCapability(spv::CapabilitySampleRateShading); + m_common.msSampleShadingEnable = m_shaders.fs != nullptr && m_shaders.fs->hasCapability(spv::CapabilitySampleRateShading); m_common.msSampleShadingFactor = 1.0f; } @@ -87,11 +83,11 @@ namespace dxvk { Rc DxvkGraphicsPipeline::getShader( VkShaderStageFlagBits stage) const { switch (stage) { - case VK_SHADER_STAGE_VERTEX_BIT: return m_vs; - case VK_SHADER_STAGE_GEOMETRY_BIT: return m_gs; - case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT: return m_tcs; - case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT: return m_tes; - case VK_SHADER_STAGE_FRAGMENT_BIT: return m_fs; + case VK_SHADER_STAGE_VERTEX_BIT: return m_shaders.vs; + case VK_SHADER_STAGE_GEOMETRY_BIT: return m_shaders.gs; + case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT: return m_shaders.tcs; + case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT: return m_shaders.tes; + case VK_SHADER_STAGE_FRAGMENT_BIT: return m_shaders.fs; default: return nullptr; } @@ -212,11 +208,11 @@ namespace dxvk { util::isDualSourceBlendFactor(state.omBlendAttachments[0].srcAlphaBlendFactor) || util::isDualSourceBlendFactor(state.omBlendAttachments[0].dstAlphaBlendFactor)); - auto vsm = createShaderModule(m_vs, moduleInfo); - auto gsm = createShaderModule(m_gs, moduleInfo); - auto tcsm = createShaderModule(m_tcs, moduleInfo); - auto tesm = createShaderModule(m_tes, moduleInfo); - auto fsm = createShaderModule(m_fs, moduleInfo); + auto vsm = createShaderModule(m_shaders.vs, moduleInfo); + auto gsm = createShaderModule(m_shaders.gs, moduleInfo); + auto tcsm = createShaderModule(m_shaders.tcs, moduleInfo); + auto tesm = createShaderModule(m_shaders.tes, moduleInfo); + auto fsm = createShaderModule(m_shaders.fs, moduleInfo); std::vector stages; if (vsm) stages.push_back(vsm.stageInfo(&specInfo)); @@ -262,8 +258,8 @@ namespace dxvk { } } - int32_t rasterizedStream = m_gs != nullptr - ? m_gs->shaderOptions().rasterizedStream + int32_t rasterizedStream = m_shaders.gs != nullptr + ? m_shaders.gs->shaderOptions().rasterizedStream : 0; // Compact vertex bindings so that we can more easily update vertex buffers @@ -475,7 +471,7 @@ namespace dxvk { // If there are no tessellation shaders, we // obviously cannot use tessellation patches. - if ((state.iaPatchVertexCount != 0) && (m_tcs == nullptr || m_tes == nullptr)) + if ((state.iaPatchVertexCount != 0) && (m_shaders.tcs == nullptr || m_shaders.tes == nullptr)) return false; // Prevent unintended out-of-bounds access to the IL arrays @@ -495,11 +491,11 @@ namespace dxvk { return; DxvkStateCacheKey key; - if (m_vs != nullptr) key.vs = m_vs->getShaderKey(); - if (m_tcs != nullptr) key.tcs = m_tcs->getShaderKey(); - if (m_tes != nullptr) key.tes = m_tes->getShaderKey(); - if (m_gs != nullptr) key.gs = m_gs->getShaderKey(); - if (m_fs != nullptr) key.fs = m_fs->getShaderKey(); + if (m_shaders.vs != nullptr) key.vs = m_shaders.vs->getShaderKey(); + if (m_shaders.tcs != nullptr) key.tcs = m_shaders.tcs->getShaderKey(); + if (m_shaders.tes != nullptr) key.tes = m_shaders.tes->getShaderKey(); + if (m_shaders.gs != nullptr) key.gs = m_shaders.gs->getShaderKey(); + if (m_shaders.fs != nullptr) key.fs = m_shaders.fs->getShaderKey(); m_pipeMgr->m_stateCache->addGraphicsPipeline(key, state, format); } @@ -508,11 +504,11 @@ namespace dxvk { void DxvkGraphicsPipeline::logPipelineState( LogLevel level, const DxvkGraphicsPipelineStateInfo& state) const { - if (m_vs != nullptr) Logger::log(level, str::format(" vs : ", m_vs ->debugName())); - if (m_tcs != nullptr) Logger::log(level, str::format(" tcs : ", m_tcs->debugName())); - if (m_tes != nullptr) Logger::log(level, str::format(" tes : ", m_tes->debugName())); - if (m_gs != nullptr) Logger::log(level, str::format(" gs : ", m_gs ->debugName())); - if (m_fs != nullptr) Logger::log(level, str::format(" fs : ", m_fs ->debugName())); + if (m_shaders.vs != nullptr) Logger::log(level, str::format(" vs : ", m_shaders.vs ->debugName())); + if (m_shaders.tcs != nullptr) Logger::log(level, str::format(" tcs : ", m_shaders.tcs->debugName())); + if (m_shaders.tes != nullptr) Logger::log(level, str::format(" tes : ", m_shaders.tes->debugName())); + if (m_shaders.gs != nullptr) Logger::log(level, str::format(" gs : ", m_shaders.gs ->debugName())); + if (m_shaders.fs != nullptr) Logger::log(level, str::format(" fs : ", m_shaders.fs ->debugName())); for (uint32_t i = 0; i < state.ilAttributeCount; i++) { const VkVertexInputAttributeDescription& attr = state.ilAttributes[i]; diff --git a/src/dxvk/dxvk_graphics.h b/src/dxvk/dxvk_graphics.h index 8a95d9400..027f9a73c 100644 --- a/src/dxvk/dxvk_graphics.h +++ b/src/dxvk/dxvk_graphics.h @@ -203,12 +203,9 @@ namespace dxvk { public: DxvkGraphicsPipeline( - DxvkPipelineManager* pipeMgr, - const Rc& vs, - const Rc& tcs, - const Rc& tes, - const Rc& gs, - const Rc& fs); + DxvkPipelineManager* pipeMgr, + DxvkGraphicsPipelineShaders shaders); + ~DxvkGraphicsPipeline(); /** @@ -263,17 +260,13 @@ namespace dxvk { VkPipeline pipeline; }; - Rc m_vkd; - DxvkPipelineManager* m_pipeMgr; + Rc m_vkd; + DxvkPipelineManager* m_pipeMgr; - DxvkDescriptorSlotMapping m_slotMapping; + DxvkGraphicsPipelineShaders m_shaders; + DxvkDescriptorSlotMapping m_slotMapping; - Rc m_vs; - Rc m_tcs; - Rc m_tes; - Rc m_gs; - Rc m_fs; - Rc m_layout; + Rc m_layout; uint32_t m_vsIn = 0; uint32_t m_fsOut = 0; diff --git a/src/dxvk/dxvk_pipemanager.cpp b/src/dxvk/dxvk_pipemanager.cpp index 5a6ed582f..b6447e834 100644 --- a/src/dxvk/dxvk_pipemanager.cpp +++ b/src/dxvk/dxvk_pipemanager.cpp @@ -70,8 +70,7 @@ namespace dxvk { if (pair != m_computePipelines.end()) return pair->second; - const Rc pipeline - = new DxvkComputePipeline(this, cs); + Rc pipeline = new DxvkComputePipeline(this, key); m_computePipelines.insert(std::make_pair(key, pipeline)); return pipeline; @@ -100,8 +99,7 @@ namespace dxvk { if (pair != m_graphicsPipelines.end()) return pair->second; - Rc pipeline = new DxvkGraphicsPipeline( - this, vs, tcs, tes, gs, fs); + Rc pipeline = new DxvkGraphicsPipeline(this, key); m_graphicsPipelines.insert(std::make_pair(key, pipeline)); return pipeline;