Skip to content

feat: complete three-layer WebGPU public API (v0.21.0)#103

Merged
kolkov merged 13 commits intomainfrom
feat/v0.21.0-public-api
Mar 15, 2026
Merged

feat: complete three-layer WebGPU public API (v0.21.0)#103
kolkov merged 13 commits intomainfrom
feat/v0.21.0-public-api

Conversation

@kolkov
Copy link
Contributor

@kolkov kolkov commented Mar 15, 2026

Summary

Complete three-layer WebGPU public API (wgpu → core → hal). Consumers never need to import wgpu/hal for standard use.

13 commits, ~3500 lines added:

  • core layer: 12 resource types completed (CORE-001), Surface state machine (CORE-002), CommandEncoder state machine (CORE-003), resource accessors (CORE-004)
  • public API: Surface delegation (CORE-005), Fence + async submission, HAL accessors, CommandEncoder extensions
  • WGPU-API-002: Proper type definitions replacing hal aliases (Extent3D, DepthStencilState, TextureBarrier, etc.)
  • SetLogger/Logger: Stack-wide logging propagation
  • naga v0.14.7: MSL binding index fix
  • Triangle examples: Single-threaded + multi-threaded wgpu API demos

Test plan

  • GOWORK=off go build ./... passes
  • GOWORK=off golangci-lint run — 0 issues
  • go fmt clean
  • gogpu_integration example runs (Vulkan, Intel Iris Xe)
  • CI (Linux + Windows)

kolkov added 13 commits March 14, 2026 22:58
Replace empty struct{} stubs in core/resource.go with full implementations
following the existing Buffer pattern:
- Texture: format, dimension, usage, size, mip levels, sample count
- Sampler, ShaderModule, QuerySet: HAL handle + properties
- BindGroupLayout, PipelineLayout, BindGroup: binding infrastructure
- RenderPipeline, ComputePipeline: pipeline types
- CommandEncoder, CommandBuffer: command recording types
- Surface: HAL surface (not Snatchable, owned by Instance)

Each type has: Snatchable HAL handle (where applicable), device reference,
WebGPU properties, constructor function, and Raw() accessor.

Foundation for CORE-002 (Surface lifecycle), CORE-003 (CommandEncoder
state machine), and CORE-004 (pipeline validation).
…ORE-002)

Implement full surface lifecycle management in core.Surface:
- State machine: Unconfigured → Configured → Acquired → Configured
- Mutex-protected thread-safe transitions
- Configure/Unconfigure with device validation
- AcquireTexture with state check + PrepareFrame hook
- Present with acquired texture validation
- DiscardTexture for error recovery
- PrepareFrameFunc callback for platform DPI/scale integration
  (Metal contentsScale, Windows WM_DPICHANGED, Wayland wl_output.scale)
- Auto-reconfigure on dimension change from PrepareFrame

Global registry changed from Registry[Surface] to Registry[*Surface]
to support sync.Mutex (non-copyable).

16 new tests covering all state transitions and error conditions.
wgpu.Surface now delegates to core.Surface instead of using hal.Surface
directly. All lifecycle methods go through core validation and state
tracking:
- Configure/Unconfigure → core state machine validation
- GetCurrentTexture → PrepareFrame hook + state check + HAL acquire
- Present → acquired texture validation + HAL present

New public methods:
- SetPrepareFrame(fn) — platform hook for HiDPI/DPI changes
  (Metal contentsScale, Windows WM_DPICHANGED, Wayland wl_output.scale)
- HAL() — escape hatch for backward-compatible direct HAL access

This enables gogpu PLAT-001 (PrepareFrame architecture) to register
platform callbacks on the wgpu Surface.
CommandEncoder tracks pass state with validated transitions:
- Recording → BeginRenderPass → InRenderPass → EndRenderPass → Recording
- Recording → BeginComputePass → InComputePass → EndComputePass → Recording
- Recording → Finish → Finished (validates no open passes)
- Any state → RecordError → Error (captures first error message)

CommandBuffer tracks submission state:
- Available → MarkSubmitted → Submitted (prevents double-submit)

13 new tests covering all state transitions and error conditions.
…-004)

Add read-only accessors and idempotent Destroy for 9 resource types:
- Texture: Format, Dimension, Usage, Size, MipLevelCount, SampleCount
- BindGroupLayout: Entries, EntryCount
- QuerySet: QueryType, Count
- All types: Label, Destroy, IsDestroyed

Destroy follows Buffer snatch-and-release pattern: read-lock device,
release lock, write-lock to snatch HAL handle, destroy via device.
Safe to call multiple times (idempotent).

Methods in separate resource_accessors.go with full test coverage.
Add missing public API methods needed for full gogpu migration from
HAL direct to wgpu public API:

- Fence type wrapper with Release() (fence.go)
- Device: CreateFence, ResetFence, GetFenceStatus, WaitForFence,
  FreeCommandBuffer (for FencePool pattern)
- Queue: SubmitWithFence for non-blocking async submission
- Surface: DiscardTexture for error recovery

All existing resource types already had Release() methods.
CommandEncoder/RenderPassEncoder/CommandBuffer wrappers already existed.

This completes the wgpu public API surface needed for gogpu to stop
using HAL directly and go through the proper wgpu → core → HAL chain.
- texture.go: HalTextureView() on *TextureView for gg integration
- wrap.go: HalDevice(), HalQueue() on *Device for legacy HAL access
- surface.go: fix nil TextureViewDescriptor (pass nil to HAL, not empty),
  remove unnecessary fence in GetCurrentTexture, remove debug logging
- cmd/wgpu-triangle/: single-threaded wgpu public API triangle example
- cmd/wgpu-triangle-mt/: multi-threaded wgpu public API triangle example
  (same architecture as gogpu renderer — validates wgpu API thread safety)
…migration

CommandEncoder: CopyTextureToBuffer, TransitionTextures, DiscardEncoding.
Texture: HalTexture() accessor for texture barrier interop.
Required by gg GPU-API-001 migration (readback + Vulkan layout transitions).
Replace type aliases to hal with proper struct definitions + toHAL() converters:
- Extent3D, Origin3D, ImageDataLayout, DepthStencilState, StencilFaceState
- New: TextureBarrier, TextureRange, TextureUsageTransition, BufferTextureCopy
- StencilOperation kept as alias (uint8 enum, same as CompareFunction)
- CommandEncoder signatures use wgpu types (no hal in public API)
- New wgpu.SetLogger()/Logger() for stack-wide logging propagation
- Device.CreateTexture uses desc.toHAL() (removed duplication)
Fixes MSL sequential per-type binding indices across bind groups.
@kolkov kolkov merged commit 12e58bd into main Mar 15, 2026
10 checks passed
@codecov
Copy link

codecov bot commented Mar 15, 2026

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