Home | History | Annotate | Line # | Download | only in layers
      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