• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2021 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  */
23 
24 #include "iris_batch.h"
25 #include "iris_context.h"
26 #include "iris_utrace.h"
27 
28 #include "util/u_trace_gallium.h"
29 
30 #include "ds/intel_driver_ds.h"
31 
32 #ifdef MAJOR_IN_MKDEV
33 #include <sys/mkdev.h>
34 #endif
35 #ifdef MAJOR_IN_SYSMACROS
36 #include <sys/sysmacros.h>
37 #endif
38 #include <sys/types.h>
39 #include <sys/stat.h>
40 #include <unistd.h>
41 
42 static void
iris_utrace_record_ts(struct u_trace * trace,void * cs,void * timestamps,unsigned idx,bool end_of_pipe)43 iris_utrace_record_ts(struct u_trace *trace, void *cs,
44                       void *timestamps, unsigned idx,
45                       bool end_of_pipe)
46 {
47    struct iris_batch *batch = container_of(trace, struct iris_batch, trace);
48    struct iris_resource *res = (void *) timestamps;
49    struct iris_bo *bo = res->bo;
50 
51    iris_use_pinned_bo(batch, bo, true, IRIS_DOMAIN_NONE);
52 
53    if (end_of_pipe) {
54       iris_emit_pipe_control_write(batch, "query: pipelined snapshot write",
55                                    PIPE_CONTROL_WRITE_TIMESTAMP,
56                                    bo, idx * sizeof(uint64_t), 0ull);
57    } else {
58       batch->screen->vtbl.store_register_mem64(batch,
59                                                0x2358,
60                                                bo, idx * sizeof(uint64_t),
61                                                false);
62    }
63 }
64 
65 static uint64_t
iris_utrace_read_ts(struct u_trace_context * utctx,void * timestamps,unsigned idx,void * flush_data)66 iris_utrace_read_ts(struct u_trace_context *utctx,
67                     void *timestamps, unsigned idx, void *flush_data)
68 {
69    struct iris_context *ice =
70       container_of(utctx, struct iris_context, ds.trace_context);
71    struct pipe_context *ctx = &ice->ctx;
72    struct iris_screen *screen = (struct iris_screen *)ctx->screen;
73    struct iris_resource *res = (void *) timestamps;
74    struct iris_bo *bo = res->bo;
75 
76    if (idx == 0)
77       iris_bo_wait_rendering(bo);
78 
79    uint64_t *ts = iris_bo_map(NULL, bo, MAP_READ);
80 
81    /* Don't translate the no-timestamp marker: */
82    if (ts[idx] == U_TRACE_NO_TIMESTAMP)
83       return U_TRACE_NO_TIMESTAMP;
84 
85    return intel_device_info_timebase_scale(&screen->devinfo, ts[idx]);
86 }
87 
88 static void
iris_utrace_delete_flush_data(struct u_trace_context * utctx,void * flush_data)89 iris_utrace_delete_flush_data(struct u_trace_context *utctx,
90                               void *flush_data)
91 {
92    free(flush_data);
93 }
94 
iris_utrace_flush(struct iris_batch * batch,uint64_t submission_id)95 void iris_utrace_flush(struct iris_batch *batch, uint64_t submission_id)
96 {
97    struct intel_ds_flush_data *flush_data = malloc(sizeof(*flush_data));
98    intel_ds_flush_data_init(flush_data, batch->ds, submission_id);
99    u_trace_flush(&batch->trace, flush_data, false);
100 }
101 
iris_utrace_init(struct iris_context * ice)102 void iris_utrace_init(struct iris_context *ice)
103 {
104    struct iris_screen *screen = (struct iris_screen *)ice->ctx.screen;
105 
106    struct stat st;
107    uint32_t minor;
108 
109    if (fstat(screen->fd, &st) == 0)
110       minor = minor(st.st_rdev);
111    else
112       minor = 0;
113 
114    /* We could be dealing with /dev/dri/card0 or /dev/dri/renderD128 so to get
115     * a GPU ID we % 128 the minor number.
116     */
117    intel_ds_device_init(&ice->ds, &screen->devinfo, screen->fd, minor % 128,
118                         INTEL_DS_API_OPENGL);
119    u_trace_pipe_context_init(&ice->ds.trace_context, &ice->ctx,
120                              iris_utrace_record_ts,
121                              iris_utrace_read_ts,
122                              iris_utrace_delete_flush_data);
123 
124    for (int i = 0; i < IRIS_BATCH_COUNT; i++) {
125       ice->batches[i].ds =
126          intel_ds_device_add_queue(&ice->ds, "%s",
127                                    iris_batch_name_to_string(i));
128    }
129 }
130 
iris_utrace_fini(struct iris_context * ice)131 void iris_utrace_fini(struct iris_context *ice)
132 {
133    intel_ds_device_fini(&ice->ds);
134 }
135 
136 enum intel_ds_stall_flag
iris_utrace_pipe_flush_bit_to_ds_stall_flag(uint32_t flags)137 iris_utrace_pipe_flush_bit_to_ds_stall_flag(uint32_t flags)
138 {
139    static const struct {
140       uint32_t iris;
141       enum intel_ds_stall_flag ds;
142    } iris_to_ds_flags[] = {
143       { .iris = PIPE_CONTROL_DEPTH_CACHE_FLUSH,        .ds = INTEL_DS_DEPTH_CACHE_FLUSH_BIT, },
144       { .iris = PIPE_CONTROL_DATA_CACHE_FLUSH,         .ds = INTEL_DS_DATA_CACHE_FLUSH_BIT, },
145       { .iris = PIPE_CONTROL_TILE_CACHE_FLUSH,         .ds = INTEL_DS_TILE_CACHE_FLUSH_BIT, },
146       { .iris = PIPE_CONTROL_RENDER_TARGET_FLUSH,      .ds = INTEL_DS_RENDER_TARGET_CACHE_FLUSH_BIT, },
147       { .iris = PIPE_CONTROL_STATE_CACHE_INVALIDATE,   .ds = INTEL_DS_STATE_CACHE_INVALIDATE_BIT, },
148       { .iris = PIPE_CONTROL_CONST_CACHE_INVALIDATE,   .ds = INTEL_DS_CONST_CACHE_INVALIDATE_BIT, },
149       { .iris = PIPE_CONTROL_VF_CACHE_INVALIDATE,      .ds = INTEL_DS_VF_CACHE_INVALIDATE_BIT, },
150       { .iris = PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE, .ds = INTEL_DS_TEXTURE_CACHE_INVALIDATE_BIT, },
151       { .iris = PIPE_CONTROL_INSTRUCTION_INVALIDATE,   .ds = INTEL_DS_INST_CACHE_INVALIDATE_BIT, },
152       { .iris = PIPE_CONTROL_DEPTH_STALL,              .ds = INTEL_DS_DEPTH_STALL_BIT, },
153       { .iris = PIPE_CONTROL_CS_STALL,                 .ds = INTEL_DS_CS_STALL_BIT, },
154       { .iris = PIPE_CONTROL_FLUSH_HDC,                .ds = INTEL_DS_HDC_PIPELINE_FLUSH_BIT, },
155       { .iris = PIPE_CONTROL_STALL_AT_SCOREBOARD,      .ds = INTEL_DS_STALL_AT_SCOREBOARD_BIT, },
156    };
157 
158    enum intel_ds_stall_flag ret = 0;
159    for (uint32_t i = 0; i < ARRAY_SIZE(iris_to_ds_flags); i++) {
160       if (iris_to_ds_flags[i].iris & flags)
161          ret |= iris_to_ds_flags[i].ds;
162    }
163 
164    assert(ret != 0);
165 
166    return ret;
167 }
168