Merge pull request #15222 from hrydgard/fix-shutdown-assert

Fix shutdown assert / potential crash
This commit is contained in:
Unknown W. Brackets 2021-12-10 12:44:39 -08:00 committed by GitHub
commit 204b2a48e4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 17 additions and 13 deletions

View File

@ -26,13 +26,14 @@
using namespace PPSSPP_VK; using namespace PPSSPP_VK;
VulkanPushBuffer::VulkanPushBuffer(VulkanContext *vulkan, size_t size, VkBufferUsageFlags usage, PushBufferType type) VulkanPushBuffer::VulkanPushBuffer(VulkanContext *vulkan, const char *name, size_t size, VkBufferUsageFlags usage, PushBufferType type)
: vulkan_(vulkan), size_(size), usage_(usage), type_(type) { : vulkan_(vulkan), name_(name), size_(size), usage_(usage), type_(type) {
bool res = AddBuffer(); bool res = AddBuffer();
_assert_(res); _assert_(res);
} }
VulkanPushBuffer::~VulkanPushBuffer() { VulkanPushBuffer::~VulkanPushBuffer() {
_dbg_assert_(!writePtr_);
_assert_(buffers_.empty()); _assert_(buffers_.empty());
} }
@ -64,6 +65,7 @@ bool VulkanPushBuffer::AddBuffer() {
} }
void VulkanPushBuffer::Destroy(VulkanContext *vulkan) { void VulkanPushBuffer::Destroy(VulkanContext *vulkan) {
_dbg_assert_(!writePtr_);
for (BufInfo &info : buffers_) { for (BufInfo &info : buffers_) {
vulkan->Delete().QueueDeleteBufferAllocation(info.buffer, info.allocation); vulkan->Delete().QueueDeleteBufferAllocation(info.buffer, info.allocation);
} }

View File

@ -37,7 +37,7 @@ public:
// NOTE: If you create a push buffer with PushBufferType::GPU_ONLY, // NOTE: If you create a push buffer with PushBufferType::GPU_ONLY,
// then you can't use any of the push functions as pointers will not be reachable from the CPU. // then you can't use any of the push functions as pointers will not be reachable from the CPU.
// You must in this case use Allocate() only, and pass the returned offset and the VkBuffer to Vulkan APIs. // You must in this case use Allocate() only, and pass the returned offset and the VkBuffer to Vulkan APIs.
VulkanPushBuffer(VulkanContext *vulkan, size_t size, VkBufferUsageFlags usage, PushBufferType type); VulkanPushBuffer(VulkanContext *vulkan, const char *name, size_t size, VkBufferUsageFlags usage, PushBufferType type);
~VulkanPushBuffer(); ~VulkanPushBuffer();
void Destroy(VulkanContext *vulkan); void Destroy(VulkanContext *vulkan);
@ -135,6 +135,7 @@ private:
size_t size_ = 0; size_t size_ = 0;
uint8_t *writePtr_ = nullptr; uint8_t *writePtr_ = nullptr;
VkBufferUsageFlags usage_; VkBufferUsageFlags usage_;
const char *name_;
}; };
// Only appropriate for use in a per-frame pool. // Only appropriate for use in a per-frame pool.

View File

@ -850,7 +850,7 @@ VKContext::VKContext(VulkanContext *vulkan, bool splitSubmit)
for (int i = 0; i < VulkanContext::MAX_INFLIGHT_FRAMES; i++) { for (int i = 0; i < VulkanContext::MAX_INFLIGHT_FRAMES; i++) {
VkBufferUsageFlags usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT; VkBufferUsageFlags usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
frame_[i].pushBuffer = new VulkanPushBuffer(vulkan_, 1024 * 1024, usage, PushBufferType::CPU_TO_GPU); frame_[i].pushBuffer = new VulkanPushBuffer(vulkan_, "pushBuffer", 1024 * 1024, usage, PushBufferType::CPU_TO_GPU);
frame_[i].descriptorPool.Create(vulkan_, dp, dpTypes); frame_[i].descriptorPool.Create(vulkan_, dp, dpTypes);
} }

View File

@ -747,7 +747,6 @@ void SoftwareTransform::ExpandRectangles(int vertexCount, int &maxIndex, u16 *&i
if (tlz <= minZValue && brz <= minZValue) if (tlz <= minZValue && brz <= minZValue)
continue; continue;
} }
RotateUV(trans, params_.flippedY); RotateUV(trans, params_.flippedY);
} }

View File

@ -165,9 +165,9 @@ void DrawEngineVulkan::InitDeviceObjects() {
// Note that pushUBO is also used for tessellation data (search for SetPushBuffer), and to upload // Note that pushUBO is also used for tessellation data (search for SetPushBuffer), and to upload
// the null texture. This should be cleaned up... // the null texture. This should be cleaned up...
frame_[i].pushUBO = new VulkanPushBuffer(vulkan, 8 * 1024 * 1024, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT, PushBufferType::CPU_TO_GPU); frame_[i].pushUBO = new VulkanPushBuffer(vulkan, "pushUBO", 8 * 1024 * 1024, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT, PushBufferType::CPU_TO_GPU);
frame_[i].pushVertex = new VulkanPushBuffer(vulkan, 2 * 1024 * 1024, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, PushBufferType::CPU_TO_GPU); frame_[i].pushVertex = new VulkanPushBuffer(vulkan, "pushVertex", 2 * 1024 * 1024, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, PushBufferType::CPU_TO_GPU);
frame_[i].pushIndex = new VulkanPushBuffer(vulkan, 1 * 1024 * 1024, VK_BUFFER_USAGE_INDEX_BUFFER_BIT, PushBufferType::CPU_TO_GPU); frame_[i].pushIndex = new VulkanPushBuffer(vulkan, "pushIndex", 1 * 1024 * 1024, VK_BUFFER_USAGE_INDEX_BUFFER_BIT, PushBufferType::CPU_TO_GPU);
} }
VkPipelineLayoutCreateInfo pl{ VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO }; VkPipelineLayoutCreateInfo pl{ VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO };
@ -192,7 +192,7 @@ void DrawEngineVulkan::InitDeviceObjects() {
res = vkCreateSampler(device, &samp, nullptr, &nullSampler_); res = vkCreateSampler(device, &samp, nullptr, &nullSampler_);
_dbg_assert_(VK_SUCCESS == res); _dbg_assert_(VK_SUCCESS == res);
vertexCache_ = new VulkanPushBuffer(vulkan, VERTEX_CACHE_SIZE, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, PushBufferType::CPU_TO_GPU); vertexCache_ = new VulkanPushBuffer(vulkan, "pushVertexCache", VERTEX_CACHE_SIZE, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, PushBufferType::CPU_TO_GPU);
tessDataTransferVulkan = new TessellationDataTransferVulkan(vulkan); tessDataTransferVulkan = new TessellationDataTransferVulkan(vulkan);
tessDataTransfer = tessDataTransferVulkan; tessDataTransfer = tessDataTransferVulkan;
@ -295,7 +295,7 @@ void DrawEngineVulkan::BeginFrame() {
if (vertexCache_->GetTotalSize() > VERTEX_CACHE_SIZE) { if (vertexCache_->GetTotalSize() > VERTEX_CACHE_SIZE) {
vertexCache_->Destroy(vulkan); vertexCache_->Destroy(vulkan);
delete vertexCache_; // orphans the buffers, they'll get deleted once no longer used by an in-flight frame. delete vertexCache_; // orphans the buffers, they'll get deleted once no longer used by an in-flight frame.
vertexCache_ = new VulkanPushBuffer(vulkan, VERTEX_CACHE_SIZE, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, PushBufferType::CPU_TO_GPU); vertexCache_ = new VulkanPushBuffer(vulkan, "vertexCacheR", VERTEX_CACHE_SIZE, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, PushBufferType::CPU_TO_GPU);
vai_.Iterate([&](uint32_t hash, VertexArrayInfoVulkan *vai) { vai_.Iterate([&](uint32_t hash, VertexArrayInfoVulkan *vai) {
delete vai; delete vai;
}); });

View File

@ -500,8 +500,8 @@ void GPU_Vulkan::InitDeviceObjects() {
// Initialize framedata // Initialize framedata
for (int i = 0; i < VulkanContext::MAX_INFLIGHT_FRAMES; i++) { for (int i = 0; i < VulkanContext::MAX_INFLIGHT_FRAMES; i++) {
_assert_(!frameData_[i].push_); _assert_(!frameData_[i].push_);
VkBufferUsageFlags usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; VkBufferUsageFlags usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
frameData_[i].push_ = new VulkanPushBuffer(vulkan, 256 * 1024, usage, PushBufferType::CPU_TO_GPU); frameData_[i].push_ = new VulkanPushBuffer(vulkan, "gpuPush", 256 * 1024, usage, PushBufferType::CPU_TO_GPU);
} }
VulkanRenderManager *rm = (VulkanRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); VulkanRenderManager *rm = (VulkanRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER);

View File

@ -1413,9 +1413,11 @@ void EmuScreen::render() {
break; break;
} }
PSP_EndHostFrame();
// This must happen after PSP_EndHostFrame so that things like push buffers are end-frame'd before we start destroying stuff.
checkPowerDown(); checkPowerDown();
PSP_EndHostFrame();
if (invalid_) if (invalid_)
return; return;