CNA-BUG-212: cna_graphics_resource_get_graphics_device returns CNA_RESULT_INVALID_HANDLE for every resource created on a caller-created GraphicsDevice

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.

A resource made on a device from cna_graphics_device_create carries that device's handle as its owner token, and the route passes it to the game-only BorrowGameGraphicsDevice, so asking such a valid resource for its device always fails.

Identifier
CNA-BUG-212
Category
Bug
Subsystem
C API & bindings
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
Yes: see Current tests
Affected contract
cna_graphics_resource_get_graphics_device(CNA_Handle resource, CNA_Handle* out_graphics_device) (CNA/C/graphics_resource.h) for resources created on a cna_graphics_device_create device

Expected behaviour

graphics_device.h says a caller-created device's handle “is accepted everywhere a borrowed device handle is” and that “resources remember which device made them”; graphics_resource.h promises success with CNA_INVALID_HANDLE for a standalone resource and the owning device's handle for a device-owned one. A valid resource on a live caller-created device should therefore yield that device's handle, or a documented refusal such as CNA_RESULT_NOT_SUPPORTED, never a claim that a handle is invalid.

Actual behaviour at TARGET

cna_graphics_device_create builds the device's view as BorrowedGraphicsDevice{device, own handle}, so every resource created on it stores the device handle in its parentGame owner token (for example IndexBufferResource, CreateOwnedTexture2D). cna_graphics_resource_get_graphics_device sees a non-null device pointer and a non-invalid owner and calls BorrowGameGraphicsDevice(parentGame, ...), which calls GetGame; HandleRegistry::Get finds a slot of kind OwnedGraphicsDevice where it expects Game and answers CNA_RESULT_INVALID_HANDLE, reported as “The CNA game handle is invalid for this call.” The route thus fails for every such resource, while the device is alive and after it is destroyed alike.

Source locations

Evidence

Checked by reading CnaCApiGraphicsResource.cpp, CnaCApiRuntime.cpp, CnaCApiDisplay.cpp and CnaCApiDetail.hpp at 009d40f5; the owner token was traced for index buffers and 2D textures. Not executed (the C library was not built). graphics_resource.h's wording predates caller-created devices and does not name this case, so the exact intended answer (the device handle or a documented refusal) is an owner decision; returning CNA_RESULT_INVALID_HANDLE for a valid resource is the defect.

Independently observed as a separate finding (merged): A resource made on a device from cna_graphics_device_create carries that device's handle as its owner token, and the route passes the token to the game-only BorrowGameGraphicsDevice, so asking a valid resource for its device fails.

Focused reproduction

Illustrative only, not compiled:

CNA_Handle device = CNA_INVALID_HANDLE, texture = CNA_INVALID_HANDLE, owner = CNA_INVALID_HANDLE;
cna_graphics_device_create(0U, CNA_GRAPHICS_PROFILE_REACH, &parameters, &device);
cna_texture2d_create(device, &texture_info, &texture);
CNA_Result r = cna_graphics_resource_get_graphics_device(texture, &owner);
/* by reading: r == CNA_RESULT_INVALID_HANDLE, owner == CNA_INVALID_HANDLE */

Current tests

GraphicsResourceSmoke.c calls the route for standalone resources, wrong kinds and game-device resources inside callbacks; OwnedGraphicsDeviceSmoke.c never calls it. The C tests are not run in CI.

Regression test

In OwnedGraphicsDeviceSmoke.c: create a texture on a caller-created device and assert that cna_graphics_resource_get_graphics_device succeeds with that device's handle (or returns the refusal the header is amended to document).

Blast radius

C and binding callers that ask a resource for its device when the resource was made on a caller-created device (the cross-device scenario that route was added for); creating, using and destroying such resources is unaffected, and game-device resources answer as documented.

Workaround

Keep the device handle that created each resource instead of asking the resource for it.

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

Known issues
Bug index