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
,
57 }, NULL
, ©_image
);
58 assert(result
== VK_SUCCESS
);
60 VkMemoryRequirements reqs
;
61 anv_GetImageMemoryRequirements(vk_device
, copy_image
, &reqs
);
63 VkDeviceMemory memory
;
64 result
= anv_AllocateMemory(vk_device
,
65 &(VkMemoryAllocateInfo
) {
66 .sType
= VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_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,
81 }, NULL
, &commandPool
);
82 assert(result
== VK_SUCCESS
);
85 result
= anv_AllocateCommandBuffers(vk_device
,
86 &(VkCommandBufferAllocateInfo
) {
87 .sType
= VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_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_COMMAND_BUFFER_USAGE_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_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 .srcAccessMask
= VK_ACCESS_HOST_READ_BIT
,
138 .dstAccessMask
= VK_ACCESS_TRANSFER_WRITE_BIT
,
139 .oldLayout
= VK_IMAGE_LAYOUT_GENERAL
,
140 .newLayout
= VK_IMAGE_LAYOUT_GENERAL
,
141 .srcQueueFamilyIndex
= 0,
142 .dstQueueFamilyIndex
= 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
), 1,
166 .sType
= VK_STRUCTURE_TYPE_SUBMIT_INFO
,
167 .commandBufferCount
= 1,
168 .pCommandBuffers
= &cmd
,
170 assert(result
== VK_SUCCESS
);
172 result
= anv_WaitForFences(vk_device
, 1, &fence
, true, UINT64_MAX
);
173 assert(result
== VK_SUCCESS
);
175 anv_DestroyFence(vk_device
, fence
, NULL
);
176 anv_DestroyCommandPool(vk_device
, commandPool
, NULL
);
179 result
= anv_MapMemory(vk_device
, memory
, 0, reqs
.size
, 0, (void **)&map
);
180 assert(result
== VK_SUCCESS
);
182 VkSubresourceLayout layout
;
183 anv_GetImageSubresourceLayout(vk_device
, copy_image
,
184 &(VkImageSubresource
) {
185 .aspectMask
= VK_IMAGE_ASPECT_COLOR_BIT
,
190 map
+= layout
.offset
;
192 /* Now we can finally write the PPM file */
193 FILE *file
= fopen(filename
, "wb");
196 fprintf(file
, "P6\n%d %d\n255\n", extent
.width
, extent
.height
);
197 for (unsigned y
= 0; y
< extent
.height
; y
++) {
198 uint8_t row
[extent
.width
* 3];
199 for (unsigned x
= 0; x
< extent
.width
; x
++) {
200 row
[x
* 3 + 0] = map
[x
* 4 + 0];
201 row
[x
* 3 + 1] = map
[x
* 4 + 1];
202 row
[x
* 3 + 2] = map
[x
* 4 + 2];
204 fwrite(row
, 3, extent
.width
, file
);
206 map
+= layout
.rowPitch
;
210 anv_UnmapMemory(vk_device
, memory
);
211 anv_DestroyImage(vk_device
, copy_image
, NULL
);
212 anv_FreeMemory(vk_device
, memory
, NULL
);