The open source OpenXR runtime
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

u/pacing: Add gpu done time tracking to app pacer

authored by

Jakob Bornecrantz and committed by
Jakob Bornecrantz
8e8a0b38 04b9602d

+55 -4
+23
src/xrt/auxiliary/util/u_pacing.h
··· 326 326 void (*mark_delivered)(struct u_pacing_app *upa, int64_t frame_id, uint64_t when_ns); 327 327 328 328 /*! 329 + * A frame has been completed rendered by the GPU, this can happen after `xrEndFrame` has returned. 330 + * 331 + * @param upa Render timing helper. 332 + * @param[in] frame_id The frame ID to mark as delivered. 333 + * @param[in] when_ns The time when it the gpu was finished, nominally from @ref os_monotonic_get_ns 334 + */ 335 + void (*mark_gpu_done)(struct u_pacing_app *upa, int64_t frame_id, uint64_t when_ns); 336 + 337 + /*! 329 338 * Add a new sample point from the main render loop. 330 339 * 331 340 * This is called in the main renderer loop that tightly submits frames to the ··· 414 423 u_pa_mark_delivered(struct u_pacing_app *upa, int64_t frame_id, uint64_t when_ns) 415 424 { 416 425 upa->mark_delivered(upa, frame_id, when_ns); 426 + } 427 + 428 + /*! 429 + * @copydoc u_pacing_app::mark_gpu_done 430 + * 431 + * Helper for calling through the function pointer. 432 + * 433 + * @public @memberof u_pacing_app 434 + * @ingroup aux_pacing 435 + */ 436 + static inline void 437 + u_pa_mark_gpu_done(struct u_pacing_app *upa, int64_t frame_id, uint64_t when_ns) 438 + { 439 + upa->mark_gpu_done(upa, frame_id, when_ns); 417 440 } 418 441 419 442 /*!
+24 -2
src/xrt/auxiliary/util/u_pacing_app.c
··· 43 43 U_RT_WAIT_LEFT, 44 44 U_RT_PREDICTED, 45 45 U_RT_BEGUN, 46 + U_RT_DELIVERED, 46 47 }; 47 48 48 49 struct u_pa_frame ··· 65 66 uint64_t wait_woke_ns; 66 67 uint64_t begin_ns; 67 68 uint64_t delivered_ns; 69 + uint64_t gpu_done_ns; 68 70 } when; 69 71 70 72 enum u_pa_state state; ··· 318 320 assert(f->frame_id == frame_id); 319 321 assert(f->state == U_RT_BEGUN); 320 322 321 - // Update all data. 322 323 f->when.delivered_ns = when_ns; 324 + f->state = U_RT_DELIVERED; 325 + } 326 + 327 + static void 328 + pa_mark_gpu_done(struct u_pacing_app *upa, int64_t frame_id, uint64_t when_ns) 329 + { 330 + struct pacing_app *pa = pacing_app(upa); 331 + 332 + DEBUG_PRINT_FRAME_ID(); 333 + 334 + size_t index = GET_INDEX_FROM_ID(pa, frame_id); 335 + struct u_pa_frame *f = &pa->frames[index]; 336 + assert(f->frame_id == frame_id); 337 + assert(f->state == U_RT_DELIVERED); 338 + 339 + // Update all data. 340 + f->when.gpu_done_ns = when_ns; 323 341 324 342 325 343 /* ··· 336 354 #define NS_TO_MS_F(ns) (time_ns_to_s(ns) * 1000.0) 337 355 338 356 uint64_t diff_cpu_ns = f->when.begin_ns - f->when.wait_woke_ns; 339 - uint64_t diff_draw_ns = f->when.delivered_ns - f->when.begin_ns; 357 + uint64_t diff_draw_ns = f->when.gpu_done_ns - f->when.begin_ns; 340 358 341 359 UPA_LOG_D( 342 360 "Delivered frame %.2fms %s." // ··· 366 384 367 385 TE_BEG(pa_draw, f->when.begin_ns, "draw"); 368 386 TE_END(pa_draw, f->when.delivered_ns); 387 + 388 + TE_BEG(pa_wait, f->when.delivered_ns, "wait"); 389 + TE_END(pa_wait, f->when.gpu_done_ns); 369 390 } 370 391 371 392 #undef TE_BEG ··· 411 432 pa->base.mark_point = pa_mark_point; 412 433 pa->base.mark_discarded = pa_mark_discarded; 413 434 pa->base.mark_delivered = pa_mark_delivered; 435 + pa->base.mark_gpu_done = pa_mark_gpu_done; 414 436 pa->base.info = pa_info; 415 437 pa->base.destroy = pa_destroy; 416 438 pa->app.cpu_time_ns = U_TIME_1MS_IN_NS * 2;
+8 -2
src/xrt/compositor/multi/comp_multi_compositor.c
··· 324 324 { 325 325 struct multi_compositor *mc = multi_compositor(xc); 326 326 327 + // As early as possible. 328 + uint64_t now_ns = os_monotonic_get_ns(); 329 + os_mutex_lock(&mc->msc->list_and_timing_lock); 330 + u_pa_mark_delivered(mc->upa, frame_id, now_ns); 331 + os_mutex_unlock(&mc->msc->list_and_timing_lock); 332 + 327 333 assert(mc->progress.layer_count == 0); 328 334 U_ZERO(&mc->progress); 329 335 ··· 545 551 uint64_t now_ns = os_monotonic_get_ns(); 546 552 547 553 os_mutex_lock(&mc->msc->list_and_timing_lock); 548 - u_pa_mark_delivered(mc->upa, frame_id, now_ns); 554 + u_pa_mark_gpu_done(mc->upa, frame_id, now_ns); 549 555 os_mutex_unlock(&mc->msc->list_and_timing_lock); 550 556 551 557 return XRT_SUCCESS; ··· 587 593 uint64_t now_ns = os_monotonic_get_ns(); 588 594 589 595 os_mutex_lock(&mc->msc->list_and_timing_lock); 590 - u_pa_mark_delivered(mc->upa, frame_id, now_ns); 596 + u_pa_mark_gpu_done(mc->upa, frame_id, now_ns); 591 597 os_mutex_unlock(&mc->msc->list_and_timing_lock); 592 598 593 599 return XRT_SUCCESS;