Merge pull request #16495 from unknownbrackets/vulkan-shutdown

Cleanup shader module lifetime handling for Vulkan
This commit is contained in:
Henrik Rydgård 2022-12-04 00:16:58 +01:00 committed by GitHub
commit 7e97ce1760
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 38 additions and 11 deletions

View File

@ -101,8 +101,12 @@ bool VKRGraphicsPipeline::Create(VulkanContext *vulkan, VkRenderPass compatibleR
double start = time_now_d();
VkPipeline vkpipeline;
VkResult result = vkCreateGraphicsPipelines(vulkan->GetDevice(), desc->pipelineCache, 1, &pipe, nullptr, &vkpipeline);
double taken_ms = (time_now_d() - start) * 1000.0;
INFO_LOG(G3D, "Pipeline creation time: %0.2f ms", (time_now_d() - start) * 1000.0);
if (taken_ms < 0.1)
DEBUG_LOG(G3D, "Pipeline creation time: %0.2f ms (fast)", taken_ms);
else
INFO_LOG(G3D, "Pipeline creation time: %0.2f ms", taken_ms);
bool success = true;
if (result == VK_INCOMPLETE) {
@ -512,6 +516,7 @@ VKRGraphicsPipeline *VulkanRenderManager::CreateGraphicsPipeline(VKRGraphicsPipe
_dbg_assert_(desc->vertexShader);
_dbg_assert_(desc->fragmentShader);
pipeline->desc = desc;
pipeline->desc->AddRef();
if (curRenderStep_) {
// The common case
pipelinesToCheck_.push_back(pipeline);

View File

@ -22,6 +22,7 @@
#include "Common/GPU/MiscTypes.h"
#include "Common/GPU/Vulkan/VulkanQueueRunner.h"
#include "Common/GPU/Vulkan/VulkanFramebuffer.h"
#include "Common/GPU/thin3d.h"
// Forward declaration
VK_DEFINE_HANDLE(VmaAllocation);
@ -74,7 +75,7 @@ struct BoundingRect {
};
// All the data needed to create a graphics pipeline.
struct VKRGraphicsPipelineDesc {
struct VKRGraphicsPipelineDesc : Draw::RefCountedObject {
VkPipelineCache pipelineCache = VK_NULL_HANDLE;
VkPipelineColorBlendStateCreateInfo cbs{ VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO };
VkPipelineColorBlendAttachmentState blend0{};
@ -120,6 +121,8 @@ struct VKRGraphicsPipeline {
for (size_t i = 0; i < (size_t)RenderPassType::TYPE_COUNT; i++) {
delete pipeline[i];
}
if (desc)
desc->Release();
}
bool Create(VulkanContext *vulkan, VkRenderPass compatibleRenderPass, RenderPassType rpType, VkSampleCountFlagBits sampleCount);
@ -133,7 +136,7 @@ struct VKRGraphicsPipeline {
void LogCreationFailure() const;
VKRGraphicsPipelineDesc *desc = nullptr; // not owned!
VKRGraphicsPipelineDesc *desc = nullptr;
Promise<VkPipeline> *pipeline[(size_t)RenderPassType::TYPE_COUNT]{};
VkSampleCountFlagBits SampleCount() const { return sampleCount_; }

View File

@ -203,7 +203,10 @@ public:
DEBUG_LOG(G3D, "Queueing %s (shmodule %p) for release", tag_.c_str(), module_);
VkShaderModule shaderModule = module_->BlockUntilReady();
vulkan_->Delete().QueueDeleteShaderModule(shaderModule);
delete module_;
vulkan_->Delete().QueueCallback([](void *m) {
auto module = (Promise<VkShaderModule> *)m;
delete module;
}, module_);
}
}
Promise<VkShaderModule> *Get() const { return module_; }
@ -264,6 +267,7 @@ public:
VKPipeline(VulkanContext *vulkan, size_t size, PipelineFlags _flags, const char *tag) : vulkan_(vulkan), flags(_flags), tag_(tag) {
uboSize_ = (int)size;
ubo_ = new uint8_t[uboSize_];
vkrDesc = new VKRGraphicsPipelineDesc();
}
~VKPipeline() {
DEBUG_LOG(G3D, "Queueing %s (pipeline) for release", tag_.c_str());
@ -274,6 +278,7 @@ public:
dep->Release();
}
delete[] ubo_;
vkrDesc->Release();
}
void SetDynamicUniformData(const void *data, size_t size) {
@ -291,7 +296,7 @@ public:
}
VKRGraphicsPipeline *pipeline = nullptr;
VKRGraphicsPipelineDesc vkrDesc;
VKRGraphicsPipelineDesc *vkrDesc = nullptr;
PipelineFlags flags;
std::vector<VKShaderModule *> deps;
@ -1163,7 +1168,7 @@ Pipeline *VKContext::CreateGraphicsPipeline(const PipelineDesc &desc, const char
VKPipeline *pipeline = new VKPipeline(vulkan_, desc.uniformDesc ? desc.uniformDesc->uniformBufferSize : 16 * sizeof(float), pipelineFlags, tag);
VKRGraphicsPipelineDesc &gDesc = pipeline->vkrDesc;
VKRGraphicsPipelineDesc &gDesc = *pipeline->vkrDesc;
std::vector<VkPipelineShaderStageCreateInfo> stages;
stages.resize(desc.shaders.size());

View File

@ -181,7 +181,8 @@ static VulkanPipeline *CreateVulkanPipeline(VulkanRenderManager *renderManager,
VkPipelineLayout layout, PipelineFlags pipelineFlags, VkSampleCountFlagBits sampleCount, const VulkanPipelineRasterStateKey &key,
const DecVtxFormat *decFmt, VulkanVertexShader *vs, VulkanFragmentShader *fs, VulkanGeometryShader *gs, bool useHwTransform, u32 variantBitmask) {
VulkanPipeline *vulkanPipeline = new VulkanPipeline();
VKRGraphicsPipelineDesc *desc = &vulkanPipeline->desc;
vulkanPipeline->desc = new VKRGraphicsPipelineDesc();
VKRGraphicsPipelineDesc *desc = vulkanPipeline->desc;
desc->pipelineCache = pipelineCache;
PROFILE_THIS_SCOPE("pipelinebuild");

View File

@ -54,8 +54,12 @@ struct VulkanPipelineKey {
// Simply wraps a Vulkan pipeline, providing some metadata.
struct VulkanPipeline {
~VulkanPipeline() {
desc->Release();
}
VKRGraphicsPipeline *pipeline;
VKRGraphicsPipelineDesc desc;
VKRGraphicsPipelineDesc *desc;
PipelineFlags pipelineFlags; // PipelineFlags enum above.
bool UsesBlendConstant() const { return (pipelineFlags & PipelineFlags::USES_BLEND_CONSTANT) != 0; }

View File

@ -120,7 +120,10 @@ VulkanFragmentShader::~VulkanFragmentShader() {
if (module_) {
VkShaderModule shaderModule = module_->BlockUntilReady();
vulkan_->Delete().QueueDeleteShaderModule(shaderModule);
delete module_;
vulkan_->Delete().QueueCallback([](void *m) {
auto module = (Promise<VkShaderModule> *)m;
delete module;
}, module_);
}
}
@ -150,7 +153,10 @@ VulkanVertexShader::~VulkanVertexShader() {
if (module_) {
VkShaderModule shaderModule = module_->BlockUntilReady();
vulkan_->Delete().QueueDeleteShaderModule(shaderModule);
delete module_;
vulkan_->Delete().QueueCallback([](void *m) {
auto module = (Promise<VkShaderModule> *)m;
delete module;
}, module_);
}
}
@ -180,7 +186,10 @@ VulkanGeometryShader::~VulkanGeometryShader() {
if (module_) {
VkShaderModule shaderModule = module_->BlockUntilReady();
vulkan_->Delete().QueueDeleteShaderModule(shaderModule);
delete module_;
vulkan_->Delete().QueueCallback([](void *m) {
auto module = (Promise<VkShaderModule> *)m;
delete module;
}, module_);
}
}