CNA-BUG-103: VULKAN clears every colour attachment of a multiple-render-target set, so PreserveContents targets lose their contents when bound as part of an MRT set

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.

GetOrCreateMRTRenderPass begins each colour attachment with LOAD_OP_CLEAR from an undefined layout (except split-pass continuations), and its cache key has no usage flag, unlike the single-target pass that honours DiscardContents versus PreserveContents.

Identifier
CNA-BUG-103
Category
Bug
Subsystem
Graphics & renderers
Status
Open
Verified against
CNA 009d40f5 (009d40f5dd085c4e674d3479675fac84b12b3e0a)
Severity
Medium (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::SetRenderTargets with two or more RenderTarget2D bindings whose RenderTargetUsage is PreserveContents, on VULKAN

Expected behaviour

A PreserveContents render target keeps its pixels when it is bound again (XNA's RenderTargetUsage contract, which CNA's single-target Vulkan path implements through GetOrCreateRTRenderPass(depthFormat, discardContents)).

Actual behaviour at TARGET

In VulkanRenderer.cpp, GetOrCreateMRTRenderPass keys passes by colour formats, sample count, depth format and split role only, and for a non-continuation pass sets every colour attachment to loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR with initialLayout = VK_IMAGE_LAYOUT_UNDEFINED (depth and stencil likewise). Re-binding an MRT set therefore discards what each target held, whatever its usage.

Source locations

Evidence

Checked by reading the named sources at 009d40f5; nothing was built or executed for this entry. A grep of the Vulkan and shared MRT fixtures found PreserveContents targets used in MRT sets (mrt_stock_effect_contract_test.cpp) but no leg that draws, unbinds, re-binds the same set and checks the earlier pixels; that search was not exhaustive.

Focused reproduction

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

Current tests

Vulkan_MRT_* fixtures (vulkan_mrt_msaa_test.cpp and siblings) check writes within one binding.

Regression test

An MRT fixture: bind two PreserveContents targets, draw, unbind, re-bind without clearing, draw elsewhere, and assert both draws survive on both targets.

Blast radius

Deferred-rendering and accumulation techniques on VULKAN that build G-buffers over several MRT passes; single-target rendering is unaffected.

Workaround

Composite into a separate target after each MRT pass, or re-bind MRT targets only when you intend to overwrite them.

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

Known issues
Bug index