CNA-BUG-246: docs/graphics-resource-lifetime.md says existing XNA resources hold a unique_ptr renderer and names a non-existent ITexture2DRenderer; Texture2D, Texture3D and TextureCube hold shared_ptr renderers and Texture2D's public copies share one
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 c1c316b9; unless a sentence says otherwise, nothing here was built or executed. Nothing on this page was executed unless the Evidence section says so.
The document's Ownership Model gives unique_ptr renderer ownership for existing XNA resources, a list its scope sentence extends to Texture2D and RenderTarget2D, and knows only one kind of sharing: an internal record on non-copyable modern resources. Texture2D, Texture3D and TextureCube hold shared_ptr renderers, and Texture2D's public copies share the renderer and CPU shadow.
- Identifier
CNA-BUG-246- Category
- Bug
- Subsystem
- Documentation & release tooling
- Status
- Open
- Verified against
- CNA
c1c316b9(c1c316b9c7a846ce8002809c151fcd1af14942c9) - 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
- docs/graphics-resource-lifetime.md section 1 (Ownership Model) against Microsoft::Xna::Framework::Graphics::Texture2D (copy constructor, copy assignment, GetRendererWeak, GetCpuPixelsWeak), Texture3D and TextureCube
Expected behaviour
The lifetime document describes the ownership that the resource classes implement, so that a maintainer reasoning about disposal, copies and native-handle retention starts from the right model.
Actual behaviour at TARGET
graphics-resource-lifetime.md section 1 says existing XNA resources hold a std::unique_ptr<IXxxRenderer> (for example IVertexBufferRenderer or ITexture2DRenderer) and that a modern resource such as Texture2DArray may instead own an internal shared record that never reaches the public API; its scope sentence names Texture2D and RenderTarget2D among the covered types. At TARGET no type named ITexture2DRenderer exists under modules/ (the real interface is ITextureRenderer). Texture2D.hpp holds std::shared_ptr<ITextureRenderer> renderer_, a shared cpuPixels_ vector and shared extraMipLevels_; its public CNAEXT copy constructor and copy assignment (user-defined since af3c5037c so that every live copy registers with the device for disposal, as TextureCube's now do too) are documented as 'a second handle to the same texture' (shared until a full-level SetData, KF-4), and GetRendererWeak()/GetCpuPixelsWeak() hand out weak references. Texture3D.hpp and TextureCube.hpp hold std::shared_ptr renderers too. Of the five resource headers read, only VertexBuffer.hpp and IndexBuffer.hpp follow the unique-ownership rule, which is the shape section 5's move example uses. The document has no account of the texture family's public value-copy sharing.
Source locations
docs/graphics-resource-lifetime.md— section 1, Ownership Modelmodules/graphics/include/Microsoft/Xna/Framework/Graphics/Texture2D.hpp— renderer_, cpuPixels_, extraMipLevels_, copy operations that share the renderer, GetRendererWeak, GetCpuPixelsWeakmodules/graphics/include/Microsoft/Xna/Framework/Graphics/Texture3D.hpp— renderer_ is a shared_ptrmodules/graphics/include/Microsoft/Xna/Framework/Graphics/TextureCube.hpp— renderer_ is a shared_ptrmodules/graphics/include/Microsoft/Xna/Framework/Graphics/VertexBuffer.hpp— renderer_ is a unique_ptrmodules/graphics/include/Microsoft/Xna/Framework/Graphics/IndexBuffer.hpp— renderer_ is a unique_ptrmodules/graphics/include/CNA/Internal/Renderers/Common/IGraphicsRenderer.hpp— ITextureRenderer, the real texture renderer interface
Evidence
Checked by reading at c1c316b9; not executed. Read the document's section 1 and 5 and the member declarations and Doxygen of the five resource headers; searched modules/ for ITexture2DRenderer (no match). The document last changed in 1321ca346 and is identical at TARGET; another sentence of the same document is tracked separately.
Independent re-verification: Checked by reading at c1c316b9; not executed. Read the document's sections 1, 2 and 5, the member declarations and Doxygen of the five resource headers; searched modules/ for ITexture2DRenderer (only the document names it). Correction to the earlier wording: the sentence that sharing never reaches the public API is about the internal record of modern resources such as Texture2DArray, a class the public API no longer has at c1c316b9 although the document still names it; the defect is that the two-way model has no place for the texture family's shared_ptr holders and public copies.
Re-verified at c1c316b9: the document is unchanged; the texture headers still hold shared_ptr renderers, and the copy operations of Texture2D and TextureCube are now user-defined (af3c5037c) but still share one renderer and CPU shadow. Not executed.
Focused reproduction
No focused reproduction is known. Nothing has been invented here; the evidence above is what exists.
Current tests
Texture2DTests.cpp checks that copies preserve width, height and format; nothing checks the document.
Regression test
Documentation fix: state per resource family which holder is used (shared for the texture family, with value copies sharing the renderer and CPU shadow; unique for buffers) and replace ITexture2DRenderer with ITextureRenderer.
Blast radius
Maintainers and extension authors who reason about texture disposal, copying or native-handle retention from this document; no runtime behaviour is affected.
Workaround
Read the ownership from the headers: textures are shared value wrappers; buffers own their renderer uniquely.
Related pages
The same subject is explained at several altitudes. These are the neighbouring pages at each one.
- User guide
- 3D rendering guide
- Deep dives
- Texture data transfer: Texture2D shape
- Known issues
- Bug index