Skip to content

fix: track native texture copy usage - #312

Merged
kolkov merged 5 commits into
gogpu:mainfrom
besmpl:agent/track-texture-copy-usage
Aug 23, 2026
Merged

fix: track native texture copy usage#312
kolkov merged 5 commits into
gogpu:mainfrom
besmpl:agent/track-texture-copy-usage

Conversation

@besmpl

@besmpl besmpl commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Summary

  • record CopySrc/CopyDst texture usage for all three native texture-copy APIs
  • preflight multi-resource usage changes atomically before mutating command scopes
  • retain buffer endpoints until submitted GPU work retires
  • preserve explicit-transition replacement semantics
  • add scope, conflict, released-resource, lifetime, barrier, and guard-path regressions

Why

The native encoder tracked buffer usage for texture↔buffer copies but never recorded texture usage. Texture↔texture copies recorded neither endpoint. Submit-time tracking therefore could not generate transitions from an already tracked Resource or ColorTarget state to the transfer layouts required by Vulkan/DX12.

Copy commands now validate every endpoint first and commit their scopes only when the complete operation is valid. Failed operations leave scopes, resource refs, submit-validation sets, and the HAL command stream untouched. Source/destination buffers are retained through queue retirement.

Verification

  • archived baseline fails all three copy-scope cases, released-resource cases, lifetime cases, and seven atomic-conflict cases
  • tracked Resource/ColorTarget → CopySrc/CopyDst transitions are generated
  • explicit transitions remain compatible with following copies
  • conflicting same-texture copy roles are rejected without partial state
  • buffer refcounts remain live through submission and drop at completion
  • copy-usage guard, compatibility, conflict, and explicit-transition branches are exercised
  • Codecov patch coverage: 100%; all modified and coverable lines covered
  • go test ./...
  • go test -race . ./core ./core/track
  • go build ./...
  • go vet . ./core ./core/track
  • Rust-tag, WASM, Linux, and Windows builds
  • golangci-lint v2.7.2 changed lines: 0 issues
  • gofmt and git diff --check

Known prerequisite dependencies

This PR intentionally fixes command-scope recording, not the complete queue transition engine. It remains draft because correct emitted transitions require coordinated state-model and submission-order work:

  1. First-use and lifecycle state. Newly created textures are not registered as Uninitialized. Registration cannot stand alone: tracker state must be removed exactly once before tracker-index reuse, swapchain acquire/present must account for each physical image, and pending WriteTexture/explicit-transition paths must keep the tracker synchronized.
  2. Command-buffer ordering and atomicity. Submission currently gathers transitions into one preamble before all command buffers. Correct ordering needs scopes interleaved with pending-write buffers and each HAL command-buffer segment (one public command buffer may own several HAL buffers), plus transactional tracker commit/rollback so an encoder or submit failure cannot advance CPU state without the corresponding GPU transition.

Until those dependencies are solved, this PR's claims are limited to correct atomic copy-scope and resource-lifetime recording.

Review follow-up (2026-08-12)

  • CopyBufferToBuffer now validates both endpoint usages atomically before mutating scope state, retaining refs, or recording HAL commands.
  • Added success and conflict regressions for both buffer endpoints.
  • Documented the unconditional/preflight-only contract of ReplaceUsage and added the matching wgpu-core command/transfer.rs references.

The PR intentionally remains draft for the broader queue-transition prerequisites already listed above.

@codecov

codecov Bot commented Aug 10, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@kolkov kolkov left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent work — this fills a gap our own validation agents identified (copy commands not recording texture usage). The atomic preflight pattern (prepare → validate all → commit) is clean and well-tested.

Code quality: enterprise level. 1,102 LOC tests, 100% patch coverage, 7 atomic-conflict scenarios, full lifecycle test through Submit. Consistent with our ADR-060 patterns.

ADR-060 compatibility: changes to core/track/texture.go and core/track/buffer.go are purely additive (ReplaceUsage). encoder_native.go restructures copy commands — consistent with our tracker direction.

Prerequisites (from your description): confirmed real but pre-existing, not introduced by this PR. The scope recording is independently correct.

Three items to address:

  1. CopyBufferToBuffer consistency. The PR changes recordBufferUsage return type to bool but CopyBufferToBuffer (lines 181-182) still ignores the return value and proceeds to the HAL call on conflict. The other three copy commands use the new atomic pattern. Either update CopyBufferToBuffer to match, or note the exclusion in the PR description.

  2. Rust reference comments. RecordTextureUsage and ReplaceTextureUsage in core/command.go should reference wgpu-core command/transfer.rs for consistency with RecordBufferUsage.

  3. ReplaceUsage doc comment. A note that it is intended for use after preflight validation only (unconditional write, no conflict check) would clarify the contract.

None of these are architectural — happy to approve once item 1 is addressed.

@besmpl
besmpl force-pushed the agent/track-texture-copy-usage branch from c78a110 to 2228fe8 Compare August 12, 2026 06:57
@besmpl
besmpl force-pushed the agent/track-texture-copy-usage branch from 8864a06 to 92f8974 Compare August 12, 2026 07:08

@kolkov kolkov left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All three items from the previous review are addressed:

  1. CopyBufferToBuffer atomic preflight — now uses recordCopyBufferUsages with prepare → validate → commit pattern, consistent with the other 3 copy commands. Failed copies no longer clone ResourceRefs.

  2. Rust reference comments — added on RecordTextureUsage and ReplaceTextureUsage.

  3. ReplaceUsage doc comment — added on both BufferUsageScope.ReplaceUsage and TextureUsageScope.ReplaceUsage, clarifying post-preflight intent.

Test quality is excellent — 5 test files covering atomicity invariants (7 sub-tests for all copy command combinations), resource lifecycle through encoding/submit/retirement, guard branches, and edge cases.

LGTM.

@kolkov

kolkov commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Hey @besmpl — all review items addressed, CI green. Please double-check everything on your side and mark "Ready for review" when you're confident. We'll merge with --squash.

@kolkov
kolkov marked this pull request as ready for review August 23, 2026 09:00
@kolkov
kolkov merged commit ac9035a into gogpu:main Aug 23, 2026
15 checks passed
@kolkov

kolkov commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

Merged — thank you for the excellent work on this. The atomic preflight pattern across all 4 copy commands is exactly what we needed, and the test coverage (atomicity invariants, refcount lifecycle, guard branches) is enterprise quality.

Apologies for not waiting for you to remove draft — this has been important for our tracker pipeline and we wanted to get it into the next release. All review items were addressed and CI was green, so we went ahead with the squash merge.

Also appreciated the extra fixes bundled in: CopyBufferToBuffer now properly reports an error on released buffers (was silently returning), and CopyBufferToTexture caches halSrc with a nil check (was calling halBuffer() unchecked at the call site).

@kolkov kolkov mentioned this pull request Aug 23, 2026
kolkov added a commit that referenced this pull request Aug 23, 2026
* chore: prepare release v0.31.6

- CHANGELOG: add v0.31.6 entry (PR #312 copy usage tracking, docs updates)
- AGENTS.md: update version v0.30.22 → v0.31.6 and all dep versions
- README.md: goffi v0.6.1 → v0.6.3
- ARCHITECTURE.md: update all dep versions to current
- .gitignore: add .backup-investigation/

* fix: exclude nolintlint for browser convert files (CI lint blind spot)

CI lint runs on ubuntu (GOOS=linux) — browser files with //go:build js,wasm
are invisible. nolintlint flags //nolint:goconst as unused because goconst
never runs on these files in CI. Same root cause as Metal lint blind spot
(v0.31.3). Widened exclusion to cover all convert_*.go browser files.

* fix: complete cross-platform lint exclusions (browser + rust backends)

Extend golangci-lint exclusions for all platform-specific files invisible
to CI lint runner (ubuntu, GOOS=linux). Known upstream bug
(golangci/golangci-lint#3833).

Browser (internal/browser/): revive var-naming (ref_ avoids Ref() collision),
gocritic, nestif (JS interop nesting).
Rust (*_rust.go): nolintlint for invisible //nolint directives.
Browser mapped_range: nolintlint for //nolint:gosec.

Verified: 0 issues on all 4 targets (Windows, Linux, macOS, WASM).
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.

2 participants