From 06c084616f93876b093fb4aa85cae56fdad23b55 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 5 Jul 2022 18:46:11 +0200 Subject: [PATCH] [dxvk] Clean up graphics and compute pipeline constructors --- src/dxvk/dxvk_compute.cpp | 31 +++++++++++++----------- src/dxvk/dxvk_compute.h | 12 +++++++--- src/dxvk/dxvk_graphics.cpp | 44 +++++++++++++++++++++-------------- src/dxvk/dxvk_graphics.h | 12 +++++++--- src/dxvk/dxvk_pipemanager.cpp | 8 +++---- src/dxvk/dxvk_pipemanager.h | 11 ++++++--- 6 files changed, 73 insertions(+), 45 deletions(-) diff --git a/src/dxvk/dxvk_compute.cpp b/src/dxvk/dxvk_compute.cpp index 52849d8d..d85070f2 100644 --- a/src/dxvk/dxvk_compute.cpp +++ b/src/dxvk/dxvk_compute.cpp @@ -11,11 +11,16 @@ namespace dxvk { DxvkComputePipeline::DxvkComputePipeline( + DxvkDevice* device, DxvkPipelineManager* pipeMgr, DxvkComputePipelineShaders shaders, DxvkBindingLayoutObjects* layout) - : m_vkd(pipeMgr->m_device->vkd()), m_pipeMgr(pipeMgr), - m_shaders(std::move(shaders)), m_bindings(layout) { + : m_device (device), + m_cache (&pipeMgr->m_cache), + m_stateCache (&pipeMgr->m_stateCache), + m_stats (&pipeMgr->m_stats), + m_shaders (std::move(shaders)), + m_bindings (layout) { } @@ -57,7 +62,7 @@ namespace dxvk { const DxvkComputePipelineStateInfo& state) { VkPipeline newPipelineHandle = this->createPipeline(state); - m_pipeMgr->m_numComputePipelines += 1; + m_stats->numComputePipelines += 1; return &(*m_pipelines.emplace(state, newPipelineHandle)); } @@ -75,7 +80,7 @@ namespace dxvk { VkPipeline DxvkComputePipeline::createPipeline( const DxvkComputePipelineStateInfo& state) const { - std::vector bindings; + auto vk = m_device->vkd(); if (Logger::logLevel() <= LogLevel::Debug) { Logger::debug("Compiling compute pipeline..."); @@ -92,15 +97,11 @@ namespace dxvk { DxvkShaderModuleCreateInfo moduleInfo; moduleInfo.fsDualSrcBlend = false; - auto csm = m_shaders.cs->createShaderModule(m_vkd, m_bindings, moduleInfo); + auto csm = m_shaders.cs->createShaderModule(vk, m_bindings, moduleInfo); - VkComputePipelineCreateInfo info; - info.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO; - info.pNext = nullptr; - info.flags = 0; + VkComputePipelineCreateInfo info = { VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO }; info.stage = csm.stageInfo(&specInfo); info.layout = m_bindings->getPipelineLayout(); - info.basePipelineHandle = VK_NULL_HANDLE; info.basePipelineIndex = -1; // Time pipeline compilation for debugging purposes @@ -110,8 +111,8 @@ namespace dxvk { t0 = dxvk::high_resolution_clock::now(); VkPipeline pipeline = VK_NULL_HANDLE; - if (m_vkd->vkCreateComputePipelines(m_vkd->device(), - m_pipeMgr->m_cache.handle(), 1, &info, nullptr, &pipeline) != VK_SUCCESS) { + if (vk->vkCreateComputePipelines(vk->device(), + m_cache->handle(), 1, &info, nullptr, &pipeline) != VK_SUCCESS) { Logger::err("DxvkComputePipeline: Failed to compile pipeline"); Logger::err(str::format(" cs : ", m_shaders.cs->debugName())); return VK_NULL_HANDLE; @@ -128,7 +129,9 @@ namespace dxvk { void DxvkComputePipeline::destroyPipeline(VkPipeline pipeline) { - m_vkd->vkDestroyPipeline(m_vkd->device(), pipeline, nullptr); + auto vk = m_device->vkd(); + + vk->vkDestroyPipeline(vk->device(), pipeline, nullptr); } @@ -139,7 +142,7 @@ namespace dxvk { if (m_shaders.cs != nullptr) key.cs = m_shaders.cs->getShaderKey(); - m_pipeMgr->m_stateCache.addComputePipeline(key, state); + m_stateCache->addComputePipeline(key, state); } } diff --git a/src/dxvk/dxvk_compute.h b/src/dxvk/dxvk_compute.h index 51566389..4da2c14a 100644 --- a/src/dxvk/dxvk_compute.h +++ b/src/dxvk/dxvk_compute.h @@ -15,8 +15,11 @@ namespace dxvk { class DxvkDevice; + class DxvkStateCache; class DxvkPipelineManager; - + struct DxvkPipelineStats; + + /** * \brief Shaders used in compute pipelines */ @@ -90,6 +93,7 @@ namespace dxvk { public: DxvkComputePipeline( + DxvkDevice* device, DxvkPipelineManager* pipeMgr, DxvkComputePipelineShaders shaders, DxvkBindingLayoutObjects* layout); @@ -137,8 +141,10 @@ namespace dxvk { private: - Rc m_vkd; - DxvkPipelineManager* m_pipeMgr; + DxvkDevice* m_device; + DxvkPipelineCache* m_cache; + DxvkStateCache* m_stateCache; + DxvkPipelineStats* m_stats; DxvkComputePipelineShaders m_shaders; DxvkBindingLayoutObjects* m_bindings; diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index 614f8a3e..2f5ea8c3 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -456,12 +456,17 @@ namespace dxvk { DxvkGraphicsPipeline::DxvkGraphicsPipeline( + DxvkDevice* device, DxvkPipelineManager* pipeMgr, DxvkGraphicsPipelineShaders shaders, DxvkBindingLayoutObjects* layout) - : m_vkd(pipeMgr->m_device->vkd()), m_pipeMgr(pipeMgr), - m_shaders(std::move(shaders)), m_bindings(layout), - m_barrier(layout->getGlobalBarrier()) { + : m_device (device), + m_cache (&pipeMgr->m_cache), + m_stateCache (&pipeMgr->m_stateCache), + m_stats (&pipeMgr->m_stats), + m_shaders (std::move(shaders)), + m_bindings (layout), + m_barrier (layout->getGlobalBarrier()) { m_vsIn = m_shaders.vs != nullptr ? m_shaders.vs->info().inputMask : 0; m_fsOut = m_shaders.fs != nullptr ? m_shaders.fs->info().outputMask : 0; @@ -557,7 +562,7 @@ namespace dxvk { const DxvkGraphicsPipelineStateInfo& state) { VkPipeline pipeline = this->createPipeline(state); - m_pipeMgr->m_numGraphicsPipelines += 1; + m_stats->numGraphicsPipelines += 1; return &(*m_pipelines.emplace(state, pipeline)); } @@ -575,7 +580,7 @@ namespace dxvk { VkPipeline DxvkGraphicsPipeline::createPipeline( const DxvkGraphicsPipelineStateInfo& state) const { - const DxvkDevice* device = m_pipeMgr->m_device; + auto vk = m_device->vkd(); if (Logger::logLevel() <= LogLevel::Debug) { Logger::debug("Compiling graphics pipeline..."); @@ -630,10 +635,10 @@ namespace dxvk { if (gsm) stages.push_back(gsm.stageInfo(&specInfo)); if (fsm) stages.push_back(fsm.stageInfo(&specInfo)); - DxvkGraphicsPipelineVertexInputState viState(device, state); - DxvkGraphicsPipelinePreRasterizationState prState(device, state, m_shaders.gs.ptr()); - DxvkGraphicsPipelineFragmentShaderState fsState(device, state); - DxvkGraphicsPipelineFragmentOutputState foState(device, state, m_shaders.fs.ptr()); + DxvkGraphicsPipelineVertexInputState viState(m_device, state); + DxvkGraphicsPipelinePreRasterizationState prState(m_device, state, m_shaders.gs.ptr()); + DxvkGraphicsPipelineFragmentShaderState fsState(m_device, state); + DxvkGraphicsPipelineFragmentOutputState foState(m_device, state, m_shaders.fs.ptr()); VkPipelineDynamicStateCreateInfo dyInfo = { VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO }; dyInfo.dynamicStateCount = dynamicStateCount; @@ -664,7 +669,7 @@ namespace dxvk { t0 = dxvk::high_resolution_clock::now(); VkPipeline pipeline = VK_NULL_HANDLE; - if (m_vkd->vkCreateGraphicsPipelines(m_vkd->device(), m_pipeMgr->m_cache.handle(), 1, &info, nullptr, &pipeline) != VK_SUCCESS) { + if (vk->vkCreateGraphicsPipelines(vk->device(), m_cache->handle(), 1, &info, nullptr, &pipeline) != VK_SUCCESS) { Logger::err("DxvkGraphicsPipeline: Failed to compile pipeline"); this->logPipelineState(LogLevel::Error, state); return VK_NULL_HANDLE; @@ -681,13 +686,17 @@ namespace dxvk { void DxvkGraphicsPipeline::destroyPipeline(VkPipeline pipeline) const { - m_vkd->vkDestroyPipeline(m_vkd->device(), pipeline, nullptr); + auto vk = m_device->vkd(); + + vk->vkDestroyPipeline(vk->device(), pipeline, nullptr); } DxvkShaderModule DxvkGraphicsPipeline::createShaderModule( const Rc& shader, const DxvkGraphicsPipelineStateInfo& state) const { + auto vk = m_device->vkd(); + if (shader == nullptr) return DxvkShaderModule(); @@ -720,7 +729,7 @@ namespace dxvk { } info.undefinedInputs = (providedInputs & consumedInputs) ^ consumedInputs; - return shader->createShaderModule(m_vkd, m_bindings, info); + return shader->createShaderModule(vk, m_bindings, info); } @@ -782,7 +791,6 @@ namespace dxvk { } // Validate vertex input layout - const DxvkDevice* device = m_pipeMgr->m_device; uint32_t ilLocationMask = 0; uint32_t ilBindingMask = 0; @@ -802,7 +810,7 @@ namespace dxvk { return false; } - VkFormatProperties formatInfo = device->adapter()->formatProperties(attribute.format()); + VkFormatProperties formatInfo = m_device->adapter()->formatProperties(attribute.format()); if (!(formatInfo.bufferFeatures & VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)) { Logger::err(str::format("Invalid pipeline: Format ", attribute.format(), " not supported for vertex buffers")); @@ -814,20 +822,20 @@ namespace dxvk { // Validate rasterization state if (state.rs.conservativeMode() != VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT) { - if (!device->extensions().extConservativeRasterization) { + if (!m_device->extensions().extConservativeRasterization) { Logger::err("Conservative rasterization not supported by device"); return false; } if (state.rs.conservativeMode() == VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT - && !device->properties().extConservativeRasterization.primitiveUnderestimation) { + && !m_device->properties().extConservativeRasterization.primitiveUnderestimation) { Logger::err("Primitive underestimation not supported by device"); return false; } } // Validate depth-stencil state - if (state.ds.enableDepthBoundsTest() && !device->features().core.features.depthBounds) { + if (state.ds.enableDepthBoundsTest() && !m_device->features().core.features.depthBounds) { Logger::err("Depth bounds not supported by device"); return false; } @@ -845,7 +853,7 @@ namespace dxvk { 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); + m_stateCache->addGraphicsPipeline(key, state); } diff --git a/src/dxvk/dxvk_graphics.h b/src/dxvk/dxvk_graphics.h index f2757f2b..50a056f5 100644 --- a/src/dxvk/dxvk_graphics.h +++ b/src/dxvk/dxvk_graphics.h @@ -17,7 +17,10 @@ namespace dxvk { class DxvkDevice; + class DxvkStateCache; class DxvkPipelineManager; + class DxvkPipelineWorkers; + struct DxvkPipelineStats; /** * \brief Vertex input info for graphics pipelines @@ -286,6 +289,7 @@ namespace dxvk { public: DxvkGraphicsPipeline( + DxvkDevice* device, DxvkPipelineManager* pipeMgr, DxvkGraphicsPipelineShaders shaders, DxvkBindingLayoutObjects* layout); @@ -366,9 +370,11 @@ namespace dxvk { const DxvkGraphicsPipelineStateInfo& state); private: - - Rc m_vkd; - DxvkPipelineManager* m_pipeMgr; + + DxvkDevice* m_device; + DxvkPipelineCache* m_cache; + DxvkStateCache* m_stateCache; + DxvkPipelineStats* m_stats; DxvkGraphicsPipelineShaders m_shaders; DxvkBindingLayoutObjects* m_bindings; diff --git a/src/dxvk/dxvk_pipemanager.cpp b/src/dxvk/dxvk_pipemanager.cpp index 195528bd..c6c7ab89 100644 --- a/src/dxvk/dxvk_pipemanager.cpp +++ b/src/dxvk/dxvk_pipemanager.cpp @@ -192,7 +192,7 @@ namespace dxvk { auto iter = m_computePipelines.emplace( std::piecewise_construct, std::tuple(shaders), - std::tuple(this, shaders, layout)); + std::tuple(m_device, this, shaders, layout)); return &iter.first->second; } @@ -228,7 +228,7 @@ namespace dxvk { auto iter = m_graphicsPipelines.emplace( std::piecewise_construct, std::tuple(shaders), - std::tuple(this, shaders, layout)); + std::tuple(m_device, this, shaders, layout)); return &iter.first->second; } @@ -273,8 +273,8 @@ namespace dxvk { DxvkPipelineCount DxvkPipelineManager::getPipelineCount() const { DxvkPipelineCount result; - result.numComputePipelines = m_numComputePipelines.load(); - result.numGraphicsPipelines = m_numGraphicsPipelines.load(); + result.numComputePipelines = m_stats.numComputePipelines.load(); + result.numGraphicsPipelines = m_stats.numGraphicsPipelines.load(); return result; } diff --git a/src/dxvk/dxvk_pipemanager.h b/src/dxvk/dxvk_pipemanager.h index c0cc476e..9d643432 100644 --- a/src/dxvk/dxvk_pipemanager.h +++ b/src/dxvk/dxvk_pipemanager.h @@ -24,6 +24,13 @@ namespace dxvk { uint32_t numComputePipelines; }; + /** + * \brief Pipeline stats + */ + struct DxvkPipelineStats { + std::atomic numGraphicsPipelines = { 0u }; + std::atomic numComputePipelines = { 0u }; + }; /** * \brief Pipeline manager worker threads @@ -216,9 +223,7 @@ namespace dxvk { DxvkPipelineCache m_cache; DxvkPipelineWorkers m_workers; DxvkStateCache m_stateCache; - - std::atomic m_numComputePipelines = { 0 }; - std::atomic m_numGraphicsPipelines = { 0 }; + DxvkPipelineStats m_stats; dxvk::mutex m_mutex;