8000 metal: pass draw's offsets as 64-bit integers by benface · Pull Request #673 · not-fl3/miniquad · GitHub
[go: up one dir, main page]

Skip to content

metal: pass draw's offsets as 64-bit integers - #673

Open
benface wants to merge 1 commit into
not-fl3:masterfrom
benface:metal-draw-argument-types
Open

benface wants to merge 1 commit into
not-fl3:masterfrom
benface:metal-draw-argument-types

Conversation

@benface
@benface benface commented Oct 9, 2026
Copy link
Copy Markdown
Contributor

Why

draw passes indexBufferOffset, baseVertex and baseInstance to drawIndexedPrimitives: as untyped 0 literals, so Rust sends them as 32-bit integers. Metal takes NSUInteger and NSInteger, which are 64-bit. On arm64 the last two go on the stack, which Apple's ABI packs by each argument's own size, so Metal reads baseVertex from both of them and baseInstance from whatever comes next.

With Metal's validation layer on, a debug build of the triangle example fails on its first draw:

MTL_DEBUG_LAYER=1 cargo run --example triangle -- metal
-[MTLDebugRenderCommandEncoder validateCommonDrawErrors:instanceCount:baseInstance:maxVertexID:]: failed assertion `Draw Errors Validation
instance_id type is not big enough to draw this many instances (8426666660)

A release build can pass, depending on what happens to be on the stack.

Change

The three literals are typed: 0u64, 0i64 and 0u64.

Verification

  • On macOS (Apple silicon), the same debug build of triangle now draws with validation on and raises no error.
  • cargo check passes for aarch64-apple-darwin, aarch64-apple-ios and aarch64-apple-tvos.

🤖 Generated with Claude Code

@benface
benface commented Oct 9, 2026
Copy link
Copy Markdown
Contributor Author

The Android check failed before it checked out the code: Docker Hub refused to pull the notfl3/cargo-apk image ("toomanyrequests: You have reached your unauthenticated pull rate limit"). It's unrelated to this change, and a re-run of the job should pass.

`draw` passed `indexBufferOffset`, `baseVertex` and `baseInstance` as
untyped literals, so Rust sent them as 32-bit integers, where Metal
takes `NSUInteger` and `NSInteger`. On arm64 the last two go on the
stack, which Apple's ABI packs by each argument's own size, so Metal
read `baseVertex` from both and `baseInstance` from whatever came
next. With `MTL_DEBUG_LAYER=1`, a debug build of the `triangle`
example failed validation on its first draw:

    instance_id type is not big enough to draw this many instances
    (8657156772)

Verified on macOS with `MTL_DEBUG_LAYER=1`: the same build of the
example now draws without a validation error.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@benface
benface force-pushed the metal-draw-argument-types branch from 2e02ac6 to 7e982d0 Compare October 18, 2026 17:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

0