CNA-BUG-255: EasyGL family: ClearColorAndStencil leaves the stencil write mask forced to all ones, so a later draw ignores StencilWriteMask

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.

GraphicsDevice::Clear with Target and Stencil reaches EasyGLRenderer::ClearColorAndStencil, which forces the GL stencil mask open and never restores it, unlike the other EasyGL clears (REMED-GFX-237). A later StencilWriteMask-limited draw is not limited.

Identifier
CNA-BUG-255
Category
Bug
Subsystem
Graphics & renderers
Status
Narrowed (partially fixed; describes only what survives)
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(ClearOptions::Target | ClearOptions::Stencil, ...) on the EasyGL renderer family (EasyGLRenderer::ClearColorAndStencil)

Expected behaviour

XNA's Clear ignores StencilWriteMask but does not change the device's DepthStencilState, so a draw after the clear obeys the state the game assigned. EasyGL's own rule (REMED-GFX-237, stated in EasyGLRenderer.hpp and in OpenGL4Renderer.cpp) is that every clear puts back the write masks it forced open, because a game need not reassign its DepthStencilState before the next draw.

Actual behaviour at TARGET

EasyGLRenderer::ClearColorAndDepth, ClearDepth, ClearStencil, ClearDepthAndStencil and ClearColorDepthAndStencil all call RestoreWriteMasksAfterClear. ClearColorAndStencil sets the stencil mask to all ones, clears, and restores only the colour mask and the scissor. After GraphicsDevice::Clear(ClearOptions::Target | ClearOptions::Stencil, ...) the GL stencil write mask stays 0xFFFFFFFF until ApplyDepthStencilState runs again, so a later draw can write stencil bits its StencilWriteMask forbids until the depth/stencil state is applied again. OpenGL4Renderer::ClearColorAndStencil carries a comment that EasyGL's twin of this route does not put the mask back. The restore check in easygl_graphicsdevice_clear_stencil_test.cpp (Check D) uses ClearOptions::Stencil only.

Source locations

Evidence

Read at 009d40f5; nothing executed. The routine serves all five EasyGL-family identities (OPENGLES2, OPENGLES3, OPENGL33, WEBGL1, WEBGL2). Scope is narrow: it needs an explicit Target plus Stencil clear and a later draw that relies on a limited StencilWriteMask without reassigning its DepthStencilState. Stencil-clear tests exist for the other routes, none for this one.

Focused reproduction

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

Current tests

easygl_graphicsdevice_clear_stencil_test.cpp (Check D) verifies that the stencil write mask is restored after a clear, but only for ClearOptions::Stencil; no test clears colour and stencil together and then draws through a state with a restricted StencilWriteMask.

Regression test

Extend that check to ClearOptions::Target | ClearOptions::Stencil: clear, then draw through a DepthStencilState with StencilWriteMask 0 and expect the stencil buffer unchanged. The fix is to end ClearColorAndStencil with RestoreWriteMasksAfterClear(false, true) like its siblings.

Blast radius

EasyGL-family renderers only (OPENGLES2/3, OPENGL33, WEBGL1/2 and the other EasyGL identities); games that clear colour and stencil in one call and then rely on StencilWriteMask. OpenGL4 restores its masks on the same route.

Workaround

Clear colour and stencil with two calls (ClearOptions::Target, then ClearOptions::Stencil), or re-apply the depth/stencil state after the combined clear.

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

Known issues
Bug index