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
, const char *filename
)
35 VkDevice vk_device
= anv_device_to_handle(device
);
38 VkExtent2D extent
= { image
->extent
.width
, image
->extent
.height
};
39 for (unsigned i
= 0; i
< miplevel
; i
++) {
40 extent
.width
= MAX2(1, extent
.width
/ 2);
41 extent
.height
= MAX2(1, extent
.height
/ 2);
45 result
= anv_CreateImage(vk_device
,
46 &(VkImageCreateInfo
) {
47 .sType
= VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO
,
48 .imageType
= VK_IMAGE_TYPE_2D
,
49 .format
= VK_FORMAT_R8G8B8A8_UNORM
,
50 .extent
= (VkExtent3D
) { extent
.width
, extent
.height
, 1 },
54 .tiling
= VK_IMAGE_TILING_LINEAR
,
55 .usage
= VK_IMAGE_USAGE_TRANSFER_DST_BIT
,
58 assert(result
== VK_SUCCESS
);
60 VkMemoryRequirements reqs
;
61 anv_GetImageMemoryRequirements(vk_device
, copy_image
, &reqs
);
63 VkDeviceMemory memory
;
64 result
= anv_AllocMemory(vk_device
,
65 &(VkMemoryAllocInfo
) {
66 .sType
= VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO
,
67 .allocationSize
= reqs
.size
,
70 assert(result
== VK_SUCCESS
);
72 result
= anv_BindImageMemory(vk_device
, copy_image
, memory
, 0);
73 assert(result
== VK_SUCCESS
);
75 VkCommandPool commandPool
;
76 result
= anv_CreateCommandPool(vk_device
,
77 &(VkCommandPoolCreateInfo
) {
78 .sType
= VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO
,
79 .queueFamilyIndex
= 0,
82 assert(result
== VK_SUCCESS
);
85 result
= anv_CreateCommandBuffer(vk_device
,
86 &(VkCommandBufferCreateInfo
) {
87 .sType
= VK_STRUCTURE_TYPE_COMMAND_BUFFER_CREATE_INFO
,
88 .commandPool
= commandPool
,
89 .level
= VK_COMMAND_BUFFER_LEVEL_PRIMARY
,
92 assert(result
== VK_SUCCESS
);
94 result
= anv_BeginCommandBuffer(cmd
,
95 &(VkCommandBufferBeginInfo
) {
96 .sType
= VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO
,
97 .flags
= VK_CMD_BUFFER_OPTIMIZE_ONE_TIME_SUBMIT_BIT
,
99 assert(result
== VK_SUCCESS
);
101 anv_CmdBlitImage(cmd
,
102 anv_image_to_handle(image
), VK_IMAGE_LAYOUT_GENERAL
,
103 copy_image
, VK_IMAGE_LAYOUT_GENERAL
, 1,
106 .aspectMask
= VK_IMAGE_ASPECT_COLOR_BIT
,
107 .mipLevel
= miplevel
,
108 .baseArrayLayer
= array_layer
,
111 .srcOffset
= (VkOffset3D
) { 0, 0, 0 },
112 .srcExtent
= (VkExtent3D
) {
118 .aspectMask
= VK_IMAGE_ASPECT_COLOR_BIT
,
123 .dstOffset
= (VkOffset3D
) { 0, 0, 0 },
124 .dstExtent
= (VkExtent3D
) {
129 }, VK_TEX_FILTER_NEAREST
);
131 ANV_CALL(CmdPipelineBarrier
)(cmd
,
132 VK_PIPELINE_STAGE_TRANSFER_BIT
,
133 VK_PIPELINE_STAGE_TRANSFER_BIT
,
135 (const void * []) { &(VkImageMemoryBarrier
) {
136 .sType
= VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER
,
137 .outputMask
= VK_MEMORY_OUTPUT_TRANSFER_BIT
,
138 .inputMask
= VK_MEMORY_INPUT_HOST_READ_BIT
,
139 .oldLayout
= VK_IMAGE_LAYOUT_GENERAL
,
140 .newLayout
= VK_IMAGE_LAYOUT_GENERAL
,
141 .srcQueueFamilyIndex
= 0,
142 .destQueueFamilyIndex
= 0,
144 .subresourceRange
= (VkImageSubresourceRange
) {
145 .aspectMask
= VK_IMAGE_ASPECT_COLOR_BIT
,
153 result
= anv_EndCommandBuffer(cmd
);
154 assert(result
== VK_SUCCESS
);
157 result
= anv_CreateFence(vk_device
,
158 &(VkFenceCreateInfo
) {
159 .sType
= VK_STRUCTURE_TYPE_FENCE_CREATE_INFO
,
162 assert(result
== VK_SUCCESS
);
164 result
= anv_QueueSubmit(anv_queue_to_handle(&device
->queue
),
166 assert(result
== VK_SUCCESS
);
168 result
= anv_WaitForFences(vk_device
, 1, &fence
, true, UINT64_MAX
);
169 assert(result
== VK_SUCCESS
);
171 anv_DestroyFence(vk_device
, fence
);
172 anv_DestroyCommandPool(vk_device
, commandPool
);
175 result
= anv_MapMemory(vk_device
, memory
, 0, reqs
.size
, 0, (void **)&map
);
176 assert(result
== VK_SUCCESS
);
178 VkSubresourceLayout layout
;
179 anv_GetImageSubresourceLayout(vk_device
, copy_image
,
180 &(VkImageSubresource
) {
181 .aspect
= VK_IMAGE_ASPECT_COLOR
,
186 map
+= layout
.offset
;
188 /* Now we can finally write the PPM file */
189 FILE *file
= fopen(filename
, "wb");
192 fprintf(file
, "P6\n%d %d\n255\n", extent
.width
, extent
.height
);
193 for (unsigned y
= 0; y
< extent
.height
; y
++) {
194 uint8_t row
[extent
.width
* 3];
195 for (unsigned x
= 0; x
< extent
.width
; x
++) {
196 row
[x
* 3 + 0] = map
[x
* 4 + 0];
197 row
[x
* 3 + 1] = map
[x
* 4 + 1];
198 row
[x
* 3 + 2] = map
[x
* 4 + 2];
200 fwrite(row
, 3, extent
.width
, file
);
202 map
+= layout
.rowPitch
;
206 anv_UnmapMemory(vk_device
, memory
);
207 anv_DestroyImage(vk_device
, copy_image
);
208 anv_FreeMemory(vk_device
, memory
);