Skip to content

Rework GPU Timing Stats - #988

Merged
bjornbytes merged 2 commits into
devfrom
get-timing
Jul 28, 2026
Merged

Rework GPU Timing Stats#988
bjornbytes merged 2 commits into
devfrom
get-timing

Conversation

@bjornbytes

@bjornbytes bjornbytes commented Jul 26, 2026

Copy link
Copy Markdown
Owner
  • Add a new async lovr.graphics.getTiming function that returns a table of timestamps for the last GPU submission, keyed by pass.
  • The timestamps are formatted like this:
{
  [pass1] = {
    duration = t,
    start = t,
    finish = t,
    submit = t
  },
  [pass2] = {
    duration = t,
    start = t,
    finish = t,
    submit = t
  }
}
  • The start/finish times are in the same units/epoch as lovr.timer.getTime, so you can correlate it with other CPU times.
  • Not every GPU can correlate timestamps, so start/finish may be nil. But nearly every desktop GPU supports it.
  • Deprecate gpuTime/submitTime in Pass:getStats.
  • Main goals are:
    • Make it easier to get stats for multiple passes
    • Use an async function to make it easier to correlate stats to a particular submit instead of updating the pass stats asynchronously
    • Use the start/finish times to see when a Pass actually ran (measure CPU-GPU latency, see if passes are overlapping on GPU)
    • Use 64 bit queries internally, because that's all WebGPU supports

Example:

lovr.graphics.setTimingEnabled(true)

function lovr.draw(pass)
  --

  lovr.graphics.submit(pass)

  lovr.task.start(function()
    for pass, t in pairs(lovr.graphics.getTiming()) do
      print(pass, t.duration, t.start, t.finish, t.submit)
    end
  end)

  return true
end

Logs can still be produced on shutdown (Vulkan validation layers), but
modules are destroyed after the Lua state is torn down now, so logging
in destructors won't work.  Instead, we can set the log callback to NULL
and implement fallback behavior, so at least the logs show up.  There
might be slightly better ways to handle this?
- Add a new async `lovr.graphics.getTiming` function that returns a
  table of timestamps for the last GPU submission, keyed by pass.
- The timestamps are formatted like this:

    {
      [pass1] = {
        duration = t,
        start = t,
        finish = t,
        submit = t
      },
      [pass2] = {
        duration = t,
        start = t,
        finish = t,
        submit = t
      }
    }

- The start/finish times are in the same units/epoch as
  `lovr.timer.getTime`, so you can correlate it with other CPU times.
- Not every GPU can correlate timestamps, so start/finish may be nil.
  But nearly every desktop GPU supports it.
- Deprecate `gpuTime`/`submitTime` in `Pass:getStats`.
- Main goals are:
  - Make it easier to get stats for multiple passes
  - Use an async function to make it easier to correlate stats to a
    particular submit instead of updating the pass stats asynchronously
@bjornbytes
bjornbytes merged commit b6519e5 into dev Jul 28, 2026
12 checks passed
@bjornbytes
bjornbytes deleted the get-timing branch July 28, 2026 19:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant