2 * Copyright © 2015 Intel Corporation
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
24 #include "anv_private.h"
26 /* This file contains utility functions for help debugging. They can be
27 * called from GDB or similar to help inspect images and buffers.
31 anv_dump_image_to_ppm(struct anv_device
*device
,
32 struct anv_image
*image
, unsigned miplevel
,
33 unsigned array_layer
, VkImageAspectFlagBits aspect
,
36 VkDevice vk_device
= anv_device_to_handle(device
);
37 MAYBE_UNUSED VkResult result
;
39 VkExtent2D extent
= { image
->extent
.width
, image
->extent
.height
};
40 for (unsigned i
= 0; i
< miplevel
; i
++) {
41 extent
.width
= MAX2(1, extent
.width
/ 2);
42 extent
.height
= MAX2(1, extent
.height
/ 2);
46 result
= anv_CreateImage(vk_device
,
47 &(VkImageCreateInfo
) {
48 .sType
= VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO
,
49 .imageType
= VK_IMAGE_TYPE_2D
,
50 .format
= VK_FORMAT_R8G8B8A8_UNORM
,
51 .extent
= (VkExtent3D
) { extent
.width
, extent
.height
, 1 },
55 .tiling
= VK_IMAGE_TILING_LINEAR
,
56 .usage
= VK_IMAGE_USAGE_TRANSFER_DST_BIT
,
58 }, NULL
, ©_image
);
59 assert(result
== VK_SUCCESS
);
61 VkMemoryRequirements reqs
;
62 anv_GetImageMemoryRequirements(vk_device
, copy_image
, &reqs
);
64 VkDeviceMemory memory
;
65 result
= anv_AllocateMemory(vk_device
,
66 &(VkMemoryAllocateInfo
) {
67 .sType
= VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO
,
68 .allocationSize
= reqs
.size
,
71 assert(result
== VK_SUCCESS
);
73 result
= anv_BindImageMemory(vk_device
, copy_image
, memory
, 0);
74 assert(result
== VK_SUCCESS
);
76 VkCommandPool commandPool
;
77 result
= anv_CreateCommandPool(vk_device
,
78 &(VkCommandPoolCreateInfo
) {
79 .sType
= VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO
,
80 .queueFamilyIndex
= 0,
82 }, NULL
, &commandPool
);
83 assert(result
== VK_SUCCESS
);
86 result
= anv_AllocateCommandBuffers(vk_device
,
87 &(VkCommandBufferAllocateInfo
) {
88 .sType
= VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO
,
89 .commandPool
= commandPool
,
90 .level
= VK_COMMAND_BUFFER_LEVEL_PRIMARY
,
91 .commandBufferCount
= 1,
93 assert(result
== VK_SUCCESS
);
95 result
= anv_BeginCommandBuffer(cmd
,
96 &(VkCommandBufferBeginInfo
) {
97 .sType
= VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO
,
98 .flags
= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT
,
100 assert(result
== VK_SUCCESS
);
102 VkImageUsageFlags old_usage
= image
->usage
;
103 image
->usage
|= VK_IMAGE_USAGE_SAMPLED_BIT
;
105 anv_CmdBlitImage(cmd
,
106 anv_image_to_handle(image
), VK_IMAGE_LAYOUT_GENERAL
,
107 copy_image
, VK_IMAGE_LAYOUT_GENERAL
, 1,
110 .aspectMask
= aspect
,
111 .mipLevel
= miplevel
,
112 .baseArrayLayer
= array_layer
,
117 { extent
.width
, extent
.height
, 1 },
120 .aspectMask
= VK_IMAGE_ASPECT_COLOR_BIT
,
127 { extent
.width
, extent
.height
, 1 },
129 }, VK_FILTER_NEAREST
);
131 image
->usage
= old_usage
;
133 ANV_CALL(CmdPipelineBarrier
)(cmd
,
134 VK_PIPELINE_STAGE_TRANSFER_BIT
,
135 VK_PIPELINE_STAGE_TRANSFER_BIT
,
136 true, 0, NULL
, 0, NULL
, 1,
137 &(VkImageMemoryBarrier
) {
138 .sType
= VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER
,
139 .srcAccessMask
= VK_ACCESS_HOST_READ_BIT
,
140 .dstAccessMask
= VK_ACCESS_TRANSFER_WRITE_BIT
,
141 .oldLayout
= VK_IMAGE_LAYOUT_GENERAL
,
142 .newLayout
= VK_IMAGE_LAYOUT_GENERAL
,
143 .srcQueueFamilyIndex
= 0,
144 .dstQueueFamilyIndex
= 0,
146 .subresourceRange
= (VkImageSubresourceRange
) {
147 .aspectMask
= VK_IMAGE_ASPECT_COLOR_BIT
,
155 result
= anv_EndCommandBuffer(cmd
);
156 assert(result
== VK_SUCCESS
);
159 result
= anv_CreateFence(vk_device
,
160 &(VkFenceCreateInfo
) {
161 .sType
= VK_STRUCTURE_TYPE_FENCE_CREATE_INFO
,
164 assert(result
== VK_SUCCESS
);
166 result
= anv_QueueSubmit(anv_queue_to_handle(&device
->queue
), 1,
168 .sType
= VK_STRUCTURE_TYPE_SUBMIT_INFO
,
169 .commandBufferCount
= 1,
170 .pCommandBuffers
= &cmd
,
172 assert(result
== VK_SUCCESS
);
174 result
= anv_WaitForFences(vk_device
, 1, &fence
, true, UINT64_MAX
);
175 assert(result
== VK_SUCCESS
);
177 anv_DestroyFence(vk_device
, fence
, NULL
);
178 anv_DestroyCommandPool(vk_device
, commandPool
, NULL
);
181 result
= anv_MapMemory(vk_device
, memory
, 0, reqs
.size
, 0, (void **)&map
);
182 assert(result
== VK_SUCCESS
);
184 VkSubresourceLayout layout
;
185 anv_GetImageSubresourceLayout(vk_device
, copy_image
,
186 &(VkImageSubresource
) {
187 .aspectMask
= VK_IMAGE_ASPECT_COLOR_BIT
,
192 map
+= layout
.offset
;
194 /* Now we can finally write the PPM file */
195 FILE *file
= fopen(filename
, "wb");
198 fprintf(file
, "P6\n%d %d\n255\n", extent
.width
, extent
.height
);
199 for (unsigned y
= 0; y
< extent
.height
; y
++) {
200 uint8_t row
[extent
.width
* 3];
201 for (unsigned x
= 0; x
< extent
.width
; x
++) {
202 row
[x
* 3 + 0] = map
[x
* 4 + 0];
203 row
[x
* 3 + 1] = map
[x
* 4 + 1];
204 row
[x
* 3 + 2] = map
[x
* 4 + 2];
206 fwrite(row
, 3, extent
.width
, file
);
208 map
+= layout
.rowPitch
;
212 anv_UnmapMemory(vk_device
, memory
);
213 anv_DestroyImage(vk_device
, copy_image
, NULL
);
214 anv_FreeMemory(vk_device
, memory
, NULL
);