[GPU] Make TraceDump error handling more robust

Exit with code -1 if GraphicsSystem::Capture failed
This commit is contained in:
DrChat 2017-12-15 22:31:10 -06:00
parent 8cabc114e9
commit 66d19a462b
3 changed files with 35 additions and 16 deletions

View File

@ -98,8 +98,7 @@ int TraceDump::Main(const std::vector<std::wstring>& args) {
// Ensure output path exists. // Ensure output path exists.
xe::filesystem::CreateParentFolder(base_output_path_); xe::filesystem::CreateParentFolder(base_output_path_);
Run(); return Run();
return 0;
} }
bool TraceDump::Setup() { bool TraceDump::Setup() {
@ -172,7 +171,7 @@ bool TraceDump::Load(std::wstring trace_file_path) {
return true; return true;
} }
void TraceDump::Run() { int TraceDump::Run() {
loop_->Post([&]() { loop_->Post([&]() {
player_->SeekFrame(0); player_->SeekFrame(0);
player_->SeekCommand( player_->SeekCommand(
@ -188,13 +187,14 @@ void TraceDump::Run() {
}); });
xe::threading::Fence capture_fence; xe::threading::Fence capture_fence;
bool did_capture = false; int result = 0;
loop_->PostDelayed( loop_->PostDelayed(
[&]() { [&]() {
// Capture. // Capture.
auto raw_image = graphics_system_->Capture(); auto raw_image = graphics_system_->Capture();
if (!raw_image) { if (!raw_image) {
// Failed to capture anything. // Failed to capture anything.
result = -1;
capture_fence.Signal(); capture_fence.Signal();
return; return;
} }
@ -206,7 +206,7 @@ void TraceDump::Run() {
raw_image->data.data(), raw_image->data.data(),
static_cast<int>(raw_image->stride)); static_cast<int>(raw_image->stride));
did_capture = true; result = 0;
capture_fence.Signal(); capture_fence.Signal();
}, },
50); 50);
@ -223,7 +223,7 @@ void TraceDump::Run() {
player_.reset(); player_.reset();
emulator_.reset(); emulator_.reset();
// TODO(benvanik): die if failed to capture? return result;
} }
} // namespace gpu } // namespace gpu

View File

@ -53,7 +53,7 @@ class TraceDump {
private: private:
bool Setup(); bool Setup();
bool Load(std::wstring trace_file_path); bool Load(std::wstring trace_file_path);
void Run(); int Run();
std::wstring trace_file_path_; std::wstring trace_file_path_;
std::wstring base_output_path_; std::wstring base_output_path_;

View File

@ -88,6 +88,9 @@ std::unique_ptr<RawImage> VulkanGraphicsSystem::Capture() {
VkCommandBuffer cmd = nullptr; VkCommandBuffer cmd = nullptr;
status = vkAllocateCommandBuffers(*device_, &alloc_info, &cmd); status = vkAllocateCommandBuffers(*device_, &alloc_info, &cmd);
CheckResult(status, "vkAllocateCommandBuffers"); CheckResult(status, "vkAllocateCommandBuffers");
if (status != VK_SUCCESS) {
return nullptr;
}
VkCommandBufferBeginInfo begin_info = { VkCommandBufferBeginInfo begin_info = {
VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr, VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr,
@ -98,7 +101,11 @@ std::unique_ptr<RawImage> VulkanGraphicsSystem::Capture() {
auto front_buffer = auto front_buffer =
reinterpret_cast<VkImage>(swap_state.front_buffer_texture); reinterpret_cast<VkImage>(swap_state.front_buffer_texture);
CreateCaptureBuffer(cmd, {swap_state.width, swap_state.height}); status = CreateCaptureBuffer(cmd, {swap_state.width, swap_state.height});
if (status != VK_SUCCESS) {
vkFreeCommandBuffers(*device_, command_pool_, 1, &cmd);
return nullptr;
}
VkImageMemoryBarrier barrier; VkImageMemoryBarrier barrier;
std::memset(&barrier, 0, sizeof(VkImageMemoryBarrier)); std::memset(&barrier, 0, sizeof(VkImageMemoryBarrier));
@ -140,10 +147,10 @@ std::unique_ptr<RawImage> VulkanGraphicsSystem::Capture() {
VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, nullptr, 1, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, nullptr, 1,
&memory_barrier, 0, nullptr); &memory_barrier, 0, nullptr);
vkEndCommandBuffer(cmd); status = vkEndCommandBuffer(cmd);
// Submit commands and wait. // Submit commands and wait.
{ if (status == VK_SUCCESS) {
std::lock_guard<std::mutex>(device_->primary_queue_mutex()); std::lock_guard<std::mutex>(device_->primary_queue_mutex());
VkSubmitInfo submit_info = { VkSubmitInfo submit_info = {
VK_STRUCTURE_TYPE_SUBMIT_INFO, VK_STRUCTURE_TYPE_SUBMIT_INFO,
@ -168,9 +175,12 @@ std::unique_ptr<RawImage> VulkanGraphicsSystem::Capture() {
vkFreeCommandBuffers(*device_, command_pool_, 1, &cmd); vkFreeCommandBuffers(*device_, command_pool_, 1, &cmd);
void* data; void* data;
status = if (status == VK_SUCCESS) {
vkMapMemory(*device_, capture_buffer_memory_, 0, VK_WHOLE_SIZE, 0, &data); status = vkMapMemory(*device_, capture_buffer_memory_, 0, VK_WHOLE_SIZE, 0,
CheckResult(status, "vkMapMemory"); &data);
CheckResult(status, "vkMapMemory");
}
if (status == VK_SUCCESS) { if (status == VK_SUCCESS) {
std::unique_ptr<RawImage> raw_image(new RawImage()); std::unique_ptr<RawImage> raw_image(new RawImage());
raw_image->width = swap_state.width; raw_image->width = swap_state.width;
@ -186,11 +196,14 @@ std::unique_ptr<RawImage> VulkanGraphicsSystem::Capture() {
return raw_image; return raw_image;
} }
DestroyCaptureBuffer();
return nullptr; return nullptr;
} }
VkResult VulkanGraphicsSystem::CreateCaptureBuffer(VkCommandBuffer cmd, VkResult VulkanGraphicsSystem::CreateCaptureBuffer(VkCommandBuffer cmd,
VkExtent2D extents) { VkExtent2D extents) {
VkResult status = VK_SUCCESS;
VkBufferCreateInfo buffer_info = { VkBufferCreateInfo buffer_info = {
VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
nullptr, nullptr,
@ -201,8 +214,10 @@ VkResult VulkanGraphicsSystem::CreateCaptureBuffer(VkCommandBuffer cmd,
0, 0,
nullptr, nullptr,
}; };
auto status = status = vkCreateBuffer(*device_, &buffer_info, nullptr, &capture_buffer_);
vkCreateBuffer(*device_, &buffer_info, nullptr, &capture_buffer_); if (status != VK_SUCCESS) {
return status;
}
capture_buffer_size_ = extents.width * extents.height * 4; capture_buffer_size_ = extents.width * extents.height * 4;
@ -217,8 +232,12 @@ VkResult VulkanGraphicsSystem::CreateCaptureBuffer(VkCommandBuffer cmd,
status = status =
vkBindBufferMemory(*device_, capture_buffer_, capture_buffer_memory_, 0); vkBindBufferMemory(*device_, capture_buffer_, capture_buffer_memory_, 0);
CheckResult(status, "vkBindImageMemory"); CheckResult(status, "vkBindImageMemory");
if (status != VK_SUCCESS) {
vkDestroyBuffer(*device_, capture_buffer_, nullptr);
return status;
}
return VK_SUCCESS; return status;
} }
void VulkanGraphicsSystem::DestroyCaptureBuffer() { void VulkanGraphicsSystem::DestroyCaptureBuffer() {