anv/dump: Refactor the guts into helpers
Reviewed-by: Chad Versace <chad.versace@intel.com>
This commit is contained in:
+175
-121
@@ -27,6 +27,173 @@
|
||||
* called from GDB or similar to help inspect images and buffers.
|
||||
*/
|
||||
|
||||
struct dump_image {
|
||||
const char *filename;
|
||||
|
||||
VkExtent2D extent;
|
||||
VkImage image;
|
||||
VkDeviceMemory memory;
|
||||
};
|
||||
|
||||
static void
|
||||
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;
|
||||
|
||||
image->filename = filename;
|
||||
image->extent = (VkExtent2D) { width, height };
|
||||
|
||||
result = anv_CreateImage(vk_device,
|
||||
&(VkImageCreateInfo) {
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
|
||||
.imageType = VK_IMAGE_TYPE_2D,
|
||||
.format = VK_FORMAT_R8G8B8A8_UNORM,
|
||||
.extent = (VkExtent3D) { width, height, 1 },
|
||||
.mipLevels = 1,
|
||||
.arrayLayers = 1,
|
||||
.samples = 1,
|
||||
.tiling = VK_IMAGE_TILING_LINEAR,
|
||||
.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT,
|
||||
.flags = 0,
|
||||
}, NULL, &image->image);
|
||||
assert(result == VK_SUCCESS);
|
||||
|
||||
VkMemoryRequirements reqs;
|
||||
anv_GetImageMemoryRequirements(vk_device, image->image, &reqs);
|
||||
|
||||
result = anv_AllocateMemory(vk_device,
|
||||
&(VkMemoryAllocateInfo) {
|
||||
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
|
||||
.allocationSize = reqs.size,
|
||||
.memoryTypeIndex = 0,
|
||||
}, NULL, &image->memory);
|
||||
assert(result == VK_SUCCESS);
|
||||
|
||||
result = anv_BindImageMemory(vk_device, image->image, image->memory, 0);
|
||||
assert(result == VK_SUCCESS);
|
||||
}
|
||||
|
||||
static void
|
||||
dump_image_finish(struct anv_device *device, struct dump_image *image)
|
||||
{
|
||||
VkDevice vk_device = anv_device_to_handle(device);
|
||||
|
||||
anv_DestroyImage(vk_device, image->image, NULL);
|
||||
anv_FreeMemory(vk_device, image->memory, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
dump_image_do_blit(struct anv_device *device, struct dump_image *image,
|
||||
struct anv_cmd_buffer *cmd_buffer, struct anv_image *src,
|
||||
VkImageAspectFlagBits aspect,
|
||||
unsigned miplevel, unsigned array_layer)
|
||||
{
|
||||
/* We need to do a blit so the image needs to be declared as sampled. The
|
||||
* only thing these are used for is making sure we create the correct
|
||||
* views, so it should be find to just stomp it and set it back.
|
||||
*/
|
||||
VkImageUsageFlags old_usage = src->usage;
|
||||
src->usage |= VK_IMAGE_USAGE_SAMPLED_BIT;
|
||||
|
||||
anv_CmdBlitImage(anv_cmd_buffer_to_handle(cmd_buffer),
|
||||
anv_image_to_handle(src), VK_IMAGE_LAYOUT_GENERAL,
|
||||
image->image, VK_IMAGE_LAYOUT_GENERAL, 1,
|
||||
&(VkImageBlit) {
|
||||
.srcSubresource = {
|
||||
.aspectMask = aspect,
|
||||
.mipLevel = miplevel,
|
||||
.baseArrayLayer = array_layer,
|
||||
.layerCount = 1,
|
||||
},
|
||||
.srcOffsets = {
|
||||
{ 0, 0, 0 },
|
||||
{ image->extent.width, image->extent.height, 1 },
|
||||
},
|
||||
.dstSubresource = {
|
||||
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
.mipLevel = 0,
|
||||
.baseArrayLayer = 0,
|
||||
.layerCount = 1,
|
||||
},
|
||||
.dstOffsets = {
|
||||
{ 0, 0, 0 },
|
||||
{ image->extent.width, image->extent.height, 1 },
|
||||
},
|
||||
}, VK_FILTER_NEAREST);
|
||||
|
||||
src->usage = old_usage;
|
||||
|
||||
ANV_CALL(CmdPipelineBarrier)(anv_cmd_buffer_to_handle(cmd_buffer),
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
true, 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,
|
||||
.oldLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||
.newLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||
.srcQueueFamilyIndex = 0,
|
||||
.dstQueueFamilyIndex = 0,
|
||||
.image = image->image,
|
||||
.subresourceRange = (VkImageSubresourceRange) {
|
||||
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
.baseMipLevel = 0,
|
||||
.levelCount = 1,
|
||||
.baseArrayLayer = 0,
|
||||
.layerCount = 1,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
VkMemoryRequirements reqs;
|
||||
anv_GetImageMemoryRequirements(vk_device, image->image, &reqs);
|
||||
|
||||
uint8_t *map;
|
||||
result = anv_MapMemory(vk_device, image->memory, 0, reqs.size, 0, (void **)&map);
|
||||
assert(result == VK_SUCCESS);
|
||||
|
||||
VkSubresourceLayout layout;
|
||||
anv_GetImageSubresourceLayout(vk_device, image->image,
|
||||
&(VkImageSubresource) {
|
||||
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
.mipLevel = 0,
|
||||
.arrayLayer = 0,
|
||||
}, &layout);
|
||||
|
||||
map += layout.offset;
|
||||
|
||||
FILE *file = fopen(image->filename, "wb");
|
||||
assert(file);
|
||||
|
||||
uint8_t *row = malloc(image->extent.width * 3);
|
||||
assert(row);
|
||||
|
||||
fprintf(file, "P6\n%d %d\n255\n", image->extent.width, image->extent.height);
|
||||
for (unsigned y = 0; y < image->extent.height; y++) {
|
||||
for (unsigned x = 0; x < image->extent.width; x++) {
|
||||
row[x * 3 + 0] = map[x * 4 + 0];
|
||||
row[x * 3 + 1] = map[x * 4 + 1];
|
||||
row[x * 3 + 2] = map[x * 4 + 2];
|
||||
}
|
||||
fwrite(row, 3, image->extent.width, file);
|
||||
|
||||
map += layout.rowPitch;
|
||||
}
|
||||
free(row);
|
||||
fclose(file);
|
||||
|
||||
anv_UnmapMemory(vk_device, image->memory);
|
||||
}
|
||||
|
||||
void
|
||||
anv_dump_image_to_ppm(struct anv_device *device,
|
||||
struct anv_image *image, unsigned miplevel,
|
||||
@@ -36,41 +203,11 @@ anv_dump_image_to_ppm(struct anv_device *device,
|
||||
VkDevice vk_device = anv_device_to_handle(device);
|
||||
MAYBE_UNUSED VkResult result;
|
||||
|
||||
VkExtent2D extent = {
|
||||
anv_minify(image->extent.width, miplevel),
|
||||
anv_minify(image->extent.height, miplevel),
|
||||
};
|
||||
const uint32_t width = anv_minify(image->extent.width, miplevel);
|
||||
const uint32_t height = anv_minify(image->extent.height, miplevel);
|
||||
|
||||
VkImage copy_image;
|
||||
result = anv_CreateImage(vk_device,
|
||||
&(VkImageCreateInfo) {
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
|
||||
.imageType = VK_IMAGE_TYPE_2D,
|
||||
.format = VK_FORMAT_R8G8B8A8_UNORM,
|
||||
.extent = (VkExtent3D) { extent.width, extent.height, 1 },
|
||||
.mipLevels = 1,
|
||||
.arrayLayers = 1,
|
||||
.samples = 1,
|
||||
.tiling = VK_IMAGE_TILING_LINEAR,
|
||||
.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT,
|
||||
.flags = 0,
|
||||
}, NULL, ©_image);
|
||||
assert(result == VK_SUCCESS);
|
||||
|
||||
VkMemoryRequirements reqs;
|
||||
anv_GetImageMemoryRequirements(vk_device, copy_image, &reqs);
|
||||
|
||||
VkDeviceMemory memory;
|
||||
result = anv_AllocateMemory(vk_device,
|
||||
&(VkMemoryAllocateInfo) {
|
||||
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
|
||||
.allocationSize = reqs.size,
|
||||
.memoryTypeIndex = 0,
|
||||
}, NULL, &memory);
|
||||
assert(result == VK_SUCCESS);
|
||||
|
||||
result = anv_BindImageMemory(vk_device, copy_image, memory, 0);
|
||||
assert(result == VK_SUCCESS);
|
||||
struct dump_image dump;
|
||||
dump_image_init(device, &dump, width, height, filename);
|
||||
|
||||
VkCommandPool commandPool;
|
||||
result = anv_CreateCommandPool(vk_device,
|
||||
@@ -98,58 +235,8 @@ anv_dump_image_to_ppm(struct anv_device *device,
|
||||
});
|
||||
assert(result == VK_SUCCESS);
|
||||
|
||||
VkImageUsageFlags old_usage = image->usage;
|
||||
image->usage |= VK_IMAGE_USAGE_SAMPLED_BIT;
|
||||
|
||||
anv_CmdBlitImage(cmd,
|
||||
anv_image_to_handle(image), VK_IMAGE_LAYOUT_GENERAL,
|
||||
copy_image, VK_IMAGE_LAYOUT_GENERAL, 1,
|
||||
&(VkImageBlit) {
|
||||
.srcSubresource = {
|
||||
.aspectMask = aspect,
|
||||
.mipLevel = miplevel,
|
||||
.baseArrayLayer = array_layer,
|
||||
.layerCount = 1,
|
||||
},
|
||||
.srcOffsets = {
|
||||
{ 0, 0, 0 },
|
||||
{ extent.width, extent.height, 1 },
|
||||
},
|
||||
.dstSubresource = {
|
||||
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
.mipLevel = 0,
|
||||
.baseArrayLayer = 0,
|
||||
.layerCount = 1,
|
||||
},
|
||||
.dstOffsets = {
|
||||
{ 0, 0, 0 },
|
||||
{ extent.width, extent.height, 1 },
|
||||
},
|
||||
}, VK_FILTER_NEAREST);
|
||||
|
||||
image->usage = old_usage;
|
||||
|
||||
ANV_CALL(CmdPipelineBarrier)(cmd,
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
true, 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,
|
||||
.oldLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||
.newLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||
.srcQueueFamilyIndex = 0,
|
||||
.dstQueueFamilyIndex = 0,
|
||||
.image = copy_image,
|
||||
.subresourceRange = (VkImageSubresourceRange) {
|
||||
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
.baseMipLevel = 0,
|
||||
.levelCount = 1,
|
||||
.baseArrayLayer = 0,
|
||||
.layerCount = 1,
|
||||
},
|
||||
});
|
||||
dump_image_do_blit(device, &dump, anv_cmd_buffer_from_handle(cmd), image,
|
||||
aspect, miplevel, array_layer);
|
||||
|
||||
result = anv_EndCommandBuffer(cmd);
|
||||
assert(result == VK_SUCCESS);
|
||||
@@ -176,39 +263,6 @@ anv_dump_image_to_ppm(struct anv_device *device,
|
||||
anv_DestroyFence(vk_device, fence, NULL);
|
||||
anv_DestroyCommandPool(vk_device, commandPool, NULL);
|
||||
|
||||
uint8_t *map;
|
||||
result = anv_MapMemory(vk_device, memory, 0, reqs.size, 0, (void **)&map);
|
||||
assert(result == VK_SUCCESS);
|
||||
|
||||
VkSubresourceLayout layout;
|
||||
anv_GetImageSubresourceLayout(vk_device, copy_image,
|
||||
&(VkImageSubresource) {
|
||||
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
.mipLevel = 0,
|
||||
.arrayLayer = 0,
|
||||
}, &layout);
|
||||
|
||||
map += layout.offset;
|
||||
|
||||
/* Now we can finally write the PPM file */
|
||||
FILE *file = fopen(filename, "wb");
|
||||
assert(file);
|
||||
|
||||
fprintf(file, "P6\n%d %d\n255\n", extent.width, extent.height);
|
||||
for (unsigned y = 0; y < extent.height; y++) {
|
||||
uint8_t row[extent.width * 3];
|
||||
for (unsigned x = 0; x < extent.width; x++) {
|
||||
row[x * 3 + 0] = map[x * 4 + 0];
|
||||
row[x * 3 + 1] = map[x * 4 + 1];
|
||||
row[x * 3 + 2] = map[x * 4 + 2];
|
||||
}
|
||||
fwrite(row, 3, extent.width, file);
|
||||
|
||||
map += layout.rowPitch;
|
||||
}
|
||||
fclose(file);
|
||||
|
||||
anv_UnmapMemory(vk_device, memory);
|
||||
anv_DestroyImage(vk_device, copy_image, NULL);
|
||||
anv_FreeMemory(vk_device, memory, NULL);
|
||||
dump_image_write_to_ppm(device, &dump);
|
||||
dump_image_finish(device, &dump);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user