1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright © 2019 Intel Corporation 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 7bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 9bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 10bf215546Sopenharmony_ci * 11bf215546Sopenharmony_ci * The above copyright notice and this permission notice shall be included 12bf215546Sopenharmony_ci * in all copies or substantial portions of the Software. 13bf215546Sopenharmony_ci * 14bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15bf215546Sopenharmony_ci * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20bf215546Sopenharmony_ci * DEALINGS IN THE SOFTWARE. 21bf215546Sopenharmony_ci */ 22bf215546Sopenharmony_ci 23bf215546Sopenharmony_ci/** 24bf215546Sopenharmony_ci * @file iris_measure.c 25bf215546Sopenharmony_ci */ 26bf215546Sopenharmony_ci 27bf215546Sopenharmony_ci#include <stdio.h> 28bf215546Sopenharmony_ci#include "util/debug.h" 29bf215546Sopenharmony_ci#include "util/list.h" 30bf215546Sopenharmony_ci#include "util/crc32.h" 31bf215546Sopenharmony_ci#include "iris_context.h" 32bf215546Sopenharmony_ci#include "iris_defines.h" 33bf215546Sopenharmony_ci#include "compiler/shader_info.h" 34bf215546Sopenharmony_ci 35bf215546Sopenharmony_ci/** 36bf215546Sopenharmony_ci * This callback is registered with intel_measure. It will be called when 37bf215546Sopenharmony_ci * snapshot data has been fully collected, so iris can release the associated 38bf215546Sopenharmony_ci * resources. 39bf215546Sopenharmony_ci */ 40bf215546Sopenharmony_cistatic void 41bf215546Sopenharmony_cimeasure_batch_free(struct intel_measure_batch *base) 42bf215546Sopenharmony_ci{ 43bf215546Sopenharmony_ci struct iris_measure_batch *batch = 44bf215546Sopenharmony_ci container_of(base, struct iris_measure_batch, base); 45bf215546Sopenharmony_ci iris_destroy_batch_measure(batch); 46bf215546Sopenharmony_ci} 47bf215546Sopenharmony_ci 48bf215546Sopenharmony_civoid 49bf215546Sopenharmony_ciiris_init_screen_measure(struct iris_screen *screen) 50bf215546Sopenharmony_ci{ 51bf215546Sopenharmony_ci struct intel_measure_device *measure_device = &screen->measure; 52bf215546Sopenharmony_ci 53bf215546Sopenharmony_ci memset(measure_device, 0, sizeof(*measure_device)); 54bf215546Sopenharmony_ci intel_measure_init(measure_device); 55bf215546Sopenharmony_ci measure_device->release_batch = &measure_batch_free; 56bf215546Sopenharmony_ci struct intel_measure_config *config = measure_device->config; 57bf215546Sopenharmony_ci if (config == NULL) 58bf215546Sopenharmony_ci return; 59bf215546Sopenharmony_ci 60bf215546Sopenharmony_ci /* the final member of intel_measure_ringbuffer is a zero-length array of 61bf215546Sopenharmony_ci * intel_measure_buffered_result objects. Allocate additional space for 62bf215546Sopenharmony_ci * the buffered objects based on the run-time configurable buffer_size 63bf215546Sopenharmony_ci */ 64bf215546Sopenharmony_ci const size_t rb_bytes = sizeof(struct intel_measure_ringbuffer) + 65bf215546Sopenharmony_ci config->buffer_size * sizeof(struct intel_measure_buffered_result); 66bf215546Sopenharmony_ci struct intel_measure_ringbuffer *rb = rzalloc_size(screen, rb_bytes); 67bf215546Sopenharmony_ci measure_device->ringbuffer = rb; 68bf215546Sopenharmony_ci} 69bf215546Sopenharmony_ci 70bf215546Sopenharmony_cistatic struct intel_measure_config * 71bf215546Sopenharmony_ciconfig_from_screen(struct iris_screen *screen) 72bf215546Sopenharmony_ci{ 73bf215546Sopenharmony_ci return screen->measure.config; 74bf215546Sopenharmony_ci} 75bf215546Sopenharmony_ci 76bf215546Sopenharmony_cistatic struct intel_measure_config * 77bf215546Sopenharmony_ciconfig_from_context(struct iris_context *ice) 78bf215546Sopenharmony_ci{ 79bf215546Sopenharmony_ci return ((struct iris_screen *) ice->ctx.screen)->measure.config; 80bf215546Sopenharmony_ci} 81bf215546Sopenharmony_ci 82bf215546Sopenharmony_civoid 83bf215546Sopenharmony_ciiris_destroy_screen_measure(struct iris_screen *screen) 84bf215546Sopenharmony_ci{ 85bf215546Sopenharmony_ci if (!config_from_screen(screen)) 86bf215546Sopenharmony_ci return; 87bf215546Sopenharmony_ci 88bf215546Sopenharmony_ci struct intel_measure_device *measure_device = &screen->measure; 89bf215546Sopenharmony_ci 90bf215546Sopenharmony_ci if (measure_device->config->file && 91bf215546Sopenharmony_ci measure_device->config->file != stderr) 92bf215546Sopenharmony_ci fclose(screen->measure.config->file); 93bf215546Sopenharmony_ci 94bf215546Sopenharmony_ci ralloc_free(measure_device->ringbuffer); 95bf215546Sopenharmony_ci measure_device->ringbuffer = NULL; 96bf215546Sopenharmony_ci} 97bf215546Sopenharmony_ci 98bf215546Sopenharmony_ci 99bf215546Sopenharmony_civoid 100bf215546Sopenharmony_ciiris_init_batch_measure(struct iris_context *ice, struct iris_batch *batch) 101bf215546Sopenharmony_ci{ 102bf215546Sopenharmony_ci const struct intel_measure_config *config = config_from_context(ice); 103bf215546Sopenharmony_ci struct iris_screen *screen = batch->screen; 104bf215546Sopenharmony_ci struct iris_bufmgr *bufmgr = screen->bufmgr; 105bf215546Sopenharmony_ci 106bf215546Sopenharmony_ci if (!config) 107bf215546Sopenharmony_ci return; 108bf215546Sopenharmony_ci 109bf215546Sopenharmony_ci /* the final member of iris_measure_batch is a zero-length array of 110bf215546Sopenharmony_ci * intel_measure_snapshot objects. Create additional space for the 111bf215546Sopenharmony_ci * snapshot objects based on the run-time configurable batch_size 112bf215546Sopenharmony_ci */ 113bf215546Sopenharmony_ci const size_t batch_bytes = sizeof(struct iris_measure_batch) + 114bf215546Sopenharmony_ci config->batch_size * sizeof(struct intel_measure_snapshot); 115bf215546Sopenharmony_ci assert(batch->measure == NULL); 116bf215546Sopenharmony_ci batch->measure = malloc(batch_bytes); 117bf215546Sopenharmony_ci memset(batch->measure, 0, batch_bytes); 118bf215546Sopenharmony_ci struct iris_measure_batch *measure = batch->measure; 119bf215546Sopenharmony_ci 120bf215546Sopenharmony_ci measure->bo = iris_bo_alloc(bufmgr, "measure", 121bf215546Sopenharmony_ci config->batch_size * sizeof(uint64_t), 8, 122bf215546Sopenharmony_ci IRIS_MEMZONE_OTHER, BO_ALLOC_ZEROED); 123bf215546Sopenharmony_ci measure->base.timestamps = iris_bo_map(NULL, measure->bo, MAP_READ); 124bf215546Sopenharmony_ci measure->base.framebuffer = 125bf215546Sopenharmony_ci (uintptr_t)util_hash_crc32(&ice->state.framebuffer, 126bf215546Sopenharmony_ci sizeof(ice->state.framebuffer)); 127bf215546Sopenharmony_ci} 128bf215546Sopenharmony_ci 129bf215546Sopenharmony_civoid 130bf215546Sopenharmony_ciiris_destroy_batch_measure(struct iris_measure_batch *batch) 131bf215546Sopenharmony_ci{ 132bf215546Sopenharmony_ci if (!batch) 133bf215546Sopenharmony_ci return; 134bf215546Sopenharmony_ci iris_bo_unmap(batch->bo); 135bf215546Sopenharmony_ci iris_bo_unreference(batch->bo); 136bf215546Sopenharmony_ci batch->bo = NULL; 137bf215546Sopenharmony_ci free(batch); 138bf215546Sopenharmony_ci} 139bf215546Sopenharmony_ci 140bf215546Sopenharmony_cistatic void 141bf215546Sopenharmony_cimeasure_start_snapshot(struct iris_context *ice, 142bf215546Sopenharmony_ci struct iris_batch *batch, 143bf215546Sopenharmony_ci enum intel_measure_snapshot_type type, 144bf215546Sopenharmony_ci const char *event_name, 145bf215546Sopenharmony_ci uint32_t count) 146bf215546Sopenharmony_ci{ 147bf215546Sopenharmony_ci struct intel_measure_batch *measure_batch = &batch->measure->base; 148bf215546Sopenharmony_ci const struct intel_measure_config *config = config_from_context(ice); 149bf215546Sopenharmony_ci const struct iris_screen *screen = (void *) ice->ctx.screen; 150bf215546Sopenharmony_ci const unsigned screen_frame = screen->measure.frame; 151bf215546Sopenharmony_ci 152bf215546Sopenharmony_ci /* if the command buffer is not associated with a frame, associate it with 153bf215546Sopenharmony_ci * the most recent acquired frame 154bf215546Sopenharmony_ci */ 155bf215546Sopenharmony_ci if (measure_batch->frame == 0) 156bf215546Sopenharmony_ci measure_batch->frame = screen_frame; 157bf215546Sopenharmony_ci 158bf215546Sopenharmony_ci uintptr_t framebuffer = measure_batch->framebuffer; 159bf215546Sopenharmony_ci 160bf215546Sopenharmony_ci if (measure_batch->index == config->batch_size) { 161bf215546Sopenharmony_ci /* Snapshot buffer is full. The batch must be flushed before additional 162bf215546Sopenharmony_ci * snapshots can be taken. 163bf215546Sopenharmony_ci */ 164bf215546Sopenharmony_ci static bool warned = false; 165bf215546Sopenharmony_ci if (unlikely(!warned)) { 166bf215546Sopenharmony_ci fprintf(config->file, 167bf215546Sopenharmony_ci "WARNING: batch size exceeds INTEL_MEASURE limit: %d. " 168bf215546Sopenharmony_ci "Data has been dropped. " 169bf215546Sopenharmony_ci "Increase setting with INTEL_MEASURE=batch_size={count}\n", 170bf215546Sopenharmony_ci config->batch_size); 171bf215546Sopenharmony_ci warned = true; 172bf215546Sopenharmony_ci } 173bf215546Sopenharmony_ci return; 174bf215546Sopenharmony_ci } 175bf215546Sopenharmony_ci 176bf215546Sopenharmony_ci unsigned index = measure_batch->index++; 177bf215546Sopenharmony_ci assert(index < config->batch_size); 178bf215546Sopenharmony_ci iris_emit_pipe_control_write(batch, "measurement snapshot", 179bf215546Sopenharmony_ci PIPE_CONTROL_WRITE_TIMESTAMP | 180bf215546Sopenharmony_ci PIPE_CONTROL_CS_STALL, 181bf215546Sopenharmony_ci batch->measure->bo, index * sizeof(uint64_t), 0ull); 182bf215546Sopenharmony_ci if (event_name == NULL) 183bf215546Sopenharmony_ci event_name = intel_measure_snapshot_string(type); 184bf215546Sopenharmony_ci 185bf215546Sopenharmony_ci struct intel_measure_snapshot *snapshot = &(measure_batch->snapshots[index]); 186bf215546Sopenharmony_ci memset(snapshot, 0, sizeof(*snapshot)); 187bf215546Sopenharmony_ci snapshot->type = type; 188bf215546Sopenharmony_ci snapshot->count = (unsigned) count; 189bf215546Sopenharmony_ci snapshot->event_count = measure_batch->event_count; 190bf215546Sopenharmony_ci snapshot->event_name = event_name; 191bf215546Sopenharmony_ci snapshot->framebuffer = framebuffer; 192bf215546Sopenharmony_ci 193bf215546Sopenharmony_ci if (type == INTEL_SNAPSHOT_COMPUTE) { 194bf215546Sopenharmony_ci snapshot->cs = (uintptr_t) ice->shaders.prog[MESA_SHADER_COMPUTE]; 195bf215546Sopenharmony_ci } else { 196bf215546Sopenharmony_ci snapshot->vs = (uintptr_t) ice->shaders.prog[MESA_SHADER_VERTEX]; 197bf215546Sopenharmony_ci snapshot->tcs = (uintptr_t) ice->shaders.prog[MESA_SHADER_TESS_CTRL]; 198bf215546Sopenharmony_ci snapshot->tes = (uintptr_t) ice->shaders.prog[MESA_SHADER_TESS_EVAL]; 199bf215546Sopenharmony_ci snapshot->gs = (uintptr_t) ice->shaders.prog[MESA_SHADER_GEOMETRY]; 200bf215546Sopenharmony_ci snapshot->fs = (uintptr_t) ice->shaders.prog[MESA_SHADER_FRAGMENT]; 201bf215546Sopenharmony_ci } 202bf215546Sopenharmony_ci} 203bf215546Sopenharmony_ci 204bf215546Sopenharmony_cistatic void 205bf215546Sopenharmony_cimeasure_end_snapshot(struct iris_batch *batch, 206bf215546Sopenharmony_ci uint32_t event_count) 207bf215546Sopenharmony_ci{ 208bf215546Sopenharmony_ci struct intel_measure_batch *measure_batch = &batch->measure->base; 209bf215546Sopenharmony_ci 210bf215546Sopenharmony_ci unsigned index = measure_batch->index++; 211bf215546Sopenharmony_ci assert(index % 2 == 1); 212bf215546Sopenharmony_ci 213bf215546Sopenharmony_ci iris_emit_pipe_control_write(batch, "measurement snapshot", 214bf215546Sopenharmony_ci PIPE_CONTROL_WRITE_TIMESTAMP | 215bf215546Sopenharmony_ci PIPE_CONTROL_CS_STALL, 216bf215546Sopenharmony_ci batch->measure->bo, 217bf215546Sopenharmony_ci index * sizeof(uint64_t), 0ull); 218bf215546Sopenharmony_ci 219bf215546Sopenharmony_ci struct intel_measure_snapshot *snapshot = &(measure_batch->snapshots[index]); 220bf215546Sopenharmony_ci memset(snapshot, 0, sizeof(*snapshot)); 221bf215546Sopenharmony_ci snapshot->type = INTEL_SNAPSHOT_END; 222bf215546Sopenharmony_ci snapshot->event_count = event_count; 223bf215546Sopenharmony_ci} 224bf215546Sopenharmony_ci 225bf215546Sopenharmony_cistatic bool 226bf215546Sopenharmony_cistate_changed(const struct iris_context *ice, 227bf215546Sopenharmony_ci const struct iris_batch *batch, 228bf215546Sopenharmony_ci enum intel_measure_snapshot_type type) 229bf215546Sopenharmony_ci{ 230bf215546Sopenharmony_ci uintptr_t vs=0, tcs=0, tes=0, gs=0, fs=0, cs=0; 231bf215546Sopenharmony_ci 232bf215546Sopenharmony_ci if (type == INTEL_SNAPSHOT_COMPUTE) { 233bf215546Sopenharmony_ci cs = (uintptr_t) ice->shaders.prog[MESA_SHADER_COMPUTE]; 234bf215546Sopenharmony_ci } else if (type == INTEL_SNAPSHOT_DRAW) { 235bf215546Sopenharmony_ci vs = (uintptr_t) ice->shaders.prog[MESA_SHADER_VERTEX]; 236bf215546Sopenharmony_ci tcs = (uintptr_t) ice->shaders.prog[MESA_SHADER_TESS_CTRL]; 237bf215546Sopenharmony_ci tes = (uintptr_t) ice->shaders.prog[MESA_SHADER_TESS_EVAL]; 238bf215546Sopenharmony_ci gs = (uintptr_t) ice->shaders.prog[MESA_SHADER_GEOMETRY]; 239bf215546Sopenharmony_ci fs = (uintptr_t) ice->shaders.prog[MESA_SHADER_FRAGMENT]; 240bf215546Sopenharmony_ci } 241bf215546Sopenharmony_ci /* else blorp, all programs NULL */ 242bf215546Sopenharmony_ci 243bf215546Sopenharmony_ci return intel_measure_state_changed(&batch->measure->base, 244bf215546Sopenharmony_ci vs, tcs, tes, gs, fs, cs); 245bf215546Sopenharmony_ci} 246bf215546Sopenharmony_ci 247bf215546Sopenharmony_cistatic void 248bf215546Sopenharmony_ciiris_measure_renderpass(struct iris_context *ice) 249bf215546Sopenharmony_ci{ 250bf215546Sopenharmony_ci const struct intel_measure_config *config = config_from_context(ice); 251bf215546Sopenharmony_ci struct intel_measure_batch *batch = 252bf215546Sopenharmony_ci &ice->batches[IRIS_BATCH_RENDER].measure->base; 253bf215546Sopenharmony_ci 254bf215546Sopenharmony_ci if (!config) 255bf215546Sopenharmony_ci return; 256bf215546Sopenharmony_ci uint32_t framebuffer_crc = util_hash_crc32(&ice->state.framebuffer, 257bf215546Sopenharmony_ci sizeof(ice->state.framebuffer)); 258bf215546Sopenharmony_ci if (framebuffer_crc == batch->framebuffer) 259bf215546Sopenharmony_ci return; 260bf215546Sopenharmony_ci bool filtering = config->flags & INTEL_MEASURE_RENDERPASS; 261bf215546Sopenharmony_ci if (filtering && batch->index % 2 == 1) { 262bf215546Sopenharmony_ci /* snapshot for previous renderpass was not ended */ 263bf215546Sopenharmony_ci measure_end_snapshot(&ice->batches[IRIS_BATCH_RENDER], 264bf215546Sopenharmony_ci batch->event_count); 265bf215546Sopenharmony_ci batch->event_count = 0; 266bf215546Sopenharmony_ci } 267bf215546Sopenharmony_ci 268bf215546Sopenharmony_ci batch->framebuffer = framebuffer_crc; 269bf215546Sopenharmony_ci} 270bf215546Sopenharmony_ci 271bf215546Sopenharmony_civoid 272bf215546Sopenharmony_ci_iris_measure_snapshot(struct iris_context *ice, 273bf215546Sopenharmony_ci struct iris_batch *batch, 274bf215546Sopenharmony_ci enum intel_measure_snapshot_type type, 275bf215546Sopenharmony_ci const struct pipe_draw_info *draw, 276bf215546Sopenharmony_ci const struct pipe_draw_indirect_info *indirect, 277bf215546Sopenharmony_ci const struct pipe_draw_start_count_bias *sc) 278bf215546Sopenharmony_ci{ 279bf215546Sopenharmony_ci 280bf215546Sopenharmony_ci const struct intel_measure_config *config = config_from_context(ice); 281bf215546Sopenharmony_ci struct intel_measure_batch* measure_batch = &batch->measure->base; 282bf215546Sopenharmony_ci 283bf215546Sopenharmony_ci assert(config); 284bf215546Sopenharmony_ci if (!config->enabled) 285bf215546Sopenharmony_ci return; 286bf215546Sopenharmony_ci if (measure_batch == NULL) 287bf215546Sopenharmony_ci return; 288bf215546Sopenharmony_ci 289bf215546Sopenharmony_ci assert(type != INTEL_SNAPSHOT_END); 290bf215546Sopenharmony_ci iris_measure_renderpass(ice); 291bf215546Sopenharmony_ci 292bf215546Sopenharmony_ci if (!state_changed(ice, batch, type)) { 293bf215546Sopenharmony_ci /* filter out this event */ 294bf215546Sopenharmony_ci return; 295bf215546Sopenharmony_ci } 296bf215546Sopenharmony_ci 297bf215546Sopenharmony_ci /* increment event count */ 298bf215546Sopenharmony_ci ++measure_batch->event_count; 299bf215546Sopenharmony_ci if (measure_batch->event_count == 1 || 300bf215546Sopenharmony_ci measure_batch->event_count == config->event_interval + 1) { 301bf215546Sopenharmony_ci /* the first event of an interval */ 302bf215546Sopenharmony_ci if (measure_batch->index % 2) { 303bf215546Sopenharmony_ci /* end the previous event */ 304bf215546Sopenharmony_ci measure_end_snapshot(batch, measure_batch->event_count - 1); 305bf215546Sopenharmony_ci } 306bf215546Sopenharmony_ci measure_batch->event_count = 1; 307bf215546Sopenharmony_ci 308bf215546Sopenharmony_ci const char *event_name = NULL; 309bf215546Sopenharmony_ci int count = 0; 310bf215546Sopenharmony_ci if (sc) 311bf215546Sopenharmony_ci count = sc->count; 312bf215546Sopenharmony_ci 313bf215546Sopenharmony_ci if (draw != NULL) { 314bf215546Sopenharmony_ci const struct shader_info *fs_info = 315bf215546Sopenharmony_ci iris_get_shader_info(ice, MESA_SHADER_FRAGMENT); 316bf215546Sopenharmony_ci if (fs_info && fs_info->name && strncmp(fs_info->name, "st/", 2) == 0) { 317bf215546Sopenharmony_ci event_name = fs_info->name; 318bf215546Sopenharmony_ci } else if (indirect) { 319bf215546Sopenharmony_ci event_name = "DrawIndirect"; 320bf215546Sopenharmony_ci if (indirect->count_from_stream_output) { 321bf215546Sopenharmony_ci event_name = "DrawTransformFeedback"; 322bf215546Sopenharmony_ci } 323bf215546Sopenharmony_ci } 324bf215546Sopenharmony_ci else if (draw->index_size) 325bf215546Sopenharmony_ci event_name = "DrawElements"; 326bf215546Sopenharmony_ci else 327bf215546Sopenharmony_ci event_name = "DrawArrays"; 328bf215546Sopenharmony_ci count = count * (draw->instance_count ? draw->instance_count : 1); 329bf215546Sopenharmony_ci } 330bf215546Sopenharmony_ci 331bf215546Sopenharmony_ci measure_start_snapshot(ice, batch, type, event_name, count); 332bf215546Sopenharmony_ci return; 333bf215546Sopenharmony_ci } 334bf215546Sopenharmony_ci} 335bf215546Sopenharmony_ci 336bf215546Sopenharmony_civoid 337bf215546Sopenharmony_ciiris_destroy_ctx_measure(struct iris_context *ice) 338bf215546Sopenharmony_ci{ 339bf215546Sopenharmony_ci /* All outstanding snapshots must be collected before the context is 340bf215546Sopenharmony_ci * destroyed. 341bf215546Sopenharmony_ci */ 342bf215546Sopenharmony_ci struct iris_screen *screen = (struct iris_screen *) ice->ctx.screen; 343bf215546Sopenharmony_ci intel_measure_gather(&screen->measure, &screen->devinfo); 344bf215546Sopenharmony_ci} 345bf215546Sopenharmony_ci 346bf215546Sopenharmony_civoid 347bf215546Sopenharmony_ciiris_measure_batch_end(struct iris_context *ice, struct iris_batch *batch) 348bf215546Sopenharmony_ci{ 349bf215546Sopenharmony_ci const struct intel_measure_config *config = config_from_context(ice); 350bf215546Sopenharmony_ci struct iris_screen *screen = (struct iris_screen *) ice->ctx.screen; 351bf215546Sopenharmony_ci struct iris_measure_batch *iris_measure_batch = batch->measure; 352bf215546Sopenharmony_ci struct intel_measure_batch *measure_batch = &iris_measure_batch->base; 353bf215546Sopenharmony_ci struct intel_measure_device *measure_device = &screen->measure; 354bf215546Sopenharmony_ci 355bf215546Sopenharmony_ci if (!config) 356bf215546Sopenharmony_ci return; 357bf215546Sopenharmony_ci if (!config->enabled) 358bf215546Sopenharmony_ci return; 359bf215546Sopenharmony_ci 360bf215546Sopenharmony_ci assert(measure_batch); 361bf215546Sopenharmony_ci assert(measure_device); 362bf215546Sopenharmony_ci 363bf215546Sopenharmony_ci static unsigned batch_count = 0; 364bf215546Sopenharmony_ci measure_batch->batch_count = p_atomic_inc_return(&batch_count); 365bf215546Sopenharmony_ci 366bf215546Sopenharmony_ci if (measure_batch->index % 2) { 367bf215546Sopenharmony_ci /* We hit the end of the batch, but never terminated our section of 368bf215546Sopenharmony_ci * drawing with the same render target or shaders. End it now. 369bf215546Sopenharmony_ci */ 370bf215546Sopenharmony_ci measure_end_snapshot(batch, measure_batch->event_count); 371bf215546Sopenharmony_ci } 372bf215546Sopenharmony_ci 373bf215546Sopenharmony_ci if (measure_batch->index == 0) 374bf215546Sopenharmony_ci return; 375bf215546Sopenharmony_ci 376bf215546Sopenharmony_ci /* enqueue snapshot for gathering */ 377bf215546Sopenharmony_ci pthread_mutex_lock(&measure_device->mutex); 378bf215546Sopenharmony_ci list_addtail(&iris_measure_batch->base.link, &measure_device->queued_snapshots); 379bf215546Sopenharmony_ci batch->measure = NULL; 380bf215546Sopenharmony_ci pthread_mutex_unlock(&measure_device->mutex); 381bf215546Sopenharmony_ci /* init new measure_batch */ 382bf215546Sopenharmony_ci iris_init_batch_measure(ice, batch); 383bf215546Sopenharmony_ci 384bf215546Sopenharmony_ci static int interval = 0; 385bf215546Sopenharmony_ci if (++interval > 10) { 386bf215546Sopenharmony_ci intel_measure_gather(measure_device, &screen->devinfo); 387bf215546Sopenharmony_ci interval = 0; 388bf215546Sopenharmony_ci } 389bf215546Sopenharmony_ci} 390bf215546Sopenharmony_ci 391bf215546Sopenharmony_civoid 392bf215546Sopenharmony_ciiris_measure_frame_end(struct iris_context *ice) 393bf215546Sopenharmony_ci{ 394bf215546Sopenharmony_ci struct iris_screen *screen = (struct iris_screen *) ice->ctx.screen; 395bf215546Sopenharmony_ci struct intel_measure_device *measure_device = &screen->measure; 396bf215546Sopenharmony_ci const struct intel_measure_config *config = measure_device->config; 397bf215546Sopenharmony_ci 398bf215546Sopenharmony_ci if (!config) 399bf215546Sopenharmony_ci return; 400bf215546Sopenharmony_ci 401bf215546Sopenharmony_ci /* increment frame counter */ 402bf215546Sopenharmony_ci intel_measure_frame_transition(p_atomic_inc_return(&measure_device->frame)); 403bf215546Sopenharmony_ci 404bf215546Sopenharmony_ci intel_measure_gather(measure_device, &screen->devinfo); 405bf215546Sopenharmony_ci} 406