CNAEXT catalogue: extension surfaces by namespace
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. Marker counts were made at 009d40f5 by the two methods stated on the page. The strict-check CTests exist; no result is claimed for them here.
CNA adds a large surface that XNA 4.0 never had, and much of it lives inside the XNA namespaces next to faithful declarations. This page is a catalogue of that extension surface at snapshot 009d40f5, namespace by namespace, with the real member names, why each extension exists and where its boundary is; it also explains how much of it the CNAEXT marker actually covers and what the strict compile check does and does not prove. For the opt-in CNA::Graphics engine layer in depth, read CNAEXT Engine Layer.
Three mechanisms that share a name
"CNA extension" names three related but non-equivalent mechanisms. Keeping them apart prevents both API over-claiming and build confusion.
| Name | What it is | What it is not |
|---|---|---|
CNAEXT | An empty marker macro in CNAHelper.hpp, placed on a declaration inside an XNA-shaped namespace that is not part of XNA 4.0; under CNA_STRICT_XNA_API it becomes [[deprecated("CNAEXT: not part of the XNA 4.0 API surface")]] | A compile guard: everything it marks is compiled in every build |
CNA::* namespaces | Project-owned namespaces for helpers, renderer and platform contracts, input and device services, diagnostics and engine-layer types that do not pretend to be Microsoft declarations | Individually marked; they are identified by the namespace itself |
CNA_CNAEXT and CNA::CnaExt | A CMake option (default OFF) that compiles the CNA::Graphics engine layer, and an interface target, defined in modules/CMakeLists.txt, that composes cna_graphics_ext with cna_devices_ext (it carried a NoXna name before the CNAEXT naming was normalised in August 2026) | The declaration marker, or a promise that marked members disappear when the option is off |
The build-side switches (CNA_CNAEXT, CNA_DEVICES) and the fact that CNA_STRICT_XNA_API is a compile definition rather than a CMake option are tabulated on What CNAEXT is; Two things named CNAEXT is the maintainer's view.
How much of the surface is marked
The authoritative inventory is the source together with the reference-surface census, not a hand-copied list. How large the marked surface looks depends on how it is counted: at this snapshot the marker occurs as a code token (comments stripped) 1,843 times in 330 public headers under modules/*/include, and as a whole word including comments 2,279 times in 353 of the .hpp headers (2,320 times in 358 files if the C API's plain .h headers are included). Neither figure counts extension members, and both will move as APIs are classified. The CNA:: namespaces, which hold most of the non-XNA headers, are not tagged declaration by declaration.
The EXT suffix is a naming convention and is independent of the marker in both directions. Marked declarations without the suffix include ShaderEffect, BasicEffect::SetOwnedTexture and GraphicsDevice::SetContextRecoveryEnabled. Conversely, a few public suffixed members carry no marker at this snapshot: Texture::GetFormatSizeEXT and Texture::GetBlockSizeSquaredEXT, and the GameWindow::getIsBorderlessEXTProperty()/setIsBorderlessEXTProperty() pair. Strict mode does not flag those, which is one reason neither spelling can decide by itself what is an extension; compare against the reference surface instead.
Framework and math bridges
| Surface | Extension members | Why it exists |
|---|---|---|
GameWindow | MinimizeEXT(), RestoreEXT(), GetNativeWindowHandleEXT() (a platform-neutral CNA::Platform::NativeWindowHandle, not an SDL pointer), the FileDropEXT and TextDropEXT events, SetLogicalSizeProviderEXT(), and the borderless accessors noted above | Desktop window operations and drag-and-drop that XNA's console-era window contract never expressed |
GraphicsDeviceManager | The marked enum PresentationMode (Letterbox, Overscan, Stretch, NativeBackBuffer, FixedHeightDynamicWidth) with getPreferredPresentationModeProperty()/setPreferredPresentationModeProperty(), and a default constructor | Scaling policies layered around XNA's manager; the default is Letterbox, so the viewport keeps the back-buffer size whatever the window's shape |
Matrix | ToColumnMajor(float out[16]) | An explicit bridge from XNA's row-vector storage to shader APIs that want column-major uniform data, used with ShaderEffect (see Shader effects: setting uniforms) |
Color | Byte-component constructors Color(bytecs r, bytecs g, bytecs b) and with alpha, the commutative operator*(float, const Color&), and the public getDebugDisplayStringProperty() | C++ convenience; the commutative multiply exists in neither XNA nor FNA |
Every System::Object-derived class | GetTypeName() overrides returning the fully qualified .NET name | A runtime type-name bridge from sharp-runtime's object model, not an XNA member family |
Graphics and model extensions
Graphics extensions span three physical modules (graphics, content and graphics-ext); directory ownership and API classification are different axes. Everything in this table except the last row is compiled in every build.
| Area | Representative members | Boundary |
|---|---|---|
Capability queries on GraphicsDevice | GetRendererCapabilityProfileEXT(), SupportsRendererFeatureEXT(), GetRendererLimitEXT(), GetRendererSurfaceFormatSupportEXT(), GetRendererCapabilityReportEXT(), SupportsShaderLanguageEXT(), ExecutesShaderEffectSourceEXT(), SupportsShadowSamplingEXT(), SupportsImageBasedLightingEXT(), SupportsSurfaceFormatAsRenderTargetEXT(), the compute work-group limits, Get/SetDisplayColorSpaceEXT() | They report what the renderer's code declares; see the capability profile |
| Extra draws | DrawInstancedPrimitivesBaseInstanceEXT(), DrawPrimitivesIndirectEXT(), DrawIndexedPrimitivesIndirectEXT() | Refused where the renderer lacks the capability |
| Diagnostics and recovery | SetStringMarkerEXT(), SetContextRecoveryEnabled(), NotifyContentLostResourcesEXT(), SetGraphicsProfileEXT(), SetUnsupported3DGraphicsCallBehavior(), GetLogicalSizeEXT() | Simulating a lost context is an internal renderer hook (IGraphicsRenderer::DebugSimulateContextLoss), not public API; hook presence and host evidence are separate claims |
| Effects | ShaderEffect; PbrEffect and SkinnedPbrEffect; ColorMatrixEffect; the shadow and image-based-light receiving types such as IShadowReceiverEXT | ShaderEffect does not make a renderer support the separate compiled-effect route; PBR support is renderer-qualified |
| Skeletal animation | SkinningData and AnimationPlayer, modelled on the classic XNA skinned-model sample; a model's Tag carries the SkinningData | Sample-derived, not framework-assembly API; separate from the avatar system |
| Avatars | SkinnedModelEXT with keyframed bone tracks (clip names follow AvatarAnimationPreset) | Real rendering through the CNAEXT avatar path; XNA's own AvatarRenderer.Draw() stays inert, as in XNA |
| Morph targets | MorphTargetDataEXT (PositionDeltas, NormalDeltas, TangentDeltas), weight keyframes with CUBICSPLINE tangents, CPU blending by BlendMorphTargetsEXT() | Tangent deltas are blended too, as a direction only: the handedness w stays on the base vertex because interpolating +1 and −1 passes through 0 (MorphTargetEXT.cpp). Texture coordinates and skinning attributes are copied unchanged |
| Textures and formats | TextureCube::DDSFromStreamEXT(), Texture::GetFormatSizeEXT() and GetBlockSizeSquaredEXT(), extra SurfaceFormat values such as Dxt5SrgbEXT, Bc7EXT and Bc7SrgbEXT | Presence is not support on every renderer; ask the format-support query |
Engine layer (CNA_CNAEXT=ON only) | The CNA::Graphics module: render pipeline and post-processing, shadows, lights and image-based lighting, geometry throughput, compute resources, shader packages, observation | See below |
Content extensions
| Surface | Members | Boundary |
|---|---|---|
| CNJ descriptors | ContentManager::RegisterCnjLoader<T>(typeName, factory) and the built-in typed .cnj loaders | A project-owned format with per-loader payload rules, not a universal schema; registration fails fast on an empty or duplicate name |
| Content introspection | RefreshContentManifest(), GetContentManifest(), GetXnbReaderUsageSummary() | Enumerates discovered assets and the XNB reader names they use, for audits and tools; it neither resolves nor validates every asset |
| Reflective XNB types | ReflectiveTypeReaderBuilder<T>, ReflectiveTypeReader<T>, CanonicalReflectiveReaderNameEXT() | Replaces XNA's reflection-driven reader with a field list the game declares once, in wire order |
Input, audio, media and host services
| Area | Representative extension surface | Why it is separate |
|---|---|---|
| Input | GamePad: GetGUIDEXT(), GetNameEXT(), SetLightBarEXT(), SetTriggerVibrationEXT(), GetGyroEXT(), GetAccelerometerEXT(), GetPowerInfoEXT(), GetTouchpadFingerEXT(), GetSteamHandleEXT(); Keyboard: GetKeyFromScancodeEXT(), GetScancodeNameEXT(), GetModStateEXT(); Mouse: SetCaptureEXT(), GetGlobalPositionEXT(), relative mode; TextInputEXT; and the CNA::Input clipboard, joystick and haptics types | Modern controllers and SDL3 expose far more than XNA's Xbox 360 input model |
| Audio | DynamicSoundEffectInstance::SubmitFloatBufferEXT() | XNA's streaming instance accepts 16-bit PCM bytes only; the float path is CNA's |
| Media | Video::FromUriEXT(), Video::SetAudioTrackEXT(), VideoPlayer::SetAudioTrackEXT() and SetVideoTrackEXT(), frame-generation queries | The URI and track members mirror FNA's own extensions (present in FNA's Video.cs and VideoPlayer.cs) and are still outside XNA |
| Devices | CNA::Devices in the devices-ext module: camera, file dialogs, message boxes, locale, URL launching, system, display and power information, tray, clipboard; compiled only with CNA_DEVICES=ON | Kept apart from the always-built Microsoft::Devices::Sensors, which is Windows Phone API |
| Sensors | Accelerometer::InjectSyntheticSensorUpdate() and the ...ForTesting() members, extra VibrateController members, operators on the reading structs | Testing and platform bridges marked inside Microsoft-shaped classes; exactly these are what the strict harness avoids |
| Storage | StorageDevice::SetAppNameEXT(), StorageDevice::GetStorageRootEXT() | CNA needs a deterministic local root where XNA chose a storage device through platform UI; without SetAppNameEXT the application folder is the literal name game |
| GamerServices | Guide overlay helpers such as WasKeyboardInputCanceledEXT(), and ...ForTestingEXT() accessors for the pending keyboard request | They make the local overlay behaviour testable without claiming Xbox LIVE services |
| Networking | NetworkGamer: SetId(), SetIsHost(), SetHasLeftSession(), SetRoundtripTime(); NetworkSession: SendNetworkEvent(), AddRemoteGamer(), RemoveGamer() and, private to the ENetBackend friend, SetHostFromTransport() and SetSessionPropertiesFromTransport(); LocalNetworkGamer::EnqueuePacket() and ClearPacketQueue(); AvailableNetworkSession::GetConnectAddress(), GetConnectPort(), GetSessionType(); CreateInternal() factories on the value types; and the lifetime counters GetOwnedGamerCountForTesting(), GetActiveActionInstanceCountForTesting(), GetInstanceCountForTesting() | Public and internal setters and delivery controls that the ENet-backed implementation needs where the reference keeps state private, internal or inert (the header comments record that FNA reports every gamer as id 0 and as host and never sets HasLeftSession); SendNetworkEvent() is public because a sibling class must enqueue events. The ...ForTesting() counters are the lifetime checks |
The marker says only "not original XNA". An extension still needs the same ownership, failure, hostile-input and host-evidence analysis as a faithful member, and several of these surfaces are host-dependent (camera, haptics, sensors). XNA compatibility: what CNA adds gives the user-level summary.
The engine layer at a glance
The graphics-ext module is an engine-oriented layer over GraphicsDevice: not another renderer, and not a turn towards an editor-led runtime. At this snapshot its public CNA/Graphics directory holds 98 headers and its test tree 92 C++ sources; those counts describe scope, not uniform execution. Its surfaces form six cooperating groups: materials and environments (PbrMaterial, glTF material bridge, environment processing, sky, light probes), lights and shadows (single, cube and cascaded shadow maps; the clustered-forward many-light path), the frame pipeline (RenderPipeline, target pooling, a depth-normal prepass and an ordered post-process chain), geometry scale (InstancedRendererEXT, FrustumCullerEXT, LodGroupEXT, GPU culling, particles, transparency ordering), modern resources (ComputeShader, storage and constant buffers, texture arrays, shader packages) and observation (GPU timers, pipeline diagnostics, debug draw).
The layer checks named GraphicsCapability values and validates resources where they are used. Some algorithms keep an intentional CPU path: clustered light assignment runs without compute through ClusteredLightAssignment, and ClusteredLightComputeTests.cpp compares the CPU and GPU assignments. Features that need GPU primitives refuse by name instead of substituting silently. Its tests must be read by kind: arithmetic, grid and material tests run against recording test doubles; shader-package tests prove that generated payloads are fresh; resource and interop tests need an engaged renderer; and visibility, shadow, post-process and readback tests reach pixels. So 92 test sources are not 92 renderer-qualified pixel suites, and no CI workflow configures CNA_CNAEXT=ON. Application repositories built on the layer add integrated observations, each for its own pinned revision and host. The full account, with per-renderer support and the degradation rules, is CNAEXT Engine Layer.
How the strict check proves itself
In a normal build CNAEXT expands to nothing. Two standalone targets in cmake/Harnesses.cmake give it force, and they are built only when CNA_BUILD_TESTS is on and the compiler is GCC or Clang:
- The positive direction.
cna_strict_xna_api_checkcompilesStrictXnaApiSurfaceCheck.cppwithCNA_STRICT_XNA_APIand-Werror=deprecated-declarations. The file exercises the genuineMicrosoft::Devicesand sensor API and its header lists every marked member it deliberately does not call. The CTestStrictXnaApiSurfaceCheck_Compile_Runruns the result (under Wine in a Direct3D cross-build tree). - The negative direction.
cna_strict_xna_api_leak_checkisEXCLUDE_FROM_ALL, so it never takes part in an ordinary build. Its whole body is one deliberate violation:
The CTestMicrosoft::Devices::Sensors::Accelerometer accelerometer; accelerometer.InjectSyntheticSensorUpdate(1.0f, 0.0f, 0.0f); // CNAEXT -- must fail to compile here.StrictXnaApiSurfaceLeakCheck_MustFailToCompilerunscmake --buildfor that target withWILL_FAIL TRUE, so it passes only if the build fails.
A positive-only check ("the real API still compiles") is equally consistent with a guard that never fires. The pair proves both acceptance and sensitivity for the slice it exercises: if a change to the macro or to the define's wiring ever let the leak compile, the negative test would turn red, catching a regression in the safety net itself. What the pair does not prove is that every addition elsewhere is marked, or that other namespaces are pure; that still takes comparison with the reference surface. (The comment in CNAHelper.hpp still names an old tests/Microsoft/Devices/ location for the positive check; the files live under tools/devices/.)
A game can use the same mechanism on its own code. Define the macro on the target to check and promote the warning:
target_compile_definitions(my_game PRIVATE CNA_STRICT_XNA_API)
target_compile_options(my_game PRIVATE -Werror=deprecated-declarations)
Passing -DCNA_STRICT_XNA_API=ON to the CMake configure step instead only creates an unused cache variable. Tutorial 115 walks through the marker, strict mode and the build gate with code.
Related pages
The same subject is explained at several altitudes. These are the neighbouring pages at each one.
- User guide
- CNAEXT Engine Layer · What CNA adds beyond XNA
- Architecture
- Physical module graph
- Internals
- Graphics extension internals · Devices internals
- Maintainer workflow
- Two things named CNAEXT · Change public XNA behaviour: the marker
- Tests and validation
- Test architecture
- Reference
- Public header index