Skip to content

fix(surface): centralize acquisition and teardown ownership#269

Open
besmpl wants to merge 1 commit into
gogpu:mainfrom
besmpl:besmpl/surface-lifetime-ownership
Open

fix(surface): centralize acquisition and teardown ownership#269
besmpl wants to merge 1 commit into
gogpu:mainfrom
besmpl:besmpl/surface-lifetime-ownership

Conversation

@besmpl

@besmpl besmpl commented Jul 15, 2026

Copy link
Copy Markdown

Summary

Make the existing public lifetime contract enforceable without adding a HAL interface:

  • core.Surface owns an opaque acquisition lease, invalidated by present, discard, unconfigure, replacement, and destruction.
  • Texture and TextureView use one private HAL resolver, so retained swapchain wrappers fail before native access at render, copy, binding, write, and submit boundaries.
  • the public Instance owns the wrappers it creates and releases devices, then platform surfaces, then the native instance; cross-instance surface/device configuration is rejected.
  • Vulkan Device owns the set of configured swapchains and retires all of them in one device-destroy pass. Vulkan Surface continues to own only VkSurfaceKHR; Vulkan Instance needs no child registry.
  • a batched Queue.WriteTexture retains and revalidates the wrapper that authorized it, so a write recorded before present/discard cannot later submit a retired swapchain image.

This is an Android-independent prerequisite for #268. Android exposed the ownership gap, but the borrowed-surface-texture rule is common to every backend.

Ownership and release order

public Instance
├── Device ── configured swapchains / device children
├── Surface ─ platform surface handle
└── core Instance ─ native instance

release: Device → Surface → core Instance

Active acquisitions are discarded while the device is alive. After device teardown, the logical core configuration is retired before the platform surface is destroyed. Small DX12 guards keep its surface-owned swapchain cleanup safe in that order; Vulkan device loss uses a handle-abandon path rather than issuing child destroys through a lost device.

Verification

  • GOWORK=off go test ./...
  • GOWORK=off go test -race . ./core ./hal/vulkan
  • GOWORK=off go vet . ./core ./hal/vulkan
  • GOWORK=off go test -tags rust ./...
  • GOWORK=off go mod verify
  • golangci-lint v2.12.2 run --new-from-rev upstream/main (0 issues)
  • Windows/amd64 cgo-disabled DX12 test binary cross-compile
  • Linux/amd64 cgo-disabled root test binary cross-compile

Focused public tests cover present, discard, reconfigure, unconfigure, surface release, device/instance release, foreign acquisition, retained views, idempotent wrapper release, render/copy/bind/submit rejection, deferred writes, submit failure cleanup, and cross-instance ownership. Vulkan tests cover configured-surface ownership and the device-loss abandon path.

Android preview relationship

This Android-independent prerequisite is stacked into draft #268 at exact head 85eeeb02a278bf4caebf66310b6baad8c328dd87. The draft will rebase it out after merge; Android runtime claims remain gated in that PR.

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