• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2015 Intel Corporation
3  *
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:
10  *
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
13  * Software.
14  *
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
21  * IN THE SOFTWARE.
22  */
23 
24 #include <stdarg.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <errno.h>
29 #include <assert.h>
30 #include <sys/stat.h>
31 
32 #include "anv_private.h"
33 #include "vk_enum_to_str.h"
34 
35 void
__anv_perf_warn(struct anv_device * device,const struct vk_object_base * object,const char * file,int line,const char * format,...)36 __anv_perf_warn(struct anv_device *device,
37                 const struct vk_object_base *object,
38                 const char *file, int line, const char *format, ...)
39 {
40    va_list ap;
41    char buffer[256];
42 
43    va_start(ap, format);
44    vsnprintf(buffer, sizeof(buffer), format, ap);
45    va_end(ap);
46 
47    if (object) {
48       __vk_log(VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT,
49                VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT,
50                VK_LOG_OBJS(object), file, line,
51                "PERF: %s", buffer);
52    } else {
53       __vk_log(VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT,
54                VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT,
55                VK_LOG_NO_OBJS(device->physical->instance), file, line,
56                "PERF: %s", buffer);
57    }
58 }
59 
60 void
anv_cmd_buffer_pending_pipe_debug(struct anv_cmd_buffer * cmd_buffer,enum anv_pipe_bits bits,const char * reason)61 anv_cmd_buffer_pending_pipe_debug(struct anv_cmd_buffer *cmd_buffer,
62                                   enum anv_pipe_bits bits,
63                                   const char* reason)
64 {
65    if (bits == 0)
66       return;
67 
68    fprintf(stdout, "acc: ");
69 
70    fprintf(stdout, "bits: ");
71    anv_dump_pipe_bits(bits, stdout);
72    fprintf(stdout, "reason: %s", reason);
73 
74    if (cmd_buffer->batch.pc_reasons_count < ARRAY_SIZE(cmd_buffer->batch.pc_reasons))
75       cmd_buffer->batch.pc_reasons[cmd_buffer->batch.pc_reasons_count++] = reason;
76    fprintf(stdout, "\n");
77 }
78 
79 void
anv_dump_pipe_bits(enum anv_pipe_bits bits,FILE * f)80 anv_dump_pipe_bits(enum anv_pipe_bits bits, FILE *f)
81 {
82    if (bits & ANV_PIPE_DEPTH_CACHE_FLUSH_BIT)
83       fputs("+depth_flush ", f);
84    if (bits & ANV_PIPE_DATA_CACHE_FLUSH_BIT)
85       fputs("+dc_flush ", f);
86    if (bits & ANV_PIPE_HDC_PIPELINE_FLUSH_BIT)
87       fputs("+hdc_flush ", f);
88    if (bits & ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT)
89       fputs("+rt_flush ", f);
90    if (bits & ANV_PIPE_TILE_CACHE_FLUSH_BIT)
91       fputs("+tile_flush ", f);
92    if (bits & ANV_PIPE_L3_FABRIC_FLUSH_BIT)
93       fputs("+l3_fabric_flush ", f);
94    if (bits & ANV_PIPE_STATE_CACHE_INVALIDATE_BIT)
95       fputs("+state_inval ", f);
96    if (bits & ANV_PIPE_CONSTANT_CACHE_INVALIDATE_BIT)
97       fputs("+const_inval ", f);
98    if (bits & ANV_PIPE_VF_CACHE_INVALIDATE_BIT)
99       fputs("+vf_inval ", f);
100    if (bits & ANV_PIPE_TEXTURE_CACHE_INVALIDATE_BIT)
101       fputs("+tex_inval ", f);
102    if (bits & ANV_PIPE_INSTRUCTION_CACHE_INVALIDATE_BIT)
103       fputs("+ic_inval ", f);
104    if (bits & ANV_PIPE_STALL_AT_SCOREBOARD_BIT)
105       fputs("+pb_stall ", f);
106    if (bits & ANV_PIPE_PSS_STALL_SYNC_BIT)
107       fputs("+pss_stall ", f);
108    if (bits & ANV_PIPE_DEPTH_STALL_BIT)
109       fputs("+depth_stall ", f);
110    if (bits & ANV_PIPE_CS_STALL_BIT ||
111        bits & ANV_PIPE_END_OF_PIPE_SYNC_BIT)
112       fputs("+cs_stall ", f);
113    if (bits & ANV_PIPE_UNTYPED_DATAPORT_CACHE_FLUSH_BIT)
114       fputs("+utdp_flush ", f);
115    if (bits & ANV_PIPE_CCS_CACHE_FLUSH_BIT)
116       fputs("+ccs_flush ", f);
117 }
118 
119 const char *
anv_gfx_state_bit_to_str(enum anv_gfx_state_bits state)120 anv_gfx_state_bit_to_str(enum anv_gfx_state_bits state)
121 {
122 #define NAME(name) case ANV_GFX_STATE_##name: return #name;
123    switch (state) {
124       NAME(URB);
125       NAME(VF_STATISTICS);
126       NAME(VF_SGVS);
127       NAME(VF_SGVS_2);
128       NAME(VF_SGVS_INSTANCING);
129       NAME(PRIMITIVE_REPLICATION);
130       NAME(MULTISAMPLE);
131       NAME(SBE);
132       NAME(SBE_SWIZ);
133       NAME(SO_DECL_LIST);
134       NAME(VS);
135       NAME(HS);
136       NAME(DS);
137       NAME(GS);
138       NAME(PS);
139       NAME(PS_EXTRA);
140       NAME(SBE_MESH);
141       NAME(CLIP_MESH);
142       NAME(MESH_CONTROL);
143       NAME(MESH_SHADER);
144       NAME(MESH_DISTRIB);
145       NAME(TASK_CONTROL);
146       NAME(TASK_SHADER);
147       NAME(TASK_REDISTRIB);
148       NAME(BLEND_STATE_PTR);
149       NAME(CLIP);
150       NAME(CC_STATE);
151       NAME(CC_STATE_PTR);
152       NAME(CPS);
153       NAME(DEPTH_BOUNDS);
154       NAME(INDEX_BUFFER);
155       NAME(LINE_STIPPLE);
156       NAME(PS_BLEND);
157       NAME(RASTER);
158       NAME(SAMPLE_MASK);
159       NAME(SAMPLE_PATTERN);
160       NAME(SCISSOR);
161       NAME(SF);
162       NAME(STREAMOUT);
163       NAME(TE);
164       NAME(VERTEX_INPUT);
165       NAME(VF);
166       NAME(VF_TOPOLOGY);
167       NAME(VFG);
168       NAME(VIEWPORT_CC);
169       NAME(VIEWPORT_CC_PTR);
170       NAME(VIEWPORT_SF_CLIP);
171       NAME(WM);
172       NAME(WM_DEPTH_STENCIL);
173       NAME(PMA_FIX);
174       NAME(WA_18019816803);
175       NAME(TBIMR_TILE_PASS_INFO);
176    default: unreachable("invalid state");
177    }
178 }
179 
180 VkResult
anv_device_print_init(struct anv_device * device)181 anv_device_print_init(struct anv_device *device)
182 {
183    VkResult result =
184       anv_device_alloc_bo(device, "printf",
185                           anv_printf_buffer_size(),
186                           ANV_BO_ALLOC_CAPTURE |
187                           ANV_BO_ALLOC_MAPPED |
188                           ANV_BO_ALLOC_HOST_COHERENT |
189                           ANV_BO_ALLOC_NO_LOCAL_MEM,
190                           0 /* explicit_address */,
191                           &device->printf.bo);
192    if (result != VK_SUCCESS)
193       return result;
194 
195    util_dynarray_init(&device->printf.prints, ralloc_context(NULL));
196    simple_mtx_init(&device->printf.mutex, mtx_plain);
197 
198    *((uint32_t *)device->printf.bo->map) = 4;
199 
200    return VK_SUCCESS;
201 }
202 
203 void
anv_device_print_fini(struct anv_device * device)204 anv_device_print_fini(struct anv_device *device)
205 {
206    anv_device_release_bo(device, device->printf.bo);
207    util_dynarray_fini(&device->printf.prints);
208    simple_mtx_destroy(&device->printf.mutex);
209 }
210 
211 void
anv_device_print_shader_prints(struct anv_device * device)212 anv_device_print_shader_prints(struct anv_device *device)
213 {
214    simple_mtx_lock(&device->printf.mutex);
215 
216    uint32_t *size = device->printf.bo->map;
217 
218    u_printf_ptr(stdout,
219                 device->printf.bo->map + sizeof(uint32_t),
220                 *size - 4,
221                 util_dynarray_begin(&device->printf.prints),
222                 util_dynarray_num_elements(&device->printf.prints, u_printf_info*));
223 
224    /* Reset */
225    *size = 4;
226 
227    simple_mtx_unlock(&device->printf.mutex);
228 }
229 
230 
231 static void
create_directory(const char * dir,const char * sub_dir)232 create_directory(const char *dir, const char *sub_dir)
233 {
234    char full_path[PATH_MAX];
235    snprintf(full_path, sizeof(full_path), "%s/%s", dir, sub_dir);
236 
237    if (mkdir(dir, 0777) == -1 && errno != EEXIST) {
238       perror("Error creating directory");
239       return;
240    }
241 
242    if (mkdir(full_path, 0777) == -1 && errno != EEXIST) {
243       perror("Error creating sub directory");
244       return;
245    }
246 }
247 
248 static void
create_bvh_dump_file(struct anv_bvh_dump * bvh)249 create_bvh_dump_file(struct anv_bvh_dump *bvh)
250 {
251    if (bvh == NULL) {
252       fprintf(stderr, "Error: BVH DUMP structure is NULL\n");
253       return;
254    }
255 
256    char file_name[256];
257    const char *dump_directory = "bvh_dump";
258    const char *dump_sub_directory = NULL;
259 
260    switch (bvh->dump_type) {
261    case BVH_ANV:
262       dump_sub_directory = "BVH_ANV";
263       break;
264    case BVH_IR_HDR:
265       dump_sub_directory = "BVH_IR_HDR";
266       break;
267    case BVH_IR_AS:
268       dump_sub_directory = "BVH_IR_AS";
269       break;
270    default:
271       unreachable("invalid dump type");
272    }
273 
274    create_directory(dump_directory, dump_sub_directory);
275 
276    snprintf(file_name, sizeof(file_name),
277             bvh->geometry_type == VK_GEOMETRY_TYPE_INSTANCES_KHR
278                ? "%s/%s/tlas_%d.txt"
279                : "%s/%s/blas_%d.txt",
280             dump_directory, dump_sub_directory, bvh->bvh_id);
281 
282    FILE *file = fopen(file_name, "w");
283    if (file == NULL) {
284       perror("Error creating file");
285       return;
286    }
287 
288    fprintf(stderr, "BVH Dump File created: %s\n", file_name);
289 
290    uint8_t *addr = (uint8_t *)(bvh->bo->map);
291    /* Dump every bytes like this: B0 B1 B2 B3 ... B15 */
292    for (uint64_t i = 0; i < bvh->dump_size; i++) {
293       uint8_t result = *(volatile uint8_t *)((uint8_t *)addr + i);
294       fprintf(file, "%02" PRIx8 " ", result);
295       if ((i + 1) % 16 == 0) {
296          fprintf(file, "\n");
297       }
298    }
299 
300    fclose(file);
301 }
302 
anv_dump_bvh_to_files(struct anv_device * device)303 void anv_dump_bvh_to_files(struct anv_device *device)
304 {
305    /* device->mutex is acquired in anv_queue_submit, so no need to lock here. */
306    list_for_each_entry_safe(struct anv_bvh_dump, bvh_dump, &device->bvh_dumps,
307                             link) {
308       create_bvh_dump_file(bvh_dump);
309 
310       anv_device_release_bo(device, bvh_dump->bo);
311       list_del(&bvh_dump->link);
312       free(bvh_dump);
313    }
314 }
315