Home | History | Annotate | Line # | Download | only in common
      1 /*
      2  * Copyright 2020 Advanced Micro Devices, Inc.
      3  * Copyright 2020 Valve Corporation
      4  * All Rights Reserved.
      5  *
      6  * Permission is hereby granted, free of charge, to any person obtaining a
      7  * copy of this software and associated documentation files (the "Software"),
      8  * to deal in the Software without restriction, including without limitation
      9  * on the rights to use, copy, modify, merge, publish, distribute, sub
     10  * license, and/or sell copies of the Software, and to permit persons to whom
     11  * the Software is furnished to do so, subject to the following conditions:
     12  *
     13  * The above copyright notice and this permission notice (including the next
     14  * paragraph) shall be included in all copies or substantial portions of the
     15  * Software.
     16  *
     17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     19  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
     20  * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
     21  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
     22  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
     23  * USE OR OTHER DEALINGS IN THE SOFTWARE.
     24  */
     25 
     26 #ifndef AC_SQTT_H
     27 #define AC_SQTT_H
     28 
     29 #include <stdint.h>
     30 #include <stdbool.h>
     31 
     32 #include <assert.h>
     33 #include "c11_compat.h"
     34 #include "ac_rgp.h"
     35 
     36 struct radeon_cmdbuf;
     37 struct radeon_info;
     38 
     39 struct ac_thread_trace_data {
     40    struct radeon_cmdbuf *start_cs[2];
     41    struct radeon_cmdbuf *stop_cs[2];
     42    /* struct radeon_winsys_bo or struct pb_buffer */
     43    void *bo;
     44    void *ptr;
     45    uint32_t buffer_size;
     46    int start_frame;
     47    char *trigger_file;
     48 
     49    struct rgp_code_object rgp_code_object;
     50    struct rgp_loader_events rgp_loader_events;
     51    struct rgp_pso_correlation rgp_pso_correlation;
     52 };
     53 
     54 #define SQTT_BUFFER_ALIGN_SHIFT 12
     55 
     56 struct ac_thread_trace_info {
     57    uint32_t cur_offset;
     58    uint32_t trace_status;
     59    union {
     60       uint32_t gfx9_write_counter;
     61       uint32_t gfx10_dropped_cntr;
     62    };
     63 };
     64 
     65 struct ac_thread_trace_se {
     66    struct ac_thread_trace_info info;
     67    void *data_ptr;
     68    uint32_t shader_engine;
     69    uint32_t compute_unit;
     70 };
     71 
     72 struct ac_thread_trace {
     73    struct ac_thread_trace_data *data;
     74    uint32_t num_traces;
     75    struct ac_thread_trace_se traces[4];
     76 };
     77 
     78 uint64_t
     79 ac_thread_trace_get_info_offset(unsigned se);
     80 
     81 uint64_t
     82 ac_thread_trace_get_data_offset(const struct radeon_info *rad_info,
     83                                 const struct ac_thread_trace_data *data, unsigned se);
     84 uint64_t
     85 ac_thread_trace_get_info_va(uint64_t va, unsigned se);
     86 
     87 uint64_t
     88 ac_thread_trace_get_data_va(const struct radeon_info *rad_info,
     89                             const struct ac_thread_trace_data *data, uint64_t va, unsigned se);
     90 
     91 bool
     92 ac_is_thread_trace_complete(struct radeon_info *rad_info,
     93                             const struct ac_thread_trace_data *data,
     94                             const struct ac_thread_trace_info *info);
     95 
     96 uint32_t
     97 ac_get_expected_buffer_size(struct radeon_info *rad_info,
     98                             const struct ac_thread_trace_info *info);
     99 
    100 /**
    101  * Identifiers for RGP SQ thread-tracing markers (Table 1)
    102  */
    103 enum rgp_sqtt_marker_identifier
    104 {
    105    RGP_SQTT_MARKER_IDENTIFIER_EVENT = 0x0,
    106    RGP_SQTT_MARKER_IDENTIFIER_CB_START = 0x1,
    107    RGP_SQTT_MARKER_IDENTIFIER_CB_END = 0x2,
    108    RGP_SQTT_MARKER_IDENTIFIER_BARRIER_START = 0x3,
    109    RGP_SQTT_MARKER_IDENTIFIER_BARRIER_END = 0x4,
    110    RGP_SQTT_MARKER_IDENTIFIER_USER_EVENT = 0x5,
    111    RGP_SQTT_MARKER_IDENTIFIER_GENERAL_API = 0x6,
    112    RGP_SQTT_MARKER_IDENTIFIER_SYNC = 0x7,
    113    RGP_SQTT_MARKER_IDENTIFIER_PRESENT = 0x8,
    114    RGP_SQTT_MARKER_IDENTIFIER_LAYOUT_TRANSITION = 0x9,
    115    RGP_SQTT_MARKER_IDENTIFIER_RENDER_PASS = 0xA,
    116    RGP_SQTT_MARKER_IDENTIFIER_RESERVED2 = 0xB,
    117    RGP_SQTT_MARKER_IDENTIFIER_BIND_PIPELINE = 0xC,
    118    RGP_SQTT_MARKER_IDENTIFIER_RESERVED4 = 0xD,
    119    RGP_SQTT_MARKER_IDENTIFIER_RESERVED5 = 0xE,
    120    RGP_SQTT_MARKER_IDENTIFIER_RESERVED6 = 0xF
    121 };
    122 
    123 /**
    124  * RGP SQ thread-tracing marker for the start of a command buffer. (Table 2)
    125  */
    126 struct rgp_sqtt_marker_cb_start {
    127    union {
    128       struct {
    129          uint32_t identifier : 4;
    130          uint32_t ext_dwords : 3;
    131          uint32_t cb_id : 20;
    132          uint32_t queue : 5;
    133       };
    134       uint32_t dword01;
    135    };
    136    union {
    137       uint32_t device_id_low;
    138       uint32_t dword02;
    139    };
    140    union {
    141       uint32_t device_id_high;
    142       uint32_t dword03;
    143    };
    144    union {
    145       uint32_t queue_flags;
    146       uint32_t dword04;
    147    };
    148 };
    149 
    150 static_assert(sizeof(struct rgp_sqtt_marker_cb_start) == 16,
    151               "rgp_sqtt_marker_cb_start doesn't match RGP spec");
    152 
    153 /**
    154  *
    155  * RGP SQ thread-tracing marker for the end of a command buffer. (Table 3)
    156  */
    157 struct rgp_sqtt_marker_cb_end {
    158    union {
    159       struct {
    160          uint32_t identifier : 4;
    161          uint32_t ext_dwords : 3;
    162          uint32_t cb_id : 20;
    163          uint32_t reserved : 5;
    164       };
    165       uint32_t dword01;
    166    };
    167    union {
    168       uint32_t device_id_low;
    169       uint32_t dword02;
    170    };
    171    union {
    172       uint32_t device_id_high;
    173       uint32_t dword03;
    174    };
    175 };
    176 
    177 static_assert(sizeof(struct rgp_sqtt_marker_cb_end) == 12,
    178               "rgp_sqtt_marker_cb_end doesn't match RGP spec");
    179 
    180 /**
    181  * API types used in RGP SQ thread-tracing markers for the "General API"
    182  * packet.
    183  */
    184 enum rgp_sqtt_marker_general_api_type
    185 {
    186    ApiCmdBindPipeline = 0,
    187    ApiCmdBindDescriptorSets = 1,
    188    ApiCmdBindIndexBuffer = 2,
    189    ApiCmdBindVertexBuffers = 3,
    190    ApiCmdDraw = 4,
    191    ApiCmdDrawIndexed = 5,
    192    ApiCmdDrawIndirect = 6,
    193    ApiCmdDrawIndexedIndirect = 7,
    194    ApiCmdDrawIndirectCountAMD = 8,
    195    ApiCmdDrawIndexedIndirectCountAMD = 9,
    196    ApiCmdDispatch = 10,
    197    ApiCmdDispatchIndirect = 11,
    198    ApiCmdCopyBuffer = 12,
    199    ApiCmdCopyImage = 13,
    200    ApiCmdBlitImage = 14,
    201    ApiCmdCopyBufferToImage = 15,
    202    ApiCmdCopyImageToBuffer = 16,
    203    ApiCmdUpdateBuffer = 17,
    204    ApiCmdFillBuffer = 18,
    205    ApiCmdClearColorImage = 19,
    206    ApiCmdClearDepthStencilImage = 20,
    207    ApiCmdClearAttachments = 21,
    208    ApiCmdResolveImage = 22,
    209    ApiCmdWaitEvents = 23,
    210    ApiCmdPipelineBarrier = 24,
    211    ApiCmdBeginQuery = 25,
    212    ApiCmdEndQuery = 26,
    213    ApiCmdResetQueryPool = 27,
    214    ApiCmdWriteTimestamp = 28,
    215    ApiCmdCopyQueryPoolResults = 29,
    216    ApiCmdPushConstants = 30,
    217    ApiCmdBeginRenderPass = 31,
    218    ApiCmdNextSubpass = 32,
    219    ApiCmdEndRenderPass = 33,
    220    ApiCmdExecuteCommands = 34,
    221    ApiCmdSetViewport = 35,
    222    ApiCmdSetScissor = 36,
    223    ApiCmdSetLineWidth = 37,
    224    ApiCmdSetDepthBias = 38,
    225    ApiCmdSetBlendConstants = 39,
    226    ApiCmdSetDepthBounds = 40,
    227    ApiCmdSetStencilCompareMask = 41,
    228    ApiCmdSetStencilWriteMask = 42,
    229    ApiCmdSetStencilReference = 43,
    230    ApiCmdDrawIndirectCount = 44,
    231    ApiCmdDrawIndexedIndirectCount = 45,
    232    ApiInvalid = 0xffffffff
    233 };
    234 
    235 /**
    236  * RGP SQ thread-tracing marker for a "General API" instrumentation packet.
    237  */
    238 struct rgp_sqtt_marker_general_api {
    239    union {
    240       struct {
    241          uint32_t identifier : 4;
    242          uint32_t ext_dwords : 3;
    243          uint32_t api_type : 20;
    244          uint32_t is_end : 1;
    245          uint32_t reserved : 4;
    246       };
    247       uint32_t dword01;
    248    };
    249 };
    250 
    251 static_assert(sizeof(struct rgp_sqtt_marker_general_api) == 4,
    252               "rgp_sqtt_marker_general_api doesn't match RGP spec");
    253 
    254 /**
    255  * API types used in RGP SQ thread-tracing markers (Table 16).
    256  */
    257 enum rgp_sqtt_marker_event_type
    258 {
    259    EventCmdDraw = 0,
    260    EventCmdDrawIndexed = 1,
    261    EventCmdDrawIndirect = 2,
    262    EventCmdDrawIndexedIndirect = 3,
    263    EventCmdDrawIndirectCountAMD = 4,
    264    EventCmdDrawIndexedIndirectCountAMD = 5,
    265    EventCmdDispatch = 6,
    266    EventCmdDispatchIndirect = 7,
    267    EventCmdCopyBuffer = 8,
    268    EventCmdCopyImage = 9,
    269    EventCmdBlitImage = 10,
    270    EventCmdCopyBufferToImage = 11,
    271    EventCmdCopyImageToBuffer = 12,
    272    EventCmdUpdateBuffer = 13,
    273    EventCmdFillBuffer = 14,
    274    EventCmdClearColorImage = 15,
    275    EventCmdClearDepthStencilImage = 16,
    276    EventCmdClearAttachments = 17,
    277    EventCmdResolveImage = 18,
    278    EventCmdWaitEvents = 19,
    279    EventCmdPipelineBarrier = 20,
    280    EventCmdResetQueryPool = 21,
    281    EventCmdCopyQueryPoolResults = 22,
    282    EventRenderPassColorClear = 23,
    283    EventRenderPassDepthStencilClear = 24,
    284    EventRenderPassResolve = 25,
    285    EventInternalUnknown = 26,
    286    EventCmdDrawIndirectCount = 27,
    287    EventCmdDrawIndexedIndirectCount = 28,
    288    EventInvalid = 0xffffffff
    289 };
    290 
    291 /**
    292  * "Event (Per-draw/dispatch)" RGP SQ thread-tracing marker. (Table 4)
    293  */
    294 struct rgp_sqtt_marker_event {
    295    union {
    296       struct {
    297          uint32_t identifier : 4;
    298          uint32_t ext_dwords : 3;
    299          uint32_t api_type : 24;
    300          uint32_t has_thread_dims : 1;
    301       };
    302       uint32_t dword01;
    303    };
    304    union {
    305       struct {
    306          uint32_t cb_id : 20;
    307          uint32_t vertex_offset_reg_idx : 4;
    308          uint32_t instance_offset_reg_idx : 4;
    309          uint32_t draw_index_reg_idx : 4;
    310       };
    311       uint32_t dword02;
    312    };
    313    union {
    314       uint32_t cmd_id;
    315       uint32_t dword03;
    316    };
    317 };
    318 
    319 static_assert(sizeof(struct rgp_sqtt_marker_event) == 12,
    320               "rgp_sqtt_marker_event doesn't match RGP spec");
    321 
    322 /**
    323  * Per-dispatch specific marker where workgroup dims are included.
    324  */
    325 struct rgp_sqtt_marker_event_with_dims {
    326    struct rgp_sqtt_marker_event event;
    327    uint32_t thread_x;
    328    uint32_t thread_y;
    329    uint32_t thread_z;
    330 };
    331 
    332 static_assert(sizeof(struct rgp_sqtt_marker_event_with_dims) == 24,
    333               "rgp_sqtt_marker_event_with_dims doesn't match RGP spec");
    334 
    335 /**
    336  * "Barrier Start" RGP SQTT instrumentation marker (Table 5)
    337  */
    338 struct rgp_sqtt_marker_barrier_start {
    339    union {
    340       struct {
    341          uint32_t identifier : 4;
    342          uint32_t ext_dwords : 3;
    343          uint32_t cb_id : 20;
    344          uint32_t reserved : 5;
    345       };
    346       uint32_t dword01;
    347    };
    348    union {
    349       struct {
    350          uint32_t driver_reason : 31;
    351          uint32_t internal : 1;
    352       };
    353       uint32_t dword02;
    354    };
    355 };
    356 
    357 static_assert(sizeof(struct rgp_sqtt_marker_barrier_start) == 8,
    358               "rgp_sqtt_marker_barrier_start doesn't match RGP spec");
    359 
    360 /**
    361  * "Barrier End" RGP SQTT instrumentation marker (Table 6)
    362  */
    363 struct rgp_sqtt_marker_barrier_end {
    364    union {
    365       struct {
    366          uint32_t identifier : 4;
    367          uint32_t ext_dwords : 3;
    368          uint32_t cb_id : 20;
    369          uint32_t wait_on_eop_ts : 1;
    370          uint32_t vs_partial_flush : 1;
    371          uint32_t ps_partial_flush : 1;
    372          uint32_t cs_partial_flush : 1;
    373          uint32_t pfp_sync_me : 1;
    374       };
    375       uint32_t dword01;
    376    };
    377    union {
    378       struct {
    379          uint32_t sync_cp_dma : 1;
    380          uint32_t inval_tcp : 1;
    381          uint32_t inval_sqI : 1;
    382          uint32_t inval_sqK : 1;
    383          uint32_t flush_tcc : 1;
    384          uint32_t inval_tcc : 1;
    385          uint32_t flush_cb : 1;
    386          uint32_t inval_cb : 1;
    387          uint32_t flush_db : 1;
    388          uint32_t inval_db : 1;
    389          uint32_t num_layout_transitions : 16;
    390          uint32_t inval_gl1 : 1;
    391          uint32_t reserved : 5;
    392       };
    393       uint32_t dword02;
    394    };
    395 };
    396 
    397 static_assert(sizeof(struct rgp_sqtt_marker_barrier_end) == 8,
    398               "rgp_sqtt_marker_barrier_end doesn't match RGP spec");
    399 
    400 /**
    401  * "Layout Transition" RGP SQTT instrumentation marker (Table 7)
    402  */
    403 struct rgp_sqtt_marker_layout_transition {
    404    union {
    405       struct {
    406          uint32_t identifier : 4;
    407          uint32_t ext_dwords : 3;
    408          uint32_t depth_stencil_expand : 1;
    409          uint32_t htile_hiz_range_expand : 1;
    410          uint32_t depth_stencil_resummarize : 1;
    411          uint32_t dcc_decompress : 1;
    412          uint32_t fmask_decompress : 1;
    413          uint32_t fast_clear_eliminate : 1;
    414          uint32_t fmask_color_expand : 1;
    415          uint32_t init_mask_ram : 1;
    416          uint32_t reserved1 : 17;
    417       };
    418       uint32_t dword01;
    419    };
    420    union {
    421       struct {
    422          uint32_t reserved2 : 32;
    423       };
    424       uint32_t dword02;
    425    };
    426 };
    427 
    428 static_assert(sizeof(struct rgp_sqtt_marker_layout_transition) == 8,
    429               "rgp_sqtt_marker_layout_transition doesn't match RGP spec");
    430 
    431 
    432 /**
    433  * "User Event" RGP SQTT instrumentation marker (Table 8)
    434  */
    435 struct rgp_sqtt_marker_user_event {
    436    union {
    437       struct {
    438          uint32_t identifier : 4;
    439          uint32_t reserved0 : 8;
    440          uint32_t data_type : 8;
    441          uint32_t reserved1 : 12;
    442       };
    443       uint32_t dword01;
    444    };
    445 };
    446 struct rgp_sqtt_marker_user_event_with_length {
    447    struct rgp_sqtt_marker_user_event user_event;
    448    uint32_t length;
    449 };
    450 
    451 static_assert(sizeof(struct rgp_sqtt_marker_user_event) == 4,
    452               "rgp_sqtt_marker_user_event doesn't match RGP spec");
    453 
    454 enum rgp_sqtt_marker_user_event_type
    455 {
    456    UserEventTrigger = 0,
    457    UserEventPop,
    458    UserEventPush,
    459    UserEventObjectName,
    460 };
    461 
    462 /**
    463  * "Pipeline bind" RGP SQTT instrumentation marker (Table 12)
    464  */
    465 struct rgp_sqtt_marker_pipeline_bind {
    466    union {
    467       struct {
    468          uint32_t identifier : 4;
    469          uint32_t ext_dwords : 3;
    470          uint32_t bind_point : 1;
    471          uint32_t cb_id : 20;
    472          uint32_t reserved : 4;
    473       };
    474       uint32_t dword01;
    475    };
    476    union {
    477       uint32_t api_pso_hash[2];
    478       struct {
    479          uint32_t dword02;
    480          uint32_t dword03;
    481       };
    482    };
    483 };
    484 
    485 static_assert(sizeof(struct rgp_sqtt_marker_pipeline_bind) == 12,
    486               "rgp_sqtt_marker_pipeline_bind doesn't match RGP spec");
    487 
    488 
    489 bool ac_sqtt_add_pso_correlation(struct ac_thread_trace_data *thread_trace_data,
    490                                  uint64_t pipeline_hash);
    491 
    492 bool ac_sqtt_add_code_object_loader_event(struct ac_thread_trace_data *thread_trace_data,
    493                                           uint64_t pipeline_hash,
    494                                           uint64_t base_address);
    495 
    496 #endif
    497