From 363ede5e9916d4ea28a9e3150c53f59cb4805e17 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 9 Oct 2016 10:53:01 -0700 Subject: [PATCH] Vulkan: Setup draw engine for device restore. --- GPU/Vulkan/DrawEngineVulkan.cpp | 72 ++++++++++++++++++++++++++------- GPU/Vulkan/DrawEngineVulkan.h | 9 ++++- 2 files changed, 66 insertions(+), 15 deletions(-) diff --git a/GPU/Vulkan/DrawEngineVulkan.cpp b/GPU/Vulkan/DrawEngineVulkan.cpp index d2ca8b65ee..06379c467b 100644 --- a/GPU/Vulkan/DrawEngineVulkan.cpp +++ b/GPU/Vulkan/DrawEngineVulkan.cpp @@ -99,6 +99,10 @@ DrawEngineVulkan::DrawEngineVulkan(VulkanContext *vulkan) uvScale = new UVScale[MAX_DEFERRED_DRAW_CALLS]; } + InitDeviceObjects(); +} + +void DrawEngineVulkan::InitDeviceObjects() { // All resources we need for PSP drawing. Usually only bindings 0 and 2-4 are populated. VkDescriptorSetLayoutBinding bindings[5]; bindings[0].descriptorCount = 1; @@ -197,24 +201,65 @@ DrawEngineVulkan::~DrawEngineVulkan() { FreeMemoryPages(transformed, TRANSFORMED_VERTEX_BUFFER_SIZE); FreeMemoryPages(transformedExpanded, 3 * TRANSFORMED_VERTEX_BUFFER_SIZE); - for (int i = 0; i < 2; i++) { - vulkan_->Delete().QueueDeleteDescriptorPool(frame_[i].descPool); - frame_[i].pushUBO->Destroy(vulkan_); - frame_[i].pushVertex->Destroy(vulkan_); - frame_[i].pushIndex->Destroy(vulkan_); - delete frame_[i].pushUBO; - delete frame_[i].pushVertex; - delete frame_[i].pushIndex; + DestroyDeviceObjects(); + delete[] uvScale; +} + +void DrawEngineVulkan::FrameData::Destroy(VulkanContext *vulkan) { + if (descPool != VK_NULL_HANDLE) { + vulkan->Delete().QueueDeleteDescriptorPool(descPool); + descPool = VK_NULL_HANDLE; } - vulkan_->Delete().QueueDeleteSampler(depalSampler_); - vulkan_->Delete().QueueDeleteSampler(nullSampler_); + + if (pushUBO) { + pushUBO->Destroy(vulkan); + delete pushUBO; + pushUBO = nullptr; + } + if (pushVertex) { + pushVertex->Destroy(vulkan); + delete pushVertex; + pushVertex = nullptr; + } + if (pushIndex) { + pushIndex->Destroy(vulkan); + delete pushIndex; + pushIndex = nullptr; + } +} + +void DrawEngineVulkan::DestroyDeviceObjects() { + for (int i = 0; i < 2; i++) { + frame_[i].Destroy(vulkan_); + } + if (depalSampler_ != VK_NULL_HANDLE) + vulkan_->Delete().QueueDeleteSampler(depalSampler_); + depalSampler_ = VK_NULL_HANDLE; + if (nullSampler_ != VK_NULL_HANDLE) + vulkan_->Delete().QueueDeleteSampler(nullSampler_); + nullSampler_ = VK_NULL_HANDLE; + if (pipelineLayout_ != VK_NULL_HANDLE) + vkDestroyPipelineLayout(vulkan_->GetDevice(), pipelineLayout_, nullptr); + pipelineLayout_ = VK_NULL_HANDLE; + if (descriptorSetLayout_ != VK_NULL_HANDLE) + vkDestroyDescriptorSetLayout(vulkan_->GetDevice(), descriptorSetLayout_, nullptr); + descriptorSetLayout_ = VK_NULL_HANDLE; if (nullTexture_) { nullTexture_->Destroy(); delete nullTexture_; + nullTexture_ = nullptr; } - delete[] uvScale; - vkDestroyPipelineLayout(vulkan_->GetDevice(), pipelineLayout_, nullptr); - vkDestroyDescriptorSetLayout(vulkan_->GetDevice(), descriptorSetLayout_, nullptr); +} + +void DrawEngineVulkan::DeviceLost() { + DestroyDeviceObjects(); + DirtyAllUBOs(); +} + +void DrawEngineVulkan::DeviceRestore(VulkanContext *vulkan) { + vulkan_ = vulkan; + + InitDeviceObjects(); } void DrawEngineVulkan::BeginFrame() { @@ -867,7 +912,6 @@ void DrawEngineVulkan::Resized() { decJitCache_->Clear(); lastVTypeID_ = -1; dec_ = NULL; - // TODO: We must also wipe pipelines. for (auto iter = decoderMap_.begin(); iter != decoderMap_.end(); iter++) { delete iter->second; } diff --git a/GPU/Vulkan/DrawEngineVulkan.h b/GPU/Vulkan/DrawEngineVulkan.h index 280555aed8..7d4a364ceb 100644 --- a/GPU/Vulkan/DrawEngineVulkan.h +++ b/GPU/Vulkan/DrawEngineVulkan.h @@ -87,7 +87,9 @@ public: framebufferManager_ = fbManager; } - void Resized(); // TODO: Call + void Resized(); + void DeviceLost(); + void DeviceRestore(VulkanContext *vulkan); void SetupVertexDecoder(u32 vertType); void SetupVertexDecoderInternal(u32 vertType); @@ -160,6 +162,9 @@ public: private: struct FrameData; + void InitDeviceObjects(); + void DestroyDeviceObjects(); + void DecodeVerts(VulkanPushBuffer *push, uint32_t *bindOffset, VkBuffer *vkbuf); void DecodeVertsStep(u8 *dest, int &i, int &decodedVerts); @@ -200,6 +205,8 @@ private: VulkanPushBuffer *pushIndex; // We do rolling allocation and reset instead of caching across frames. That we might do later. std::map descSets; + + void Destroy(VulkanContext *vulkan); }; int curFrame_;