1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2024-12-13 07:08:50 +01:00

[dxvk] Clean up graphics and compute pipeline constructors

This commit is contained in:
Philip Rebohle 2022-07-05 18:46:11 +02:00
parent f2f1f86500
commit 06c084616f
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
6 changed files with 73 additions and 45 deletions

View File

@ -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<VkDescriptorSetLayoutBinding> 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);
}
}

View File

@ -15,7 +15,10 @@
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<vk::DeviceFn> m_vkd;
DxvkPipelineManager* m_pipeMgr;
DxvkDevice* m_device;
DxvkPipelineCache* m_cache;
DxvkStateCache* m_stateCache;
DxvkPipelineStats* m_stats;
DxvkComputePipelineShaders m_shaders;
DxvkBindingLayoutObjects* m_bindings;

View File

@ -456,11 +456,16 @@ 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_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<DxvkShader>& 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);
}

View File

@ -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);
@ -367,8 +371,10 @@ namespace dxvk {
private:
Rc<vk::DeviceFn> m_vkd;
DxvkPipelineManager* m_pipeMgr;
DxvkDevice* m_device;
DxvkPipelineCache* m_cache;
DxvkStateCache* m_stateCache;
DxvkPipelineStats* m_stats;
DxvkGraphicsPipelineShaders m_shaders;
DxvkBindingLayoutObjects* m_bindings;

View File

@ -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;
}

View File

@ -24,6 +24,13 @@ namespace dxvk {
uint32_t numComputePipelines;
};
/**
* \brief Pipeline stats
*/
struct DxvkPipelineStats {
std::atomic<uint32_t> numGraphicsPipelines = { 0u };
std::atomic<uint32_t> numComputePipelines = { 0u };
};
/**
* \brief Pipeline manager worker threads
@ -216,9 +223,7 @@ namespace dxvk {
DxvkPipelineCache m_cache;
DxvkPipelineWorkers m_workers;
DxvkStateCache m_stateCache;
std::atomic<uint32_t> m_numComputePipelines = { 0 };
std::atomic<uint32_t> m_numGraphicsPipelines = { 0 };
DxvkPipelineStats m_stats;
dxvk::mutex m_mutex;