CNA-BUG-257: PORTABLEGL depth clears force glDepthMask(GL_TRUE) and never restore it, although their own comment says both masks are restored as EasyGL does

CNA snapshot 009d40f5  ·  Known Issues › Current bugs  ·  source links pinned to 009d40f5

✓

Evidence basis: source-verified at the pinned commit; tests exist (not executed for this page). Claims on this page were checked by reading the CNA source at commit 009d40f5; unless a sentence says otherwise, nothing here was built or executed. Nothing on this page was executed unless the Evidence section says so.

ClearColorAndDepth, ClearDepth, ClearDepthAndStencil and ClearColorDepthAndStencil call glDepthMask(GL_TRUE) and never put the depth write mask back; only the colour mask is restored.

Identifier
CNA-BUG-257
Category
Bug
Subsystem
Graphics & renderers
Status
Open
Verified against
CNA 009d40f5 (009d40f5dd085c4e674d3479675fac84b12b3e0a)
Severity
Low (a triage suggestion, not a project priority)
Evidence basis
Source-verified: read at TARGET, not executed
Tests touching this area
Yes: see Current tests
Affected contract
GraphicsDevice::Clear with a depth option on the PORTABLEGL renderer (PortableGLRenderer::ClearColorAndDepth, ClearDepth, ClearDepthAndStencil, ClearColorDepthAndStencil)

Expected behaviour

The comment in ClearColorAndDepth states the rule: XNA's Clear ignores DepthBufferWriteEnable and ColorWriteChannels, so both masks are “neutralized here and restored afterwards, exactly as EasyGL does”. EasyGL implements the restore with RestoreWriteMasksAfterClear (REMED-GFX-237: “restores the write masks a clear had to force open”), so a clear never changes what a later draw's depth/stencil state says.

Actual behaviour at TARGET

In PortableGLRenderer.cpp the four clears that touch depth call glDepthMask(GL_TRUE) before glClear. Only the colour mask is put back afterwards (from colorWriteChannels); the depth write mask is left GL_TRUE until ApplyDepthStencilState next runs glDepthMask(depthWriteEnable ? GL_TRUE : GL_FALSE). A later draw through a state with DepthBufferWriteEnable false can therefore write depth after such a clear, if the state has not been re-applied in between.

Source locations

Evidence

Read at 009d40f5; nothing was built or executed. Whether a later draw is actually affected depends on when the depth/stencil state is next applied, which was not traced through GraphicsDevice. Reported as an unpublished observation by the independent dismissal review (D1) and re-verified by the orchestrator against the source.

Focused reproduction

No focused reproduction is known. Nothing has been invented here; the evidence above is what exists.

Current tests

The PORTABLEGL examples exercise clears and depth state separately (portablegl_blend_test.cpp covers the colour mask through Clear, portablegl_raster_state_test.cpp depth state), but none clears depth and then draws through a state with DepthBufferWriteEnable false.

Regression test

Clear depth, then draw a quad through a DepthStencilState with DepthBufferWriteEnable false and expect the depth buffer unchanged. The fix is to restore the depth mask after each of the four clears, as EasyGL does.

Blast radius

PORTABLEGL only (a CPU rasteriser renderer); games that clear depth and rely on read-only depth for a following pass.

Workaround

Re-apply the depth/stencil state after a clear that touches depth.

The same subject is explained at several altitudes. These are the neighbouring pages at each one.

Known issues
Bug index