X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fintel%2Fvulkan%2Fanv_dump.c;h=f3447f43b2190af65616cfaec9b69abe8b3baa8c;hb=c9bebae2877e55cdcd94f9f9f3f6805238caeb28;hp=59a6f2af6900eeb795920b95da73d72602f5133a;hpb=fad0b7b0b3fbea55a1cf14ee731531e706083716;p=mesa.git diff --git a/src/intel/vulkan/anv_dump.c b/src/intel/vulkan/anv_dump.c index 59a6f2af690..f3447f43b21 100644 --- a/src/intel/vulkan/anv_dump.c +++ b/src/intel/vulkan/anv_dump.c @@ -23,11 +23,33 @@ #include "anv_private.h" +#include "util/list.h" +#include "util/ralloc.h" + /* This file contains utility functions for help debugging. They can be * called from GDB or similar to help inspect images and buffers. + * + * To dump the framebuffers of an application after each render pass, all you + * have to do is the following + * + * 1) Start the application in GDB + * 2) Run until you get to the point where the rendering errors occur + * 3) Pause in GDB and set a breakpoint in anv_QueuePresentKHR + * 4) Continue until it reaches anv_QueuePresentKHR + * 5) Call anv_dump_start(queue->device, ANV_DUMP_FRAMEBUFFERS_BIT) + * 6) Continue until the next anv_QueuePresentKHR call + * 7) Call anv_dump_finish() to complete the dump and write files + * + * While it's a bit manual, the process does allow you to do some very + * valuable debugging by dumping every render target at the end of every + * render pass. It's worth noting that this assumes that the application + * creates all of the command buffers more-or-less in-order and between the + * two anv_QueuePresentKHR calls. */ struct dump_image { + struct list_head link; + const char *filename; VkExtent2D extent; @@ -40,7 +62,7 @@ dump_image_init(struct anv_device *device, struct dump_image *image, uint32_t width, uint32_t height, const char *filename) { VkDevice vk_device = anv_device_to_handle(device); - MAYBE_UNUSED VkResult result; + ASSERTED VkResult result; image->filename = filename; image->extent = (VkExtent2D) { width, height }; @@ -90,7 +112,11 @@ dump_image_do_blit(struct anv_device *device, struct dump_image *image, VkImageAspectFlagBits aspect, unsigned miplevel, unsigned array_layer) { - ANV_CALL(CmdPipelineBarrier)(anv_cmd_buffer_to_handle(cmd_buffer), + PFN_vkCmdPipelineBarrier CmdPipelineBarrier = + (void *)anv_GetDeviceProcAddr(anv_device_to_handle(device), + "vkCmdPipelineBarrier"); + + CmdPipelineBarrier(anv_cmd_buffer_to_handle(cmd_buffer), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, NULL, 0, NULL, 1, @@ -147,14 +173,14 @@ dump_image_do_blit(struct anv_device *device, struct dump_image *image, src->usage = old_usage; - ANV_CALL(CmdPipelineBarrier)(anv_cmd_buffer_to_handle(cmd_buffer), + CmdPipelineBarrier(anv_cmd_buffer_to_handle(cmd_buffer), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, - true, 0, NULL, 0, NULL, 1, + 0, 0, NULL, 0, NULL, 1, &(VkImageMemoryBarrier) { .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, - .srcAccessMask = VK_ACCESS_HOST_READ_BIT, - .dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT, + .srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT, + .dstAccessMask = VK_ACCESS_HOST_READ_BIT, .oldLayout = VK_IMAGE_LAYOUT_GENERAL, .newLayout = VK_IMAGE_LAYOUT_GENERAL, .srcQueueFamilyIndex = 0, @@ -174,7 +200,7 @@ static void dump_image_write_to_ppm(struct anv_device *device, struct dump_image *image) { VkDevice vk_device = anv_device_to_handle(device); - MAYBE_UNUSED VkResult result; + ASSERTED VkResult result; VkMemoryRequirements reqs; anv_GetImageMemoryRequirements(vk_device, image->image, &reqs); @@ -223,7 +249,14 @@ anv_dump_image_to_ppm(struct anv_device *device, const char *filename) { VkDevice vk_device = anv_device_to_handle(device); - MAYBE_UNUSED VkResult result; + ASSERTED VkResult result; + + PFN_vkBeginCommandBuffer BeginCommandBuffer = + (void *)anv_GetDeviceProcAddr(anv_device_to_handle(device), + "vkBeginCommandBuffer"); + PFN_vkEndCommandBuffer EndCommandBuffer = + (void *)anv_GetDeviceProcAddr(anv_device_to_handle(device), + "vkEndCommandBuffer"); const uint32_t width = anv_minify(image->extent.width, miplevel); const uint32_t height = anv_minify(image->extent.height, miplevel); @@ -250,7 +283,7 @@ anv_dump_image_to_ppm(struct anv_device *device, }, &cmd); assert(result == VK_SUCCESS); - result = anv_BeginCommandBuffer(cmd, + result = BeginCommandBuffer(cmd, &(VkCommandBufferBeginInfo) { .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, .flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, @@ -260,7 +293,7 @@ anv_dump_image_to_ppm(struct anv_device *device, dump_image_do_blit(device, &dump, anv_cmd_buffer_from_handle(cmd), image, aspect, miplevel, array_layer); - result = anv_EndCommandBuffer(cmd); + result = EndCommandBuffer(cmd); assert(result == VK_SUCCESS); VkFence fence; @@ -288,3 +321,130 @@ anv_dump_image_to_ppm(struct anv_device *device, dump_image_write_to_ppm(device, &dump); dump_image_finish(device, &dump); } + +static pthread_mutex_t dump_mutex = PTHREAD_MUTEX_INITIALIZER; + +static enum anv_dump_action dump_actions = 0; + +/* Used to prevent recursive dumping */ +static enum anv_dump_action dump_old_actions; + +struct list_head dump_list; +static void *dump_ctx; +static struct anv_device *dump_device; +static unsigned dump_count; + +void +anv_dump_start(struct anv_device *device, enum anv_dump_action actions) +{ + pthread_mutex_lock(&dump_mutex); + + dump_device = device; + dump_actions = actions; + list_inithead(&dump_list); + dump_ctx = ralloc_context(NULL); + dump_count = 0; + + pthread_mutex_unlock(&dump_mutex); +} + +void +anv_dump_finish() +{ + anv_DeviceWaitIdle(anv_device_to_handle(dump_device)); + + pthread_mutex_lock(&dump_mutex); + + list_for_each_entry(struct dump_image, dump, &dump_list, link) { + dump_image_write_to_ppm(dump_device, dump); + dump_image_finish(dump_device, dump); + } + + dump_actions = 0; + dump_device = NULL; + list_inithead(&dump_list); + + ralloc_free(dump_ctx); + dump_ctx = NULL; + + pthread_mutex_unlock(&dump_mutex); +} + +static bool +dump_lock(enum anv_dump_action action) +{ + if (likely((dump_actions & action) == 0)) + return false; + + pthread_mutex_lock(&dump_mutex); + + /* Prevent recursive dumping */ + dump_old_actions = dump_actions; + dump_actions = 0; + + return true; +} + +static void +dump_unlock() +{ + dump_actions = dump_old_actions; + pthread_mutex_unlock(&dump_mutex); +} + +static void +dump_add_image(struct anv_cmd_buffer *cmd_buffer, struct anv_image *image, + VkImageAspectFlagBits aspect, + unsigned miplevel, unsigned array_layer, const char *filename) +{ + const uint32_t width = anv_minify(image->extent.width, miplevel); + const uint32_t height = anv_minify(image->extent.height, miplevel); + + struct dump_image *dump = ralloc(dump_ctx, struct dump_image); + + dump_image_init(cmd_buffer->device, dump, width, height, filename); + dump_image_do_blit(cmd_buffer->device, dump, cmd_buffer, image, + aspect, miplevel, array_layer); + + list_addtail(&dump->link, &dump_list); +} + +void +anv_dump_add_attachments(struct anv_cmd_buffer *cmd_buffer) +{ + if (!dump_lock(ANV_DUMP_FRAMEBUFFERS_BIT)) + return; + + unsigned dump_idx = dump_count++; + + for (unsigned i = 0; i < cmd_buffer->state.pass->attachment_count; i++) { + struct anv_image_view *iview = cmd_buffer->state.attachments[i].image_view; + + uint32_t b; + for_each_bit(b, iview->image->aspects) { + VkImageAspectFlagBits aspect = (1 << b); + const char *suffix; + switch (aspect) { + case VK_IMAGE_ASPECT_COLOR_BIT: suffix = "c"; break; + case VK_IMAGE_ASPECT_DEPTH_BIT: suffix = "d"; break; + case VK_IMAGE_ASPECT_STENCIL_BIT: suffix = "s"; break; + case VK_IMAGE_ASPECT_PLANE_0_BIT: suffix = "c0"; break; + case VK_IMAGE_ASPECT_PLANE_1_BIT: suffix = "c1"; break; + case VK_IMAGE_ASPECT_PLANE_2_BIT: suffix = "c2"; break; + default: + unreachable("Invalid aspect"); + } + + char *filename = ralloc_asprintf(dump_ctx, "attachment%04d-%d%s.ppm", + dump_idx, i, suffix); + + unsigned plane = anv_image_aspect_to_plane(iview->image->aspects, aspect); + dump_add_image(cmd_buffer, (struct anv_image *)iview->image, aspect, + iview->planes[plane].isl.base_level, + iview->planes[plane].isl.base_array_layer, + filename); + } + } + + dump_unlock(); +}