1 /* 2 * Copyright 2020 Valve 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 "radv_private.h" 25 #include "radv_shader.h" 26 27 #include "ac_rgp.h" 28 #include "ac_sqtt.h" 29 30 static void 31 radv_write_begin_general_api_marker(struct radv_cmd_buffer *cmd_buffer, 32 enum rgp_sqtt_marker_general_api_type api_type) 33 { 34 struct rgp_sqtt_marker_general_api marker = {0}; 35 struct radeon_cmdbuf *cs = cmd_buffer->cs; 36 37 marker.identifier = RGP_SQTT_MARKER_IDENTIFIER_GENERAL_API; 38 marker.api_type = api_type; 39 40 radv_emit_thread_trace_userdata(cmd_buffer->device, cs, &marker, sizeof(marker) / 4); 41 } 42 43 static void 44 radv_write_end_general_api_marker(struct radv_cmd_buffer *cmd_buffer, 45 enum rgp_sqtt_marker_general_api_type api_type) 46 { 47 struct rgp_sqtt_marker_general_api marker = {0}; 48 struct radeon_cmdbuf *cs = cmd_buffer->cs; 49 50 marker.identifier = RGP_SQTT_MARKER_IDENTIFIER_GENERAL_API; 51 marker.api_type = api_type; 52 marker.is_end = 1; 53 54 radv_emit_thread_trace_userdata(cmd_buffer->device, cs, &marker, sizeof(marker) / 4); 55 } 56 57 static void 58 radv_write_event_marker(struct radv_cmd_buffer *cmd_buffer, 59 enum rgp_sqtt_marker_event_type api_type, uint32_t vertex_offset_user_data, 60 uint32_t instance_offset_user_data, uint32_t draw_index_user_data) 61 { 62 struct rgp_sqtt_marker_event marker = {0}; 63 struct radeon_cmdbuf *cs = cmd_buffer->cs; 64 65 marker.identifier = RGP_SQTT_MARKER_IDENTIFIER_EVENT; 66 marker.api_type = api_type; 67 marker.cmd_id = cmd_buffer->state.num_events++; 68 marker.cb_id = 0; 69 70 if (vertex_offset_user_data == UINT_MAX || instance_offset_user_data == UINT_MAX) { 71 vertex_offset_user_data = 0; 72 instance_offset_user_data = 0; 73 } 74 75 if (draw_index_user_data == UINT_MAX) 76 draw_index_user_data = vertex_offset_user_data; 77 78 marker.vertex_offset_reg_idx = vertex_offset_user_data; 79 marker.instance_offset_reg_idx = instance_offset_user_data; 80 marker.draw_index_reg_idx = draw_index_user_data; 81 82 radv_emit_thread_trace_userdata(cmd_buffer->device, cs, &marker, sizeof(marker) / 4); 83 } 84 85 static void 86 radv_write_event_with_dims_marker(struct radv_cmd_buffer *cmd_buffer, 87 enum rgp_sqtt_marker_event_type api_type, uint32_t x, uint32_t y, 88 uint32_t z) 89 { 90 struct rgp_sqtt_marker_event_with_dims marker = {0}; 91 struct radeon_cmdbuf *cs = cmd_buffer->cs; 92 93 marker.event.identifier = RGP_SQTT_MARKER_IDENTIFIER_EVENT; 94 marker.event.api_type = api_type; 95 marker.event.cmd_id = cmd_buffer->state.num_events++; 96 marker.event.cb_id = 0; 97 marker.event.has_thread_dims = 1; 98 99 marker.thread_x = x; 100 marker.thread_y = y; 101 marker.thread_z = z; 102 103 radv_emit_thread_trace_userdata(cmd_buffer->device, cs, &marker, sizeof(marker) / 4); 104 } 105 106 static void 107 radv_write_user_event_marker(struct radv_cmd_buffer *cmd_buffer, 108 enum rgp_sqtt_marker_user_event_type type, const char *str) 109 { 110 struct radeon_cmdbuf *cs = cmd_buffer->cs; 111 112 if (type == UserEventPop) { 113 assert(str == NULL); 114 struct rgp_sqtt_marker_user_event marker = {0}; 115 marker.identifier = RGP_SQTT_MARKER_IDENTIFIER_USER_EVENT; 116 marker.data_type = type; 117 118 radv_emit_thread_trace_userdata(cmd_buffer->device, cs, &marker, sizeof(marker) / 4); 119 } else { 120 assert(str != NULL); 121 unsigned len = strlen(str); 122 struct rgp_sqtt_marker_user_event_with_length marker = {0}; 123 marker.user_event.identifier = RGP_SQTT_MARKER_IDENTIFIER_USER_EVENT; 124 marker.user_event.data_type = type; 125 marker.length = align(len, 4); 126 127 uint8_t *buffer = alloca(sizeof(marker) + marker.length); 128 memset(buffer, 0, sizeof(marker) + marker.length); 129 memcpy(buffer, &marker, sizeof(marker)); 130 memcpy(buffer + sizeof(marker), str, len); 131 132 radv_emit_thread_trace_userdata(cmd_buffer->device, cs, buffer, 133 sizeof(marker) / 4 + marker.length / 4); 134 } 135 } 136 137 void 138 radv_describe_begin_cmd_buffer(struct radv_cmd_buffer *cmd_buffer) 139 { 140 uint64_t device_id = (uintptr_t)cmd_buffer->device; 141 struct rgp_sqtt_marker_cb_start marker = {0}; 142 struct radeon_cmdbuf *cs = cmd_buffer->cs; 143 144 if (likely(!cmd_buffer->device->thread_trace.bo)) 145 return; 146 147 marker.identifier = RGP_SQTT_MARKER_IDENTIFIER_CB_START; 148 marker.cb_id = 0; 149 marker.device_id_low = device_id; 150 marker.device_id_high = device_id >> 32; 151 marker.queue = cmd_buffer->queue_family_index; 152 marker.queue_flags = VK_QUEUE_COMPUTE_BIT | VK_QUEUE_TRANSFER_BIT | VK_QUEUE_SPARSE_BINDING_BIT; 153 154 if (cmd_buffer->queue_family_index == RADV_QUEUE_GENERAL) 155 marker.queue_flags |= VK_QUEUE_GRAPHICS_BIT; 156 157 radv_emit_thread_trace_userdata(cmd_buffer->device, cs, &marker, sizeof(marker) / 4); 158 } 159 160 void 161 radv_describe_end_cmd_buffer(struct radv_cmd_buffer *cmd_buffer) 162 { 163 uint64_t device_id = (uintptr_t)cmd_buffer->device; 164 struct rgp_sqtt_marker_cb_end marker = {0}; 165 struct radeon_cmdbuf *cs = cmd_buffer->cs; 166 167 if (likely(!cmd_buffer->device->thread_trace.bo)) 168 return; 169 170 marker.identifier = RGP_SQTT_MARKER_IDENTIFIER_CB_END; 171 marker.cb_id = 0; 172 marker.device_id_low = device_id; 173 marker.device_id_high = device_id >> 32; 174 175 radv_emit_thread_trace_userdata(cmd_buffer->device, cs, &marker, sizeof(marker) / 4); 176 } 177 178 void 179 radv_describe_draw(struct radv_cmd_buffer *cmd_buffer) 180 { 181 if (likely(!cmd_buffer->device->thread_trace.bo)) 182 return; 183 184 radv_write_event_marker(cmd_buffer, cmd_buffer->state.current_event_type, UINT_MAX, UINT_MAX, 185 UINT_MAX); 186 } 187 188 void 189 radv_describe_dispatch(struct radv_cmd_buffer *cmd_buffer, int x, int y, int z) 190 { 191 if (likely(!cmd_buffer->device->thread_trace.bo)) 192 return; 193 194 radv_write_event_with_dims_marker(cmd_buffer, cmd_buffer->state.current_event_type, x, y, z); 195 } 196 197 void 198 radv_describe_begin_render_pass_clear(struct radv_cmd_buffer *cmd_buffer, 199 VkImageAspectFlagBits aspects) 200 { 201 cmd_buffer->state.current_event_type = (aspects & VK_IMAGE_ASPECT_COLOR_BIT) 202 ? EventRenderPassColorClear 203 : EventRenderPassDepthStencilClear; 204 } 205 206 void 207 radv_describe_end_render_pass_clear(struct radv_cmd_buffer *cmd_buffer) 208 { 209 cmd_buffer->state.current_event_type = EventInternalUnknown; 210 } 211 212 void 213 radv_describe_begin_render_pass_resolve(struct radv_cmd_buffer *cmd_buffer) 214 { 215 cmd_buffer->state.current_event_type = EventRenderPassResolve; 216 } 217 218 void 219 radv_describe_end_render_pass_resolve(struct radv_cmd_buffer *cmd_buffer) 220 { 221 cmd_buffer->state.current_event_type = EventInternalUnknown; 222 } 223 224 void 225 radv_describe_barrier_end_delayed(struct radv_cmd_buffer *cmd_buffer) 226 { 227 struct rgp_sqtt_marker_barrier_end marker = {0}; 228 struct radeon_cmdbuf *cs = cmd_buffer->cs; 229 230 if (likely(!cmd_buffer->device->thread_trace.bo) || !cmd_buffer->state.pending_sqtt_barrier_end) 231 return; 232 233 cmd_buffer->state.pending_sqtt_barrier_end = false; 234 235 marker.identifier = RGP_SQTT_MARKER_IDENTIFIER_BARRIER_END; 236 marker.cb_id = 0; 237 238 marker.num_layout_transitions = cmd_buffer->state.num_layout_transitions; 239 240 if (cmd_buffer->state.sqtt_flush_bits & RGP_FLUSH_WAIT_ON_EOP_TS) 241 marker.wait_on_eop_ts = true; 242 if (cmd_buffer->state.sqtt_flush_bits & RGP_FLUSH_VS_PARTIAL_FLUSH) 243 marker.vs_partial_flush = true; 244 if (cmd_buffer->state.sqtt_flush_bits & RGP_FLUSH_PS_PARTIAL_FLUSH) 245 marker.ps_partial_flush = true; 246 if (cmd_buffer->state.sqtt_flush_bits & RGP_FLUSH_CS_PARTIAL_FLUSH) 247 marker.cs_partial_flush = true; 248 if (cmd_buffer->state.sqtt_flush_bits & RGP_FLUSH_PFP_SYNC_ME) 249 marker.pfp_sync_me = true; 250 if (cmd_buffer->state.sqtt_flush_bits & RGP_FLUSH_SYNC_CP_DMA) 251 marker.sync_cp_dma = true; 252 if (cmd_buffer->state.sqtt_flush_bits & RGP_FLUSH_INVAL_VMEM_L0) 253 marker.inval_tcp = true; 254 if (cmd_buffer->state.sqtt_flush_bits & RGP_FLUSH_INVAL_ICACHE) 255 marker.inval_sqI = true; 256 if (cmd_buffer->state.sqtt_flush_bits & RGP_FLUSH_INVAL_SMEM_L0) 257 marker.inval_sqK = true; 258 if (cmd_buffer->state.sqtt_flush_bits & RGP_FLUSH_FLUSH_L2) 259 marker.flush_tcc = true; 260 if (cmd_buffer->state.sqtt_flush_bits & RGP_FLUSH_INVAL_L2) 261 marker.inval_tcc = true; 262 if (cmd_buffer->state.sqtt_flush_bits & RGP_FLUSH_FLUSH_CB) 263 marker.flush_cb = true; 264 if (cmd_buffer->state.sqtt_flush_bits & RGP_FLUSH_INVAL_CB) 265 marker.inval_cb = true; 266 if (cmd_buffer->state.sqtt_flush_bits & RGP_FLUSH_FLUSH_DB) 267 marker.flush_db = true; 268 if (cmd_buffer->state.sqtt_flush_bits & RGP_FLUSH_INVAL_DB) 269 marker.inval_db = true; 270 if (cmd_buffer->state.sqtt_flush_bits & RGP_FLUSH_INVAL_L1) 271 marker.inval_gl1 = true; 272 273 radv_emit_thread_trace_userdata(cmd_buffer->device, cs, &marker, sizeof(marker) / 4); 274 275 cmd_buffer->state.num_layout_transitions = 0; 276 } 277 278 void 279 radv_describe_barrier_start(struct radv_cmd_buffer *cmd_buffer, enum rgp_barrier_reason reason) 280 { 281 struct rgp_sqtt_marker_barrier_start marker = {0}; 282 struct radeon_cmdbuf *cs = cmd_buffer->cs; 283 284 if (likely(!cmd_buffer->device->thread_trace.bo)) 285 return; 286 287 radv_describe_barrier_end_delayed(cmd_buffer); 288 cmd_buffer->state.sqtt_flush_bits = 0; 289 290 marker.identifier = RGP_SQTT_MARKER_IDENTIFIER_BARRIER_START; 291 marker.cb_id = 0; 292 marker.dword02 = reason; 293 294 radv_emit_thread_trace_userdata(cmd_buffer->device, cs, &marker, sizeof(marker) / 4); 295 } 296 297 void 298 radv_describe_barrier_end(struct radv_cmd_buffer *cmd_buffer) 299 { 300 cmd_buffer->state.pending_sqtt_barrier_end = true; 301 } 302 303 void 304 radv_describe_layout_transition(struct radv_cmd_buffer *cmd_buffer, 305 const struct radv_barrier_data *barrier) 306 { 307 struct rgp_sqtt_marker_layout_transition marker = {0}; 308 struct radeon_cmdbuf *cs = cmd_buffer->cs; 309 310 if (likely(!cmd_buffer->device->thread_trace.bo)) 311 return; 312 313 marker.identifier = RGP_SQTT_MARKER_IDENTIFIER_LAYOUT_TRANSITION; 314 marker.depth_stencil_expand = barrier->layout_transitions.depth_stencil_expand; 315 marker.htile_hiz_range_expand = barrier->layout_transitions.htile_hiz_range_expand; 316 marker.depth_stencil_resummarize = barrier->layout_transitions.depth_stencil_resummarize; 317 marker.dcc_decompress = barrier->layout_transitions.dcc_decompress; 318 marker.fmask_decompress = barrier->layout_transitions.fmask_decompress; 319 marker.fast_clear_eliminate = barrier->layout_transitions.fast_clear_eliminate; 320 marker.fmask_color_expand = barrier->layout_transitions.fmask_color_expand; 321 marker.init_mask_ram = barrier->layout_transitions.init_mask_ram; 322 323 radv_emit_thread_trace_userdata(cmd_buffer->device, cs, &marker, sizeof(marker) / 4); 324 325 cmd_buffer->state.num_layout_transitions++; 326 } 327 328 static void 329 radv_describe_pipeline_bind(struct radv_cmd_buffer *cmd_buffer, 330 VkPipelineBindPoint pipelineBindPoint, struct radv_pipeline *pipeline) 331 { 332 struct rgp_sqtt_marker_pipeline_bind marker = {0}; 333 struct radeon_cmdbuf *cs = cmd_buffer->cs; 334 335 if (likely(!cmd_buffer->device->thread_trace.bo)) 336 return; 337 338 marker.identifier = RGP_SQTT_MARKER_IDENTIFIER_BIND_PIPELINE; 339 marker.cb_id = 0; 340 marker.bind_point = pipelineBindPoint; 341 marker.api_pso_hash[0] = pipeline->pipeline_hash; 342 marker.api_pso_hash[1] = pipeline->pipeline_hash >> 32; 343 344 radv_emit_thread_trace_userdata(cmd_buffer->device, cs, &marker, sizeof(marker) / 4); 345 } 346 347 /* TODO: Improve the way to trigger capture (overlay, etc). */ 348 static void 349 radv_handle_thread_trace(VkQueue _queue) 350 { 351 RADV_FROM_HANDLE(radv_queue, queue, _queue); 352 static bool thread_trace_enabled = false; 353 static uint64_t num_frames = 0; 354 bool resize_trigger = false; 355 356 if (thread_trace_enabled) { 357 struct ac_thread_trace thread_trace = {0}; 358 359 radv_end_thread_trace(queue); 360 thread_trace_enabled = false; 361 362 /* TODO: Do something better than this whole sync. */ 363 radv_QueueWaitIdle(_queue); 364 365 if (radv_get_thread_trace(queue, &thread_trace)) { 366 ac_dump_rgp_capture(&queue->device->physical_device->rad_info, &thread_trace); 367 } else { 368 /* Trigger a new capture if the driver failed to get 369 * the trace because the buffer was too small. 370 */ 371 resize_trigger = true; 372 } 373 } 374 375 if (!thread_trace_enabled) { 376 bool frame_trigger = num_frames == queue->device->thread_trace.start_frame; 377 bool file_trigger = false; 378 #ifndef _WIN32 379 if (queue->device->thread_trace.trigger_file && 380 access(queue->device->thread_trace.trigger_file, W_OK) == 0) { 381 if (unlink(queue->device->thread_trace.trigger_file) == 0) { 382 file_trigger = true; 383 } else { 384 /* Do not enable tracing if we cannot remove the file, 385 * because by then we'll trace every frame ... */ 386 fprintf(stderr, "RADV: could not remove thread trace trigger file, ignoring\n"); 387 } 388 } 389 #endif 390 391 if (frame_trigger || file_trigger || resize_trigger) { 392 radv_begin_thread_trace(queue); 393 assert(!thread_trace_enabled); 394 thread_trace_enabled = true; 395 } 396 } 397 num_frames++; 398 } 399 400 VkResult 401 sqtt_QueuePresentKHR(VkQueue _queue, const VkPresentInfoKHR *pPresentInfo) 402 { 403 VkResult result; 404 405 result = radv_QueuePresentKHR(_queue, pPresentInfo); 406 if (result != VK_SUCCESS) 407 return result; 408 409 radv_handle_thread_trace(_queue); 410 411 return VK_SUCCESS; 412 } 413 414 #define EVENT_MARKER_ALIAS(cmd_name, api_name, ...) \ 415 RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer); \ 416 radv_write_begin_general_api_marker(cmd_buffer, ApiCmd##api_name); \ 417 cmd_buffer->state.current_event_type = EventCmd##api_name; \ 418 radv_Cmd##cmd_name(__VA_ARGS__); \ 419 cmd_buffer->state.current_event_type = EventInternalUnknown; \ 420 radv_write_end_general_api_marker(cmd_buffer, ApiCmd##api_name); 421 422 #define EVENT_MARKER(cmd_name, ...) EVENT_MARKER_ALIAS(cmd_name, cmd_name, __VA_ARGS__); 423 424 void 425 sqtt_CmdDraw(VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t instanceCount, 426 uint32_t firstVertex, uint32_t firstInstance) 427 { 428 EVENT_MARKER(Draw, commandBuffer, vertexCount, instanceCount, firstVertex, firstInstance); 429 } 430 431 void 432 sqtt_CmdDrawIndexed(VkCommandBuffer commandBuffer, uint32_t indexCount, uint32_t instanceCount, 433 uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance) 434 { 435 EVENT_MARKER(DrawIndexed, commandBuffer, indexCount, instanceCount, firstIndex, vertexOffset, 436 firstInstance); 437 } 438 439 void 440 sqtt_CmdDrawIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, 441 uint32_t drawCount, uint32_t stride) 442 { 443 EVENT_MARKER(DrawIndirect, commandBuffer, buffer, offset, drawCount, stride); 444 } 445 446 void 447 sqtt_CmdDrawIndexedIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, 448 uint32_t drawCount, uint32_t stride) 449 { 450 EVENT_MARKER(DrawIndexedIndirect, commandBuffer, buffer, offset, drawCount, stride); 451 } 452 453 void 454 sqtt_CmdDrawIndirectCount(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, 455 VkBuffer countBuffer, VkDeviceSize countBufferOffset, 456 uint32_t maxDrawCount, uint32_t stride) 457 { 458 EVENT_MARKER(DrawIndirectCount, commandBuffer, buffer, offset, countBuffer, countBufferOffset, 459 maxDrawCount, stride); 460 } 461 462 void 463 sqtt_CmdDrawIndexedIndirectCount(VkCommandBuffer commandBuffer, VkBuffer buffer, 464 VkDeviceSize offset, VkBuffer countBuffer, 465 VkDeviceSize countBufferOffset, uint32_t maxDrawCount, 466 uint32_t stride) 467 { 468 EVENT_MARKER(DrawIndexedIndirectCount, commandBuffer, buffer, offset, countBuffer, 469 countBufferOffset, maxDrawCount, stride); 470 } 471 472 void 473 sqtt_CmdDispatch(VkCommandBuffer commandBuffer, uint32_t x, uint32_t y, uint32_t z) 474 { 475 EVENT_MARKER(Dispatch, commandBuffer, x, y, z); 476 } 477 478 void 479 sqtt_CmdDispatchIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset) 480 { 481 EVENT_MARKER(DispatchIndirect, commandBuffer, buffer, offset); 482 } 483 484 void 485 sqtt_CmdCopyBuffer2KHR(VkCommandBuffer commandBuffer, const VkCopyBufferInfo2KHR *pCopyBufferInfo) 486 { 487 EVENT_MARKER_ALIAS(CopyBuffer2KHR, CopyBuffer, commandBuffer, pCopyBufferInfo); 488 } 489 490 void 491 sqtt_CmdFillBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, 492 VkDeviceSize fillSize, uint32_t data) 493 { 494 EVENT_MARKER(FillBuffer, commandBuffer, dstBuffer, dstOffset, fillSize, data); 495 } 496 497 void 498 sqtt_CmdUpdateBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, 499 VkDeviceSize dataSize, const void *pData) 500 { 501 EVENT_MARKER(UpdateBuffer, commandBuffer, dstBuffer, dstOffset, dataSize, pData); 502 } 503 504 void 505 sqtt_CmdCopyImage2KHR(VkCommandBuffer commandBuffer, const VkCopyImageInfo2KHR *pCopyImageInfo) 506 { 507 EVENT_MARKER_ALIAS(CopyImage2KHR, CopyImage, commandBuffer, pCopyImageInfo); 508 } 509 510 void 511 sqtt_CmdCopyBufferToImage2KHR(VkCommandBuffer commandBuffer, 512 const VkCopyBufferToImageInfo2KHR *pCopyBufferToImageInfo) 513 { 514 EVENT_MARKER_ALIAS(CopyBufferToImage2KHR, CopyBufferToImage, commandBuffer, 515 pCopyBufferToImageInfo); 516 } 517 518 void 519 sqtt_CmdCopyImageToBuffer2KHR(VkCommandBuffer commandBuffer, 520 const VkCopyImageToBufferInfo2KHR *pCopyImageToBufferInfo) 521 { 522 EVENT_MARKER_ALIAS(CopyImageToBuffer2KHR, CopyImageToBuffer, commandBuffer, 523 pCopyImageToBufferInfo); 524 } 525 526 void 527 sqtt_CmdBlitImage2KHR(VkCommandBuffer commandBuffer, const VkBlitImageInfo2KHR *pBlitImageInfo) 528 { 529 EVENT_MARKER_ALIAS(BlitImage2KHR, BlitImage, commandBuffer, pBlitImageInfo); 530 } 531 532 void 533 sqtt_CmdClearColorImage(VkCommandBuffer commandBuffer, VkImage image_h, VkImageLayout imageLayout, 534 const VkClearColorValue *pColor, uint32_t rangeCount, 535 const VkImageSubresourceRange *pRanges) 536 { 537 EVENT_MARKER(ClearColorImage, commandBuffer, image_h, imageLayout, pColor, rangeCount, pRanges); 538 } 539 540 void 541 sqtt_CmdClearDepthStencilImage(VkCommandBuffer commandBuffer, VkImage image_h, 542 VkImageLayout imageLayout, 543 const VkClearDepthStencilValue *pDepthStencil, uint32_t rangeCount, 544 const VkImageSubresourceRange *pRanges) 545 { 546 EVENT_MARKER(ClearDepthStencilImage, commandBuffer, image_h, imageLayout, pDepthStencil, 547 rangeCount, pRanges); 548 } 549 550 void 551 sqtt_CmdClearAttachments(VkCommandBuffer commandBuffer, uint32_t attachmentCount, 552 const VkClearAttachment *pAttachments, uint32_t rectCount, 553 const VkClearRect *pRects) 554 { 555 EVENT_MARKER(ClearAttachments, commandBuffer, attachmentCount, pAttachments, rectCount, pRects); 556 } 557 558 void 559 sqtt_CmdResolveImage2KHR(VkCommandBuffer commandBuffer, 560 const VkResolveImageInfo2KHR *pResolveImageInfo) 561 { 562 EVENT_MARKER_ALIAS(ResolveImage2KHR, ResolveImage, commandBuffer, pResolveImageInfo); 563 } 564 565 void 566 sqtt_CmdWaitEvents(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent *pEvents, 567 VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, 568 uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers, 569 uint32_t bufferMemoryBarrierCount, 570 const VkBufferMemoryBarrier *pBufferMemoryBarriers, 571 uint32_t imageMemoryBarrierCount, 572 const VkImageMemoryBarrier *pImageMemoryBarriers) 573 { 574 EVENT_MARKER(WaitEvents, commandBuffer, eventCount, pEvents, srcStageMask, dstStageMask, 575 memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount, 576 pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers); 577 } 578 579 void 580 sqtt_CmdPipelineBarrier(VkCommandBuffer commandBuffer, VkPipelineStageFlags srcStageMask, 581 VkPipelineStageFlags destStageMask, VkBool32 byRegion, 582 uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers, 583 uint32_t bufferMemoryBarrierCount, 584 const VkBufferMemoryBarrier *pBufferMemoryBarriers, 585 uint32_t imageMemoryBarrierCount, 586 const VkImageMemoryBarrier *pImageMemoryBarriers) 587 { 588 EVENT_MARKER(PipelineBarrier, commandBuffer, srcStageMask, destStageMask, byRegion, 589 memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount, 590 pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers); 591 } 592 593 void 594 sqtt_CmdResetQueryPool(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t firstQuery, 595 uint32_t queryCount) 596 { 597 EVENT_MARKER(ResetQueryPool, commandBuffer, queryPool, firstQuery, queryCount); 598 } 599 600 void 601 sqtt_CmdCopyQueryPoolResults(VkCommandBuffer commandBuffer, VkQueryPool queryPool, 602 uint32_t firstQuery, uint32_t queryCount, VkBuffer dstBuffer, 603 VkDeviceSize dstOffset, VkDeviceSize stride, VkQueryResultFlags flags) 604 { 605 EVENT_MARKER(CopyQueryPoolResults, commandBuffer, queryPool, firstQuery, queryCount, dstBuffer, 606 dstOffset, stride, flags); 607 } 608 609 #undef EVENT_MARKER 610 #define API_MARKER_ALIAS(cmd_name, api_name, ...) \ 611 RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer); \ 612 radv_write_begin_general_api_marker(cmd_buffer, ApiCmd##api_name); \ 613 radv_Cmd##cmd_name(__VA_ARGS__); \ 614 radv_write_end_general_api_marker(cmd_buffer, ApiCmd##api_name); 615 616 #define API_MARKER(cmd_name, ...) API_MARKER_ALIAS(cmd_name, cmd_name, __VA_ARGS__); 617 618 void 619 sqtt_CmdBindPipeline(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, 620 VkPipeline _pipeline) 621 { 622 RADV_FROM_HANDLE(radv_pipeline, pipeline, _pipeline); 623 624 API_MARKER(BindPipeline, commandBuffer, pipelineBindPoint, _pipeline); 625 626 if (radv_is_instruction_timing_enabled()) 627 radv_describe_pipeline_bind(cmd_buffer, pipelineBindPoint, pipeline); 628 } 629 630 void 631 sqtt_CmdBindDescriptorSets(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, 632 VkPipelineLayout layout, uint32_t firstSet, uint32_t descriptorSetCount, 633 const VkDescriptorSet *pDescriptorSets, uint32_t dynamicOffsetCount, 634 const uint32_t *pDynamicOffsets) 635 { 636 API_MARKER(BindDescriptorSets, commandBuffer, pipelineBindPoint, layout, firstSet, 637 descriptorSetCount, pDescriptorSets, dynamicOffsetCount, pDynamicOffsets); 638 } 639 640 void 641 sqtt_CmdBindIndexBuffer(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, 642 VkIndexType indexType) 643 { 644 API_MARKER(BindIndexBuffer, commandBuffer, buffer, offset, indexType); 645 } 646 647 void 648 sqtt_CmdBindVertexBuffers(VkCommandBuffer commandBuffer, uint32_t firstBinding, 649 uint32_t bindingCount, const VkBuffer *pBuffers, 650 const VkDeviceSize *pOffsets) 651 { 652 API_MARKER(BindVertexBuffers, commandBuffer, firstBinding, bindingCount, pBuffers, pOffsets); 653 } 654 655 void 656 sqtt_CmdBeginQuery(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t query, 657 VkQueryControlFlags flags) 658 { 659 API_MARKER(BeginQuery, commandBuffer, queryPool, query, flags); 660 } 661 662 void 663 sqtt_CmdEndQuery(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t query) 664 { 665 API_MARKER(EndQuery, commandBuffer, queryPool, query); 666 } 667 668 void 669 sqtt_CmdWriteTimestamp(VkCommandBuffer commandBuffer, VkPipelineStageFlagBits pipelineStage, 670 VkQueryPool queryPool, uint32_t flags) 671 { 672 API_MARKER(WriteTimestamp, commandBuffer, pipelineStage, queryPool, flags); 673 } 674 675 void 676 sqtt_CmdPushConstants(VkCommandBuffer commandBuffer, VkPipelineLayout layout, 677 VkShaderStageFlags stageFlags, uint32_t offset, uint32_t size, 678 const void *pValues) 679 { 680 API_MARKER(PushConstants, commandBuffer, layout, stageFlags, offset, size, pValues); 681 } 682 683 void 684 sqtt_CmdBeginRenderPass2(VkCommandBuffer commandBuffer, 685 const VkRenderPassBeginInfo *pRenderPassBeginInfo, 686 const VkSubpassBeginInfo *pSubpassBeginInfo) 687 { 688 API_MARKER_ALIAS(BeginRenderPass2, BeginRenderPass, commandBuffer, pRenderPassBeginInfo, 689 pSubpassBeginInfo); 690 } 691 692 void 693 sqtt_CmdNextSubpass2(VkCommandBuffer commandBuffer, const VkSubpassBeginInfo *pSubpassBeginInfo, 694 const VkSubpassEndInfo *pSubpassEndInfo) 695 { 696 API_MARKER_ALIAS(NextSubpass2, NextSubpass, commandBuffer, pSubpassBeginInfo, pSubpassEndInfo); 697 } 698 699 void 700 sqtt_CmdEndRenderPass2(VkCommandBuffer commandBuffer, const VkSubpassEndInfo *pSubpassEndInfo) 701 { 702 API_MARKER_ALIAS(EndRenderPass2, EndRenderPass, commandBuffer, pSubpassEndInfo); 703 } 704 705 void 706 sqtt_CmdExecuteCommands(VkCommandBuffer commandBuffer, uint32_t commandBufferCount, 707 const VkCommandBuffer *pCmdBuffers) 708 { 709 API_MARKER(ExecuteCommands, commandBuffer, commandBufferCount, pCmdBuffers); 710 } 711 712 void 713 sqtt_CmdSetViewport(VkCommandBuffer commandBuffer, uint32_t firstViewport, uint32_t viewportCount, 714 const VkViewport *pViewports) 715 { 716 API_MARKER(SetViewport, commandBuffer, firstViewport, viewportCount, pViewports); 717 } 718 719 void 720 sqtt_CmdSetScissor(VkCommandBuffer commandBuffer, uint32_t firstScissor, uint32_t scissorCount, 721 const VkRect2D *pScissors) 722 { 723 API_MARKER(SetScissor, commandBuffer, firstScissor, scissorCount, pScissors); 724 } 725 726 void 727 sqtt_CmdSetLineWidth(VkCommandBuffer commandBuffer, float lineWidth) 728 { 729 API_MARKER(SetLineWidth, commandBuffer, lineWidth); 730 } 731 732 void 733 sqtt_CmdSetDepthBias(VkCommandBuffer commandBuffer, float depthBiasConstantFactor, 734 float depthBiasClamp, float depthBiasSlopeFactor) 735 { 736 API_MARKER(SetDepthBias, commandBuffer, depthBiasConstantFactor, depthBiasClamp, 737 depthBiasSlopeFactor); 738 } 739 740 void 741 sqtt_CmdSetBlendConstants(VkCommandBuffer commandBuffer, const float blendConstants[4]) 742 { 743 API_MARKER(SetBlendConstants, commandBuffer, blendConstants); 744 } 745 746 void 747 sqtt_CmdSetDepthBounds(VkCommandBuffer commandBuffer, float minDepthBounds, float maxDepthBounds) 748 { 749 API_MARKER(SetDepthBounds, commandBuffer, minDepthBounds, maxDepthBounds); 750 } 751 752 void 753 sqtt_CmdSetStencilCompareMask(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, 754 uint32_t compareMask) 755 { 756 API_MARKER(SetStencilCompareMask, commandBuffer, faceMask, compareMask); 757 } 758 759 void 760 sqtt_CmdSetStencilWriteMask(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, 761 uint32_t writeMask) 762 { 763 API_MARKER(SetStencilWriteMask, commandBuffer, faceMask, writeMask); 764 } 765 766 void 767 sqtt_CmdSetStencilReference(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, 768 uint32_t reference) 769 { 770 API_MARKER(SetStencilReference, commandBuffer, faceMask, reference); 771 } 772 773 /* VK_EXT_debug_marker */ 774 void 775 sqtt_CmdDebugMarkerBeginEXT(VkCommandBuffer commandBuffer, 776 const VkDebugMarkerMarkerInfoEXT *pMarkerInfo) 777 { 778 RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer); 779 radv_write_user_event_marker(cmd_buffer, UserEventPush, pMarkerInfo->pMarkerName); 780 } 781 782 void 783 sqtt_CmdDebugMarkerEndEXT(VkCommandBuffer commandBuffer) 784 { 785 RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer); 786 radv_write_user_event_marker(cmd_buffer, UserEventPop, NULL); 787 } 788 789 void 790 sqtt_CmdDebugMarkerInsertEXT(VkCommandBuffer commandBuffer, 791 const VkDebugMarkerMarkerInfoEXT *pMarkerInfo) 792 { 793 RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer); 794 radv_write_user_event_marker(cmd_buffer, UserEventTrigger, pMarkerInfo->pMarkerName); 795 } 796 797 VkResult 798 sqtt_DebugMarkerSetObjectNameEXT(VkDevice device, const VkDebugMarkerObjectNameInfoEXT *pNameInfo) 799 { 800 /* no-op */ 801 return VK_SUCCESS; 802 } 803 804 VkResult 805 sqtt_DebugMarkerSetObjectTagEXT(VkDevice device, const VkDebugMarkerObjectTagInfoEXT *pTagInfo) 806 { 807 /* no-op */ 808 return VK_SUCCESS; 809 } 810 811 /* Pipelines */ 812 static enum rgp_hardware_stages 813 radv_mesa_to_rgp_shader_stage(struct radv_pipeline *pipeline, gl_shader_stage stage) 814 { 815 struct radv_shader_variant *shader = pipeline->shaders[stage]; 816 817 switch (stage) { 818 case MESA_SHADER_VERTEX: 819 if (shader->info.vs.as_ls) 820 return RGP_HW_STAGE_LS; 821 else if (shader->info.vs.as_es) 822 return RGP_HW_STAGE_ES; 823 else if (shader->info.is_ngg) 824 return RGP_HW_STAGE_GS; 825 else 826 return RGP_HW_STAGE_VS; 827 case MESA_SHADER_TESS_CTRL: 828 return RGP_HW_STAGE_HS; 829 case MESA_SHADER_TESS_EVAL: 830 if (shader->info.tes.as_es) 831 return RGP_HW_STAGE_ES; 832 else if (shader->info.is_ngg) 833 return RGP_HW_STAGE_GS; 834 else 835 return RGP_HW_STAGE_VS; 836 case MESA_SHADER_GEOMETRY: 837 return RGP_HW_STAGE_GS; 838 case MESA_SHADER_FRAGMENT: 839 return RGP_HW_STAGE_PS; 840 case MESA_SHADER_COMPUTE: 841 return RGP_HW_STAGE_CS; 842 default: 843 unreachable("invalid mesa shader stage"); 844 } 845 } 846 847 static VkResult 848 radv_add_code_object(struct radv_device *device, struct radv_pipeline *pipeline) 849 { 850 struct ac_thread_trace_data *thread_trace_data = &device->thread_trace; 851 struct rgp_code_object *code_object = &thread_trace_data->rgp_code_object; 852 struct rgp_code_object_record *record; 853 854 record = malloc(sizeof(struct rgp_code_object_record)); 855 if (!record) 856 return VK_ERROR_OUT_OF_HOST_MEMORY; 857 858 record->shader_stages_mask = 0; 859 record->num_shaders_combined = 0; 860 record->pipeline_hash[0] = pipeline->pipeline_hash; 861 record->pipeline_hash[1] = pipeline->pipeline_hash; 862 863 for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { 864 struct radv_shader_variant *shader = pipeline->shaders[i]; 865 uint8_t *code; 866 uint64_t va; 867 868 if (!shader) 869 continue; 870 871 code = malloc(shader->code_size); 872 if (!code) { 873 free(record); 874 return VK_ERROR_OUT_OF_HOST_MEMORY; 875 } 876 memcpy(code, shader->code_ptr, shader->code_size); 877 878 va = radv_shader_variant_get_va(shader); 879 880 record->shader_data[i].hash[0] = (uint64_t)(uintptr_t)shader; 881 record->shader_data[i].hash[1] = (uint64_t)(uintptr_t)shader >> 32; 882 record->shader_data[i].code_size = shader->code_size; 883 record->shader_data[i].code = code; 884 record->shader_data[i].vgpr_count = shader->config.num_vgprs; 885 record->shader_data[i].sgpr_count = shader->config.num_sgprs; 886 record->shader_data[i].scratch_memory_size = shader->config.scratch_bytes_per_wave; 887 record->shader_data[i].wavefront_size = shader->info.wave_size; 888 record->shader_data[i].base_address = va & 0xffffffffffff; 889 record->shader_data[i].elf_symbol_offset = 0; 890 record->shader_data[i].hw_stage = radv_mesa_to_rgp_shader_stage(pipeline, i); 891 record->shader_data[i].is_combined = false; 892 893 record->shader_stages_mask |= (1 << i); 894 record->num_shaders_combined++; 895 } 896 897 simple_mtx_lock(&code_object->lock); 898 list_addtail(&record->list, &code_object->record); 899 code_object->record_count++; 900 simple_mtx_unlock(&code_object->lock); 901 902 return VK_SUCCESS; 903 } 904 905 static VkResult 906 radv_register_pipeline(struct radv_device *device, struct radv_pipeline *pipeline) 907 { 908 bool result; 909 uint64_t base_va = ~0; 910 911 result = ac_sqtt_add_pso_correlation(&device->thread_trace, pipeline->pipeline_hash); 912 if (!result) 913 return VK_ERROR_OUT_OF_HOST_MEMORY; 914 915 /* Find the lowest shader BO VA. */ 916 for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { 917 struct radv_shader_variant *shader = pipeline->shaders[i]; 918 uint64_t va; 919 920 if (!shader) 921 continue; 922 923 va = radv_shader_variant_get_va(shader); 924 base_va = MIN2(base_va, va); 925 } 926 927 result = 928 ac_sqtt_add_code_object_loader_event(&device->thread_trace, pipeline->pipeline_hash, base_va); 929 if (!result) 930 return VK_ERROR_OUT_OF_HOST_MEMORY; 931 932 result = radv_add_code_object(device, pipeline); 933 if (result != VK_SUCCESS) 934 return result; 935 936 return VK_SUCCESS; 937 } 938 939 static void 940 radv_unregister_pipeline(struct radv_device *device, struct radv_pipeline *pipeline) 941 { 942 struct ac_thread_trace_data *thread_trace_data = &device->thread_trace; 943 struct rgp_pso_correlation *pso_correlation = &thread_trace_data->rgp_pso_correlation; 944 struct rgp_loader_events *loader_events = &thread_trace_data->rgp_loader_events; 945 struct rgp_code_object *code_object = &thread_trace_data->rgp_code_object; 946 947 /* Destroy the PSO correlation record. */ 948 simple_mtx_lock(&pso_correlation->lock); 949 list_for_each_entry_safe(struct rgp_pso_correlation_record, record, &pso_correlation->record, 950 list) 951 { 952 if (record->pipeline_hash[0] == pipeline->pipeline_hash) { 953 pso_correlation->record_count--; 954 list_del(&record->list); 955 free(record); 956 break; 957 } 958 } 959 simple_mtx_unlock(&pso_correlation->lock); 960 961 /* Destroy the code object loader record. */ 962 simple_mtx_lock(&loader_events->lock); 963 list_for_each_entry_safe(struct rgp_loader_events_record, record, &loader_events->record, list) 964 { 965 if (record->code_object_hash[0] == pipeline->pipeline_hash) { 966 loader_events->record_count--; 967 list_del(&record->list); 968 free(record); 969 break; 970 } 971 } 972 simple_mtx_unlock(&loader_events->lock); 973 974 /* Destroy the code object record. */ 975 simple_mtx_lock(&code_object->lock); 976 list_for_each_entry_safe(struct rgp_code_object_record, record, &code_object->record, list) 977 { 978 if (record->pipeline_hash[0] == pipeline->pipeline_hash) { 979 uint32_t mask = record->shader_stages_mask; 980 int i; 981 982 /* Free the disassembly. */ 983 while (mask) { 984 i = u_bit_scan(&mask); 985 free(record->shader_data[i].code); 986 } 987 988 code_object->record_count--; 989 list_del(&record->list); 990 free(record); 991 break; 992 } 993 } 994 simple_mtx_unlock(&code_object->lock); 995 } 996 997 VkResult 998 sqtt_CreateGraphicsPipelines(VkDevice _device, VkPipelineCache pipelineCache, uint32_t count, 999 const VkGraphicsPipelineCreateInfo *pCreateInfos, 1000 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines) 1001 { 1002 RADV_FROM_HANDLE(radv_device, device, _device); 1003 VkResult result; 1004 1005 result = radv_CreateGraphicsPipelines(_device, pipelineCache, count, pCreateInfos, pAllocator, 1006 pPipelines); 1007 if (result != VK_SUCCESS) 1008 return result; 1009 1010 if (radv_is_instruction_timing_enabled()) { 1011 for (unsigned i = 0; i < count; i++) { 1012 RADV_FROM_HANDLE(radv_pipeline, pipeline, pPipelines[i]); 1013 1014 if (!pipeline) 1015 continue; 1016 1017 result = radv_register_pipeline(device, pipeline); 1018 if (result != VK_SUCCESS) 1019 goto fail; 1020 } 1021 } 1022 1023 return VK_SUCCESS; 1024 1025 fail: 1026 for (unsigned i = 0; i < count; i++) { 1027 sqtt_DestroyPipeline(_device, pPipelines[i], pAllocator); 1028 pPipelines[i] = VK_NULL_HANDLE; 1029 } 1030 return result; 1031 } 1032 1033 VkResult 1034 sqtt_CreateComputePipelines(VkDevice _device, VkPipelineCache pipelineCache, uint32_t count, 1035 const VkComputePipelineCreateInfo *pCreateInfos, 1036 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines) 1037 { 1038 RADV_FROM_HANDLE(radv_device, device, _device); 1039 VkResult result; 1040 1041 result = radv_CreateComputePipelines(_device, pipelineCache, count, pCreateInfos, pAllocator, 1042 pPipelines); 1043 if (result != VK_SUCCESS) 1044 return result; 1045 1046 if (radv_is_instruction_timing_enabled()) { 1047 for (unsigned i = 0; i < count; i++) { 1048 RADV_FROM_HANDLE(radv_pipeline, pipeline, pPipelines[i]); 1049 1050 if (!pipeline) 1051 continue; 1052 1053 result = radv_register_pipeline(device, pipeline); 1054 if (result != VK_SUCCESS) 1055 goto fail; 1056 } 1057 } 1058 1059 return VK_SUCCESS; 1060 1061 fail: 1062 for (unsigned i = 0; i < count; i++) { 1063 sqtt_DestroyPipeline(_device, pPipelines[i], pAllocator); 1064 pPipelines[i] = VK_NULL_HANDLE; 1065 } 1066 return result; 1067 } 1068 1069 void 1070 sqtt_DestroyPipeline(VkDevice _device, VkPipeline _pipeline, 1071 const VkAllocationCallbacks *pAllocator) 1072 { 1073 RADV_FROM_HANDLE(radv_device, device, _device); 1074 RADV_FROM_HANDLE(radv_pipeline, pipeline, _pipeline); 1075 1076 if (!_pipeline) 1077 return; 1078 1079 if (radv_is_instruction_timing_enabled()) 1080 radv_unregister_pipeline(device, pipeline); 1081 1082 radv_DestroyPipeline(_device, _pipeline, pAllocator); 1083 } 1084 1085 #undef API_MARKER 1086