fix(gles): 3D rendering — MappedAtCreation flush + depth fixes (#284) - #286
Merged
Conversation
…ity) v0.30.26 used GL_DEPTH_STENCIL_ATTACHMENT unconditionally — depth-only formats (Depth24Plus, Depth32Float) made FBO incomplete → 0x506 on every draw call → black screen. Now selects attachment point by texture format (Rust wgpu-hal command.rs:577-580): - depth-only → GL_DEPTH_ATTACHMENT - stencil-only → GL_STENCIL_ATTACHMENT - depth+stencil → GL_DEPTH_STENCIL_ATTACHMENT Fixes both AttachDepthStencilToFBOCommand (surface) and AttachDepthStencilCommand (offscreen). 2D overlay renders correctly. 3D rendering on GLES under separate investigation.
…rity) Three GLES depth bugs causing invisible 3D geometry: 1. ClearDepthCommand: add glDepthMask(true) before clear — prevents stale DepthMask(false) from prior pipeline masking the depth clear. Add glClearDepth(value) to set clear value (was using GL default 1.0). Rust ref: queue.rs:1199-1205. 2. SetViewportCommand: add glDepthRange(minDepth, maxDepth) — was ignoring depth range entirely. Default maxDepth=0 caused all geometry to be clipped. Rust ref: queue.rs:1295-1296. 3. gl.Context: add ClearDepth() and DepthRange() wrappers for both Windows (syscall, double) and Linux (goffi, float32 for GLES / glClearDepthf / glDepthRangef). Function pointers were loaded but had no wrapper methods. Root cause of invisible 3D cube: frame N 2D overlay sets DepthMask(false) → frame N+1 depth clear silently masked → stale depth → cube fails depth test. Confirmed by 3 parallel research agents + gg agent GL error trace.
#284) UnmapBuffer guarded glBufferSubData with BufferUsageMapWrite check. Per WebGPU spec, MappedAtCreation does NOT require MapWrite usage. Buffers with Uniform|CopyDst + MappedAtCreation (standard g3d pattern) had their shadow data silently discarded — zero MVP matrices, zero vertices, zero indices → invisible 3D geometry. Remove the MapWrite guard: if buf.mapped != nil && buf.id != 0, always flush. Matches wgpu-core which calls queue.write_buffer on unmap for non-MapWrite MappedAtCreation buffers. Root cause of invisible 3D cube on GLES (g3d hello-cube, fullscreen-overlay).
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Three GLES HAL bugs causing invisible 3D geometry. Visually confirmed fixed on Windows (Intel Iris Xe, 60 FPS).
Root cause: MappedAtCreation buffer data silently discarded
UnmapBufferguardedglBufferSubDataflush withBufferUsageMapWritecheck. Per WebGPU spec,MappedAtCreationdoes NOT requireMapWriteusage. g3d uniform/vertex/index buffers (Uniform|CopyDst + MappedAtCreation) had data thrown away — zero MVP matrices, zero vertices → invisible.Additional fixes
GL_DEPTH_ATTACHMENTfor depth-only,GL_DEPTH_STENCIL_ATTACHMENTfor combined (Rust wgpu-hal parity). Wrong attachment point caused FBO incomplete (0x506).glDepthMask(true)+glClearDepth(value)beforeglClear(GL_DEPTH_BUFFER_BIT). Stale mask from prior pipeline blocked depth clear.glDepthRange(minDepth, maxDepth)inSetViewportCommand(was ignoring depth range fields).ClearDepth(),DepthRange()for Windows (syscall) and Linux (goffi/GLES).Test plan
go build ./...— nativeGOOS=js GOARCH=wasm go build .— browsergolangci-lint— 0 issuesGOGPU_GRAPHICS_API=gles go run g3d/examples/hello-cube/— cube visible, rotatingGOGPU_GRAPHICS_API=gles go run g3d/examples/fullscreen-overlay/— 3D cube + 2D overlay, 60 FPSFixes #284.