CNA-BUG-110: Stock-effect state is captured at draw time, so a property changed after EffectPass::Apply() affects the next draw, unlike XNA

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

✓

Evidence basis: source-verified at the pinned commit. 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 calls currentEffect_->FillGpuDrawParams() inside every draw, reading the stock effect's current World, colours and so on; XNA commits effect state at Apply() and a later property change only marks the effect dirty for the next Apply.

Identifier
CNA-BUG-110
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
None
Affected contract
BasicEffect and the other stock effects' properties between EffectPass::Apply() and GraphicsDevice::Draw*Primitives

Expected behaviour

In XNA 4.0 (IL) a stock-effect setter such as BasicEffect.set_World stores the value and sets dirty flags; EffectPass.Apply runs OnApply and commits the parameters, so the draw uses the values current at Apply. Compiled effects in CNA already synchronise at Apply.

Actual behaviour at TARGET

Every draw overload in GraphicsDevice.cpp builds a GpuDrawParams with currentEffect_->FillGpuDrawParams(p) at the draw call. The sequence effect.World = A; pass.Apply(); effect.World = B; Draw(); draws with B in CNA and with A in XNA.

Source locations

Evidence

Checked by reading the named sources at 009d40f5; nothing was built or executed for this entry. XNA behaviour from the genuine XNA 4.0 Graphics IL (setter stores + dirty flags; Apply commits). The site's effect object model page already describes the draw-time capture.

Focused reproduction

// Illustrative; not compiled or run for this entry.
effect.setWorldProperty(worldA);
effect.getCurrentTechniqueProperty()->getPassesProperty()[0]->Apply();
effect.setWorldProperty(worldB);          // e.g. preparing the next object too early
device.DrawIndexedPrimitives(...);        // XNA draws with worldA, CNA with worldB

Current tests

No test changes a stock-effect property between Apply and a draw.

Regression test

A HEADLESS test that records the GpuDrawParams world matrix of a draw after such a change and expects the Apply-time value.

Blast radius

Code that mutates stock effects between Apply and Draw (batching helpers, shared effects across objects); the usual set-then-Apply-then-Draw order is unaffected.

Workaround

Set all properties before Apply and do not touch the effect until the draw.

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

Known issues
Bug index