Compare commits

..
Author SHA1 Message Date
codegirl007 f295aedf04 Merge master into draw-sprite-max-sprites-guard.
Resolve batching_test.odin by keeping master tests and the MAX_SPRITES guard test.
2026-08-14 23:17:48 -07:00
codegirl007 ba0b25980c Speed group_texture_runs for two-texture batches 2026-08-14 23:13:29 -07:00
codegirl007 c97a17f85b Speed group_texture_runs for two-texture batches. 2026-08-14 23:08:00 -07:00
codegirl007 9df98ef73d Merge pull request #31 from Codegirl-Games/test-sprite-clip-cache
Test sprite clip_def cache on set_sprite_clip
2026-08-14 22:44:52 -07:00
codegirl007 f65b0354df Test that set_sprite_clip caches clip_def on sprites.
Locks spawn/switch cache fill and that a bad clip name leaves the prior cache intact.
2026-08-14 22:43:42 -07:00
codegirl007 cc196afd2e Cache sprite clip defs to cut per-frame map lookups 2026-08-14 22:42:15 -07:00
codegirl007 8d9faaaee0 Drop verbose comments from the clip-cache change. 2026-08-14 22:40:42 -07:00
codegirl007 41fb0a3d5a Cache clip defs on sprites to avoid per-frame map lookups.
Crowd stress (128 sprites) showed Clip_Def string map_get as the top engine cost; cache on set_sprite_clip and use it in update/draw.
2026-08-14 22:32:28 -07:00
codegirl007 dcf5ea29b0 Texture batching with prepare_draw_batches test coverage 2026-08-14 22:20:08 -07:00
codegirl007 70784b0f1b Test DXIL shader runtime preference without MSL 2026-08-14 22:19:16 -07:00
codegirl007 fb63ee21f4 Test draw_sprite refuses to exceed MAX_SPRITES.
Locks the enqueue capacity guard so a full draw_list cannot grow past the vertex buffer budget.
2026-08-14 22:18:42 -07:00
codegirl007 deef204bd3 Test DXIL preference when MSL is unavailable.
Locks the MSL > DXIL > SPIRV shader runtime order so Windows paths cannot silently fall through to Vulkan.
2026-08-14 22:16:58 -07:00
codegirl007 25dd3aa920 Add texture batching with TDD coverage at enqueue and prepare seams.
Opt-in batch_group regrouping cuts texture binds; prepare_draw_batches and draw_list tests lock the contract so end_frame cannot silently drop regroup.
2026-08-14 22:15:08 -07:00
codegirl007 0d4cdbd8ca Optimize build with -o:speed 2026-08-09 14:28:21 -07:00
codegirl007 9727aa4d7a Merge branch 'master' into optimized-build 2026-08-09 14:16:11 -07:00
codegirl007 b8b05954b1 fixes 2026-08-09 14:13:13 -07:00
codegirl007 58a2d5267e optimize build for speed 2026-08-09 14:05:28 -07:00
26 changed files with 6074 additions and 1354 deletions
@@ -1,208 +0,0 @@
# Add configurable internal render scale to improve fill-bound FPS
## Summary
Complete-frame benchmarks show that the current sprite renderer is primarily
pixel/fill bound on Vulkan/Lavapipe, not CPU draw-preparation bound. Rendering
the world into a smaller offscreen color target and nearest-blitting it to the
native swapchain produced the largest measured FPS improvement.
This should be an opt-in render-quality setting with a native-resolution
fallback. For pixel art, a 50% scale is especially useful because it maps to an
exact 2× nearest-neighbor upscale.
## Evidence
Environment:
- Commit `dc66203259e92ce39291556f7b6c26c8dd999b84`
- Odin `dev-2026-05-nightly:ea5175d`
- `-debug -o:speed`
- SDL 3.4.12, Vulkan/Lavapipe, immediate present
- 800×600 swapchain
- Five 150-frame trials per invocation after 50 warm-up frames
- Order-balanced baseline/candidate invocations
- GPU idle wait included before stopping each trial timer
### Fill and overdraw scaling
The committed `perf-frame` harness produced:
| Workload | Median frame time | Median FPS |
| --- | ---: | ---: |
| 1 visible sprite | 0.592 ms | 1,690 |
| 24 visible sprites | 2.249 ms | 445 |
| 64 visible sprites | 4.017 ms | 249 |
| 128 visible sprites | 6.255 ms | 160 |
| 128 stacked sprites | 7.692 ms | 130 |
Stacking the same 128 sprites increased frame time by approximately 23%,
confirming that overdraw matters.
With one centered sprite, render-target scaling produced:
| Window size | Pixels | Median frame time |
| --- | ---: | ---: |
| 400×300 | 120,000 | 0.268 ms |
| 800×600 | 480,000 | 0.545 ms |
| 1600×1200 | 1,920,000 | 2.075 ms |
The near-linear increase at larger sizes is further evidence of a pixel-bound
workload.
### Internal render-scale prototype
The temporary candidate kept the physical swapchain at 800×600, rendered
sprites into a smaller `COLOR_TARGET | SAMPLER` texture, and used
`BlitGPUTexture` with nearest filtering to upscale into the swapchain.
Aggregate medians across ten trials per mode:
| Workload | Native | 75% scale | 50% scale |
| --- | ---: | ---: | ---: |
| 128 spread sprites | 6.082 ms / 164 FPS | 4.082 ms / 245 FPS | 3.082 ms / 325 FPS |
| 128 stacked sprites | 7.912 ms / 126 FPS | 5.116 ms / 195 FPS | 3.034 ms / 330 FPS |
Compared with native resolution:
- 75% reduced frame time by 3335% and increased FPS by 4955%.
- 50% reduced frame time by 4962% and increased FPS by 97161%.
A visual smoke test confirmed that the 50% path rendered the complete scene at
the correct orientation and 800×600 output size. It was visibly coarser, as
expected. A 75% scale at 800×600 does not produce an integer upscale and can
create uneven pixel sizing with nearest filtering.
## Reproduction harness
Native spread and stacked workloads:
```bash
make perf-frame \
PERF_FRAME_SCENARIO=0 \
PERF_FRAME_SPRITES=128 \
PERF_FRAME_WIDTH=800 \
PERF_FRAME_HEIGHT=600
make perf-frame \
PERF_FRAME_SCENARIO=3 \
PERF_FRAME_SPRITES=128 \
PERF_FRAME_WIDTH=800 \
PERF_FRAME_HEIGHT=600
```
Run the same commands on the candidate branch with internal render scale set to
75% and 50%. Keep every `PERF_FRAME_*` value unchanged between comparisons.
## Suggested fix
Add explicit logical/output and internal-render dimensions to `App`:
```odin
Render_Scale :: enum {
Native,
Three_Quarter,
Half,
}
App :: struct {
// Existing swapchain fields remain the logical/output dimensions.
swapchain_texture: ^sdl.GPUTexture,
swapchain_w: u32,
swapchain_h: u32,
render_scale: Render_Scale,
scene_texture: ^sdl.GPUTexture,
scene_w: u32,
scene_h: u32,
}
```
Create the offscreen target with the swapchain format and both usages required
by SDL's blit path:
```odin
app.scene_texture = sdl.CreateGPUTexture(
app.device,
{
type = .D2,
format = sdl.GetGPUSwapchainTextureFormat(app.device, app.window),
usage = {.COLOR_TARGET, .SAMPLER},
width = app.scene_w,
height = app.scene_h,
layer_count_or_depth = 1,
num_levels = 1,
sample_count = ._1,
},
)
```
Render the sprite pass into `scene_texture`. Continue using the logical
swapchain dimensions for camera and clip-space calculations so world layout
does not change with render scale:
```odin
color_info := sdl.GPUColorTargetInfo {
texture = app.scene_texture,
clear_color = app.clear_color,
load_op = .CLEAR,
store_op = .STORE,
cycle = true,
}
```
After ending the render pass, upscale into the full swapchain:
```odin
blit := sdl.GPUBlitInfo {
source = {
texture = app.scene_texture,
w = app.scene_w,
h = app.scene_h,
},
destination = {
texture = app.swapchain_texture,
w = app.swapchain_w,
h = app.swapchain_h,
},
load_op = .DONT_CARE,
filter = .NEAREST,
}
sdl.BlitGPUTexture(app.cmd, blit)
```
Use the existing direct-to-swapchain path at native scale to avoid an
unnecessary blit. Recreate the offscreen texture whenever the swapchain size,
format, or render-scale setting changes. If native-resolution UI or text is
added later, render it after the world blit in a separate swapchain pass.
## Rejected experiment: fragment alpha discard
Approximately 49.7% of pixels inside the baked frame rectangles have exact
alpha zero. A temporary fragment shader discarded those texels:
```glsl
vec4 texel = texture(u_tex, v_uv);
if (texel.a == 0.0) {
discard;
}
out_color = texel;
```
Despite the high transparent coverage, this regressed frame time by roughly
56% in both spread and stacked workloads. Do not add alpha discard without
contradictory hardware-GPU evidence.
## Acceptance criteria
- Native, 75%, and 50% internal render-scale settings are available.
- Native scale retains the current direct-to-swapchain path.
- The scene target is recreated safely on resize, format change, or scale
change and released during shutdown.
- Camera/world coordinates remain stable when render scale changes.
- Nearest filtering is used for pixel-art output.
- Add screenshot-based checks for output orientation, viewport coverage, and
stable sprite placement at every scale.
- Benchmark spread and stacked scenarios on at least one hardware GPU.
- Document the quality tradeoff and recommend integer upscale ratios for pixel
art.
@@ -1,218 +0,0 @@
# Add deterministic CPU and frame benchmarks for sprite rendering
## Summary
The current `make flame` workflow is valuable for finding call stacks, but it
does not provide a reproducible performance metric:
- `examples/crowd` draws only 24 sprites.
- `MAX_SPRITES` limits the renderer to 128 sprites.
- Recording starts an interactive application and asks the user to play for
1020 seconds before quitting.
- The two checked-in reports contain only 499 and 469 samples.
- CPU queue construction and GPU submission are combined in one profile.
- The profiler currently builds unoptimized code.
These limitations make it difficult to tell whether a change made
`draw_sprite` faster, changed driver behavior, or merely changed sampling noise.
## Evidence
A temporary deterministic benchmark exposed two very different results:
1. CPU-only `draw_sprite`, two million calls and seven trials:
- `-debug`: median 192.560 ns/draw
- `-debug -o:speed`: median 19.154 ns/draw
2. Full 128-sprite frames through SDL GPU on Lavapipe, 1,000 measured frames
and five trials:
- `-debug`: median 2.486 ms/frame
- `-debug -o:speed`: median 2.447 ms/frame
At the current cap, optimized CPU queue construction is approximately 3.2
microseconds for 128 sprites. The full software-rendered frame is around 2.45
milliseconds, so optimizing `draw_sprite` cannot materially improve that
specific end-to-end workload. A hardware GPU or a larger future sprite limit
may have a different balance.
This split also explains why percentages from the current unoptimized
flamegraphs overstate small helper functions.
### Follow-up enhancement benchmarks
Six proposed renderer changes were implemented temporarily and measured before
being discarded. Full-frame tests used:
- Odin `dev-2026-05-nightly:ea5175d`
- `-debug -o:speed`
- SDL 3.4.12 with Vulkan/Lavapipe
- 128 animated sprites using real baked toad metadata and textures
- Warm-up before measurement
- Paired baseline/change samples on the same device with alternating order
- Ten 400-frame samples per mode, except culling, which used seven 750-frame
samples per mode
Each row is a separate paired run, so absolute frame times should only be
compared within that row.
| Enhancement | Baseline median | Changed median | Result |
| --- | ---: | ---: | ---: |
| Viewport culling, all visible | 4.845 ms | 4.822 ms | 0.5% faster |
| Viewport culling, 50% offscreen | 2.856 ms | 2.878 ms | 0.8% slower |
| SDL transfer and vertex buffer cycling | 4.869 ms | 4.834 ms | 0.7% faster |
| Contiguous vertex queue and one upload-side copy | 4.793 ms | 4.809 ms | 0.3% slower |
| Four-vertex indexed quads | 4.745 ms | 4.830 ms | 1.8% slower |
| GPU instancing with 32-byte instance records | 5.527 ms | 5.467 ms | 1.1% faster |
| Texture sorting, including sort cost, 128 runs to 2 | 5.765 ms | 5.654 ms | 1.9% faster |
Interpretation:
- Viewport culling is neutral at the current cap. The GPU already clips
offscreen triangles, and the sprites remain in one batched draw.
- SDL buffer cycling is a small performance improvement and is also the
documented way to avoid overwriting resources still bound by prior frames.
- Repacking the CPU queue does not help at 128 sprites; extra dynamic-array
work offsets the saved small-copy loop.
- Indexed quads regress performance despite reducing dynamic vertex data.
- Instancing reduces per-sprite upload data from 96 to 32 bytes, but the 1.1%
gain does not justify a second pipeline and shader path at the current cap.
- Texture sorting has the largest full-frame gain, but unrestricted sorting can
change alpha compositing. It is only safe within compatible layer/order
groups.
The recommended order is:
1. Profile optimized builds and establish the deterministic benchmark.
2. Apply the clip-space math simplification documented in the related issue.
3. Enable SDL buffer cycling for correct cross-frame resource reuse.
4. Consider layer-aware texture grouping if a 1.9% workload-specific gain is
worth the ordering complexity.
5. Defer culling, queue repacking, indexed quads, and instancing until the
sprite limit or measured workload grows substantially.
These results are from a software Vulkan backend. Hardware drivers may have a
different balance, which is another reason to keep the benchmark reproducible
and report backend details.
## Suggested fix
Add a non-interactive benchmark target with two explicitly separate workloads.
The committed harnesses are:
```make
PERF_ODIN_FLAGS ?= -debug -o:speed
perf-draw:
odin run benchmarks/draw_sprite \
-collection:pkg=. \
$(PERF_ODIN_FLAGS) \
-define:PERF_ITERATIONS=$(PERF_DRAW_ITERATIONS)
perf-frame:
odin run benchmarks/sprite_frame \
-collection:pkg=. \
$(PERF_ODIN_FLAGS) \
-define:PERF_FRAMES=$(PERF_FRAME_FRAMES) \
-define:PERF_SCENARIO=$(PERF_FRAME_SCENARIO)
```
Run the standard workloads with:
```bash
# CPU-only draw preparation.
make perf-draw
# Complete frame: 128 visible sprites sharing one texture.
make perf-frame PERF_FRAME_SCENARIO=0
# Complete frame: every second sprite is fully offscreen.
make perf-frame PERF_FRAME_SCENARIO=1
# Complete frame: 128 sprites alternate between two texture objects.
make perf-frame PERF_FRAME_SCENARIO=2
```
Every invocation prints the Git commit, Odin version, compiler flags, workload
configuration, every trial, and the median. `perf-frame` waits for GPU idle
after warm-up and after each measured frame batch so outstanding work is
included.
### CPU queue benchmark
- Construct `App`, `Character_Data`, and `Sprite` with real baked metadata.
- Use safe fake non-null GPU handles; `draw_sprite` only checks/stores these.
- Preallocate the draw list.
- Clear the queue whenever it reaches `MAX_SPRITES`.
- Vary sprite position between calls so the compiler cannot hoist the work.
- Warm up before timing.
- Run at least one million calls and report nanoseconds per draw.
- Build with `-o:speed` by default.
The measured loop should clear the queue at its cap, vary input to prevent
compiler hoisting, and report time per draw:
```odin
PERF_ITERATIONS :: #config(PERF_ITERATIONS, 2_000_000)
start := sdl.GetTicksNS()
for i in 0 ..< PERF_ITERATIONS {
if len(app.draw_list) == eng.MAX_SPRITES {
clear(&app.draw_list)
}
sprite.position.x = f32(i & 1023)
eng.draw_sprite(&app, &sprite)
}
elapsed := sdl.GetTicksNS() - start
fmt.printfln(
"%.3f ns/draw",
f64(elapsed) / f64(PERF_ITERATIONS),
)
```
### Full-frame benchmark
- Use a real SDL GPU device and baked texture.
- Warm up before timing.
- Run a fixed number of frames without interactive input.
- Report milliseconds per frame and sprites per second.
- Record GPU backend, present mode, compiler version, compiler flags, and sprite
count.
Use a fixed frame count rather than an interactive quit time:
```odin
PERF_FRAMES :: #config(PERF_FRAMES, 1_000)
for _ in 0 ..< 100 {
draw_benchmark_frame(&app, sprites[:]) // warm-up
}
start := sdl.GetTicksNS()
for _ in 0 ..< PERF_FRAMES {
draw_benchmark_frame(&app, sprites[:])
}
elapsed := sdl.GetTicksNS() - start
fmt.printfln(
"%.3f ms/frame",
f64(elapsed) / f64(PERF_FRAMES) / 1_000_000.0,
)
```
The CPU benchmark should be available without a display or GPU. The full-frame
benchmark may remain opt-in where a suitable GPU backend is unavailable.
Do not add a strict CI regression threshold initially; hosted runner variance
will make a single threshold flaky. CI can still compile the benchmark and
verify that it completes.
## Acceptance criteria
- A Makefile target runs the optimized CPU benchmark non-interactively.
- Results include compiler flags, iteration count, median, and per-trial values.
- CPU queue time is reported separately from complete frame time.
- Sprite positions or frames vary during the measured loop.
- The draw list never silently exceeds `MAX_SPRITES`.
- The benchmark has documented commands for repeatable local comparison.
- `make check` and `make test` continue to pass.
@@ -1,116 +0,0 @@
# Add opt-in order-safe texture batching
## Summary
`end_frame` batches only consecutive sprites that use the same texture.
Alternating two textures therefore produces one sampler bind and draw call per
sprite even when some sprites could safely be regrouped.
Globally sorting transparent sprites by texture is not correct: overlapping
sprites may blend differently when submission order changes. Batching should
therefore be opt-in within explicit groups whose members are safe to reorder.
## Evidence
A temporary paired benchmark used:
- Odin `dev-2026-05-nightly:ea5175d` with `-debug -o:speed`
- SDL 3.4.12 and Vulkan/Lavapipe
- 128 animated sprites alternating between two equivalent textures
- Sorting cost included in the measured frame
- Ten order-alternated samples of 400 frames per mode
| Mode | Texture runs | Median frame time |
| --- | ---: | ---: |
| Submission order | 128 | 5.765 ms |
| Texture grouped | 2 | 5.654 ms |
Sorting and grouping improved median frame time by approximately **1.9%**.
Hardware drivers with higher draw-call overhead may show a different result.
## Reproduction harness
Run the committed alternating-texture workload on the baseline and candidate
commits:
```bash
make perf-frame \
PERF_FRAME_SCENARIO=2 \
PERF_ODIN_FLAGS="-debug -o:speed"
```
Keep all `PERF_FRAME_*` values unchanged. The baseline should produce one
texture run per sprite; the candidate should reduce runs only inside explicit
reorder-safe groups. Compare `median_ms_per_frame` and verify rendered output.
## Suggested fix
Add an explicit batch group to queued sprites. Group `0` keeps strict submission
order; nonzero groups may be reordered only when the caller guarantees that
their members are order-independent.
```odin
Queued_Sprite :: struct {
texture: ^sdl.GPUTexture,
verts: [SPRITE_VERT_COUNT]Vertex,
batch_group: u32, // 0 = strict order; nonzero = caller permits regrouping
}
```
Sort each contiguous, nonzero group by texture immediately before upload:
```odin
group_texture_runs :: proc(list: []Queued_Sprite) {
start := 0
for start < len(list) {
group := list[start].batch_group
if group == 0 {
start += 1
continue
}
end := start + 1
for end < len(list) && list[end].batch_group == group {
end += 1
}
// Stable insertion sort is sufficient while MAX_SPRITES is 128.
for i in start + 1 ..< end {
item := list[i]
j := i
for j > start {
if uintptr(list[j - 1].texture) <= uintptr(item.texture) {
break
}
list[j] = list[j - 1]
j -= 1
}
list[j] = item
}
start = end
}
}
```
Call it after all sprites are queued and before the transfer-buffer copy:
```odin
group_texture_runs(app.draw_list[:])
```
Expose batching through a separate API or explicit parameter so existing
`draw_sprite` calls remain strict-order by default:
```odin
draw_sprite_batched(&app, &sprite, batch_group = 1)
```
## Acceptance criteria
- Existing `draw_sprite` behavior preserves exact submission order.
- Reordering requires an explicit nonzero batch group.
- Sorting never moves a sprite across a strict-order entry or group boundary.
- Add tests for strict order, group boundaries, stable same-texture ordering,
and reduced texture-run count.
- Add a visual overlap test confirming default alpha compositing is unchanged.
- Benchmark sorting cost and draw-call reduction on a hardware GPU.
@@ -1,83 +0,0 @@
# Enable SDL GPU buffer cycling for per-frame sprite uploads
## Summary
`end_frame` overwrites the same transfer buffer and vertex buffer every frame,
but both SDL calls currently pass `cycle = false`:
```odin
sdl.MapGPUTransferBuffer(app.device, app.transfer_buffer, false)
sdl.UploadToGPUBuffer(copy_pass, src, dst, false)
```
SDL documents cycling as the mechanism that rotates to an unbound internal
resource when the previous frame still references the current one. Enabling it
avoids an unnecessary resource dependency and makes the overwrite pattern
explicitly safe.
## Evidence
A temporary paired benchmark used:
- Odin `dev-2026-05-nightly:ea5175d` with `-debug -o:speed`
- SDL 3.4.12 and Vulkan/Lavapipe
- 128 animated sprites
- Ten order-alternated samples of 400 frames per mode
| Mode | Median frame time |
| --- | ---: |
| Cycling disabled | 4.869 ms |
| Cycling enabled | 4.834 ms |
Cycling improved median frame time by approximately **0.7%**. This is a small
performance change, but it also follows SDL's documented resource-reuse model.
## Reproduction harness
Run the committed full-frame harness on the baseline commit and candidate
commit:
```bash
make perf-frame \
PERF_FRAME_SCENARIO=0 \
PERF_ODIN_FLAGS="-debug -o:speed"
```
Keep all `PERF_FRAME_*` values unchanged. Compare `median_ms_per_frame`; the
harness waits for GPU idle before stopping each trial timer.
## Suggested fix
Cycle both resources that are fully overwritten each frame:
```odin
map_ptr := sdl.MapGPUTransferBuffer(
app.device,
app.transfer_buffer,
true, // rotate if the previous frame still binds this transfer buffer
)
// Write the complete [0, n * SPRITE_VERTS_SIZE) range, then unmap.
sdl.UnmapGPUTransferBuffer(app.device, app.transfer_buffer)
copy_pass := sdl.BeginGPUCopyPass(cmd)
sdl.UploadToGPUBuffer(
copy_pass,
src,
dst,
true, // rotate the destination vertex buffer if it is still bound
)
sdl.EndGPUCopyPass(copy_pass)
```
Cycling makes previous contents undefined, so this remains correct only because
the renderer writes the complete vertex range used by the frame before drawing.
Do not enable cycling for partial updates that depend on untouched data.
## Acceptance criteria
- Both `MapGPUTransferBuffer` and `UploadToGPUBuffer` use `cycle = true`.
- The complete submitted vertex range is rewritten every frame.
- Existing engine tests and examples continue to pass.
- A full-frame benchmark confirms no regression on a hardware GPU backend.
- Add a comment explaining why cycling is safe for this full-overwrite path.
@@ -1,98 +0,0 @@
# Profile optimized sprite builds instead of unoptimized debug code
## Summary
`make flame-build` currently compiles the selected example with `-debug` but
without an optimization mode:
```make
odin build examples/$(FLAME_EXAMPLE) -collection:pkg=. -out:$(FLAME_BIN) -debug
```
This makes the flamegraph useful for debugging but misleading for performance
decisions. The current profiles largely describe code that will disappear or
be inlined in an optimized build.
## Evidence
The two checked-in `crowd` profiles were captured from this unoptimized binary.
They report:
- `engine::draw_sprite`: 9.56% and 12.22% self time
- `engine::to_clip`: 5.33% and 5.51% self time
- `engine::sprite_feet_quad`: 3.98% and 3.30% self time
- Additional time in string hashing/map lookup, bounds checks, and dynamic
array append helpers
A CPU-only benchmark using the real `draw_sprite`, real baked toad metadata,
preallocated draw list, changing sprite positions, and two million draws per
trial produced:
| Build | Median time per draw | Trials |
| --- | ---: | ---: |
| `-debug` (current Makefile behavior) | 192.560 ns | 7 |
| `-debug -o:speed` | 19.154 ns | 7 |
The optimized build is about **10.1x faster** without an engine code change.
An end-to-end 128-sprite benchmark on SDL 3.4.12 with Lavapipe showed only a
small full-frame difference (median 2.486 ms debug versus 2.447 ms optimized)
because software GPU/driver work dominated. This does not invalidate the CPU
result; it shows why CPU queue time and full-frame time must be reported
separately.
Environment:
- Odin `dev-2026-05-nightly:ea5175d` (the version pinned by CI)
- SDL 3.4.12
- Linux x86-64
## Suggested fix
Compile profiling binaries with optimization while retaining symbols:
```make
FLAME_ODIN_FLAGS ?= -debug -o:speed
flame-build:
odin build examples/$(FLAME_EXAMPLE) \
-collection:pkg=. \
-out:$(FLAME_BIN) \
$(FLAME_ODIN_FLAGS)
```
Keeping the flags configurable allows an explicitly unoptimized diagnostic run
without making it the performance default.
Example usage:
```bash
# Representative performance profile: optimized code with debug symbols.
make flame FLAME_EXAMPLE=crowd
# Explicitly profile unoptimized code when investigating debug-only behavior.
make flame FLAME_EXAMPLE=crowd FLAME_ODIN_FLAGS="-debug -o:none"
```
Reproduce the isolated build-mode comparison with the committed CPU harness:
```bash
make perf-draw PERF_ODIN_FLAGS="-debug -o:none"
make perf-draw PERF_ODIN_FLAGS="-debug -o:speed"
```
Both runs print the Git commit, Odin version, compiler flags, every trial, and
the median nanoseconds per draw.
Consider applying an explicit optimization mode to performance-oriented example
runs as well. Plain `odin run` currently uses Odin's unoptimized default.
## Acceptance criteria
- `make flame-build` produces an optimized binary with debug symbols.
- `FLAME_ODIN_FLAGS` can override the default for diagnostic builds.
- `make check` and `make test` continue to pass.
- A new `crowd` profile records the exact compiler flags in its report or
accompanying documentation.
- Performance conclusions distinguish CPU `draw_sprite` cost from complete
frame/GPU submission cost.
@@ -1,139 +0,0 @@
# Prototype instanced sprite rendering for larger batches
## Summary
The renderer currently generates and uploads six complete vertices per sprite:
```text
6 vertices × (position float2 + UV float2) = 96 bytes/sprite/frame
```
Instancing can keep one immutable six-corner unit quad on the GPU and upload one
rectangle/UV record per sprite:
```text
clip rectangle float4 + UV rectangle float4 = 32 bytes/sprite/frame
```
This reduces dynamic upload volume by two thirds, but requires another pipeline
and backend-specific vertex shader. At the current 128-sprite cap, the measured
gain is too small to justify enabling it unconditionally.
## Evidence
A complete temporary instanced path was implemented with:
- A static six-corner vertex buffer
- A 32-byte per-instance buffer
- Vertex-rate and instance-rate pipeline inputs
- One instanced draw per texture run
- Validated SPIR-V and SDL's debug GPU device
The paired benchmark used ten order-alternated samples of 400 frames:
| Mode | Median frame time |
| --- | ---: |
| Six dynamic vertices per sprite | 5.527 ms |
| 32-byte instance per sprite | 5.467 ms |
Instancing improved median frame time by approximately **1.1%** on
Vulkan/Lavapipe with 128 sprites.
## Reproduction harness
Run the committed visible full-frame workload on baseline and candidate commits:
```bash
make perf-frame \
PERF_FRAME_SCENARIO=0 \
PERF_FRAME_SPRITES=128 \
PERF_ODIN_FLAGS="-debug -o:speed"
```
Keep all other `PERF_FRAME_*` values unchanged and compare
`median_ms_per_frame`. To test 512 or more sprites, first raise the engine's
`MAX_SPRITES` and associated buffer capacities on the candidate branch, then
set `PERF_FRAME_SPRITES` to the same value.
## Suggested fix
Treat this as a prototype gated by larger sprite counts or a demonstrated
hardware bottleneck, not as an immediate replacement.
Define the compact instance payload:
```odin
Sprite_Instance :: struct {
clip_rect: [4]f32, // left, top, right, bottom
uv_rect: [4]f32, // u0, v0, u1, v1
}
```
Queue one record after the existing quad and UV calculations:
```odin
instance := Sprite_Instance {
clip_rect = {p0.x, p0.y, p2.x, p2.y},
uv_rect = {u0, v0, u1, v1},
}
append(&app.instance_list, instance)
```
Use a static unit quad:
```odin
UNIT_QUAD := [6]Vec2 {
{0, 0}, {1, 0}, {1, 1},
{0, 0}, {1, 1}, {0, 1},
}
```
The instanced vertex shader reconstructs position and UV:
```glsl
#version 450
layout(location = 0) in vec2 in_corner;
layout(location = 1) in vec4 in_clip_rect;
layout(location = 2) in vec4 in_uv_rect;
layout(location = 0) out vec2 v_uv;
void main() {
vec2 position = mix(in_clip_rect.xy, in_clip_rect.zw, in_corner);
v_uv = mix(in_uv_rect.xy, in_uv_rect.zw, in_corner);
gl_Position = vec4(position, 0.0, 1.0);
}
```
Configure slot 0 as vertex-rate and slot 1 as instance-rate, then draw each
texture run with six vertices and `run` instances:
```odin
vb_descs := [2]sdl.GPUVertexBufferDescription {
{slot = 0, pitch = u32(size_of(Vec2)), input_rate = .VERTEX},
{slot = 1, pitch = u32(size_of(Sprite_Instance)), input_rate = .INSTANCE},
}
sdl.DrawGPUPrimitives(
app.render_pass,
6, // unit-quad vertices
u32(run), // sprite instances in this texture run
0,
0,
)
```
Keep the current path as a fallback until the instanced implementation exists
for Vulkan, D3D12, and Metal and demonstrates a meaningful hardware win.
## Acceptance criteria
- Benchmark at 128, 512, 2,048, and 10,000 sprites or the highest supported
counts.
- Report CPU queue time, bytes uploaded, and complete frame time separately.
- Require a meaningful hardware improvement before changing the default path.
- Supply equivalent Vulkan, D3D12, and Metal shaders.
- Preserve texture-run batching and sprite flip/trim behavior.
- Add visual equivalence tests for position, UVs, animation frames, and flip.
- Retain the existing six-vertex path as a fallback during evaluation.
@@ -1,130 +0,0 @@
# Reduce repeated clip-space work in `draw_sprite`
## Summary
`draw_sprite` calls `to_clip` four times for an axis-aligned quad:
```odin
p0 := to_clip(x0_px, y0_px, sw, sh)
p1 := to_clip(x1_px, y0_px, sw, sh)
p2 := to_clip(x1_px, y1_px, sw, sh)
p3 := to_clip(x0_px, y1_px, sw, sh)
```
This repeats the same divisions and converts duplicate x/y coordinates. An
axis-aligned sprite has only two unique x values and two unique y values.
This is a measurable optimization, but it is low priority at the current
128-sprite limit because the absolute saving is small.
## Evidence
The checked-in unoptimized profiles report `engine::to_clip` at 5.33% and 5.51%
self time. Those percentages are inflated by the unoptimized profiling build,
so the change was also measured with `-debug -o:speed`.
A temporary benchmark used the real baked toad metadata, changed sprite
position on every iteration, preallocated the queue, and performed two million
draws per mode over seven trials:
| Mode | Median time per draw |
| --- | ---: |
| Current `draw_sprite` | 25.128 ns |
| Precomputed clip scale and reused coordinates | 21.531 ns |
| Same math plus cached `Frame_Def` | 21.778 ns |
Simplifying the math improved isolated draw time by approximately **14.3%**.
Caching the resolved frame did not provide an additional benefit and should not
be included without new evidence.
At `MAX_SPRITES == 128`, the measured math saving is only about 0.46
microseconds per completely full frame. GPU/driver work dominated the
end-to-end benchmark, so this should follow the profiling and deterministic
benchmark improvements.
Follow-up paired full-frame experiments at the 128-sprite cap found no larger
renderer-architecture win: buffer cycling improved median frame time by 0.7%,
GPU instancing by 1.1%, and texture sorting by 1.9%, while culling, queue
repacking, and indexed quads were neutral or slower. The clip-space change
therefore remains the strongest measured optimization specifically inside
`draw_sprite`, although its absolute frame impact is still small.
Environment:
- Odin `dev-2026-05-nightly:ea5175d`
- Optimized with `-debug -o:speed`
- Linux x86-64
## Reproduction harness
Run the committed CPU harness on the baseline commit and again after applying
the suggested fix:
```bash
make perf-draw PERF_ODIN_FLAGS="-debug -o:speed"
```
Keep `PERF_DRAW_ITERATIONS`, `PERF_DRAW_WARMUP`, and `PERF_DRAW_TRIALS`
unchanged between commits. Compare `median_ns_per_draw`.
## Suggested fix
Compute clip scaling once and construct corners from the unique coordinates:
```odin
sprite_quad_to_clip :: proc(x0, y0, x1, y1, sw, sh: f32) -> [4]Vec2 {
sx := 2.0 / sw
sy := 2.0 / sh
left := x0 * sx - 1
right := x1 * sx - 1
top := 1 - y0 * sy
bottom := 1 - y1 * sy
return {
{left, top},
{right, top},
{right, bottom},
{left, bottom},
}
}
points := sprite_quad_to_clip(x0_px, y0_px, x1_px, y1_px, sw, sh)
p0, p1, p2, p3 := points[0], points[1], points[2], points[3]
```
Keep `to_clip` for general callers and its existing tests; this change only
specializes quad construction inside `draw_sprite`.
Add an equivalence test before replacing the current calls:
```odin
@(test)
sprite_quad_clip_math_matches_to_clip :: proc(t: ^testing.T) {
x0, y0 := f32(125), f32(80)
x1, y1 := f32(325), f32(280)
sw, sh := f32(800), f32(600)
expected := [4]Vec2 {
to_clip(x0, y0, sw, sh),
to_clip(x1, y0, sw, sh),
to_clip(x1, y1, sw, sh),
to_clip(x0, y1, sw, sh),
}
actual := sprite_quad_to_clip(x0, y0, x1, y1, sw, sh)
for i in 0 ..< 4 {
testing.expect_value(t, actual[i], expected[i])
}
}
```
## Acceptance criteria
- Existing sprite geometry, camera, UV, and batching tests pass.
- Add or extend a test that compares all four generated corners against
`to_clip` for representative viewport and sprite coordinates.
- Flipped and unflipped sprites produce identical vertices to the current code.
- An optimized deterministic benchmark shows at least a 10% improvement in
isolated `draw_sprite` time under comparable conditions.
- Do not add a per-sprite frame cache as part of this issue.
+2 -40
View File
@@ -1,6 +1,5 @@
.PHONY: shaders-vulkan shaders-d3d12 shaders-metal shaders-all bake toad hello_sprite crowd camera_sandbox clips check test help
.PHONY: flame flame-build flame-record flame-svg flame-report flame-tools
.PHONY: perf-draw perf-frame
# Flamegraph profiling (needs: pacman -S perf). Example: make flame or make flame FLAME_EXAMPLE=toad
FLAME_EXAMPLE ?= crowd
@@ -13,19 +12,6 @@ FLAME_STAMP := $(shell date +%Y%m%d-%H%M%S)
endif
FLAME_PREFIX := $(FLAME_OUT_DIR)/$(FLAME_EXAMPLE)-$(FLAME_STAMP)
PERF_DRAW_ITERATIONS ?= 2000000
PERF_DRAW_WARMUP ?= 10000
PERF_DRAW_TRIALS ?= 7
PERF_ODIN_FLAGS ?= -debug -o:speed
PERF_FRAME_SPRITES ?= 128
PERF_FRAME_FRAMES ?= 400
PERF_FRAME_WARMUP ?= 100
PERF_FRAME_TRIALS ?= 10
# 0=visible, 1=half offscreen, 2=alternating textures, 3=stacked
PERF_FRAME_SCENARIO ?= 0
PERF_FRAME_WIDTH ?= 800
PERF_FRAME_HEIGHT ?= 600
help:
@echo "Targets:"
@echo " bake Bake all characters under content/characters/"
@@ -41,12 +27,10 @@ help:
@echo " camera_sandbox Pan camera / Space toggles follow"
@echo " clips Keys 1/2 switch idle/walk"
@echo " flame Build+record+SVG+JPG+text report (FLAME_EXAMPLE=$(FLAME_EXAMPLE))"
@echo " flame-build Debug binary only ($(FLAME_BIN))"
@echo " flame-build Optimized debug binary ($(FLAME_BIN))"
@echo " flame-record perf record (play, then quit)"
@echo " flame-svg Convert perf.data -> $(FLAME_PREFIX).svg/.jpg"
@echo " flame-report Convert perf.data -> $(FLAME_PREFIX)-report.txt"
@echo " perf-draw Deterministic CPU draw benchmark"
@echo " perf-frame Deterministic SDL GPU frame benchmark (scenario 0/1/2/3)"
bake:
./scripts/bake_all.sh
@@ -73,28 +57,6 @@ check:
odin check examples/camera_sandbox -collection:pkg=.
odin check examples/clips -collection:pkg=.
perf-draw:
@echo "git_commit=$$(git rev-parse HEAD)"
@echo "odin_version=$$(odin version)"
@echo "odin_flags=$(PERF_ODIN_FLAGS)"
odin run benchmarks/draw_sprite -collection:pkg=. $(PERF_ODIN_FLAGS) \
-define:PERF_ITERATIONS=$(PERF_DRAW_ITERATIONS) \
-define:PERF_WARMUP=$(PERF_DRAW_WARMUP) \
-define:PERF_TRIALS=$(PERF_DRAW_TRIALS)
perf-frame:
@echo "git_commit=$$(git rev-parse HEAD)"
@echo "odin_version=$$(odin version)"
@echo "odin_flags=$(PERF_ODIN_FLAGS)"
odin run benchmarks/sprite_frame -collection:pkg=. $(PERF_ODIN_FLAGS) \
-define:PERF_SPRITES=$(PERF_FRAME_SPRITES) \
-define:PERF_FRAMES=$(PERF_FRAME_FRAMES) \
-define:PERF_WARMUP_FRAMES=$(PERF_FRAME_WARMUP) \
-define:PERF_TRIALS=$(PERF_FRAME_TRIALS) \
-define:PERF_SCENARIO=$(PERF_FRAME_SCENARIO) \
-define:PERF_WIDTH=$(PERF_FRAME_WIDTH) \
-define:PERF_HEIGHT=$(PERF_FRAME_HEIGHT)
toad:
odin run examples/toad -collection:pkg=.
@@ -117,7 +79,7 @@ flame-tools:
fi
flame-build:
odin build examples/$(FLAME_EXAMPLE) -collection:pkg=. -out:$(FLAME_BIN) -debug
odin build examples/$(FLAME_EXAMPLE) -collection:pkg=. -out:$(FLAME_BIN) -debug -o:speed
flame-record: flame-build
@echo ">>> Profiling ./$(FLAME_BIN) — play for ~1020s under load, then quit the window."
-102
View File
@@ -1,102 +0,0 @@
package main
import "core:fmt"
import "core:os"
import eng "pkg:engine"
import sdl "vendor:sdl3"
PERF_ITERATIONS :: #config(PERF_ITERATIONS, 2_000_000)
PERF_WARMUP :: #config(PERF_WARMUP, 10_000)
PERF_TRIALS :: #config(PERF_TRIALS, 7)
@(private)
median :: proc(values: []f64) -> f64 {
for i in 1 ..< len(values) {
value := values[i]
j := i
for j > 0 {
if values[j - 1] <= value do break
values[j] = values[j - 1]
j -= 1
}
values[j] = value
}
middle := len(values) / 2
if len(values) & 1 == 1 do return values[middle]
return (values[middle - 1] + values[middle]) / 2
}
@(private)
run_draws :: proc(app: ^eng.App, sprite: ^eng.Sprite, iterations: int) -> u64 {
clear(&app.draw_list)
start := sdl.GetTicksNS()
for i in 0 ..< iterations {
if len(app.draw_list) >= eng.MAX_SPRITES {
clear(&app.draw_list)
}
// Vary an input so optimized builds cannot hoist the draw calculations.
sprite.position.x = f32(i & 1023)
eng.draw_sprite(app, sprite)
}
return sdl.GetTicksNS() - start
}
main :: proc() {
#assert(PERF_ITERATIONS > 0)
#assert(PERF_WARMUP > 0)
#assert(PERF_TRIALS > 0)
file_data, err := os.read_entire_file(
"assets_baked/characters/toad/toad.char.json",
context.allocator,
)
if err != nil {
fmt.eprintfln("benchmark asset read failed: %v", err)
return
}
defer delete(file_data)
def, ok := eng.parse_char_def(file_data)
if !ok do return
data := eng.Character_Data {
def = def,
texture = cast(^sdl.GPUTexture)uintptr(1),
width = 1911,
height = 1526,
}
app := eng.App {
cmd = cast(^sdl.GPUCommandBuffer)uintptr(1),
swapchain_texture = cast(^sdl.GPUTexture)uintptr(2),
swapchain_w = 800,
swapchain_h = 600,
camera = eng.camera_default(),
draw_list = make(
[dynamic]eng.Queued_Sprite,
0,
eng.MAX_SPRITES,
),
}
defer delete(app.draw_list)
sprite := eng.spawn_sprite(&data, {400, 400}, "walk", 4)
_ = run_draws(&app, &sprite, PERF_WARMUP)
samples: [PERF_TRIALS]f64
fmt.printfln(
"benchmark=draw_sprite iterations=%d warmup=%d trials=%d sprites_per_queue=%d",
PERF_ITERATIONS,
PERF_WARMUP,
PERF_TRIALS,
eng.MAX_SPRITES,
)
for trial in 0 ..< PERF_TRIALS {
elapsed := run_draws(&app, &sprite, PERF_ITERATIONS)
samples[trial] = f64(elapsed) / f64(PERF_ITERATIONS)
fmt.printfln("trial=%d ns_per_draw=%.3f", trial + 1, samples[trial])
}
fmt.printfln("median_ns_per_draw=%.3f", median(samples[:]))
}
-174
View File
@@ -1,174 +0,0 @@
package main
import "core:fmt"
import eng "pkg:engine"
import sdl "vendor:sdl3"
PERF_SPRITES :: #config(PERF_SPRITES, 128)
PERF_FRAMES :: #config(PERF_FRAMES, 400)
PERF_WARMUP_FRAMES :: #config(PERF_WARMUP_FRAMES, 100)
PERF_TRIALS :: #config(PERF_TRIALS, 10)
PERF_SCENARIO :: #config(PERF_SCENARIO, 0)
PERF_WIDTH :: #config(PERF_WIDTH, 800)
PERF_HEIGHT :: #config(PERF_HEIGHT, 600)
Scenario :: enum {
Visible,
Half_Offscreen,
Alternating_Textures,
Stacked,
}
@(private)
median :: proc(values: []f64) -> f64 {
for i in 1 ..< len(values) {
value := values[i]
j := i
for j > 0 {
if values[j - 1] <= value do break
values[j] = values[j - 1]
j -= 1
}
values[j] = value
}
middle := len(values) / 2
if len(values) & 1 == 1 do return values[middle]
return (values[middle - 1] + values[middle]) / 2
}
@(private)
scenario_name :: proc(scenario: Scenario) -> string {
switch scenario {
case .Visible:
return "visible"
case .Half_Offscreen:
return "half_offscreen"
case .Alternating_Textures:
return "alternating_textures"
case .Stacked:
return "stacked"
}
return "unknown"
}
@(private)
present_mode_name :: proc(app: ^eng.App) -> string {
if sdl.WindowSupportsGPUPresentMode(app.device, app.window, .IMMEDIATE) {
return "immediate"
}
if sdl.WindowSupportsGPUPresentMode(app.device, app.window, .MAILBOX) {
return "mailbox"
}
return "vsync"
}
@(private)
draw_frame :: proc(app: ^eng.App, sprites: []eng.Sprite) {
for &sprite in sprites {
eng.update_sprite(&sprite, 1.0 / 60.0)
}
eng.begin_frame(app)
for &sprite in sprites {
eng.draw_sprite(app, &sprite)
}
eng.end_frame(app)
}
main :: proc() {
#assert(PERF_SPRITES > 0)
#assert(PERF_SPRITES <= eng.MAX_SPRITES)
#assert(PERF_FRAMES > 0)
#assert(PERF_WARMUP_FRAMES > 0)
#assert(PERF_TRIALS > 0)
#assert(PERF_SCENARIO >= 0 && PERF_SCENARIO <= 3)
#assert(PERF_WIDTH > 0)
#assert(PERF_HEIGHT > 0)
scenario := Scenario(PERF_SCENARIO)
app: eng.App
if !eng.init(&app, "sprite frame benchmark", PERF_WIDTH, PERF_HEIGHT) {
return
}
defer eng.shutdown(&app)
path := "assets_baked/characters/toad/toad.char.json"
data_a, ok := eng.load_character_data(&app, path)
if !ok do return
defer eng.destroy_character_data(&app, &data_a)
data_b: eng.Character_Data
data_b, ok = eng.load_character_data(&app, path)
if !ok do return
defer eng.destroy_character_data(&app, &data_b)
sprites: [PERF_SPRITES]eng.Sprite
for i in 0 ..< PERF_SPRITES {
data := &data_a
if scenario == .Alternating_Textures && (i & 1) == 1 {
data = &data_b
}
position := eng.Vec2 {
f32(40 + (i % 16) * 48),
f32(120 + (i / 16) * 60),
}
if scenario == .Half_Offscreen && (i & 1) == 1 {
position = {-10_000, -10_000}
} else if scenario == .Stacked {
position = {f32(PERF_WIDTH / 2), f32(PERF_HEIGHT / 2)}
}
sprites[i] = eng.spawn_sprite(data, position, "walk", i % 17)
}
for _ in 0 ..< PERF_WARMUP_FRAMES {
draw_frame(&app, sprites[:])
}
if !sdl.WaitForGPUIdle(app.device) {
fmt.eprintfln("GPU wait failed after warm-up: %s", sdl.GetError())
return
}
fmt.printfln(
"benchmark=sprite_frame scenario=%s sprites=%d resolution=%dx%d frames=%d warmup=%d trials=%d backend=%v driver=%s present=%s",
scenario_name(scenario),
PERF_SPRITES,
PERF_WIDTH,
PERF_HEIGHT,
PERF_FRAMES,
PERF_WARMUP_FRAMES,
PERF_TRIALS,
app.shader.backend,
sdl.GetGPUDeviceDriver(app.device),
present_mode_name(&app),
)
samples: [PERF_TRIALS]f64
for trial in 0 ..< PERF_TRIALS {
start := sdl.GetTicksNS()
for _ in 0 ..< PERF_FRAMES {
draw_frame(&app, sprites[:])
}
if !sdl.WaitForGPUIdle(app.device) {
fmt.eprintfln("GPU wait failed after trial %d: %s", trial + 1, sdl.GetError())
return
}
elapsed := sdl.GetTicksNS() - start
samples[trial] = f64(elapsed) / f64(PERF_FRAMES) / 1_000_000.0
fmt.printfln(
"trial=%d ms_per_frame=%.3f fps=%.1f",
trial + 1,
samples[trial],
1_000.0 / samples[trial],
)
}
median_ms := median(samples[:])
fmt.printfln(
"median_ms_per_frame=%.3f median_fps=%.1f",
median_ms,
1_000.0 / median_ms,
)
}
Executable
BIN
View File
Binary file not shown.
+26
View File
@@ -118,6 +118,32 @@ set_sprite_clip_switch_and_guards :: proc(t: ^testing.T) {
testing.expect_value(t, sprite.time, f32(0.09))
}
@(test)
set_sprite_clip_caches_clip_def :: proc(t: ^testing.T) {
data := make_test_character()
defer destroy_test_character(&data)
sprite := spawn_sprite(&data, {}, "idle", 0)
testing.expect(t, sprite.has_clip, "spawn should cache a valid clip")
testing.expect_value(t, sprite.clip, "idle")
testing.expect(t, sprite.clip_def.loop, "idle clip loops")
testing.expect_value(t, sprite.clip_def.fps, f32(10))
testing.expect_value(t, len(sprite.clip_def.frames), 3)
set_sprite_clip(&sprite, "once")
testing.expect(t, sprite.has_clip, "switch should refresh cache")
testing.expect_value(t, sprite.clip, "once")
testing.expect(t, !sprite.clip_def.loop, "once clip does not loop")
testing.expect_value(t, sprite.clip_def.fps, f32(10))
testing.expect_value(t, len(sprite.clip_def.frames), 3)
set_sprite_clip(&sprite, "nope")
testing.expect(t, sprite.has_clip, "bad clip must leave cache intact")
testing.expect_value(t, sprite.clip, "once")
testing.expect(t, !sprite.clip_def.loop, "cached once clip preserved")
testing.expect_value(t, len(sprite.clip_def.frames), 3)
}
@(test)
spawn_sprite_valid_and_invalid :: proc(t: ^testing.T) {
data := make_test_character()
+137 -12
View File
@@ -16,8 +16,15 @@ SPRITE_VERTS_SIZE :: SPRITE_VERT_COUNT * size_of(Vertex)
VERTEX_BUFFER_SIZE :: MAX_SPRITES * SPRITE_VERTS_SIZE
Queued_Sprite :: struct {
texture: ^sdl.GPUTexture,
verts: [SPRITE_VERT_COUNT]Vertex,
batch_group: u32, // 0 = strict order; nonzero = caller permits regrouping
}
Draw_Batch :: struct {
start: int,
count: int,
texture: ^sdl.GPUTexture,
verts: [SPRITE_VERT_COUNT]Vertex,
}
App :: struct {
@@ -65,7 +72,7 @@ init :: proc(app: ^App, title: cstring, width, height: i32) -> bool {
}
requested: sdl.GPUShaderFormat = {.SPIRV, .DXIL, .MSL}
app.device = sdl.CreateGPUDevice(requested, true, nil)
app.device = sdl.CreateGPUDevice(requested, false, nil)
if app.device == nil {
fmt.eprintfln("CreateGPUDevice failed: %s", sdl.GetError())
return false
@@ -76,6 +83,10 @@ init :: proc(app: ^App, title: cstring, width, height: i32) -> bool {
return false
}
if !sdl.SetGPUAllowedFramesInFlight(app.device, 3) {
fmt.eprintfln("SetGPUAllowedFramesInFlight failed: %s", sdl.GetError())
}
// Prefer uncapped present for profiling; fall back if unsupported.
present := sdl.GPUPresentMode.VSYNC
if sdl.WindowSupportsGPUPresentMode(app.device, app.window, .IMMEDIATE) {
@@ -242,7 +253,11 @@ end_frame :: proc(app: ^App) {
}
n := len(app.draw_list)
batches: [dynamic]Draw_Batch
defer delete(batches)
if n > 0 {
prepare_draw_batches(app.draw_list[:], &batches)
map_ptr := sdl.MapGPUTransferBuffer(app.device, app.transfer_buffer, false)
if map_ptr == nil {
fmt.eprintfln("MapGPUTransferBuffer failed: %s", sdl.GetError())
@@ -286,26 +301,20 @@ end_frame :: proc(app: ^App) {
app.render_pass = sdl.BeginGPURenderPass(cmd, &color_info, 1, nil)
sdl.BindGPUGraphicsPipeline(app.render_pass, app.pipeline)
i := 0
for i < n {
run := texture_run_len(app.draw_list[:], i)
q0 := app.draw_list[i]
for batch in batches {
sampler_binding := sdl.GPUTextureSamplerBinding {
texture = q0.texture,
texture = batch.texture,
sampler = app.sampler,
}
sdl.BindGPUFragmentSamplers(app.render_pass, 0, &sampler_binding, 1)
vb_binding := sdl.GPUBufferBinding {
buffer = app.vertex_buffer,
offset = u32(i * SPRITE_VERTS_SIZE),
offset = u32(batch.start * SPRITE_VERTS_SIZE),
}
sdl.BindGPUVertexBuffers(app.render_pass, 0, &vb_binding, 1)
sdl.DrawGPUPrimitives(app.render_pass, u32(run * SPRITE_VERT_COUNT), 1, 0, 0)
i += run
sdl.DrawGPUPrimitives(app.render_pass, u32(batch.count * SPRITE_VERT_COUNT), 1, 0, 0)
}
sdl.EndGPURenderPass(app.render_pass)
app.render_pass = nil
@@ -454,3 +463,119 @@ texture_run_len :: proc(list: []Queued_Sprite, start: int) -> int {
return n
}
texture_run_count :: proc(list: []Queued_Sprite) -> int {
if len(list) == 0 do return 0
count := 0
i := 0
for i < len(list) {
run := texture_run_len(list, i)
count += 1
i += run
}
return count
}
prepare_draw_batches :: proc(list: []Queued_Sprite, batches: ^[dynamic]Draw_Batch) {
clear(batches)
group_texture_runs(list)
i := 0
for i < len(list) {
run := texture_run_len(list, i)
append(batches, Draw_Batch{start = i, count = run, texture = list[i].texture})
i += run
}
}
// Within each contiguous nonzero batch_group, stably sort by texture so
// consecutive same-texture sprites become one draw. Group 0 and group
// boundaries are never crossed.
group_texture_runs :: proc(list: []Queued_Sprite) {
start := 0
for start < len(list) {
group := list[start].batch_group
if group == 0 {
start += 1
continue
}
end := start + 1
for end < len(list) && list[end].batch_group == group {
end += 1
}
stable_group_by_texture(list[start:end])
start = end
}
}
// Stably orders window by texture pointer. Fast path for 12 textures
// (common); insertion sort for 3+.
stable_group_by_texture :: proc(window: []Queued_Sprite) {
n := len(window)
if n <= 1 do return
already := true
for i in 1 ..< n {
if uintptr(window[i].texture) < uintptr(window[i - 1].texture) {
already = false
break
}
}
if already do return
first := uintptr(window[0].texture)
second: uintptr
has_second := false
third := false
for i in 1 ..< n {
t := uintptr(window[i].texture)
if t == first do continue
if !has_second {
second = t
has_second = true
continue
}
if t != second {
third = true
break
}
}
if !has_second do return
if third {
for i in 1 ..< n {
item := window[i]
j := i
for j > 0 {
if uintptr(window[j - 1].texture) <= uintptr(item.texture) {
break
}
window[j] = window[j - 1]
j -= 1
}
window[j] = item
}
return
}
lo, hi := first, second
if lo > hi do lo, hi = hi, lo
tmp: [MAX_SPRITES]Queued_Sprite
w := 0
for q in window {
if uintptr(q.texture) == lo {
tmp[w] = q
w += 1
}
}
for q in window {
if uintptr(q.texture) == hi {
tmp[w] = q
w += 1
}
}
copy(window, tmp[:w])
}
+365
View File
@@ -7,6 +7,18 @@ fake_tex :: proc(id: uintptr) -> ^sdl.GPUTexture {
return cast(^sdl.GPUTexture)id
}
queued :: proc(tex_id: uintptr, group: u32, marker: f32) -> Queued_Sprite {
q: Queued_Sprite
q.texture = fake_tex(tex_id)
q.batch_group = group
q.verts[0].pos = {marker, 0}
return q
}
marker_of :: proc(q: Queued_Sprite) -> f32 {
return q.verts[0].pos.x
}
@(test)
texture_run_len_empty_or_oob :: proc(t: ^testing.T) {
testing.expect_value(t, texture_run_len(nil, 0), 0)
@@ -62,3 +74,356 @@ texture_run_len_all_different :: proc(t: ^testing.T) {
testing.expect_value(t, texture_run_len(list, 1), 1)
testing.expect_value(t, texture_run_len(list, 2), 1)
}
@(test)
group_texture_runs_strict_order_unchanged :: proc(t: ^testing.T) {
// Group 0 alternates textures; sorting must not reorder (alpha order).
list := []Queued_Sprite {
queued(2, 0, 1),
queued(1, 0, 2),
queued(2, 0, 3),
queued(1, 0, 4),
}
before_runs := texture_run_count(list)
group_texture_runs(list)
testing.expect_value(t, texture_run_count(list), before_runs)
testing.expect_value(t, marker_of(list[0]), f32(1))
testing.expect_value(t, marker_of(list[1]), f32(2))
testing.expect_value(t, marker_of(list[2]), f32(3))
testing.expect_value(t, marker_of(list[3]), f32(4))
}
@(test)
group_texture_runs_reduces_runs_inside_group :: proc(t: ^testing.T) {
list := []Queued_Sprite {
queued(2, 1, 1),
queued(1, 1, 2),
queued(2, 1, 3),
queued(1, 1, 4),
}
testing.expect_value(t, texture_run_count(list), 4)
group_texture_runs(list)
testing.expect_value(t, texture_run_count(list), 2)
testing.expect(t, list[0].texture == fake_tex(1), "lower texture pointer first")
testing.expect(t, list[1].texture == fake_tex(1), "same texture run")
testing.expect(t, list[2].texture == fake_tex(2), "second texture run")
testing.expect(t, list[3].texture == fake_tex(2), "second texture run cont")
}
@(test)
group_texture_runs_stable_same_texture :: proc(t: ^testing.T) {
list := []Queued_Sprite {
queued(2, 1, 10),
queued(1, 1, 20),
queued(2, 1, 30),
queued(1, 1, 40),
}
group_texture_runs(list)
// Same-texture relative order preserved (stable sort).
testing.expect_value(t, marker_of(list[0]), f32(20))
testing.expect_value(t, marker_of(list[1]), f32(40))
testing.expect_value(t, marker_of(list[2]), f32(10))
testing.expect_value(t, marker_of(list[3]), f32(30))
}
@(test)
group_texture_runs_respects_group_boundaries :: proc(t: ^testing.T) {
list := []Queued_Sprite {
queued(2, 1, 1),
queued(1, 1, 2),
queued(2, 0, 3), // strict barrier
queued(1, 2, 4),
queued(2, 2, 5),
}
group_texture_runs(list)
testing.expect_value(t, marker_of(list[2]), f32(3)) // barrier stays put
testing.expect(t, list[0].texture == fake_tex(1))
testing.expect(t, list[1].texture == fake_tex(2))
testing.expect(t, list[3].texture == fake_tex(1))
testing.expect(t, list[4].texture == fake_tex(2))
testing.expect_value(t, list[0].batch_group, u32(1))
testing.expect_value(t, list[1].batch_group, u32(1))
testing.expect_value(t, list[2].batch_group, u32(0))
testing.expect_value(t, list[3].batch_group, u32(2))
testing.expect_value(t, list[4].batch_group, u32(2))
}
@(test)
group_texture_runs_does_not_merge_across_different_groups :: proc(t: ^testing.T) {
// Adjacent nonzero groups with different ids must not merge runs across.
list := []Queued_Sprite {
queued(1, 1, 1),
queued(2, 1, 2),
queued(1, 2, 3),
queued(2, 2, 4),
}
group_texture_runs(list)
testing.expect_value(t, texture_run_count(list), 4)
testing.expect_value(t, list[0].batch_group, u32(1))
testing.expect_value(t, list[1].batch_group, u32(1))
testing.expect_value(t, list[2].batch_group, u32(2))
testing.expect_value(t, list[3].batch_group, u32(2))
}
@(test)
group_texture_runs_empty :: proc(t: ^testing.T) {
list := []Queued_Sprite{}
testing.expect_value(t, texture_run_count(list), 0)
group_texture_runs(list)
testing.expect_value(t, texture_run_count(list), 0)
}
@(test)
group_texture_runs_already_optimal :: proc(t: ^testing.T) {
list := []Queued_Sprite {
queued(1, 1, 10),
queued(1, 1, 20),
queued(2, 1, 30),
queued(2, 1, 40),
}
testing.expect_value(t, texture_run_count(list), 2)
group_texture_runs(list)
testing.expect_value(t, texture_run_count(list), 2)
testing.expect_value(t, marker_of(list[0]), f32(10))
testing.expect_value(t, marker_of(list[1]), f32(20))
testing.expect_value(t, marker_of(list[2]), f32(30))
testing.expect_value(t, marker_of(list[3]), f32(40))
}
@(test)
group_texture_runs_alternating_many_stable :: proc(t: ^testing.T) {
// Characterization: large alternating group must collapse to two runs
// while preserving same-texture submission order (markers).
N :: 64
list := make([]Queued_Sprite, N)
defer delete(list)
for i in 0 ..< N {
tex: uintptr = 2 if (i % 2) == 0 else 1
list[i] = queued(tex, 1, f32(i + 1))
}
testing.expect_value(t, texture_run_count(list), N)
group_texture_runs(list)
testing.expect_value(t, texture_run_count(list), 2)
testing.expect(t, list[0].texture == fake_tex(1))
testing.expect(t, list[N / 2 - 1].texture == fake_tex(1))
testing.expect(t, list[N / 2].texture == fake_tex(2))
testing.expect(t, list[N - 1].texture == fake_tex(2))
for i in 0 ..< N / 2 {
testing.expect_value(t, marker_of(list[i]), f32(2 * i + 2)) // odd markers: 2,4,...,N
testing.expect_value(t, marker_of(list[N / 2 + i]), f32(2 * i + 1)) // even markers: 1,3,...,N-1
}
}
@(test)
group_texture_runs_three_textures_stable :: proc(t: ^testing.T) {
list := []Queued_Sprite {
queued(3, 1, 1),
queued(1, 1, 2),
queued(2, 1, 3),
queued(3, 1, 4),
queued(1, 1, 5),
queued(2, 1, 6),
}
testing.expect_value(t, texture_run_count(list), 6)
group_texture_runs(list)
testing.expect_value(t, texture_run_count(list), 3)
testing.expect_value(t, marker_of(list[0]), f32(2))
testing.expect_value(t, marker_of(list[1]), f32(5))
testing.expect_value(t, marker_of(list[2]), f32(3))
testing.expect_value(t, marker_of(list[3]), f32(6))
testing.expect_value(t, marker_of(list[4]), f32(1))
testing.expect_value(t, marker_of(list[5]), f32(4))
}
@(test)
group_texture_runs_noncontiguous_same_group_id :: proc(t: ^testing.T) {
// Same nonzero id split by group 0: each window regroups alone.
list := []Queued_Sprite {
queued(2, 1, 1),
queued(1, 1, 2),
queued(2, 0, 3),
queued(2, 1, 4),
queued(1, 1, 5),
}
group_texture_runs(list)
testing.expect_value(t, marker_of(list[2]), f32(3))
testing.expect(t, list[0].texture == fake_tex(1))
testing.expect(t, list[1].texture == fake_tex(2))
testing.expect_value(t, list[2].batch_group, u32(0))
testing.expect(t, list[3].texture == fake_tex(1))
testing.expect(t, list[4].texture == fake_tex(2))
testing.expect_value(t, list[0].batch_group, u32(1))
testing.expect_value(t, list[1].batch_group, u32(1))
testing.expect_value(t, list[3].batch_group, u32(1))
testing.expect_value(t, list[4].batch_group, u32(1))
}
make_test_draw_app :: proc() -> App {
app: App
app.cmd = cast(^sdl.GPUCommandBuffer)uintptr(1)
app.swapchain_texture = fake_tex(99)
app.swapchain_w = 800
app.swapchain_h = 600
app.camera = camera_default()
app.draw_list = make([dynamic]Queued_Sprite)
return app
}
destroy_test_draw_app :: proc(app: ^App) {
if app == nil do return
delete(app.draw_list)
app^ = {}
}
make_test_draw_character :: proc() -> Character_Data {
data: Character_Data
data.texture = fake_tex(42)
data.width = 100
data.height = 100
data.def.pivot = {0.5, 1.0}
data.def.clips = make(map[string]Clip_Def)
frames := make([]Frame_Def, 1)
frames[0] = Frame_Def {
rect = {0, 0, 10, 10},
source_size = {10, 10},
trim_offset = {0, 0},
}
data.def.clips["idle"] = Clip_Def {
loop = true,
fps = 10,
frames = frames,
}
return data
}
destroy_test_draw_character :: proc(data: ^Character_Data) {
if data == nil do return
keys := make([dynamic]string, context.temp_allocator)
for key, clip in data.def.clips {
delete(clip.frames)
append(&keys, key)
}
for key in keys {
delete_key(&data.def.clips, key)
}
delete(data.def.clips)
data^ = {}
}
@(test)
draw_sprite_stamps_batch_group_zero :: proc(t: ^testing.T) {
app := make_test_draw_app()
defer destroy_test_draw_app(&app)
data := make_test_draw_character()
defer destroy_test_draw_character(&data)
sprite := spawn_sprite(&data, {100, 200}, "idle", 0)
draw_sprite(&app, &sprite)
testing.expect_value(t, len(app.draw_list), 1)
testing.expect_value(t, app.draw_list[0].batch_group, u32(0))
testing.expect(t, app.draw_list[0].texture == data.texture)
}
@(test)
draw_sprite_at_max_sprites_does_not_append :: proc(t: ^testing.T) {
app := make_test_draw_app()
defer destroy_test_draw_app(&app)
data := make_test_draw_character()
defer destroy_test_draw_character(&data)
for _ in 0 ..< MAX_SPRITES {
append(&app.draw_list, Queued_Sprite{texture = data.texture})
}
testing.expect_value(t, len(app.draw_list), MAX_SPRITES)
sprite := spawn_sprite(&data, {100, 200}, "idle", 0)
draw_sprite(&app, &sprite)
testing.expect_value(t, len(app.draw_list), MAX_SPRITES)
}
@(test)
draw_sprite_batched_stamps_batch_group :: proc(t: ^testing.T) {
app := make_test_draw_app()
defer destroy_test_draw_app(&app)
data := make_test_draw_character()
defer destroy_test_draw_character(&data)
sprite := spawn_sprite(&data, {100, 200}, "idle", 0)
draw_sprite_batched(&app, &sprite, 7)
testing.expect_value(t, len(app.draw_list), 1)
testing.expect_value(t, app.draw_list[0].batch_group, u32(7))
testing.expect(t, app.draw_list[0].texture == data.texture)
}
@(test)
draw_sprite_batched_guards_leave_list_unchanged :: proc(t: ^testing.T) {
app := make_test_draw_app()
defer destroy_test_draw_app(&app)
data := make_test_draw_character()
defer destroy_test_draw_character(&data)
sprite := spawn_sprite(&data, {100, 200}, "idle", 0)
app.cmd = nil
draw_sprite_batched(&app, &sprite, 1)
testing.expect_value(t, len(app.draw_list), 0)
app.cmd = cast(^sdl.GPUCommandBuffer)uintptr(1)
app.swapchain_texture = nil
draw_sprite_batched(&app, &sprite, 1)
testing.expect_value(t, len(app.draw_list), 0)
app.swapchain_texture = fake_tex(99)
draw_sprite_batched(&app, nil, 1)
testing.expect_value(t, len(app.draw_list), 0)
no_data := sprite
no_data.data = nil
draw_sprite_batched(&app, &no_data, 1)
testing.expect_value(t, len(app.draw_list), 0)
no_tex := sprite
tex_data := data
tex_data.texture = nil
no_tex.data = &tex_data
draw_sprite_batched(&app, &no_tex, 1)
testing.expect_value(t, len(app.draw_list), 0)
}
@(test)
prepare_draw_batches_regroups_then_plans_runs :: proc(t: ^testing.T) {
list := []Queued_Sprite {
queued(2, 1, 1),
queued(1, 1, 2),
queued(2, 1, 3),
queued(1, 1, 4),
queued(3, 0, 5),
queued(1, 0, 6),
}
batches := make([dynamic]Draw_Batch)
defer delete(batches)
prepare_draw_batches(list, &batches)
testing.expect_value(t, len(batches), 4)
testing.expect_value(t, batches[0].start, 0)
testing.expect_value(t, batches[0].count, 2)
testing.expect(t, batches[0].texture == fake_tex(1))
testing.expect_value(t, batches[1].start, 2)
testing.expect_value(t, batches[1].count, 2)
testing.expect(t, batches[1].texture == fake_tex(2))
testing.expect_value(t, batches[2].start, 4)
testing.expect_value(t, batches[2].count, 1)
testing.expect(t, batches[2].texture == fake_tex(3))
testing.expect_value(t, batches[3].start, 5)
testing.expect_value(t, batches[3].count, 1)
testing.expect(t, batches[3].texture == fake_tex(1))
// Group 0 submission order preserved.
testing.expect_value(t, marker_of(list[4]), f32(5))
testing.expect_value(t, marker_of(list[5]), f32(6))
testing.expect_value(t, list[4].batch_group, u32(0))
testing.expect_value(t, list[5].batch_group, u32(0))
}
+9
View File
@@ -27,6 +27,15 @@ choose_shader_runtime_prefers_msl :: proc(t: ^testing.T) {
testing.expect_value(t, rt.format, sdl.GPUShaderFormat{.MSL})
}
@(test)
choose_shader_runtime_prefers_dxil_without_msl :: proc(t: ^testing.T) {
rt, ok := choose_shader_runtime_from_formats({.DXIL, .SPIRV})
testing.expect(t, ok, "should pick a runtime when DXIL is available")
testing.expect_value(t, rt.backend, Shader_Backend.DSD12_DXIL)
testing.expect_value(t, rt.shader_dir, "shaders/d3d12")
testing.expect_value(t, rt.format, sdl.GPUShaderFormat{.DXIL})
}
@(test)
choose_shader_runtime_spirv_only :: proc(t: ^testing.T) {
rt, ok := choose_shader_runtime_from_formats({.SPIRV})
+60 -28
View File
@@ -5,12 +5,14 @@ import sdl "vendor:sdl3"
Vec2 :: [2]f32
Sprite :: struct {
data: ^Character_Data,
position: Vec2,
clip: string,
frame: int,
time: f32,
flip_x: bool,
data: ^Character_Data,
position: Vec2,
clip: string,
clip_def: Clip_Def,
has_clip: bool,
frame: int,
time: f32,
flip_x: bool,
}
spawn_sprite :: proc(
@@ -24,16 +26,14 @@ spawn_sprite :: proc(
position = position,
}
set_sprite_clip(&sprite, clip)
if frame != 0 {
c, ok := character_clip(sprite.data, sprite.clip)
if ok {
if frame < 0 {
sprite.frame = 0
} else if frame >= len(c.frames) {
sprite.frame = len(c.frames) - 1
} else {
sprite.frame = frame
}
if frame != 0 && sprite.has_clip {
c := sprite.clip_def
if frame < 0 {
sprite.frame = 0
} else if frame >= len(c.frames) {
sprite.frame = len(c.frames) - 1
} else {
sprite.frame = frame
}
}
return sprite
@@ -42,9 +42,9 @@ spawn_sprite :: proc(
update_sprite :: proc(sprite: ^Sprite, dt: f32) {
if sprite == nil || sprite.data == nil do return
if dt <= 0 do return
if !sprite.has_clip do return
clip, ok := character_clip(sprite.data, sprite.clip)
if !ok do return
clip := sprite.clip_def
frame_count := len(clip.frames)
if frame_count <= 0 do return
@@ -82,7 +82,31 @@ to_clip :: proc(px, py, sw, sh: f32) -> [2]f32 {
}
}
// Axis-aligned quad: two unique x and y values, so scale once and reuse.
sprite_quad_to_clip :: proc(x0, y0, x1, y1, sw, sh: f32) -> [4]Vec2 {
sx := 2.0 / sw
sy := 2.0 / sh
left := x0 * sx - 1
right := x1 * sx - 1
top := 1 - y0 * sy
bottom := 1 - y1 * sy
return {
{left, top},
{right, top},
{right, bottom},
{left, bottom},
}
}
draw_sprite :: proc(app: ^App, sprite: ^Sprite) {
draw_sprite_batched(app, sprite, 0)
}
// Nonzero batch_group lets end_frame regroup consecutive same-group sprites by
// texture. Group 0 keeps exact submission order for correct alpha overlap.
draw_sprite_batched :: proc(app: ^App, sprite: ^Sprite, batch_group: u32) {
if app.cmd == nil || app.swapchain_texture == nil {
return
}
@@ -92,12 +116,13 @@ draw_sprite :: proc(app: ^App, sprite: ^Sprite) {
if len(app.draw_list) >= MAX_SPRITES {
return
}
frame, ok := character_frame(sprite.data, sprite.clip, sprite.frame)
if !ok {
if !sprite.has_clip do return
if sprite.frame < 0 || sprite.frame >= len(sprite.clip_def.frames) {
return
}
frame := sprite.clip_def.frames[sprite.frame]
src_w := f32(frame.source_size[0])
src_h := f32(frame.source_size[1])
if src_w <= 0 do src_w = f32(frame.rect[2])
@@ -124,10 +149,8 @@ draw_sprite :: proc(app: ^App, sprite: ^Sprite) {
sw := f32(app.swapchain_w)
sh := f32(app.swapchain_h)
p0 := to_clip(x0_px, y0_px, sw, sh)
p1 := to_clip(x1_px, y0_px, sw, sh)
p2 := to_clip(x1_px, y1_px, sw, sh)
p3 := to_clip(x0_px, y1_px, sw, sh)
points := sprite_quad_to_clip(x0_px, y0_px, x1_px, y1_px, sw, sh)
p0, p1, p2, p3 := points[0], points[1], points[2], points[3]
tex_w := f32(sprite.data.width)
tex_h := f32(sprite.data.height)
@@ -142,18 +165,27 @@ draw_sprite :: proc(app: ^App, sprite: ^Sprite) {
{pos = p3, uv = {u0, v1}},
}
append(&app.draw_list, Queued_Sprite{texture = sprite.data.texture, verts = verts})
append(
&app.draw_list,
Queued_Sprite {
texture = sprite.data.texture,
verts = verts,
batch_group = batch_group,
},
)
}
set_sprite_clip :: proc(sprite: ^Sprite, clip: string) {
if sprite == nil || sprite.data == nil do return
if sprite.clip == clip do return
if sprite.clip == clip && sprite.has_clip do return
_, ok := character_clip(sprite.data, clip)
def, ok := character_clip(sprite.data, clip)
if !ok do return
sprite.clip = clip
sprite.clip_def = def
sprite.has_clip = true
sprite.frame = 0
sprite.time = 0
}
+29 -6
View File
@@ -1,9 +1,12 @@
package main
import "core:fmt"
import eng "pkg:engine"
// Many sprites sharing one Character_Data (Flyweight) — good batching demo.
COUNT :: 24
COUNT :: eng.MAX_SPRITES
COLS :: 16
FRAME_LOG_EVERY :: 60
main :: proc() {
app: eng.App
@@ -16,25 +19,45 @@ main :: proc() {
sprites: [COUNT]eng.Sprite
for i in 0 ..< COUNT {
col := i % 8
row := i / 8
col := i % COLS
row := i / COLS
pos := eng.Vec2 {
f32(120 + col * 80),
f32(280 + row * 120),
f32(40 + col * 48),
f32(80 + row * 60),
}
clip := "idle" if (i % 2) == 0 else "walk"
sprites[i] = eng.spawn_sprite(&data, pos, clip, i % 5)
}
// Look at the middle of the grid
app.camera.position = {400, 400}
last := eng.now_seconds()
frame_i := 0
sum_ms: f64
peak_ms: f64
for eng.events() {
now := eng.now_seconds()
dt := f32(now - last)
last = now
frame_ms := f64(dt) * 1000.0
sum_ms += frame_ms
if frame_ms > peak_ms do peak_ms = frame_ms
frame_i += 1
if frame_i % FRAME_LOG_EVERY == 0 {
avg := sum_ms / f64(FRAME_LOG_EVERY)
fps := 1000.0 / avg if avg > 0 else 0
fmt.printfln(
"crowd frame: avg=%.2f ms (%.1f FPS) peak=%.2f ms over %d frames",
avg,
fps,
peak_ms,
FRAME_LOG_EVERY,
)
sum_ms = 0
peak_ms = 0
}
for &s in sprites {
eng.update_sprite(&s, dt)
+783
View File
@@ -0,0 +1,783 @@
# To display the perf.data header info, please use --header/--header-only options.
#
#
# Total Lost Samples: 0
#
# Samples: 1K of event 'cpu/cycles/Pu'
# Event count (approx.): 8251313686
#
# Overhead Command Shared Object Symbol
# ........ ............... .............................. ......................................................................................................................................................................
#
10.24% crowd_perf crowd_perf [.] engine::draw_sprite
|
---engine::draw_sprite
main::main
main
0x7fec32c27740
__libc_start_main
_start
5.73% crowd_perf crowd_perf [.] engine::to_clip
|
---engine::to_clip
engine::draw_sprite
main::main
main
0x7fec32c27740
__libc_start_main
_start
2.74% crowd_perf crowd_perf [.] runtime::default_hasher
|
---runtime::default_hasher
runtime::default_hasher_string
__$hasher$$string
|
|--2.10%--engine::character_clip
| engine::update_sprite
| main::main
| main
| 0x7fec32c27740
| __libc_start_main
| _start
|
--0.64%--engine::character_frame
engine::draw_sprite
main::main
main
0x7fec32c27740
__libc_start_main
_start
2.48% crowd_perf crowd_perf [.] engine::sprite_feet_quad
|
---engine::sprite_feet_quad
engine::draw_sprite
main::main
main
0x7fec32c27740
__libc_start_main
_start
2.16% crowd_perf libc.so.6 [.] pthread_mutex_lock
|
---pthread_mutex_lock
|
--0.60%--wl_proxy_marshal_array_flags
wl_proxy_marshal_flags
2.09% crowd_perf crowd_perf [.] __$map_get$$map[string]engine::Clip_Def
|
---__$map_get$$map[string]engine::Clip_Def
|
|--1.49%--engine::character_clip
| engine::update_sprite
| main::main
| main
| 0x7fec32c27740
| __libc_start_main
| _start
|
--0.60%--engine::character_frame
engine::draw_sprite
main::main
main
0x7fec32c27740
__libc_start_main
_start
2.04% crowd_perf crowd_perf [.] engine::update_sprite
|
---engine::update_sprite
main::main
main
0x7fec32c27740
__libc_start_main
_start
1.91% crowd_perf crowd_perf [.] runtime::memory_equal
|
---runtime::memory_equal
runtime::string_eq
__$map_get$$map[string]engine::Clip_Def
|
|--1.32%--engine::character_frame
| engine::draw_sprite
| main::main
| main
| 0x7fec32c27740
| __libc_start_main
| _start
|
--0.58%--engine::character_clip
engine::update_sprite
main::main
main
0x7fec32c27740
__libc_start_main
_start
1.90% crowd_perf crowd_perf [.] engine::character_clip
|
---engine::character_clip
engine::update_sprite
main::main
main
0x7fec32c27740
__libc_start_main
_start
1.85% crowd_perf crowd_perf [.] engine::world_to_screen
|
---engine::world_to_screen
engine::draw_sprite
main::main
main
0x7fec32c27740
__libc_start_main
_start
1.41% crowd_perf crowd_perf [.] runtime::_append_elem
|
---runtime::_append_elem
runtime::append_elem:proc(array:^[dynamic]engine::Queued_Sprite,arg:engine::Queued_Sprite,loc:runtime::Source_Code_Location)->(n:int,err:runtime::Allocator_Error)
engine::draw_sprite
main::main
main
0x7fec32c27740
__libc_start_main
_start
1.37% crowd_perf crowd_perf [.] engine::end_frame
|
---engine::end_frame
main::main
main
0x7fec32c27740
__libc_start_main
_start
1.15% crowd_perf libc.so.6 [.] clock_gettime
|
---clock_gettime
1.05% crowd_perf libdbus-1.so.3.38.3 [.] _dbus_atomic_dec
|
---_dbus_atomic_dec
|
--0.95%--_dbus_connection_unref_unlocked
0x7fec32e8fbae
0x7fec32e8fdad
0x7fec32e94b31
0x7fec33054fca
0x7fec33055bbd
engine::events
main::main
main
0x7fec32c27740
__libc_start_main
_start
0.95% crowd_perf crowd_perf [.] main::main
|
---main::main
main
0x7fec32c27740
__libc_start_main
_start
0.91% crowd_perf crowd_perf [.] runtime::append_elem:proc(array:^[dynamic]engine::Queued_Sprite,arg:engine::Queued_Sprite,loc:runtime::Source_Code_Location)->(n:int,err:runtime::Allocator_Error)
|
---runtime::append_elem:proc(array:^[dynamic]engine::Queued_Sprite,arg:engine::Queued_Sprite,loc:runtime::Source_Code_Location)->(n:int,err:runtime::Allocator_Error)
engine::draw_sprite
main::main
main
0x7fec32c27740
__libc_start_main
_start
0.91% crowd_perf libc.so.6 [.] 0x000000000018a4c4
|
---0x7fec32d8a4c4
|
--0.82%--engine::draw_sprite
main::main
main
0x7fec32c27740
__libc_start_main
_start
0.86% crowd_perf crowd_perf [.] runtime::string_eq
|
---runtime::string_eq
__$map_get$$map[string]engine::Clip_Def
|
--0.60%--engine::character_clip
engine::update_sprite
main::main
main
0x7fec32c27740
__libc_start_main
_start
0.84% crowd_perf crowd_perf [.] engine::character_frame
|
---engine::character_frame
engine::draw_sprite
main::main
main
0x7fec32c27740
__libc_start_main
_start
0.81% crowd_perf libwayland-client.so.0.25.0 [.] wl_proxy_marshal_array_flags
|
---wl_proxy_marshal_array_flags
wl_proxy_marshal_flags
0.77% crowd_perf libc.so.6 [.] 0x00000000000a7159
|
---0x7fec32ca7159
|
--0.61%--0x7fec12d80142
0x7fec12d82613
0x7fec12d3cff4
0x7fec12ddcaf6
0x7fec12ddccd4
0x7fec12de6f2c
0x7fec3324fec1
engine::end_frame
main::main
main
0x7fec32c27740
__libc_start_main
_start
0.74% wl_cursor_surfa libc.so.6 [.] 0x0000000000093fff
0.73% crowd_perf libSDL3.so.0.4.12 [.] 0x0000000000143ffe
|
---0x7fec33143ffe
0x7fec3314a028
0x7fec33141b9a
0.73% crowd_perf crowd_perf [.] runtime::bounds_check_error
|
---runtime::bounds_check_error
|
--0.53%--engine::character_frame
engine::draw_sprite
main::main
main
0x7fec32c27740
__libc_start_main
_start
0.71% crowd_perf libvulkan_radeon.so [.] 0x00000000001f41b7
|
---0x7fec12df41b7
0x7fec12df44e5
|
--0.59%--0x7fec12c2baf6
0x7fec12c2da03
0x7fec12c2e4ca
0x7fec12c2f277
0x7fec12de052c
0x7fec12de1521
0x7fec33247581
0x7fec33064bab
engine::end_frame
main::main
0.70% crowd_perf libSDL3.so.0.4.12 [.] 0x000000000023af6a
|
---0x7fec3323af6a
|
--0.58%--0x7fec33249f38
engine::end_frame
main::main
main
0x7fec32c27740
__libc_start_main
_start
0.69% crowd_perf crowd_perf [.] engine::frame_uvs
|
---engine::frame_uvs
engine::draw_sprite
main::main
main
0x7fec32c27740
__libc_start_main
_start
0.68% crowd_perf libc.so.6 [.] 0x000000000009ca5c
|
---0x7fec32c9ca5c
0.67% crowd_perf [vdso] [.] __vdso_clock_gettime
|
---__vdso_clock_gettime
clock_gettime
0.58% crowd_perf libdrm.so.2.134.0 [.] drmIoctl
0.58% crowd_perf libvulkan_radeon.so [.] 0x000000000033b80b
|
---0x7fec12f3b80b
0x7fec12df41ce
0x7fec12df44e5
0.53% crowd_perf libc.so.6 [.] cfree
|
---cfree
0.51% crowd_perf [unknown] [k] 0xffffffff84e00080
|
---0xffffffff84e00080
0.45% crowd_perf libc.so.6 [.] pthread_mutex_unlock
0.44% crowd_perf libc.so.6 [.] pthread_rwlock_rdlock
0.43% crowd_perf libvulkan_radeon.so [.] 0x00000000000d2c23
0.40% crowd_perf libc.so.6 [.] 0x0000000000180625
0.39% crowd_perf libc.so.6 [.] 0x000000000018a547
0.37% crowd_perf crowd_perf [.] runtime::default_hasher_string
0.36% crowd_perf libc.so.6 [.] 0x000000000018a4c0
0.35% crowd_perf libSDL3.so.0.4.12 [.] 0x0000000000247484
0.33% crowd_perf libwayland-client.so.0.25.0 [.] 0x0000000000003147
0.33% crowd_perf libc.so.6 [.] 0x0000000000189cc4
0.33% crowd_perf [unknown] [k] 0xffffffff84e00084
0.31% wl_cursor_surfa libc.so.6 [.] 0x00000000000a44b7
0.31% crowd_perf libvulkan_radeon.so [.] 0x0000000000110d98
0.31% wl_cursor_surfa libc.so.6 [.] 0x000000000018a4f3
0.30% crowd_perf libc.so.6 [.] 0x000000000018a4e2
0.30% crowd_perf libvulkan_radeon.so [.] 0x00000000000e6624
0.28% crowd_perf libvulkan_radeon.so [.] 0x000000000033b84d
0.28% crowd_perf libc.so.6 [.] 0x00000000000a4524
0.28% crowd_perf libc.so.6 [.] malloc
0.27% crowd_perf crowd_perf [.] runtime::map_seed_from_map_data
0.27% crowd_perf libvulkan_radeon.so [.] 0x00000000001822f7
0.26% crowd_perf libvulkan_radeon.so [.] 0x000000000033c9d7
0.26% crowd_perf libvulkan_radeon.so [.] 0x00000000000be362
0.26% crowd_perf libSDL3.so.0.4.12 [.] 0x000000000024cff0
0.26% crowd_perf libvulkan_radeon.so [.] 0x00000000000cd8a8
0.26% crowd_perf libvulkan_radeon.so [.] 0x000000000018d44f
0.25% crowd_perf libvulkan_radeon.so [.] 0x00000000001d131e
0.25% crowd_perf libvulkan_radeon.so [.] 0x0000000000116255
0.25% crowd_perf libdbus-1.so.3.38.3 [.] _dbus_atomic_inc
0.25% crowd_perf crowd_perf [.] __$hasher$$string
0.25% crowd_perf libSDL3.so.0.4.12 [.] 0x0000000000062360
0.25% crowd_perf libdrm.so.2.134.0 [.] drmSyncobjTimelineWait
0.24% crowd_perf libvulkan_radeon.so [.] 0x0000000000022daa
0.24% crowd_perf libc.so.6 [.] 0x000000000018a486
0.24% crowd_perf libvulkan_radeon.so [.] 0x00000000000b7b5f
0.24% crowd_perf libdbus-1.so.3.38.3 [.] _dbus_message_loader_queue_messages
0.24% crowd_perf libSDL3.so.0.4.12 [.] 0x00000000000168f4
0.24% crowd_perf libSDL3.so.0.4.12 [.] 0x0000000000144008
0.24% crowd_perf libSDL3.so.0.4.12 [.] 0x000000000024cd09
0.23% crowd_perf libc.so.6 [.] 0x00000000000a45c9
0.23% crowd_perf crowd_perf [.] engine::texture_run_len
0.23% crowd_perf [unknown] [k] 0xffffffff86355a81
0.23% crowd_perf libSDL3.so.0.4.12 [.] 0x000000000023af07
0.23% crowd_perf libSDL3.so.0.4.12 [.] 0x000000000024d030
0.23% crowd_perf libwayland-client.so.0.25.0 [.] 0x0000000000003140
0.23% crowd_perf libSDL3.so.0.4.12 [.] 0x00000000000166c5
0.22% crowd_perf libc.so.6 [.] pthread_rwlock_unlock
0.22% crowd_perf libc.so.6 [.] 0x000000000018a4ea
0.22% crowd_perf libc.so.6 [.] 0x000000000018a4ca
0.22% crowd_perf libc.so.6 [.] 0x000000000009ca36
0.22% crowd_perf crowd_perf [.] engine::begin_frame
0.22% crowd_perf libSDL3.so.0.4.12 [.] 0x00000000002501f2
0.22% crowd_perf libwayland-client.so.0.25.0 [.] 0x00000000000032b2
0.22% crowd_perf libvulkan_radeon.so [.] 0x00000000000cf9cf
0.22% crowd_perf libc.so.6 [.] 0x00000000000a58f9
0.22% crowd_perf libvulkan_radeon.so [.] 0x00000000001e47ac
0.21% crowd_perf libwayland-client.so.0.25.0 [.] 0x0000000000003263
0.21% crowd_perf libvulkan_radeon.so [.] 0x00000000001e61b8
0.21% crowd_perf libwayland-client.so.0.25.0 [.] 0x00000000000049dc
0.21% wl_cursor_surfa libSDL3.so.0.4.12 [.] 0x00000000001cd7b4
0.21% crowd_perf [unknown] [k] 0xffffffff85a7a084
0.20% crowd_perf libvulkan_radeon.so [.] 0x00000000000d2761
0.19% crowd_perf libwayland-client.so.0.25.0 [.] 0x0000000000003203
0.19% crowd_perf libvulkan_radeon.so [.] 0x000000000002295c
0.19% crowd_perf libc.so.6 [.] 0x0000000000190598
0.18% crowd_perf libvulkan_radeon.so [.] 0x00000000000d33ea
0.17% crowd_perf libSDL3.so.0.4.12 [.] 0x00000000000541ae
0.17% crowd_perf [unknown] [k] 0xffffffff855d7847
0.17% crowd_perf libvulkan_radeon.so [.] 0x000000000037a095
0.17% crowd_perf libvulkan_radeon.so [.] 0x00000000000c5b8f
0.17% crowd_perf libdbus-1.so.3.38.3 [.] 0x0000000000016a5d
0.17% crowd_perf libvulkan_radeon.so [.] 0x000000000002ca02
0.16% crowd_perf libvulkan_radeon.so [.] 0x0000000000181459
0.16% wl_cursor_surfa libwayland-client.so.0.25.0 [.] wl_display_flush
0.16% crowd_perf libvulkan_radeon.so [.] 0x00000000000ebd77
0.16% crowd_perf libvulkan_radeon.so [.] 0x00000000001e35cb
0.16% crowd_perf libdbus-1.so.3.38.3 [.] 0x0000000000031bdf
0.16% crowd_perf libvulkan_radeon.so [.] 0x00000000000bbf75
0.16% crowd_perf libvulkan_radeon.so [.] 0x00000000001e4a6a
0.15% crowd_perf libvulkan_radeon.so [.] 0x00000000001e4d24
0.15% crowd_perf libSDL3.so.0.4.12 [.] 0x0000000000016610
0.15% crowd_perf libvulkan_radeon.so [.] 0x00000000000ed46e
0.15% crowd_perf libvulkan_radeon.so [.] 0x000000000018d496
0.15% crowd_perf libvulkan_radeon.so [.] 0x00000000000b8dea
0.15% crowd_perf libSDL3.so.0.4.12 [.] 0x000000000024fd04
0.14% crowd_perf libSDL3.so.0.4.12 [.] 0x0000000000249f10
0.14% crowd_perf libvulkan_radeon.so [.] 0x00000000000ba831
0.14% crowd_perf libc.so.6 [.] 0x000000000018a55c
0.14% crowd_perf libwayland-client.so.0.25.0 [.] 0x0000000000003165
0.14% crowd_perf libvulkan_radeon.so [.] 0x000000000035f660
0.14% crowd_perf libvulkan_radeon.so [.] 0x0000000000115185
0.14% crowd_perf libSDL3.so.0.4.12 [.] 0x0000000000018584
0.14% crowd_perf libc.so.6 [.] 0x000000000009ffc4
0.14% crowd_perf libSDL3.so.0.4.12 [.] 0x00000000000657d0
0.14% crowd_perf libvulkan_radeon.so [.] 0x0000000000028528
0.14% crowd_perf libwayland-client.so.0.25.0 [.] 0x0000000000004cb4
0.14% crowd_perf libvulkan_radeon.so [.] 0x000000000021b325
0.14% crowd_perf libvulkan_radeon.so [.] 0x000000000013c5ff
0.14% wl_cursor_surfa libc.so.6 [.] 0x00000000000a7586
0.14% crowd_perf libSDL3.so.0.4.12 [.] 0x0000000000016675
0.14% crowd_perf libvulkan_radeon.so [.] 0x000000000035f6d0
0.14% crowd_perf [unknown] [k] 0xffffffff855e8fd6
0.14% crowd_perf libc.so.6 [.] 0x00000000000a44b7
0.14% crowd_perf libvulkan_radeon.so [.] 0x000000000018aae8
0.14% crowd_perf libvulkan_radeon.so [.] 0x0000000000022b11
0.14% crowd_perf libdbus-1.so.3.38.3 [.] dbus_connection_ref
0.14% crowd_perf libvulkan_radeon.so [.] 0x00000000001d9f6f
0.14% crowd_perf libvulkan_radeon.so [.] 0x00000000001814d7
0.14% crowd_perf libvulkan_radeon.so [.] 0x000000000035f634
0.13% crowd_perf libvulkan_radeon.so [.] 0x0000000000181ee4
0.13% crowd_perf libvulkan_radeon.so [.] 0x000000000033cb4a
0.13% crowd_perf libvulkan_radeon.so [.] 0x00000000000cb17f
0.13% wl_cursor_surfa libwayland-client.so.0.25.0 [.] wl_display_read_events
0.13% crowd_perf libvulkan_radeon.so [.] 0x000000000018c7aa
0.13% crowd_perf libvulkan_radeon.so [.] 0x000000000033b7e1
0.13% crowd_perf libvulkan_radeon.so [.] 0x00000000000c9cb4
0.13% crowd_perf libvulkan_radeon.so [.] 0x00000000000c5e16
0.13% crowd_perf libvulkan_radeon.so [.] 0x000000000017dbbb
0.13% crowd_perf libSDL3.so.0.4.12 [.] 0x00000000000f7a33
0.13% crowd_perf libvulkan_radeon.so [.] 0x000000000017ea01
0.13% crowd_perf libnvidia-glcore.so.610.43.03 [.] 0x0000000000fcd46c
0.13% crowd_perf libvulkan_radeon.so [.] 0x00000000000ccf75
0.13% crowd_perf libvulkan_radeon.so [.] 0x000000000002c934
0.13% crowd_perf libSDL3.so.0.4.12 [.] 0x00000000000185a9
0.13% crowd_perf libwayland-client.so.0.25.0 [.] 0x0000000000003193
0.13% crowd_perf libvulkan_radeon.so [.] 0x0000000000115378
0.13% crowd_perf libSDL3.so.0.4.12 [.] 0x0000000000062cee
0.13% crowd_perf libwayland-client.so.0.25.0 [.] 0x00000000000039f1
0.13% crowd_perf libvulkan_radeon.so [.] 0x00000000000c5525
0.13% crowd_perf libvulkan_radeon.so [.] 0x00000000001dbca4
0.13% wl_cursor_surfa libc.so.6 [.] 0x0000000000094084
0.13% wl_cursor_surfa libc.so.6 [.] 0x00000000000a66c4
0.13% crowd_perf libSDL3.so.0.4.12 [.] 0x00000000001c8cfd
0.13% crowd_perf libvulkan_radeon.so [.] 0x00000000000c5b0f
0.13% crowd_perf libvulkan_radeon.so [.] 0x0000000000116284
0.13% crowd_perf libwayland-client.so.0.25.0 [.] 0x000000000000320b
0.13% crowd_perf libvulkan_radeon.so [.] 0x000000000017d7c4
0.13% crowd_perf libSDL3.so.0.4.12 [.] 0x000000000023af40
0.13% crowd_perf libvulkan_radeon.so [.] 0x000000000002cd72
0.13% crowd_perf libvulkan_radeon.so [.] 0x00000000000cd651
0.13% crowd_perf libvulkan_radeon.so [.] 0x0000000000217945
0.12% crowd_perf libSDL3.so.0.4.12 [.] 0x000000000024e846
0.12% crowd_perf libvulkan_radeon.so [.] 0x000000000017ff51
0.12% crowd_perf libvulkan_radeon.so [.] 0x0000000000186261
0.12% crowd_perf libSDL3.so.0.4.12 [.] 0x00000000002440cf
0.12% crowd_perf libvulkan_radeon.so [.] 0x00000000000ebdf7
0.12% crowd_perf libvulkan_radeon.so [.] 0x00000000001f3ff0
0.12% crowd_perf libvulkan_radeon.so [.] 0x00000000000cb17b
0.12% crowd_perf libvulkan_radeon.so [.] 0x00000000001deb23
0.12% crowd_perf libvulkan_radeon.so [.] 0x00000000001f2e1b
0.12% crowd_perf libvulkan_radeon.so [.] 0x00000000001f44d1
0.12% crowd_perf libvulkan_radeon.so [.] 0x00000000001161e8
0.12% crowd_perf libvulkan_radeon.so [.] 0x00000000000d88e7
0.12% crowd_perf libvulkan_radeon.so [.] 0x00000000001168fc
0.12% crowd_perf libvulkan_radeon.so [.] 0x00000000000cea95
0.12% crowd_perf libvulkan_radeon.so [.] 0x00000000001e4771
0.12% crowd_perf libvulkan_radeon.so [.] 0x0000000000336cae
0.12% crowd_perf [unknown] [k] 0xffffffff84e00087
0.12% crowd_perf libvulkan_radeon.so [.] 0x00000000000cd7c4
0.12% crowd_perf libvulkan_radeon.so [.] 0x00000000000b8712
0.12% crowd_perf libvulkan_radeon.so [.] 0x000000000010da71
0.12% crowd_perf libvulkan_radeon.so [.] 0x00000000001dca18
0.12% crowd_perf libc.so.6 [.] 0x00000000000a6ed3
0.12% crowd_perf libvulkan_radeon.so [.] 0x00000000000bf533
0.12% crowd_perf libvulkan_radeon.so [.] 0x00000000000ceb86
0.12% crowd_perf libvulkan_radeon.so [.] 0x00000000001166e5
0.12% crowd_perf libvulkan_radeon.so [.] 0x000000000068cca2
0.12% crowd_perf libvulkan_radeon.so [.] 0x0000000000116312
0.12% crowd_perf libdbus-1.so.3.38.3 [.] _dbus_list_pop_first_link
0.12% crowd_perf libvulkan_radeon.so [.] 0x0000000000180ab2
0.12% crowd_perf libvulkan_radeon.so [.] 0x000000000002336f
0.12% crowd_perf crowd_perf [.] engine::now_seconds
0.12% crowd_perf libSDL3.so.0.4.12 [.] 0x000000000024fc98
0.12% crowd_perf libvulkan_radeon.so [.] 0x00000000001f3ff4
0.12% crowd_perf libvulkan_radeon.so [.] 0x0000000000116118
0.12% crowd_perf libvulkan_radeon.so [.] 0x0000000000181449
0.12% crowd_perf libdrm.so.2.134.0 [.] drmSyncobjWait
0.12% crowd_perf libvulkan_radeon.so [.] 0x00000000000b707d
0.12% crowd_perf libvulkan_radeon.so [.] 0x000000000011621a
0.12% crowd_perf libSDL3.so.0.4.12 [.] 0x000000000023c102
0.12% crowd_perf libSDL3.so.0.4.12 [.] 0x00000000002469b4
0.12% crowd_perf libvulkan_radeon.so [.] 0x00000000001d8d26
0.12% crowd_perf libvulkan_radeon.so [.] 0x00000000000bdcf2
0.12% crowd_perf libvulkan_radeon.so [.] 0x00000000001e4c57
0.12% crowd_perf libvulkan_radeon.so [.] 0x00000000000c2897
0.12% crowd_perf libSDL3.so.0.4.12 [.] 0x000000000023be6f
0.12% crowd_perf [unknown] [k] 0xffffffff84e015f4
0.12% crowd_perf libSDL3.so.0.4.12 [.] 0x000000000025442a
0.12% crowd_perf libc.so.6 [.] 0x00000000000a6403
0.12% crowd_perf libvulkan_radeon.so [.] 0x00000000001f3010
0.12% wl_cursor_surfa libSDL3.so.0.4.12 [.] 0x00000000001e3f78
0.12% crowd_perf libvulkan_radeon.so [.] 0x00000000001e61f1
0.12% crowd_perf [unknown] [k] 0xffffffff85a7a016
0.12% crowd_perf libvulkan_radeon.so [.] 0x000000000018d4e4
0.12% crowd_perf libvulkan_radeon.so [.] 0x00000000000f4af3
0.12% crowd_perf libvulkan_radeon.so [.] 0x00000000001153f9
0.12% crowd_perf libvulkan_radeon.so [.] 0x00000000000cb4b9
0.12% crowd_perf libvulkan_radeon.so [.] 0x00000000000283b6
0.12% crowd_perf libvulkan_radeon.so [.] 0x00000000000d2d0b
0.12% crowd_perf libvulkan_radeon.so [.] 0x00000000001e6d70
0.12% crowd_perf libvulkan_radeon.so [.] 0x0000000000115a48
0.12% crowd_perf libSDL3.so.0.4.12 [.] 0x000000000024d110
0.12% crowd_perf libvulkan_radeon.so [.] 0x000000000017ff7a
0.11% crowd_perf libc.so.6 [.] 0x00000000000a5735
0.11% crowd_perf libvulkan_radeon.so [.] 0x000000000011416b
0.11% crowd_perf libSDL3.so.0.4.12 [.] 0x000000000023aefa
0.11% crowd_perf libvulkan_radeon.so [.] 0x00000000000cd413
0.11% crowd_perf libvulkan_radeon.so [.] 0x000000000068cc64
0.11% crowd_perf libvulkan_radeon.so [.] 0x0000000000022d88
0.11% crowd_perf libSDL3.so.0.4.12 [.] 0x000000000025478f
0.11% crowd_perf libSDL3.so.0.4.12 [.] 0x00000000000545e3
0.11% crowd_perf libvulkan_radeon.so [.] 0x000000000018c87b
0.11% crowd_perf libc.so.6 [.] 0x000000000005bcfd
0.11% crowd_perf libwayland-client.so.0.25.0 [.] 0x00000000000032a4
0.11% crowd_perf libdbus-1.so.3.38.3 [.] 0x000000000001aa7b
0.11% wl_cursor_surfa libc.so.6 [.] 0x00000000000a674c
0.11% crowd_perf libvulkan_radeon.so [.] 0x00000000000d6749
0.11% crowd_perf libffi.so.8.4.1 [.] 0x0000000000002bf4
0.11% crowd_perf libSDL3.so.0.4.12 [.] 0x0000000000054e93
0.11% crowd_perf libSDL3.so.0.4.12 [.] 0x0000000000018567
0.11% crowd_perf libvulkan_radeon.so [.] 0x0000000000189a35
0.11% crowd_perf libvulkan_radeon.so [.] 0x0000000000182313
0.11% crowd_perf libdbus-1.so.3.38.3 [.] 0x000000000003219d
0.11% crowd_perf libSDL3.so.0.4.12 [.] SDL_UnmapGPUTransferBuffer
0.11% crowd_perf libSDL3.so.0.4.12 [.] 0x00000000000176c2
0.11% wl_cursor_surfa libwayland-client.so.0.25.0 [.] 0x0000000000003689
0.11% crowd_perf libvulkan_radeon.so [.] 0x0000000000022a03
0.11% crowd_perf libvulkan_radeon.so [.] 0x000000000002f38d
0.11% crowd_perf libvulkan_radeon.so [.] 0x00000000000d2686
0.11% crowd_perf libSDL3.so.0.4.12 [.] 0x0000000000244358
0.11% crowd_perf libvulkan_radeon.so [.] 0x00000000000ce843
0.11% crowd_perf libvulkan_radeon.so [.] 0x00000000001f41d6
0.11% crowd_perf libvulkan_radeon.so [.] 0x0000000000217e57
0.11% crowd_perf libvulkan_radeon.so [.] 0x00000000000cca9b
0.11% crowd_perf libvulkan_radeon.so [.] 0x000000000022d261
0.11% crowd_perf libvulkan_radeon.so [.] 0x00000000000ebc8d
0.11% crowd_perf libc.so.6 [.] pthread_getspecific
0.11% crowd_perf libc.so.6 [.] 0x00000000000a4520
0.11% crowd_perf libvulkan_radeon.so [.] 0x00000000000c0133
0.11% crowd_perf libSDL3.so.0.4.12 [.] 0x00000000000176d1
0.11% crowd_perf libSDL3.so.0.4.12 [.] 0x00000000002475f1
0.11% crowd_perf libvulkan_radeon.so [.] 0x000000000035f6c7
0.11% wl_cursor_surfa libc.so.6 [.] 0x00000000000a661d
0.11% crowd_perf libSDL3.so.0.4.12 [.] 0x0000000000246fbc
0.11% wl_cursor_surfa libc.so.6 [.] pthread_mutex_lock
0.11% crowd_perf libvulkan_radeon.so [.] 0x00000000000c4a78
0.11% crowd_perf libvulkan_radeon.so [.] 0x00000000000d227c
0.11% crowd_perf libvulkan_radeon.so [.] 0x00000000000cf034
0.11% crowd_perf libSDL3.so.0.4.12 [.] 0x0000000000016e32
0.11% crowd_perf libvulkan_radeon.so [.] 0x00000000000b91fb
0.11% crowd_perf libvulkan_radeon.so [.] 0x00000000001e6228
0.11% crowd_perf libc.so.6 [.] 0x0000000000189c5a
0.11% crowd_perf libvulkan_radeon.so [.] 0x00000000000b7a68
0.11% crowd_perf libvulkan_radeon.so [.] 0x00000000001f2b1b
0.11% crowd_perf libc.so.6 [.] __libc_calloc
0.11% crowd_perf libvulkan_radeon.so [.] 0x00000000000c5ba8
0.11% crowd_perf libc.so.6 [.] 0x0000000000189c6e
0.10% crowd_perf libvulkan_radeon.so [.] 0x000000000033c9cd
0.10% crowd_perf libvulkan_radeon.so [.] 0x00000000000bc661
0.10% crowd_perf libvulkan_radeon.so [.] 0x0000000000022a90
0.10% crowd_perf libvulkan_radeon.so [.] 0x00000000000d2ed4
0.10% crowd_perf libvulkan_radeon.so [.] 0x00000000000cfbdd
0.10% crowd_perf libvulkan_radeon.so [.] 0x00000000001158db
0.10% crowd_perf libwayland-client.so.0.25.0 [.] 0x000000000000315e
0.10% crowd_perf libvulkan_radeon.so [.] 0x00000000000c5b36
0.10% crowd_perf libwayland-client.so.0.25.0 [.] 0x000000000000326e
0.10% crowd_perf libvulkan_radeon.so [.] 0x000000000013c87e
0.10% crowd_perf libSDL3.so.0.4.12 [.] 0x0000000000062c29
0.10% crowd_perf libSDL3.so.0.4.12 [.] 0x000000000024e2b6
0.10% crowd_perf libSDL3.so.0.4.12 [.] 0x000000000023be24
0.10% crowd_perf libvulkan_radeon.so [.] 0x0000000000197523
0.10% crowd_perf libwayland-client.so.0.25.0 [.] wl_display_prepare_read_queue
0.10% crowd_perf libc.so.6 [.] 0x00000000000a57e4
0.10% crowd_perf libSDL3.so.0.4.12 [.] 0x00000000002441e6
0.10% crowd_perf libvulkan_radeon.so [.] 0x00000000000cd71c
0.10% crowd_perf libvulkan_radeon.so [.] 0x000000000018c8b9
0.10% crowd_perf libvulkan_radeon.so [.] 0x00000000001cfb14
0.10% crowd_perf libSDL3.so.0.4.12 [.] 0x0000000000067a27
0.10% crowd_perf libvulkan_radeon.so [.] 0x000000000022ddf5
0.10% crowd_perf libSDL3.so.0.4.12 [.] 0x0000000000254752
0.10% crowd_perf libc.so.6 [.] 0x000000000009ca4f
0.10% crowd_perf libvulkan_radeon.so [.] 0x0000000000189e7f
0.10% crowd_perf libvulkan_radeon.so [.] 0x00000000001f2d44
0.10% crowd_perf libc.so.6 [.] 0x0000000000183444
0.10% crowd_perf libc.so.6 [.] ioctl
0.10% crowd_perf libSDL3.so.0.4.12 [.] 0x000000000001662f
0.10% crowd_perf libvulkan_radeon.so [.] 0x00000000000d3c1f
0.10% crowd_perf libvulkan_radeon.so [.] 0x00000000000ed479
0.10% crowd_perf libvulkan_radeon.so [.] 0x00000000001e4e14
0.10% wl_cursor_surfa libSDL3.so.0.4.12 [.] 0x00000000001e3f76
0.10% crowd_perf libwayland-client.so.0.25.0 [.] wl_list_empty
0.10% crowd_perf libvulkan_radeon.so [.] 0x00000000000d6c8b
0.10% crowd_perf libvulkan_radeon.so [.] 0x0000000000193681
0.10% crowd_perf libvulkan_radeon.so [.] 0x00000000001dd4e5
0.10% crowd_perf libvulkan_radeon.so [.] 0x000000000018d452
0.10% crowd_perf libvulkan_radeon.so [.] 0x0000000000028474
0.10% crowd_perf libvulkan_radeon.so [.] 0x00000000000bc657
0.10% crowd_perf libdbus-1.so.3.38.3 [.] dbus_connection_get_dispatch_status
0.10% crowd_perf libvulkan_radeon.so [.] 0x000000000068fe91
0.10% crowd_perf libvulkan_radeon.so [.] 0x000000000017e9d8
0.10% crowd_perf libvulkan_radeon.so [.] 0x00000000000fa720
0.10% crowd_perf libvulkan_radeon.so [.] 0x000000000013d041
0.10% crowd_perf libvulkan_radeon.so [.] 0x000000000033b851
0.10% crowd_perf libvulkan_radeon.so [.] 0x00000000001e3616
0.09% crowd_perf libSDL3.so.0.4.12 [.] 0x000000000024f5a2
0.09% crowd_perf libSDL3.so.0.4.12 [.] 0x000000000025445f
0.09% crowd_perf libvulkan_radeon.so [.] 0x00000000000cb359
0.09% crowd_perf libc.so.6 [.] strchrnul@plt
0.09% crowd_perf libvulkan_radeon.so [.] 0x00000000000d3493
0.09% crowd_perf libvulkan_radeon.so [.] 0x0000000000022b67
0.09% crowd_perf libvulkan_radeon.so [.] 0x0000000000116982
0.09% crowd_perf libvulkan_radeon.so [.] 0x000000000035f664
0.09% crowd_perf libc.so.6 [.] 0x0000000000189c47
0.08% crowd_perf libwayland-client.so.0.25.0 [.] 0x00000000000031c3
0.08% crowd_perf libc.so.6 [.] 0x00000000000a66c4
0.08% crowd_perf libvulkan_radeon.so [.] 0x00000000000ebd95
0.08% crowd_perf libc.so.6 [.] 0x00000000000a5750
0.08% crowd_perf libvulkan_radeon.so [.] 0x00000000000ce980
0.08% crowd_perf libvulkan_radeon.so [.] 0x0000000000115f93
0.08% crowd_perf libvulkan_radeon.so [.] 0x000000000018d5e9
0.08% wl_cursor_surfa libc.so.6 [.] 0x000000000009ca5c
0.07% crowd_perf libvulkan_radeon.so [.] 0x000000000018aaf9
0.07% crowd_perf libvulkan_radeon.so [.] 0x00000000000c4a6a
0.07% wl_cursor_surfa libSDL3.so.0.4.12 [.] 0x00000000001cd7b1
0.07% crowd_perf libvulkan_radeon.so [.] 0x00000000001e4e3e
0.06% wl_cursor_surfa libwayland-client.so.0.25.0 [.] wl_list_insert
0.06% wl_cursor_surfa libc.so.6 [.] 0x00000000000a6ed3
0.03% crowd_perf libxkbcommon.so.0.13.2 [.] 0x00000000000084b7
0.03% wl_cursor_surfa libc.so.6 [.] 0x00000000000a6f67
0.02% crowd_perf libc.so.6 [.] 0x0000000000189d47
0.02% crowd_perf libvulkan_radeon.so [.] 0x00000000001e5074
0.02% crowd_perf ld-linux-x86-64.so.2 [.] 0x000000000000ac3a
0.01% crowd_perf libvulkan_radeon.so [.] 0x0000000000182d8f
0.00% crowd_perf libc.so.6 [.] __cxa_finalize
0.00% wl_cursor_surfa libc.so.6 [.] pthread_cond_broadcast
0.00% wl_cursor_surfa [unknown] [k] 0xffffffff84e00080
0.00% crowd_perf libc.so.6 [.] 0x00000000000a7681
0.00% wl_cursor_surfa libwayland-client.so.0.25.0 [.] 0x00000000000036ef
0.00% crowd_p:disk$0 libc.so.6 [.] pthread_cond_wait
0.00% wl_cursor_surfa libwayland-client.so.0.25.0 [.] 0x0000000000003621
0.00% crowd_perf libc.so.6 [.] 0x00000000000534eb
0.00% crowd_perf libdbus-1.so.3.38.3 [.] 0x0000000000037c44
0.00% wl_cursor_surfa libc.so.6 [.] 0x000000000009ca21
0.00% wl_cursor_surfa libc.so.6 [.] ppoll
0.00% crowd_perf libvulkan_radeon.so [.] 0x000000000002d5ba
0.00% crowd_perf libSDL3.so.0.4.12 [.] 0x00000000000670f4
0.00% crowd_perf libvulkan_radeon.so [.] 0x000000000037a011
0.00% crowd_perf libc.so.6 [.] 0x0000000000189cf7
0.00% crowd_perf ld-linux-x86-64.so.2 [.] 0x0000000000015951
0.00% crowd_perf libSDL3.so.0.4.12 [.] 0x000000000024e620
0.00% crowd_perf libvulkan_radeon.so [.] 0x00000000001f2f92
0.00% wl_cursor_surfa libc.so.6 [.] 0x00000000000a4463
0.00% crowd_perf libvulkan_radeon.so [.] 0x000000000001e56c
0.00% crowd_perf libdbus-1.so.3.38.3 [.] 0x000000000001004a
0.00% wl_cursor_surfa libwayland-client.so.0.25.0 [.] 0x00000000000031c3
0.00% crowd_perf ld-linux-x86-64.so.2 [.] 0x0000000000014887
0.00% crowd_perf libc.so.6 [.] 0x000000000005b734
0.00% crowd_perf libc.so.6 [.] 0x000000000005bd50
0.00% crowd_perf libvulkan_radeon.so [.] 0x00000000001e3e38
0.00% crowd_perf libc.so.6 [.] 0x0000000000064b99
0.00% crowd_perf libc.so.6 [.] 0x000000000005a244
0.00% crowd_perf libvulkan_radeon.so [.] 0x0000000000345b18
0.00% crowd_perf libc.so.6 [.] __ctype_init
0.00% crowd_perf [unknown] [k] 0xffffffff86355a14
0.00% crowd_perf [unknown] [k] 0xffffffff86355a10
0.00% crowd_perf libvulkan_radeon.so [.] 0x0000000000345ce7
0.00% crowd_perf libvulkan_radeon.so [.] 0x0000000000345adb
0.00% crowd_perf libnvidia-gpucomp.so.610.43.03 [.] 0x0000000000654f48
0.00% wl_cursor_surfa libSDL3.so.0.4.12 [.] 0x00000000001e3f74
0.00% crowd_perf libc.so.6 [.] __errno_location
0.00% crowd_perf libvulkan_radeon.so [.] 0x00000000000ca8f2
0.00% crowd_perf libnvidia-gpucomp.so.610.43.03 [.] 0x0000000001961f52
0.00% crowd_perf libvulkan_radeon.so [.] 0x0000000000345837
0.00% crowd_perf libc.so.6 [.] pthread_self
0.00% wl_cursor_surfa [unknown] [k] 0xffffffff852a9115
0.00% crowd_perf libc.so.6 [.] 0x0000000000103a63
0.00% crowd_perf libvulkan_radeon.so [.] 0x000000000018d575
0.00% crowd_perf libvulkan_radeon.so [.] 0x0000000000345cfe
0.00% crowd_perf libc.so.6 [.] 0x0000000000097417
0.00% crowd_perf libc.so.6 [.] 0x000000000009741b
0.00% crowd_perf libvulkan_radeon.so [.] 0x00000000001166ae
0.00% crowd_perf [unknown] [k] 0xffffffff84e015f0
0.00% crowd_perf libwayland-client.so.0.25.0 [.] wl_display_dispatch_queue_timeout
0.00% crowd_perf libc.so.6 [.] 0x0000000000185400
0.00% crowd_perf ld-linux-x86-64.so.2 [.] 0x0000000000008b5e
0.00% crowd_perf libvulkan_radeon.so [.] 0x0000000000022edc
0.00% crowd_perf libSDL3.so.0.4.12 [.] 0x0000000000018892
0.00% crowd_perf libvulkan_radeon.so [.] 0x000000000028ed39
0.00% wl_cursor_surfa libc.so.6 [.] 0x0000000000094040
0.00% crowd_perf libc.so.6 [.] sendmsg
0.00% crowd_perf [unknown] [k] 0xffffffff84e01280
0.00% crowd_perf libvulkan_radeon.so [.] 0x0000000000344ddb
0.00% crowd_perf libvulkan_radeon.so [.] 0x0000000000345bb3
0.00% crowd_perf libvulkan_radeon.so [.] 0x0000000000344ddd
0.00% crowd_perf libc.so.6 [.] 0x000000000011bed0
0.00% crowd_perf libvulkan_radeon.so [.] 0x0000000000344cd4
0.00% crowd_perf libvulkan_radeon.so [.] 0x0000000000345ad6
0.00% crowd_perf libc.so.6 [.] 0x0000000000094047
0.00% crowd_perf libc.so.6 [.] 0x00000000000973a0
0.00% crowd_perf libc.so.6 [.] 0x0000000000103a40
0.00% wl_cursor_surfa libc.so.6 [.] 0x0000000000094047
0.00% crowd_perf libc.so.6 [.] __poll
0.00% crowd_perf libc.so.6 [.] 0x00000000000973a4
0.00% crowd_perf libdbus-1.so.3.38.3 [.] 0x0000000000032197
0.00% crowd_perf [unknown] [k] 0xffffffff84e01630
0.00% crowd_perf ld-linux-x86-64.so.2 [.] 0x000000000000932e
0.00% crowd_perf ld-linux-x86-64.so.2 [.] 0x0000000000009339
0.00% crowd_perf ld-linux-x86-64.so.2 [.] 0x000000000001f103
0.00% crowd_perf libc.so.6 [.] ppoll
0.00% crowd_perf libc.so.6 [.] realloc
0.00% crowd_perf libc.so.6 [.] 0x0000000000094040
0.00% crowd_perf libc.so.6 [.] 0x0000000000094084
0.00% crowd_perf libc.so.6 [.] 0x00000000000a78dc
0.00% crowd_perf libnvidia-glcore.so.610.43.03 [.] 0x00000000009e786b
0.00% crowd_perf libnvidia-gpucomp.so.610.43.03 [.] 0x0000000000455dd3
0.00% crowd_perf libnvidia-gpucomp.so.610.43.03 [.] 0x000000000067d1b0
0.00% crowd_perf libnvidia-gpucomp.so.610.43.03 [.] 0x000000000067d1c2
0.00% crowd_perf libnvidia-gpucomp.so.610.43.03 [.] 0x0000000001956940
0.00% crowd_perf libnvidia-gpucomp.so.610.43.03 [.] 0x000000000195a141
0.00% crowd_perf libvulkan_radeon.so [.] 0x0000000000022e9e
0.00% crowd_perf libvulkan_radeon.so [.] 0x0000000000022ea7
0.00% crowd_perf libvulkan_radeon.so [.] 0x0000000000022ebd
0.00% crowd_perf libvulkan_radeon.so [.] 0x00000000000bafc5
0.00% crowd_perf libvulkan_radeon.so [.] 0x00000000000ca918
0.00% crowd_perf libvulkan_radeon.so [.] 0x00000000000ca91f
0.00% crowd_perf libvulkan_radeon.so [.] 0x000000000011666f
0.00% crowd_perf libvulkan_radeon.so [.] 0x00000000001166a8
0.00% crowd_perf libvulkan_radeon.so [.] 0x00000000001f2dbf
0.00% crowd_perf libvulkan_radeon.so [.] 0x00000000001f2dd0
0.00% crowd_perf libvulkan_radeon.so [.] 0x000000000028ece4
0.00% crowd_perf libvulkan_radeon.so [.] 0x000000000028ed0d
0.00% crowd_perf libvulkan_radeon.so [.] 0x0000000000345bb0
0.00% crowd_perf libvulkan_radeon.so [.] 0x000000000068d01a
0.00% crowd_perf libwayland-client.so.0.25.0 [.] 0x0000000000003aa8
0.00% crowd_perf [unknown] [k] 0xffffffff84e01670
0.00% crowd_perf [unknown] [k] 0xffffffff84e01690
0.00% wl_cursor_surfa libc.so.6 [.] 0x0000000000094050
0.00% wl_cursor_surfa libc.so.6 [.] 0x0000000000094085
0.00% wl_cursor_surfa libc.so.6 [.] 0x000000000009fff2
0.00% wl_cursor_surfa libwayland-client.so.0.25.0 [.] 0x0000000000004524
0.00% wl_cursor_surfa [unknown] [k] 0xffffffff84e01630
#
# (Tip: For tracepoint events, try: perf report -s trace_fields)
#
Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 82 KiB

+730
View File
@@ -0,0 +1,730 @@
# To display the perf.data header info, please use --header/--header-only options.
#
#
# Total Lost Samples: 0
#
# Samples: 953 of event 'cpu/cycles/Pu'
# Event count (approx.): 5763089468
#
# Overhead Command Shared Object Symbol
# ........ ............... ............................. ..........................................................................................................................................................................................
#
4.03% crowd_perf libc.so.6 [.] pthread_mutex_lock
|
---pthread_mutex_lock
|
--0.65%--0x7f80850501f1
engine::end_frame (inlined)
main::main
main
0x7f8084a27740
__libc_start_main
_start
3.19% crowd_perf crowd_perf [.] main::main
|
--0.79%--runtime::default_hasher (inlined)
runtime::default_hasher_string (inlined)
|
--0.54%--engine::character_clip (inlined)
engine::update_sprite (inlined)
main::main
main
0x7f8084a27740
__libc_start_main
_start
2.85% crowd_perf libc.so.6 [.] 0x00000000000a73e9
|
---0x7f8084aa73e9
wl_proxy_marshal_array_flags
wl_proxy_marshal_flags
0x7f8082b97614
0x7f8082b8a4f8
0x7f808504ffc9
engine::end_frame (inlined)
main::main
main
0x7f8084a27740
__libc_start_main
_start
2.20% crowd_perf crowd_perf [.] __$map_get$$map[string]engine::Clip_Def
|
---__$map_get$$map[string]engine::Clip_Def
|
--1.91%--engine::character_clip (inlined)
engine::update_sprite (inlined)
main::main
main
0x7f8084a27740
__libc_start_main
_start
2.07% crowd_perf libc.so.6 [.] 0x0000000000189c53
|
---0x7f8084b89c53
runtime::_append_elem
runtime::append_elem:proc(array:^[dynamic]engine::Queued_Sprite,arg:engine::Queued_Sprite,loc:runtime::Source_Code_Location)->(n:int,err:runtime::Allocator_Error) (inlined)
engine::draw_sprite (inlined)
main::main
main
0x7f8084a27740
__libc_start_main
_start
1.83% crowd_perf libc.so.6 [.] clock_gettime
|
---clock_gettime
|
|--0.53%--0x7f808502c819
|
--0.52%--0x7f8082d7a09a
0x7f8082d3de27
|
--0.52%--0x7f8082b975b5
0x7f8082b8a4f8
0x7f808504ffc9
engine::end_frame (inlined)
main::main
main
0x7f8084a27740
__libc_start_main
_start
1.58% crowd_perf libwayland-client.so.0.25.0 [.] wl_proxy_marshal_array_flags
|
---wl_proxy_marshal_array_flags
wl_proxy_marshal_flags
1.55% crowd_perf libvulkan_radeon.so [.] 0x000000000031fb52
|
---0x7f8082d1fb52
0x7f8082a2cc72
0x7f8082a2cf4e
0x7f8082a2e299
0x7f8082a2f277
0x7f8082be052c
0x7f8082be1521
0x7f8085047581
0x7f8084e64bab
engine::end_frame (inlined)
main::main
main
0x7f8084a27740
__libc_start_main
_start
1.34% wl_cursor_surfa libwayland-client.so.0.25.0 [.] wl_list_insert
1.30% wl_cursor_surfa libc.so.6 [.] 0x00000000000a678f
1.18% crowd_perf [unknown] [k] 0xffffffff84e00080
|
---0xffffffff84e00080
|
--0.94%--ioctl
|
--0.80%--drmIoctl
1.07% crowd_perf libc.so.6 [.] ioctl
|
---ioctl
|
--1.07%--drmIoctl
|
--0.61%--drmSyncobjTimelineWait
|
--0.50%--0x7f8082b8d8ad
0x7f8082b93f45
0x7f8082b89296
0x7f8082b89241
0x7f80850544bd
0x7f8084e69860
engine::begin_frame (inlined)
main::main
main
0x7f8084a27740
__libc_start_main
_start
1.05% crowd_perf [vdso] [.] __vdso_clock_gettime
|
---__vdso_clock_gettime
clock_gettime
|
--0.50%--0x7f8082d7a09a
0.93% crowd_perf [unknown] [k] 0xffffffff86355a81
|
---0xffffffff86355a81
0xffffffff84e0012f
|
--0.81%--ioctl
|
--0.69%--drmIoctl
0.92% crowd_perf libdrm.so.2.134.0 [.] drmIoctl
|
---drmIoctl
0.85% crowd_perf libc.so.6 [.] cfree
|
---cfree
0.81% crowd_perf libc.so.6 [.] 0x000000000009ca5c
|
---0x7f8084a9ca5c
0.78% crowd_perf libc.so.6 [.] 0x00000000000a6ed3
|
---0x7f8084aa6ed3
|
--0.55%--0x7f8084aa714d
0.70% crowd_perf libSDL3.so.0.4.12 [.] 0x00000000002501f2
|
---0x7f80850501f2
engine::end_frame (inlined)
main::main
main
0x7f8084a27740
__libc_start_main
_start
0.65% crowd_perf libvulkan_radeon.so [.] 0x0000000000022d88
|
---0x7f8082a22d88
0.62% crowd_perf libvulkan_radeon.so [.] 0x00000000001f41b7
|
---0x7f8082bf41b7
0x7f8082bf44e5
0.61% crowd_perf libvulkan_radeon.so [.] 0x00000000000d2c23
|
---0x7f8082ad2c23
0x7f8082be6325
0.60% crowd_perf libc.so.6 [.] 0x000000000018a547
|
---0x7f8084b8a547
0.56% crowd_perf libc.so.6 [.] malloc
|
---malloc
0.55% crowd_perf libvulkan_radeon.so [.] 0x00000000000e6624
|
---0x7f8082ae6624
0x7f8082be6325
0.53% crowd_perf libSDL3.so.0.4.12 [.] 0x00000000002475f1
|
---0x7f80850475f1
0x7f8084e64bab
engine::end_frame (inlined)
main::main
main
0x7f8084a27740
__libc_start_main
_start
0.53% crowd_perf libvulkan_radeon.so [.] 0x00000000001e61b8
|
---0x7f8082be61b8
0x7f808503b9d8
0x7f8085049f22
engine::end_frame (inlined)
main::main
main
0x7f8084a27740
__libc_start_main
_start
0.51% crowd_perf [unknown] [k] 0xffffffff855d7847
|
---0xffffffff855d7847
0xffffffff86355aba
0xffffffff84e0012f
ioctl
drmIoctl
0.50% crowd_perf libvulkan_radeon.so [.] 0x000000000033b80b
|
---0x7f8082d3b80b
0x7f8082bf41ce
0.50% crowd_perf libSDL3.so.0.4.12 [.] 0x000000000023af6a
0.48% crowd_perf libvulkan_radeon.so [.] 0x00000000001deb23
0.48% crowd_perf libc.so.6 [.] pthread_rwlock_unlock
0.48% crowd_perf libvulkan_radeon.so [.] 0x000000000033c9d7
0.47% crowd_perf libvulkan_radeon.so [.] 0x000000000002ca18
0.46% wl_cursor_surfa libwayland-client.so.0.25.0 [.] wl_display_flush
0.46% crowd_perf libvulkan_radeon.so [.] 0x00000000000b92b8
0.45% crowd_perf libvulkan_radeon.so [.] 0x00000000001822f7
0.44% crowd_perf libc.so.6 [.] pthread_rwlock_wrlock
0.41% crowd_perf libwayland-client.so.0.25.0 [.] 0x0000000000003203
0.41% crowd_perf libc.so.6 [.] __errno_location
0.40% crowd_perf libvulkan_radeon.so [.] 0x0000000000180ab2
0.40% crowd_perf libSDL3.so.0.4.12 [.] 0x000000000024d183
0.40% crowd_perf libvulkan_radeon.so [.] 0x00000000000d2761
0.39% crowd_perf libSDL3.so.0.4.12 [.] 0x0000000000016900
0.39% crowd_perf libSDL3.so.0.4.12 [.] 0x0000000000243e0a
0.39% wl_cursor_surfa libc.so.6 [.] 0x00000000000a6747
0.36% crowd_perf libvulkan_radeon.so [.] 0x000000000018d492
0.35% crowd_perf libvulkan_radeon.so [.] 0x00000000001814c2
0.35% crowd_perf libvulkan_radeon.so [.] 0x00000000000b8fdd
0.35% crowd_perf libvulkan_radeon.so [.] 0x00000000000e5edc
0.33% wl_cursor_surfa libSDL3.so.0.4.12 [.] 0x00000000001e3f74
0.33% crowd_perf libSDL3.so.0.4.12 [.] 0x00000000001493ed
0.32% crowd_perf libwayland-client.so.0.25.0 [.] 0x0000000000005430
0.32% crowd_perf libc.so.6 [.] 0x00000000000a7554
0.29% crowd_perf libvulkan_radeon.so [.] 0x00000000001e0534
0.29% crowd_perf libwayland-client.so.0.25.0 [.] wl_proxy_marshal_flags
0.29% crowd_perf libvulkan_radeon.so [.] 0x0000000000110d3b
0.29% crowd_perf libvulkan_radeon.so [.] 0x00000000001defd2
0.29% wl_cursor_surfa libc.so.6 [.] 0x000000000018a507
0.29% crowd_perf libwayland-client.so.0.25.0 [.] 0x0000000000003147
0.29% crowd_perf libwayland-client.so.0.25.0 [.] 0x00000000000032a4
0.28% crowd_perf libvulkan_radeon.so [.] 0x000000000018d44f
0.28% crowd_perf libvulkan_radeon.so [.] 0x000000000018d866
0.28% crowd_perf libSDL3.so.0.4.12 [.] 0x00000000000168f4
0.27% wl_cursor_surfa libc.so.6 [.] ppoll
0.27% crowd_perf libvulkan_radeon.so [.] 0x00000000000d227c
0.27% crowd_perf crowd_perf [.] runtime::_append_elem
0.27% crowd_perf libwayland-client.so.0.25.0 [.] 0x0000000000003943
0.27% crowd_perf libvulkan_radeon.so [.] 0x00000000000b91fd
0.26% crowd_perf libc.so.6 [.] pthread_mutex_unlock
0.26% crowd_perf libvulkan_radeon.so [.] 0x00000000001f41d6
0.26% crowd_perf libSDL3.so.0.4.12 [.] 0x00000000002441e6
0.26% crowd_perf libc.so.6 [.] 0x00000000000a6ed7
0.26% crowd_perf libc.so.6 [.] 0x00000000000a590c
0.26% crowd_perf [unknown] [k] 0xffffffff84e00084
0.26% wl_cursor_surfa libwayland-client.so.0.25.0 [.] wl_display_read_events
0.25% crowd_perf libvulkan_radeon.so [.] 0x000000000033cb4a
0.25% crowd_perf libvulkan_radeon.so [.] 0x00000000001f2f9e
0.25% crowd_perf libc.so.6 [.] 0x0000000000180604
0.25% crowd_perf libSDL3.so.0.4.12 [.] 0x0000000000016904
0.25% crowd_perf libvulkan_radeon.so [.] 0x0000000000181449
0.25% crowd_perf libvulkan_radeon.so [.] 0x00000000000fabbd
0.25% crowd_perf libvulkan_radeon.so [.] 0x0000000000022daa
0.25% crowd_perf libvulkan_radeon.so [.] 0x00000000000b69b6
0.24% crowd_perf libvulkan_radeon.so [.] 0x00000000000ba831
0.24% wl_cursor_surfa libc.so.6 [.] pthread_mutex_lock
0.24% crowd_perf libvulkan_radeon.so [.] 0x000000000068ccac
0.24% crowd_perf libc.so.6 [.] 0x00000000000a7101
0.24% crowd_perf libvulkan_radeon.so [.] 0x00000000001152d6
0.24% crowd_perf libvulkan_radeon.so [.] 0x00000000000bdd3d
0.24% crowd_perf libc.so.6 [.] 0x000000000018a54e
0.24% crowd_perf [unknown] [k] 0xffffffff85a7a016
0.24% wl_cursor_surfa libc.so.6 [.] recvmsg
0.23% crowd_perf libvulkan_radeon.so [.] 0x000000000035f607
0.23% crowd_perf libvulkan_radeon.so [.] 0x00000000001f3ff4
0.23% crowd_perf libdrm.so.2.134.0 [.] drmSyncobjWait
0.23% crowd_perf libwayland-client.so.0.25.0 [.] 0x000000000000320b
0.22% crowd_perf libSDL3.so.0.4.12 [.] 0x000000000023434e
0.22% crowd_perf libSDL3.so.0.4.12 [.] 0x000000000024ff8e
0.22% crowd_perf libSDL3.so.0.4.12 [.] 0x00000000002504d8
0.21% wl_cursor_surfa libc.so.6 [.] 0x0000000000093fe4
0.21% crowd_perf libvulkan_radeon.so [.] 0x00000000001f4165
0.20% crowd_perf libSDL3.so.0.4.12 [.] 0x0000000000018896
0.20% crowd_perf libc.so.6 [.] 0x0000000000183444
0.19% crowd_perf libvulkan_radeon.so [.] 0x00000000000cd91c
0.19% crowd_perf libvulkan_radeon.so [.] 0x00000000000e6243
0.19% crowd_perf libvulkan_radeon.so [.] 0x00000000000cd030
0.19% crowd_perf libSDL3.so.0.4.12 [.] 0x000000000001663d
0.18% crowd_perf libvulkan_radeon.so [.] 0x0000000000115378
0.18% crowd_perf libvulkan_radeon.so [.] 0x00000000001da01c
0.18% crowd_perf libc.so.6 [.] 0x00000000000a579b
0.18% wl_cursor_surfa libwayland-client.so.0.25.0 [.] 0x0000000000004cb4
0.17% crowd_perf libvulkan_radeon.so [.] 0x00000000000ebd58
0.17% crowd_perf libc.so.6 [.] 0x0000000000180625
0.17% crowd_perf libvulkan_radeon.so [.] 0x00000000001df838
0.17% crowd_perf libvulkan_radeon.so [.] 0x00000000000cfab0
0.17% crowd_perf libc.so.6 [.] 0x00000000000a678f
0.17% crowd_perf libvulkan_radeon.so [.] 0x00000000000cf034
0.16% crowd_perf libSDL3.so.0.4.12 [.] 0x000000000024cec9
0.16% crowd_perf [unknown] [k] 0xffffffff86355a14
0.16% crowd_perf libSDL3.so.0.4.12 [.] 0x000000000023af5d
0.16% wl_cursor_surfa libc.so.6 [.] 0x0000000000094085
0.16% crowd_perf libdbus-1.so.3.38.3 [.] _dbus_atomic_inc
0.16% crowd_perf libvulkan_radeon.so [.] 0x000000000037a25e
0.16% crowd_perf libdbus-1.so.3.38.3 [.] dbus_connection_unref
0.16% crowd_perf libvulkan_radeon.so [.] 0x0000000000181484
0.16% crowd_perf libwayland-client.so.0.25.0 [.] wl_list_remove
0.16% crowd_perf libSDL3.so.0.4.12 [.] 0x000000000025445f
0.16% crowd_perf libc.so.6 [.] 0x000000000009ca14
0.16% crowd_perf libdbus-1.so.3.38.3 [.] _dbus_connection_lock
0.16% crowd_perf libvulkan_radeon.so [.] 0x0000000000217ee9
0.16% crowd_perf libSDL3.so.0.4.12 [.] 0x0000000000254472
0.16% crowd_perf libvulkan_radeon.so [.] 0x00000000001dd6f2
0.16% crowd_perf libvulkan_radeon.so [.] 0x00000000000f4ad9
0.16% crowd_perf libnvidia-glcore.so.610.43.03 [.] 0x0000000000fcd461
0.16% crowd_perf libvulkan_radeon.so [.] 0x000000000018aaf2
0.16% crowd_perf libvulkan_radeon.so [.] 0x000000000002caab
0.15% crowd_perf libvulkan_radeon.so [.] 0x00000000001e6434
0.15% crowd_perf libvulkan_radeon.so [.] 0x000000000002ca15
0.15% crowd_perf libvulkan_radeon.so [.] 0x00000000000c5ba8
0.15% crowd_perf libwayland-client.so.0.25.0 [.] 0x0000000000003263
0.15% crowd_perf libSDL3.so.0.4.12 [.] 0x000000000015f1c3
0.15% crowd_perf libwayland-client.so.0.25.0 [.] 0x00000000000032dc
0.15% crowd_perf libvulkan_radeon.so [.] 0x00000000001f3344
0.15% crowd_perf libvulkan_radeon.so [.] 0x00000000000d7063
0.15% crowd_perf libvulkan_radeon.so [.] 0x00000000000c4a41
0.15% crowd_perf libvulkan_radeon.so [.] 0x00000000000ec895
0.15% crowd_perf libvulkan_radeon.so [.] 0x0000000000335bd4
0.15% crowd_perf libvulkan_radeon.so [.] 0x00000000000ebdc5
0.15% crowd_perf libvulkan_radeon.so [.] 0x00000000001f3ff6
0.15% crowd_perf libvulkan_radeon.so [.] 0x00000000000ebe76
0.15% crowd_perf libvulkan_radeon.so [.] 0x00000000000ed816
0.15% crowd_perf libvulkan_radeon.so [.] 0x00000000001e61f1
0.15% crowd_perf libvulkan_radeon.so [.] 0x000000000002d5ef
0.15% crowd_perf libc.so.6 [.] 0x000000000018062b
0.15% crowd_perf libvulkan_radeon.so [.] 0x00000000000d13c3
0.15% crowd_perf libvulkan_radeon.so [.] 0x00000000000d8386
0.15% wl_cursor_surfa libc.so.6 [.] 0x000000000009ca5c
0.15% crowd_perf libSDL3.so.0.4.12 [.] 0x000000000015f1a4
0.15% crowd_perf libc.so.6 [.] 0x00000000000a5735
0.15% crowd_perf [unknown] [k] 0xffffffff84e00087
0.15% crowd_perf libvulkan_radeon.so [.] 0x0000000000022b88
0.15% crowd_perf libvulkan_radeon.so [.] 0x0000000000217dba
0.15% crowd_perf libSDL3.so.0.4.12 [.] 0x00000000001da04c
0.15% crowd_perf libvulkan_radeon.so [.] 0x000000000019371b
0.15% crowd_perf libc.so.6 [.] 0x0000000000189c44
0.14% crowd_perf libdbus-1.so.3.38.3 [.] 0x000000000001ab32
0.14% crowd_perf libvulkan_radeon.so [.] 0x0000000000196829
0.14% crowd_perf libSDL3.so.0.4.12 [.] 0x0000000000017690
0.14% crowd_perf libvulkan_radeon.so [.] 0x000000000018d844
0.14% crowd_perf libvulkan_radeon.so [.] 0x00000000000bddf1
0.14% crowd_perf libvulkan_radeon.so [.] 0x000000000013ca2e
0.14% crowd_perf libSDL3.so.0.4.12 [.] 0x0000000000054e60
0.14% crowd_perf libvulkan_radeon.so [.] 0x0000000000194631
0.14% crowd_perf libvulkan_radeon.so [.] 0x00000000000c9aeb
0.14% crowd_perf libvulkan_radeon.so [.] 0x000000000017dbc1
0.14% crowd_perf libvulkan_radeon.so [.] 0x0000000000197523
0.14% crowd_perf libvulkan_radeon.so [.] 0x00000000001cf344
0.14% crowd_perf libdbus-1.so.3.38.3 [.] 0x000000000001aa6d
0.14% crowd_perf libSDL3.so.0.4.12 [.] 0x000000000024ce11
0.14% crowd_perf libSDL3.so.0.4.12 [.] 0x0000000000055379
0.14% crowd_perf libSDL3.so.0.4.12 [.] 0x000000000024bb5e
0.14% crowd_perf libdbus-1.so.3.38.3 [.] 0x0000000000031883
0.14% crowd_perf libvulkan_radeon.so [.] 0x00000000001d6418
0.14% crowd_perf libc.so.6 [.] 0x000000000018a57d
0.14% crowd_perf libc.so.6 [.] 0x0000000000189c93
0.14% crowd_perf libc.so.6 [.] 0x000000000009ca4f
0.14% crowd_perf libSDL3.so.0.4.12 [.] 0x00000000000168f0
0.14% crowd_perf libvulkan_radeon.so [.] 0x0000000000028474
0.14% crowd_perf libc.so.6 [.] 0x00000000000a7477
0.14% crowd_perf libvulkan_radeon.so [.] 0x0000000000022a86
0.14% crowd_perf libvulkan_radeon.so [.] 0x000000000018d4ac
0.14% crowd_perf libvulkan_radeon.so [.] 0x000000000035f6c7
0.14% crowd_perf libc.so.6 [.] 0x00000000000a66c4
0.14% crowd_perf libvulkan_radeon.so [.] 0x00000000002310fb
0.14% crowd_perf libSDL3.so.0.4.12 [.] 0x00000000000176c6
0.14% crowd_perf libc.so.6 [.] 0x000000000009ca19
0.14% crowd_perf libSDL3.so.0.4.12 [.] 0x000000000023b2d1
0.14% crowd_perf libvulkan_radeon.so [.] 0x000000000002d8b8
0.14% crowd_perf libvulkan_radeon.so [.] 0x00000000001d9f47
0.14% crowd_perf libvulkan_radeon.so [.] 0x00000000000bbf60
0.14% crowd_perf libvulkan_radeon.so [.] 0x00000000000cea95
0.14% crowd_perf libvulkan_radeon.so [.] 0x0000000000115ac7
0.14% crowd_perf libvulkan_radeon.so [.] 0x0000000000115b65
0.14% crowd_perf libSDL3.so.0.4.12 [.] 0x00000000002470cf
0.14% crowd_perf libSDL3.so.0.4.12 [.] 0x000000000024d18e
0.14% crowd_perf libc.so.6 [.] 0x000000000009ffc0
0.14% crowd_perf libvulkan_radeon.so [.] 0x00000000000cf4c5
0.14% crowd_perf libSDL3.so.0.4.12 [.] 0x0000000000244261
0.14% crowd_perf libvulkan_radeon.so [.] 0x000000000002d886
0.14% crowd_perf libvulkan_radeon.so [.] 0x00000000001896c4
0.14% wl_cursor_surfa libwayland-client.so.0.25.0 [.] 0x00000000000049dc
0.14% crowd_perf libvulkan_radeon.so [.] 0x00000000000c0ac8
0.14% crowd_perf libvulkan_radeon.so [.] 0x000000000002ca2a
0.14% crowd_perf libvulkan_radeon.so [.] 0x00000000000d3493
0.14% crowd_perf libvulkan_radeon.so [.] 0x000000000001e62d
0.14% crowd_perf libvulkan_radeon.so [.] 0x0000000000116118
0.14% crowd_perf libSDL3.so.0.4.12 [.] 0x0000000000053d7e
0.14% crowd_perf libvulkan_radeon.so [.] 0x00000000000c877c
0.14% crowd_perf libc.so.6 [.] 0x000000000018a4f3
0.14% crowd_perf libvulkan_radeon.so [.] 0x000000000022d354
0.14% crowd_perf libvulkan_radeon.so [.] 0x0000000000022d55
0.14% crowd_perf libvulkan_radeon.so [.] 0x00000000001e5ebd
0.14% crowd_perf libwayland-client.so.0.25.0 [.] 0x0000000000004c80
0.14% crowd_perf libvulkan_radeon.so [.] 0x00000000001f41a4
0.14% crowd_perf libwayland-client.so.0.25.0 [.] 0x0000000000003140
0.14% crowd_perf libvulkan_radeon.so [.] 0x00000000001e60b2
0.14% crowd_perf libc.so.6 [.] 0x000000000009ca5a
0.14% crowd_perf libSDL3.so.0.4.12 [.] 0x000000000023c133
0.13% crowd_perf libSDL3.so.0.4.12 [.] 0x000000000024d1c6
0.13% crowd_perf libvulkan_radeon.so [.] 0x000000000033ca1e
0.13% crowd_perf libvulkan_radeon.so [.] 0x00000000000be09c
0.13% crowd_perf libc.so.6 [.] 0x0000000000189cc4
0.13% crowd_perf libSDL3.so.0.4.12 [.] 0x00000000000185a0
0.13% crowd_perf libvulkan_radeon.so [.] 0x00000000000cc0cb
0.13% crowd_perf libvulkan_radeon.so [.] 0x00000000000b74ff
0.13% crowd_perf libdbus-1.so.3.38.3 [.] _dbus_rmutex_lock
0.13% crowd_perf libvulkan_radeon.so [.] 0x00000000000bc373
0.13% crowd_perf libwayland-client.so.0.25.0 [.] 0x0000000000003193
0.13% crowd_perf libvulkan_radeon.so [.] 0x00000000000d148b
0.13% crowd_perf libc.so.6 [.] 0x0000000000189d47
0.13% crowd_perf libSDL3.so.0.4.12 [.] 0x000000000023c3e7
0.13% crowd_perf libSDL3.so.0.4.12 [.] 0x000000000024b818
0.13% crowd_perf libvulkan_radeon.so [.] 0x0000000000217eac
0.13% crowd_perf libvulkan_radeon.so [.] 0x0000000000027f8e
0.13% crowd_perf libvulkan_radeon.so [.] 0x0000000000022aa5
0.13% crowd_perf libvulkan_radeon.so [.] 0x00000000000c9d9f
0.13% crowd_perf libvulkan_radeon.so [.] 0x000000000002f38d
0.13% crowd_perf libSDL3.so.0.4.12 [.] 0x000000000024cf70
0.13% crowd_perf [unknown] [k] 0xffffffff855e8f44
0.13% crowd_perf libwayland-client.so.0.25.0 [.] 0x00000000000032b2
0.13% crowd_perf libc.so.6 [.] 0x000000000009ca31
0.13% crowd_perf libSDL3.so.0.4.12 [.] 0x000000000005536a
0.13% crowd_perf libvulkan_radeon.so [.] 0x000000000013c684
0.13% crowd_perf libSDL3.so.0.4.12 [.] 0x000000000024fc98
0.13% crowd_perf libvulkan_radeon.so [.] 0x00000000000ed0ff
0.13% crowd_perf libvulkan_radeon.so [.] 0x00000000000c6ce6
0.13% crowd_perf libdbus-1.so.3.38.3 [.] 0x000000000003187f
0.13% crowd_perf libvulkan_radeon.so [.] 0x00000000001cfb65
0.13% crowd_perf libc.so.6 [.] 0x0000000000180614
0.13% crowd_perf libdbus-1.so.3.38.3 [.] _dbus_list_pop_first_link
0.13% crowd_perf libwayland-client.so.0.25.0 [.] 0x0000000000005485
0.13% crowd_perf libc.so.6 [.] __libc_calloc
0.13% crowd_perf libwayland-client.so.0.25.0 [.] 0x000000000000320e
0.13% crowd_perf libvulkan_radeon.so [.] 0x00000000001db541
0.13% crowd_perf libc.so.6 [.] 0x000000000009408f
0.13% crowd_perf libvulkan_radeon.so [.] 0x00000000001f2f92
0.13% crowd_perf libvulkan_radeon.so [.] 0x00000000000c5bde
0.13% crowd_perf libvulkan_radeon.so [.] 0x00000000000d16a6
0.13% crowd_perf libvulkan_radeon.so [.] 0x00000000001398b4
0.13% crowd_perf libSDL3.so.0.4.12 [.] 0x000000000024f60d
0.13% crowd_perf libvulkan_radeon.so [.] 0x000000000018d5e9
0.13% crowd_perf libvulkan_radeon.so [.] 0x00000000000d793a
0.13% crowd_perf libc.so.6 [.] 0x000000000018a4c4
0.13% crowd_perf libvulkan_radeon.so [.] 0x00000000001cf563
0.13% crowd_perf libvulkan_radeon.so [.] 0x00000000000ccf20
0.13% crowd_perf libvulkan_radeon.so [.] 0x00000000002310dc
0.13% crowd_perf libvulkan_radeon.so [.] 0x000000000002d7a3
0.13% crowd_perf libc.so.6 [.] __close
0.13% crowd_perf libvulkan_radeon.so [.] 0x000000000035f634
0.13% crowd_perf libvulkan_radeon.so [.] 0x00000000000ed45b
0.13% crowd_perf libvulkan_radeon.so [.] 0x00000000000d2d0b
0.13% crowd_perf libSDL3.so.0.4.12 [.] 0x00000000000f7a33
0.13% crowd_perf libc.so.6 [.] 0x00000000000a7491
0.13% crowd_perf libvulkan_radeon.so [.] 0x0000000000230ea5
0.13% crowd_perf libc.so.6 [.] 0x00000000000a57a6
0.13% crowd_perf libvulkan_radeon.so [.] 0x0000000000110d5e
0.12% crowd_perf libvulkan_radeon.so [.] 0x000000000068d087
0.12% crowd_perf libdbus-1.so.3.38.3 [.] 0x0000000000031820
0.12% crowd_perf libc.so.6 [.] 0x000000000009ca17
0.12% crowd_perf libSDL3.so.0.4.12 [.] 0x000000000024d030
0.12% wl_cursor_surfa libc.so.6 [.] pthread_mutex_unlock
0.12% crowd_perf libSDL3.so.0.4.12 [.] 0x000000000024e291
0.12% crowd_perf libvulkan_radeon.so [.] 0x00000000000d2ac1
0.12% crowd_perf libvulkan_radeon.so [.] 0x000000000018c879
0.12% crowd_perf libvulkan_radeon.so [.] 0x0000000000022b1c
0.12% crowd_perf libvulkan_radeon.so [.] 0x00000000001f2c85
0.12% crowd_perf libvulkan_radeon.so [.] 0x00000000001e34fc
0.12% crowd_perf libc.so.6 [.] ppoll
0.12% crowd_perf libvulkan_radeon.so [.] 0x00000000000bcb9e
0.12% crowd_perf libvulkan_radeon.so [.] 0x000000000002334f
0.12% crowd_perf libvulkan_radeon.so [.] 0x0000000000022950
0.12% crowd_perf libvulkan_radeon.so [.] 0x00000000000d649e
0.12% crowd_perf libvulkan_radeon.so [.] 0x00000000000cfa60
0.12% crowd_perf libwayland-client.so.0.25.0 [.] 0x0000000000003912
0.12% crowd_perf libvulkan_radeon.so [.] 0x00000000001d1145
0.12% crowd_perf libdbus-1.so.3.38.3 [.] 0x00000000000318bf
0.12% crowd_perf libwayland-client.so.0.25.0 [.] 0x00000000000049dc
0.12% wl_cursor_surfa libwayland-client.so.0.25.0 [.] 0x0000000000003689
0.12% crowd_perf libc.so.6 [.] 0x00000000000a6621
0.12% crowd_perf libvulkan_radeon.so [.] 0x000000000002d844
0.12% crowd_perf [unknown] [k] 0xffffffff86355a41
0.12% crowd_perf libvulkan_radeon.so [.] 0x000000000002bc13
0.12% crowd_perf libvulkan_radeon.so [.] 0x000000000033cb5b
0.12% crowd_perf libvulkan_radeon.so [.] 0x000000000002ce05
0.12% crowd_perf libvulkan_radeon.so [.] 0x000000000014f29b
0.12% crowd_perf libSDL3.so.0.4.12 [.] 0x000000000025478f
0.12% crowd_perf libvulkan_radeon.so [.] 0x000000000018d462
0.12% crowd_perf libvulkan_radeon.so [.] 0x00000000001e6d9f
0.12% crowd_perf libc.so.6 [.] 0x00000000000a6610
0.12% crowd_perf [unknown] [k] 0xffffffff850a84c5
0.12% crowd_perf libc.so.6 [.] 0x0000000000180653
0.12% crowd_perf libvulkan_radeon.so [.] 0x000000000033ca37
0.12% crowd_perf libSDL3.so.0.4.12 [.] 0x0000000000249e81
0.12% crowd_perf libvulkan_radeon.so [.] 0x00000000001dcabc
0.12% crowd_perf libvulkan_radeon.so [.] 0x0000000000110ce8
0.12% crowd_perf libwayland-client.so.0.25.0 [.] 0x000000000000328a
0.12% crowd_perf libSDL3.so.0.4.12 [.] 0x000000000024cef0
0.12% crowd_perf libvulkan_radeon.so [.] 0x00000000000cd943
0.12% crowd_perf libvulkan_radeon.so [.] 0x00000000000c2584
0.12% crowd_perf libvulkan_radeon.so [.] 0x00000000000cd7c1
0.12% crowd_perf libvulkan_radeon.so [.] 0x0000000000022f3e
0.12% crowd_perf libvulkan_radeon.so [.] 0x000000000018d635
0.12% crowd_perf libc.so.6 [.] 0x000000000009ca74
0.12% crowd_perf libvulkan_radeon.so [.] 0x00000000000cea42
0.12% crowd_perf libSDL3.so.0.4.12 [.] 0x000000000023b143
0.12% wl_cursor_surfa libc.so.6 [.] 0x000000000018a4f3
0.12% crowd_perf libvulkan_radeon.so [.] 0x00000000000cd71c
0.12% crowd_perf libvulkan_radeon.so [.] 0x00000000000d1865
0.12% crowd_perf libc.so.6 [.] 0x000000000018a486
0.12% crowd_perf libvulkan_radeon.so [.] 0x00000000001e519a
0.12% crowd_perf libc.so.6 [.] 0x00000000000a66e2
0.12% crowd_perf libvulkan_radeon.so [.] 0x000000000019678f
0.12% crowd_perf libvulkan_radeon.so [.] 0x00000000001e5134
0.12% crowd_perf libSDL3.so.0.4.12 [.] 0x00000000002463df
0.12% crowd_perf libSDL3.so.0.4.12 [.] 0x0000000000054e93
0.12% crowd_perf libvulkan_radeon.so [.] 0x000000000068cf84
0.12% crowd_perf libvulkan_radeon.so [.] 0x00000000000b6d7d
0.12% crowd_perf ld-linux-x86-64.so.2 [.] 0x000000000000af32
0.12% crowd_perf libvulkan_radeon.so [.] 0x00000000000ed081
0.12% crowd_perf libvulkan_radeon.so [.] 0x0000000000218046
0.12% crowd_perf libSDL3.so.0.4.12 [.] 0x00000000000541ae
0.12% crowd_perf libdbus-1.so.3.38.3 [.] _dbus_message_loader_queue_messages
0.12% crowd_perf libwayland-client.so.0.25.0 [.] 0x000000000000546e
0.12% crowd_perf libwayland-client.so.0.25.0 [.] 0x0000000000003233
0.11% crowd_perf libvulkan_radeon.so [.] 0x0000000000180ada
0.11% crowd_perf libvulkan_radeon.so [.] 0x0000000000028174
0.11% crowd_perf libSDL3.so.0.4.12 [.] 0x00000000000657d0
0.11% crowd_perf libvulkan_radeon.so [.] 0x00000000000ce7ac
0.11% crowd_perf libSDL3.so.0.4.12 [.] 0x0000000000250239
0.11% crowd_perf libvulkan_radeon.so [.] 0x000000000068d014
0.11% crowd_perf libSDL3.so.0.4.12 [.] 0x000000000023ba94
0.11% crowd_perf libvulkan_radeon.so [.] 0x000000000013cae3
0.11% crowd_perf libvulkan_radeon.so [.] 0x00000000000cd796
0.11% crowd_perf libSDL3.so.0.4.12 [.] 0x000000000024d1b9
0.11% crowd_perf libc.so.6 [.] 0x000000000018a507
0.11% crowd_perf libvulkan_radeon.so [.] 0x00000000001f3465
0.11% crowd_perf libvulkan_radeon.so [.] 0x000000000018d452
0.11% crowd_perf libvulkan_radeon.so [.] 0x00000000001e6363
0.11% crowd_perf libvulkan_radeon.so [.] 0x000000000021b281
0.11% crowd_perf libc.so.6 [.] 0x00000000000a5904
0.11% crowd_perf libvulkan_radeon.so [.] 0x00000000001f401a
0.11% crowd_perf libSDL3.so.0.4.12 [.] 0x00000000001c8c05
0.11% crowd_perf libvulkan_radeon.so [.] 0x00000000000d2d97
0.11% crowd_perf libvulkan_radeon.so [.] 0x0000000000379fe4
0.11% crowd_perf libvulkan_radeon.so [.] 0x00000000001529e1
0.11% wl_cursor_surfa libc.so.6 [.] 0x00000000000a6732
0.11% wl_cursor_surfa libwayland-client.so.0.25.0 [.] wl_display_prepare_read_queue
0.11% crowd_perf libSDL3.so.0.4.12 [.] 0x000000000024cddc
0.11% crowd_perf libvulkan_radeon.so [.] 0x000000000010da99
0.11% wl_cursor_surfa libwayland-client.so.0.25.0 [.] 0x0000000000004961
0.11% crowd_perf libvulkan_radeon.so [.] 0x00000000001d62b5
0.11% crowd_perf libvulkan_radeon.so [.] 0x000000000018d874
0.11% wl_cursor_surfa libc.so.6 [.] 0x00000000000a66e2
0.11% crowd_perf libvulkan_radeon.so [.] 0x0000000000182733
0.11% crowd_perf libvulkan_radeon.so [.] 0x0000000000023598
0.11% crowd_perf libSDL3.so.0.4.12 [.] 0x0000000000054f23
0.11% crowd_perf libSDL3.so.0.4.12 [.] 0x00000000000176cf
0.11% crowd_perf libSDL3.so.0.4.12 [.] 0x000000000024e2b6
0.11% crowd_perf libvulkan_radeon.so [.] 0x00000000001f44c0
0.11% crowd_perf libc.so.6 [.] 0x00000000000a6403
0.11% crowd_perf libvulkan_radeon.so [.] 0x00000000001d11b3
0.11% crowd_perf libvulkan_radeon.so [.] 0x00000000000d3c36
0.11% crowd_perf libvulkan_radeon.so [.] 0x000000000033df64
0.11% crowd_perf libvulkan_radeon.so [.] 0x00000000000d3a9c
0.11% crowd_perf libc.so.6 [.] 0x00000000000a6603
0.11% crowd_perf libvulkan_radeon.so [.] 0x00000000000283b6
0.11% crowd_perf libc.so.6 [.] 0x00000000000a456a
0.11% crowd_perf libc.so.6 [.] 0x0000000000189d0b
0.10% crowd_perf libvulkan_radeon.so [.] 0x00000000000c5581
0.10% crowd_perf libc.so.6 [.] 0x00000000000a5851
0.10% crowd_perf libvulkan_radeon.so [.] 0x00000000000ce761
0.10% crowd_perf libSDL3.so.0.4.12 [.] 0x000000000023bdb8
0.10% crowd_perf [unknown] [k] 0xffffffff86355a45
0.10% crowd_perf libSDL3.so.0.4.12 [.] 0x000000000023b914
0.10% crowd_perf libvulkan_radeon.so [.] 0x000000000022d239
0.10% crowd_perf libc.so.6 [.] 0x0000000000064888
0.10% crowd_perf libvulkan_radeon.so [.] 0x00000000000bdd81
0.10% crowd_perf libvulkan_radeon.so [.] 0x0000000000231160
0.10% crowd_perf libc.so.6 [.] 0x000000000018a4c0
0.10% crowd_perf libc.so.6 [.] 0x000000000018a56f
0.10% crowd_perf libvulkan_radeon.so [.] 0x000000000022d386
0.10% crowd_perf libvulkan_radeon.so [.] 0x00000000000280a5
0.10% crowd_perf libvulkan_radeon.so [.] 0x000000000002cd72
0.10% crowd_perf libSDL3.so.0.4.12 [.] 0x0000000000069865
0.09% crowd_perf libvulkan_radeon.so [.] 0x000000000018a489
0.09% crowd_perf libvulkan_radeon.so [.] 0x000000000033b807
0.09% crowd_perf libvulkan_radeon.so [.] 0x000000000035f6d4
0.09% crowd_perf libvulkan_radeon.so [.] 0x00000000000fa782
0.08% crowd_perf libvulkan_radeon.so [.] 0x00000000000bdfc3
0.03% crowd_perf ld-linux-x86-64.so.2 [.] 0x000000000000fea2
0.01% crowd_perf libvulkan_radeon.so [.] 0x00000000001d12c7
0.00% wl_cursor_surfa libc.so.6 [.] 0x00000000000a447d
0.00% wl_cursor_surfa libwayland-client.so.0.25.0 [.] 0x0000000000004951
0.00% crowd_perf libc.so.6 [.] 0x00000000000a5701
0.00% wl_cursor_surfa libwayland-client.so.0.25.0 [.] wl_display_dispatch_queue_pending
0.00% wl_cursor_surfa libwayland-client.so.0.25.0 [.] 0x0000000000003193
0.00% crowd_perf libvulkan_radeon.so [.] 0x00000000001dd35f
0.00% crowd_perf libc.so.6 [.] 0x0000000000040242
0.00% wl_cursor_surfa libc.so.6 [.] 0x00000000000a7491
0.00% crowd_perf libc.so.6 [.] 0x00000000000a6ea4
0.00% crowd_perf libvulkan_radeon.so [.] 0x0000000000027f18
0.00% crowd_perf [unknown] [k] 0xffffffff8632ecd9
0.00% crowd_perf ld-linux-x86-64.so.2 [.] 0x000000000000aed9
0.00% crowd_perf libc.so.6 [.] getenv
0.00% crowd_perf libGLX_nvidia.so.610.43.03 [.] 0x000000000009e60a
0.00% crowd_perf libc.so.6 [.] 0x0000000000094006
0.00% crowd_perf libvulkan_radeon.so [.] 0x00000000001895fc
0.00% crowd_perf libc.so.6 [.] __libc_secure_getenv
0.00% wl_cursor_surfa libc.so.6 [.] 0x00000000000a6ea4
0.00% crowd_perf ld-linux-x86-64.so.2 [.] 0x00000000000147ed
0.00% crowd_perf [unknown] [k] 0xffffffff850a7e70
0.00% crowd_perf libc.so.6 [.] __ctype_init
0.00% crowd_perf libc.so.6 [.] 0x0000000000064845
0.00% crowd_perf libc.so.6 [.] 0x000000000009741b
0.00% crowd_perf libvulkan_radeon.so [.] 0x0000000000345adb
0.00% wl_cursor_surfa libSDL3.so.0.4.12 [.] 0x00000000001cd7b4
0.00% crowd_perf libvulkan_radeon.so [.] 0x0000000000345cfe
0.00% wl_cursor_surfa libSDL3.so.0.4.12 [.] 0x00000000001e3f76
0.00% crowd_perf libvulkan_radeon.so [.] 0x000000000028ed0d
0.00% crowd_perf libvulkan_radeon.so [.] 0x0000000000345b18
0.00% crowd_perf libvulkan_radeon.so [.] 0x0000000000345ad6
0.00% crowd_perf libLLVM.so.22.1 [.] std::enable_if<llvm::hashing::detail::is_hashable_data<char const>::value, llvm::hash_code>::type llvm::hashing::detail::hash_combine_range_impl<char const>(char const*, char const*)
0.00% crowd_perf libc.so.6 [.] 0x0000000000097417
0.00% crowd_perf libc.so.6 [.] 0x00000000000a5770
0.00% wl_cursor_surfa libSDL3.so.0.4.12 [.] 0x00000000001cd7b9
0.00% crowd_perf libc.so.6 [.] 0x0000000000103a63
0.00% crowd_perf libnvidia-glcore.so.610.43.03 [.] 0x0000000000fcd46c
0.00% crowd_perf libvulkan_radeon.so [.] 0x000000000018d572
0.00% crowd_perf libdrm.so.2.134.0 [.] drmSyncobjExportSyncFile
0.00% crowd_perf ld-linux-x86-64.so.2 [.] 0x000000000000deb7
0.00% crowd_perf libnvidia-glsi.so.610.43.03 [.] 0x00000000000460e4
0.00% crowd_perf libvulkan_radeon.so [.] 0x000000000018d7de
0.00% crowd_perf libdrm.so.2.134.0 [.] drmSyncobjTransfer
0.00% crowd_perf libdrm_amdgpu.so.1.134.0 [.] amdgpu_query_info
0.00% crowd_perf ld-linux-x86-64.so.2 [.] 0x000000000001fce9
0.00% wl_cursor_surfa libSDL3.so.0.4.12 [.] 0x00000000001e3f78
0.00% crowd_perf libvulkan_radeon.so [.] 0x0000000000344ddb
0.00% crowd_perf libvulkan_radeon.so [.] 0x0000000000344cd4
0.00% crowd_perf libvulkan_radeon.so [.] 0x0000000000344ccb
0.00% crowd_perf libvulkan_radeon.so [.] 0x0000000000344ddd
0.00% crowd_perf libvulkan_radeon.so [.] 0x0000000000345bb3
0.00% crowd_perf [unknown] [k] 0xffffffff84e01280
0.00% wl_cursor_surfa libc.so.6 [.] 0x0000000000094040
0.00% crowd_perf libc.so.6 [.] 0x000000000011bed0
0.00% crowd_perf libc.so.6 [.] 0x00000000000973a0
0.00% wl_cursor_surfa libc.so.6 [.] 0x0000000000094084
0.00% crowd_perf libc.so.6 [.] 0x0000000000103a40
0.00% crowd_perf libvulkan_radeon.so [.] 0x000000000028ece4
0.00% crowd_perf libvulkan_radeon.so [.] 0x000000000028ed4d
0.00% crowd_perf ld-linux-x86-64.so.2 [.] 0x000000000000dedf
0.00% crowd_perf ld-linux-x86-64.so.2 [.] 0x000000000000f60f
0.00% crowd_perf ld-linux-x86-64.so.2 [.] 0x000000000000f611
0.00% crowd_perf ld-linux-x86-64.so.2 [.] 0x000000000001f103
0.00% crowd_perf libLLVM.so.22.1 [.] 0x000000000083a104
0.00% crowd_perf libLLVM.so.22.1 [.] 0x000000000083a146
0.00% crowd_perf libc.so.6 [.] wait4
0.00% crowd_perf libc.so.6 [.] 0x0000000000094040
0.00% crowd_perf libc.so.6 [.] 0x0000000000094047
0.00% crowd_perf libc.so.6 [.] 0x00000000000a58a9
0.00% crowd_perf libdrm.so.2.134.0 [.] drmCommandWrite
0.00% crowd_perf libdrm.so.2.134.0 [.] drmSyncobjTimelineWait
0.00% crowd_perf libnvidia-glcore.so.610.43.03 [.] 0x0000000000fcd46a
0.00% crowd_perf libvulkan_radeon.so [.] 0x000000000017fa4b
0.00% crowd_perf libvulkan_radeon.so [.] 0x000000000017fae8
0.00% crowd_perf [unknown] [k] 0xffffffff84e01670
0.00% wl_cursor_surfa libc.so.6 [.] 0x0000000000094050
0.00% wl_cursor_surfa libc.so.6 [.] 0x000000000009408f
0.00% wl_cursor_surfa [unknown] [k] 0xffffffff84e01630
#
# (Tip: For hierarchical output, try: perf report --hierarchy)
#
Binary file not shown.

After

Width:  |  Height:  |  Size: 144 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 92 KiB

BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+1
Submodule tools/FlameGraph added at 41fee1f99f