Merge pull request #12324 from unknownbrackets/vulkan-cache

Vulkan: Clear caches when deleting shaders
This commit is contained in:
Henrik Rydgård 2019-09-15 20:00:06 +02:00 committed by GitHub
commit 6d2be0d716
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 62 additions and 7 deletions

View file

@ -69,8 +69,10 @@ DepalShaderCacheVulkan::~DepalShaderCacheVulkan() {
void DepalShaderCacheVulkan::DeviceLost() {
Clear();
if (vshader_)
if (vshader_) {
vulkan2D_->PurgeVertexShader(vshader_);
vulkan_->Delete().QueueDeleteShaderModule(vshader_);
}
draw_ = nullptr;
vulkan_ = nullptr;
}
@ -107,6 +109,7 @@ DepalShaderVulkan *DepalShaderCacheVulkan::GetDepalettizeShader(uint32_t clutMod
VkPipeline pipeline = vulkan2D_->GetPipeline(rp, vshader_, fshader);
// Can delete the shader module now that the pipeline has been created.
// Maybe don't even need to queue it..
vulkan2D_->PurgeFragmentShader(fshader, true);
vulkan_->Delete().QueueDeleteShaderModule(fshader);
DepalShaderVulkan *depal = new DepalShaderVulkan();

View file

@ -137,24 +137,36 @@ void FramebufferManagerVulkan::DestroyDeviceObjects() {
delete drawPixelsTex_;
drawPixelsTex_ = nullptr;
if (fsBasicTex_ != VK_NULL_HANDLE)
if (fsBasicTex_ != VK_NULL_HANDLE) {
vulkan2D_->PurgeFragmentShader(fsBasicTex_);
vulkan_->Delete().QueueDeleteShaderModule(fsBasicTex_);
if (vsBasicTex_ != VK_NULL_HANDLE)
}
if (vsBasicTex_ != VK_NULL_HANDLE) {
vulkan2D_->PurgeVertexShader(vsBasicTex_);
vulkan_->Delete().QueueDeleteShaderModule(vsBasicTex_);
if (stencilFs_ != VK_NULL_HANDLE)
}
if (stencilFs_ != VK_NULL_HANDLE) {
vulkan2D_->PurgeFragmentShader(stencilFs_);
vulkan_->Delete().QueueDeleteShaderModule(stencilFs_);
if (stencilVs_ != VK_NULL_HANDLE)
}
if (stencilVs_ != VK_NULL_HANDLE) {
vulkan2D_->PurgeVertexShader(stencilVs_);
vulkan_->Delete().QueueDeleteShaderModule(stencilVs_);
}
if (linearSampler_ != VK_NULL_HANDLE)
vulkan_->Delete().QueueDeleteSampler(linearSampler_);
if (nearestSampler_ != VK_NULL_HANDLE)
vulkan_->Delete().QueueDeleteSampler(nearestSampler_);
if (postVs_)
if (postVs_) {
vulkan2D_->PurgeVertexShader(postVs_);
vulkan_->Delete().QueueDeleteShaderModule(postVs_);
if (postFs_)
}
if (postFs_) {
vulkan2D_->PurgeFragmentShader(postFs_);
vulkan_->Delete().QueueDeleteShaderModule(postFs_);
}
pipelinePostShader_ = VK_NULL_HANDLE; // actual pipeline should get destroyed by vulkan2d.
}
@ -586,9 +598,11 @@ void FramebufferManagerVulkan::Resized() {
void FramebufferManagerVulkan::CompilePostShader() {
if (postVs_) {
vulkan2D_->PurgeVertexShader(postVs_);
vulkan_->Delete().QueueDeleteShaderModule(postVs_);
}
if (postFs_) {
vulkan2D_->PurgeFragmentShader(postFs_);
vulkan_->Delete().QueueDeleteShaderModule(postFs_);
}

View file

@ -43,6 +43,10 @@ void Vulkan2D::DestroyDeviceObjects() {
vulkan_->Delete().QueueDeletePipeline(it.second);
}
pipelines_.clear();
for (auto pipeline : keptPipelines_) {
vulkan_->Delete().QueueDeletePipeline(pipeline);
}
keptPipelines_.clear();
VkDevice device = vulkan_->GetDevice();
if (descriptorSetLayout_ != VK_NULL_HANDLE) {
@ -134,6 +138,36 @@ void Vulkan2D::BeginFrame() {
void Vulkan2D::EndFrame() {
}
void Vulkan2D::PurgeVertexShader(VkShaderModule s, bool keepPipeline) {
for (auto it = pipelines_.begin(); it != pipelines_.end(); ) {
if (it->first.vs == s) {
if (keepPipeline) {
keptPipelines_.push_back(it->second);
} else {
vulkan_->Delete().QueueDeletePipeline(it->second);
}
it = pipelines_.erase(it);
} else {
++it;
}
}
}
void Vulkan2D::PurgeFragmentShader(VkShaderModule s, bool keepPipeline) {
for (auto it = pipelines_.begin(); it != pipelines_.end(); ) {
if (it->first.fs == s) {
if (keepPipeline) {
keptPipelines_.push_back(it->second);
} else {
vulkan_->Delete().QueueDeletePipeline(it->second);
}
it = pipelines_.erase(it);
} else {
++it;
}
}
}
VkDescriptorSet Vulkan2D::GetDescriptorSet(VkImageView tex1, VkSampler sampler1, VkImageView tex2, VkSampler sampler2) {
DescriptorSetKey key;
key.imageView[0] = tex1;

View file

@ -72,6 +72,9 @@ public:
void BeginFrame();
void EndFrame();
void PurgeVertexShader(VkShaderModule s, bool keepPipeline = false);
void PurgeFragmentShader(VkShaderModule s, bool keepPipeline = false);
VkDescriptorSet GetDescriptorSet(VkImageView tex1, VkSampler sampler1, VkImageView tex2, VkSampler sampler2);
struct Vertex {
@ -118,6 +121,7 @@ private:
FrameData frameData_[VulkanContext::MAX_INFLIGHT_FRAMES];
std::map<PipelineKey, VkPipeline> pipelines_;
std::vector<VkPipeline> keptPipelines_;
};