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.
35 VkDeviceMemory memory
;
39 dump_image_init(struct anv_device
*device
, struct dump_image
*image
,
40 uint32_t width
, uint32_t height
, const char *filename
)
42 VkDevice vk_device
= anv_device_to_handle(device
);
43 MAYBE_UNUSED VkResult result
;
45 image
->filename
= filename
;
46 image
->extent
= (VkExtent2D
) { width
, height
};
48 result
= anv_CreateImage(vk_device
,
49 &(VkImageCreateInfo
) {
50 .sType
= VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO
,
51 .imageType
= VK_IMAGE_TYPE_2D
,
52 .format
= VK_FORMAT_R8G8B8A8_UNORM
,
53 .extent
= (VkExtent3D
) { width
, height
, 1 },
57 .tiling
= VK_IMAGE_TILING_LINEAR
,
58 .usage
= VK_IMAGE_USAGE_TRANSFER_DST_BIT
,
60 }, NULL
, &image
->image
);
61 assert(result
== VK_SUCCESS
);
63 VkMemoryRequirements reqs
;
64 anv_GetImageMemoryRequirements(vk_device
, image
->image
, &reqs
);
66 result
= anv_AllocateMemory(vk_device
,
67 &(VkMemoryAllocateInfo
) {
68 .sType
= VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO
,
69 .allocationSize
= reqs
.size
,
71 }, NULL
, &image
->memory
);
72 assert(result
== VK_SUCCESS
);
74 result
= anv_BindImageMemory(vk_device
, image
->image
, image
->memory
, 0);
75 assert(result
== VK_SUCCESS
);
79 dump_image_finish(struct anv_device
*device
, struct dump_image
*image
)
81 VkDevice vk_device
= anv_device_to_handle(device
);
83 anv_DestroyImage(vk_device
, image
->image
, NULL
);
84 anv_FreeMemory(vk_device
, image
->memory
, NULL
);
88 dump_image_do_blit(struct anv_device
*device
, struct dump_image
*image
,
89 struct anv_cmd_buffer
*cmd_buffer
, struct anv_image
*src
,
90 VkImageAspectFlagBits aspect
,
91 unsigned miplevel
, unsigned array_layer
)
93 ANV_CALL(CmdPipelineBarrier
)(anv_cmd_buffer_to_handle(cmd_buffer
),
94 VK_PIPELINE_STAGE_TRANSFER_BIT
,
95 VK_PIPELINE_STAGE_TRANSFER_BIT
,
96 0, 0, NULL
, 0, NULL
, 1,
97 &(VkImageMemoryBarrier
) {
98 .sType
= VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER
,
100 .dstAccessMask
= VK_ACCESS_TRANSFER_READ_BIT
,
101 .oldLayout
= VK_IMAGE_LAYOUT_GENERAL
,
102 .newLayout
= VK_IMAGE_LAYOUT_GENERAL
,
103 .srcQueueFamilyIndex
= 0,
104 .dstQueueFamilyIndex
= 0,
105 .image
= anv_image_to_handle(src
),
106 .subresourceRange
= (VkImageSubresourceRange
) {
107 .aspectMask
= aspect
,
108 .baseMipLevel
= miplevel
,
110 .baseArrayLayer
= array_layer
,
115 /* We need to do a blit so the image needs to be declared as sampled. The
116 * only thing these are used for is making sure we create the correct
117 * views, so it should be find to just stomp it and set it back.
119 VkImageUsageFlags old_usage
= src
->usage
;
120 src
->usage
|= VK_IMAGE_USAGE_SAMPLED_BIT
;
122 anv_CmdBlitImage(anv_cmd_buffer_to_handle(cmd_buffer
),
123 anv_image_to_handle(src
), VK_IMAGE_LAYOUT_GENERAL
,
124 image
->image
, VK_IMAGE_LAYOUT_GENERAL
, 1,
127 .aspectMask
= aspect
,
128 .mipLevel
= miplevel
,
129 .baseArrayLayer
= array_layer
,
134 { image
->extent
.width
, image
->extent
.height
, 1 },
137 .aspectMask
= VK_IMAGE_ASPECT_COLOR_BIT
,
144 { image
->extent
.width
, image
->extent
.height
, 1 },
146 }, VK_FILTER_NEAREST
);
148 src
->usage
= old_usage
;
150 ANV_CALL(CmdPipelineBarrier
)(anv_cmd_buffer_to_handle(cmd_buffer
),
151 VK_PIPELINE_STAGE_TRANSFER_BIT
,
152 VK_PIPELINE_STAGE_TRANSFER_BIT
,
153 true, 0, NULL
, 0, NULL
, 1,
154 &(VkImageMemoryBarrier
) {
155 .sType
= VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER
,
156 .srcAccessMask
= VK_ACCESS_HOST_READ_BIT
,
157 .dstAccessMask
= VK_ACCESS_TRANSFER_WRITE_BIT
,
158 .oldLayout
= VK_IMAGE_LAYOUT_GENERAL
,
159 .newLayout
= VK_IMAGE_LAYOUT_GENERAL
,
160 .srcQueueFamilyIndex
= 0,
161 .dstQueueFamilyIndex
= 0,
162 .image
= image
->image
,
163 .subresourceRange
= (VkImageSubresourceRange
) {
164 .aspectMask
= VK_IMAGE_ASPECT_COLOR_BIT
,
174 dump_image_write_to_ppm(struct anv_device
*device
, struct dump_image
*image
)
176 VkDevice vk_device
= anv_device_to_handle(device
);
177 MAYBE_UNUSED VkResult result
;
179 VkMemoryRequirements reqs
;
180 anv_GetImageMemoryRequirements(vk_device
, image
->image
, &reqs
);
183 result
= anv_MapMemory(vk_device
, image
->memory
, 0, reqs
.size
, 0, (void **)&map
);
184 assert(result
== VK_SUCCESS
);
186 VkSubresourceLayout layout
;
187 anv_GetImageSubresourceLayout(vk_device
, image
->image
,
188 &(VkImageSubresource
) {
189 .aspectMask
= VK_IMAGE_ASPECT_COLOR_BIT
,
194 map
+= layout
.offset
;
196 FILE *file
= fopen(image
->filename
, "wb");
199 uint8_t *row
= malloc(image
->extent
.width
* 3);
202 fprintf(file
, "P6\n%d %d\n255\n", image
->extent
.width
, image
->extent
.height
);
203 for (unsigned y
= 0; y
< image
->extent
.height
; y
++) {
204 for (unsigned x
= 0; x
< image
->extent
.width
; x
++) {
205 row
[x
* 3 + 0] = map
[x
* 4 + 0];
206 row
[x
* 3 + 1] = map
[x
* 4 + 1];
207 row
[x
* 3 + 2] = map
[x
* 4 + 2];
209 fwrite(row
, 3, image
->extent
.width
, file
);
211 map
+= layout
.rowPitch
;
216 anv_UnmapMemory(vk_device
, image
->memory
);
220 anv_dump_image_to_ppm(struct anv_device
*device
,
221 struct anv_image
*image
, unsigned miplevel
,
222 unsigned array_layer
, VkImageAspectFlagBits aspect
,
223 const char *filename
)
225 VkDevice vk_device
= anv_device_to_handle(device
);
226 MAYBE_UNUSED VkResult result
;
228 const uint32_t width
= anv_minify(image
->extent
.width
, miplevel
);
229 const uint32_t height
= anv_minify(image
->extent
.height
, miplevel
);
231 struct dump_image dump
;
232 dump_image_init(device
, &dump
, width
, height
, filename
);
234 VkCommandPool commandPool
;
235 result
= anv_CreateCommandPool(vk_device
,
236 &(VkCommandPoolCreateInfo
) {
237 .sType
= VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO
,
238 .queueFamilyIndex
= 0,
240 }, NULL
, &commandPool
);
241 assert(result
== VK_SUCCESS
);
244 result
= anv_AllocateCommandBuffers(vk_device
,
245 &(VkCommandBufferAllocateInfo
) {
246 .sType
= VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO
,
247 .commandPool
= commandPool
,
248 .level
= VK_COMMAND_BUFFER_LEVEL_PRIMARY
,
249 .commandBufferCount
= 1,
251 assert(result
== VK_SUCCESS
);
253 result
= anv_BeginCommandBuffer(cmd
,
254 &(VkCommandBufferBeginInfo
) {
255 .sType
= VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO
,
256 .flags
= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT
,
258 assert(result
== VK_SUCCESS
);
260 dump_image_do_blit(device
, &dump
, anv_cmd_buffer_from_handle(cmd
), image
,
261 aspect
, miplevel
, array_layer
);
263 result
= anv_EndCommandBuffer(cmd
);
264 assert(result
== VK_SUCCESS
);
267 result
= anv_CreateFence(vk_device
,
268 &(VkFenceCreateInfo
) {
269 .sType
= VK_STRUCTURE_TYPE_FENCE_CREATE_INFO
,
272 assert(result
== VK_SUCCESS
);
274 result
= anv_QueueSubmit(anv_queue_to_handle(&device
->queue
), 1,
276 .sType
= VK_STRUCTURE_TYPE_SUBMIT_INFO
,
277 .commandBufferCount
= 1,
278 .pCommandBuffers
= &cmd
,
280 assert(result
== VK_SUCCESS
);
282 result
= anv_WaitForFences(vk_device
, 1, &fence
, true, UINT64_MAX
);
283 assert(result
== VK_SUCCESS
);
285 anv_DestroyFence(vk_device
, fence
, NULL
);
286 anv_DestroyCommandPool(vk_device
, commandPool
, NULL
);
288 dump_image_write_to_ppm(device
, &dump
);
289 dump_image_finish(device
, &dump
);