[dxvk] Always pre-compile compute shaders

We didn't initially do this because the pipeline library code
unconditionally used pNext chains to pass shader code. However,
shader module creation has since been refactored, and now there
is no good reason not to compile compute shaders immediately.

Also fix the stat counter while we're at it.
This commit is contained in:
Philip Rebohle 2022-07-16 23:41:08 +02:00
parent 8747c0f105
commit a1c3df7750
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
4 changed files with 39 additions and 14 deletions

View File

@ -35,18 +35,20 @@ namespace dxvk {
VkPipeline DxvkComputePipeline::getPipelineHandle(
const DxvkComputePipelineStateInfo& state) {
if (m_library) {
// For compute pipelines that can be precompiled, we can use that
// pipeline variant unconditionally since there is no state for us
// to worry about other than specialization constants
if (unlikely(!m_libraryHandle)) {
m_libraryHandle = m_library->getPipelineHandle(
DxvkShaderPipelineLibraryCompileArgs());
m_stats->numComputePipelines += 1;
}
if (m_libraryHandle) {
// Compute pipelines without spec constants are always
// pre-compiled, so we'll almost always hit this path
return m_libraryHandle;
} else if (m_library) {
// Retrieve actual pipeline handle on first use. This
// may wait for an ongoing compile job to finish, or
// compile the pipeline immediately on the calling thread.
m_libraryHandle = m_library->getPipelineHandle(
DxvkShaderPipelineLibraryCompileArgs());
return m_libraryHandle;
} else {
// Slow path for compute shaders that do use spec constants
DxvkComputePipelineInstance* instance = this->findInstance(state);
if (unlikely(!instance)) {

View File

@ -280,7 +280,7 @@ namespace dxvk {
void DxvkPipelineManager::registerShader(
const Rc<DxvkShader>& shader) {
if (m_device->canUseGraphicsPipelineLibrary() && shader->canUsePipelineLibrary()) {
if (canPrecompileShader(shader)) {
auto library = createPipelineLibrary(shader);
m_workers.compilePipelineLibrary(library);
}
@ -380,5 +380,17 @@ namespace dxvk {
return &pair->second;
}
bool DxvkPipelineManager::canPrecompileShader(
const Rc<DxvkShader>& shader) const {
if (!shader->canUsePipelineLibrary())
return false;
if (shader->info().stage == VK_SHADER_STAGE_COMPUTE_BIT)
return true;
return m_device->canUseGraphicsPipelineLibrary();
}
}

View File

@ -276,6 +276,9 @@ namespace dxvk {
DxvkShaderPipelineLibrary* findPipelineLibrary(
const Rc<DxvkShader>& shader);
bool canPrecompileShader(
const Rc<DxvkShader>& shader) const;
};
}

View File

@ -502,17 +502,28 @@ namespace dxvk {
if (pipeline)
return pipeline;
bool usesDefaultArgs = (args == DxvkShaderPipelineLibraryCompileArgs());
switch (stage) {
case VK_SHADER_STAGE_VERTEX_BIT:
pipeline = compileVertexShaderPipeline(args);
if (usesDefaultArgs)
m_stats->numGraphicsLibraries += 1;
break;
case VK_SHADER_STAGE_FRAGMENT_BIT:
pipeline = compileFragmentShaderPipeline();
if (usesDefaultArgs)
m_stats->numGraphicsLibraries += 1;
break;
case VK_SHADER_STAGE_COMPUTE_BIT:
pipeline = compileComputeShaderPipeline();
if (usesDefaultArgs)
m_stats->numComputePipelines += 1;
break;
default:
@ -520,9 +531,6 @@ namespace dxvk {
return VK_NULL_HANDLE;
}
if (args == DxvkShaderPipelineLibraryCompileArgs())
m_stats->numGraphicsLibraries += 1;
return pipeline;
}