mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-01-21 02:52:10 +01:00
[dxvk] Destroy shader pipeline libraries after initial compile on 32-bit
This alone saves ~700 MiB of address space in the Resident Evil 6 main menu on Nvidia.
This commit is contained in:
parent
915b03ba7b
commit
4bc2d713fb
@ -915,10 +915,7 @@ namespace dxvk {
|
|||||||
const DxvkShaderPipelineLibraryCompileArgs& args) {
|
const DxvkShaderPipelineLibraryCompileArgs& args) {
|
||||||
std::lock_guard lock(m_mutex);
|
std::lock_guard lock(m_mutex);
|
||||||
|
|
||||||
VkShaderStageFlagBits stage = VK_SHADER_STAGE_FRAGMENT_BIT;
|
VkShaderStageFlagBits stage = getShaderStage();
|
||||||
|
|
||||||
if (m_shader)
|
|
||||||
stage = m_shader->info().stage;
|
|
||||||
|
|
||||||
VkPipeline& pipeline = (stage == VK_SHADER_STAGE_VERTEX_BIT && !args.depthClipEnable)
|
VkPipeline& pipeline = (stage == VK_SHADER_STAGE_VERTEX_BIT && !args.depthClipEnable)
|
||||||
? m_pipelineNoDepthClip
|
? m_pipelineNoDepthClip
|
||||||
@ -927,28 +924,54 @@ namespace dxvk {
|
|||||||
if (pipeline)
|
if (pipeline)
|
||||||
return pipeline;
|
return pipeline;
|
||||||
|
|
||||||
bool usesDefaultArgs = (args == DxvkShaderPipelineLibraryCompileArgs());
|
pipeline = compileShaderPipelineLocked(args);
|
||||||
|
return pipeline;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DxvkShaderPipelineLibrary::compilePipeline() {
|
||||||
|
std::lock_guard lock(m_mutex);
|
||||||
|
|
||||||
|
// Skip if a pipeline has already been compiled
|
||||||
|
if (m_pipeline)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Compile the pipeline with default args
|
||||||
|
VkPipeline pipeline = compileShaderPipelineLocked(
|
||||||
|
DxvkShaderPipelineLibraryCompileArgs());
|
||||||
|
|
||||||
|
// On 32-bit, destroy the pipeline immediately in order to
|
||||||
|
// save memory. We should hit the driver's disk cache once
|
||||||
|
// we need to recreate the pipeline.
|
||||||
|
if (m_device->mustTrackPipelineLifetime()) {
|
||||||
|
auto vk = m_device->vkd();
|
||||||
|
vk->vkDestroyPipeline(vk->device(), pipeline, nullptr);
|
||||||
|
|
||||||
|
pipeline = VK_NULL_HANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write back pipeline handle for future use
|
||||||
|
m_pipeline = pipeline;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
VkPipeline DxvkShaderPipelineLibrary::compileShaderPipelineLocked(
|
||||||
|
const DxvkShaderPipelineLibraryCompileArgs& args) {
|
||||||
|
VkShaderStageFlagBits stage = getShaderStage();
|
||||||
|
VkPipeline pipeline = VK_NULL_HANDLE;
|
||||||
|
|
||||||
|
// Compile pipeline of the appropriate type
|
||||||
switch (stage) {
|
switch (stage) {
|
||||||
case VK_SHADER_STAGE_VERTEX_BIT:
|
case VK_SHADER_STAGE_VERTEX_BIT:
|
||||||
pipeline = compileVertexShaderPipeline(args);
|
pipeline = compileVertexShaderPipeline(args);
|
||||||
|
|
||||||
if (usesDefaultArgs)
|
|
||||||
m_stats->numGraphicsLibraries += 1;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VK_SHADER_STAGE_FRAGMENT_BIT:
|
case VK_SHADER_STAGE_FRAGMENT_BIT:
|
||||||
pipeline = compileFragmentShaderPipeline();
|
pipeline = compileFragmentShaderPipeline();
|
||||||
|
|
||||||
if (usesDefaultArgs)
|
|
||||||
m_stats->numGraphicsLibraries += 1;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VK_SHADER_STAGE_COMPUTE_BIT:
|
case VK_SHADER_STAGE_COMPUTE_BIT:
|
||||||
pipeline = compileComputeShaderPipeline();
|
pipeline = compileComputeShaderPipeline();
|
||||||
|
|
||||||
if (usesDefaultArgs)
|
|
||||||
m_stats->numComputePipelines += 1;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -956,18 +979,21 @@ namespace dxvk {
|
|||||||
return VK_NULL_HANDLE;
|
return VK_NULL_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Increment stat counter the first time this
|
||||||
|
// shader pipeline gets compiled successfully
|
||||||
|
if (!m_compiledOnce && pipeline) {
|
||||||
|
if (stage == VK_SHADER_STAGE_COMPUTE_BIT)
|
||||||
|
m_stats->numComputePipelines += 1;
|
||||||
|
else
|
||||||
|
m_stats->numGraphicsLibraries += 1;
|
||||||
|
|
||||||
|
m_compiledOnce = true;
|
||||||
|
}
|
||||||
|
|
||||||
return pipeline;
|
return pipeline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DxvkShaderPipelineLibrary::compilePipeline() {
|
|
||||||
// Just compile the pipeline with default args. Implicitly skips
|
|
||||||
// this step if another thread has compiled the pipeline in the
|
|
||||||
// meantime, in order to avoid duplicate work.
|
|
||||||
getPipelineHandle(DxvkShaderPipelineLibraryCompileArgs());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
VkPipeline DxvkShaderPipelineLibrary::compileVertexShaderPipeline(
|
VkPipeline DxvkShaderPipelineLibrary::compileVertexShaderPipeline(
|
||||||
const DxvkShaderPipelineLibraryCompileArgs& args) {
|
const DxvkShaderPipelineLibraryCompileArgs& args) {
|
||||||
auto vk = m_device->vkd();
|
auto vk = m_device->vkd();
|
||||||
@ -1175,4 +1201,14 @@ namespace dxvk {
|
|||||||
vk->device(), &info, &m_identifier);
|
vk->device(), &info, &m_identifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
VkShaderStageFlagBits DxvkShaderPipelineLibrary::getShaderStage() const {
|
||||||
|
VkShaderStageFlagBits stage = VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||||
|
|
||||||
|
if (m_shader != nullptr)
|
||||||
|
stage = m_shader->info().stage;
|
||||||
|
|
||||||
|
return stage;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -425,10 +425,14 @@ namespace dxvk {
|
|||||||
dxvk::mutex m_mutex;
|
dxvk::mutex m_mutex;
|
||||||
VkPipeline m_pipeline = VK_NULL_HANDLE;
|
VkPipeline m_pipeline = VK_NULL_HANDLE;
|
||||||
VkPipeline m_pipelineNoDepthClip = VK_NULL_HANDLE;
|
VkPipeline m_pipelineNoDepthClip = VK_NULL_HANDLE;
|
||||||
|
bool m_compiledOnce = false;
|
||||||
|
|
||||||
dxvk::mutex m_identifierMutex;
|
dxvk::mutex m_identifierMutex;
|
||||||
VkShaderModuleIdentifierEXT m_identifier = { VK_STRUCTURE_TYPE_SHADER_MODULE_IDENTIFIER_EXT };
|
VkShaderModuleIdentifierEXT m_identifier = { VK_STRUCTURE_TYPE_SHADER_MODULE_IDENTIFIER_EXT };
|
||||||
|
|
||||||
|
VkPipeline compileShaderPipelineLocked(
|
||||||
|
const DxvkShaderPipelineLibraryCompileArgs& args);
|
||||||
|
|
||||||
VkPipeline compileVertexShaderPipeline(
|
VkPipeline compileVertexShaderPipeline(
|
||||||
const DxvkShaderPipelineLibraryCompileArgs& args);
|
const DxvkShaderPipelineLibraryCompileArgs& args);
|
||||||
|
|
||||||
@ -444,6 +448,8 @@ namespace dxvk {
|
|||||||
void generateModuleIdentifierLocked(
|
void generateModuleIdentifierLocked(
|
||||||
const SpirvCodeBuffer& spirvCode);
|
const SpirvCodeBuffer& spirvCode);
|
||||||
|
|
||||||
|
VkShaderStageFlagBits getShaderStage() const;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user