simvx.graphics.gpu.capabilities¶
Unified, immutable render-capability snapshot (Vulkan backend).
RenderCapabilities is built once during init_vulkan after device
selection and holds probed facts only about the host interpreter and the
selected GPU. It subsumes the former _query_device_features dict: there is
one capability object, read identically everywhere, with no shim.
The web backend mirrors this shape in
packages/web/src/simvx/web/runtime/js/capabilities.js (Capabilities):
both expose a meets() predicate with the same truth-table semantics so a
pass can gate on {features, limits} regardless of backend.
Probing is deliberately separated from the dataclass. The module-level probe
helpers take raw Vulkan handles and return plain scalars; the frozen dataclass
is constructible directly from those scalars. Unit tests therefore build a
RenderCapabilities from injected values with no GPU, and only the
probe classmethod touches Vulkan.
Module Contents¶
Classes¶
Immutable snapshot of host + GPU render capabilities. |
Functions¶
True when the running interpreter has the GIL disabled (free-threaded). |
|
The |
|
Query the optional Vulkan device-feature bits SimVX cares about. |
|
Number of Vulkan-capable physical devices on this instance. |
|
Whether linked device groups ( |
|
Whether |
|
Locate dedicated compute and transfer queue families. |
|
Whether the device supports GPU timestamp queries ( |
Data¶
API¶
- simvx.graphics.gpu.capabilities.__all__¶
[‘RenderCapabilities’, ‘probe_free_threaded’, ‘probe_gil_disabled_build’, ‘probe_device_features’, ‘…
- simvx.graphics.gpu.capabilities.log¶
‘getLogger(…)’
- simvx.graphics.gpu.capabilities.probe_free_threaded() bool[source]¶
True when the running interpreter has the GIL disabled (free-threaded).
sys._is_gil_enabled()exists only on builds that know about the flag (3.13+); older builds are always GIL-enabled, so absence -> not free-threaded.
- simvx.graphics.gpu.capabilities.probe_gil_disabled_build() bool[source]¶
The
Py_GIL_DISABLEDbuild-config flag (the interpreter was built free-threaded), independent of whether the GIL is currently re-enabled at runtime viaPYTHON_GIL=1.
- simvx.graphics.gpu.capabilities.probe_device_features(physical_device: Any) dict[str, bool][source]¶
Query the optional Vulkan device-feature bits SimVX cares about.
Returns a plain
dict[str, bool]so the logical-device creation path can request exactly the features the device reports (seecreate_logical_device).RenderCapabilities.probefolds the same dict into typed fields.
- simvx.graphics.gpu.capabilities.probe_physical_device_count(instance: Any) int[source]¶
Number of Vulkan-capable physical devices on this instance.
- simvx.graphics.gpu.capabilities.probe_device_group(instance: Any) bool[source]¶
Whether linked device groups (
VK_KHR_device_group/ 1.1 core) are usable on this instance.vkEnumeratePhysicalDeviceGroupsmay be unresolvable through the loader on an instance created without the right API version / extension (observed on the dev box’s Iris Xe + 1.2 loader path); we catch that and yieldFalserather than letting an unresolvable-proc error escape init.
- simvx.graphics.gpu.capabilities.probe_external_memory_fd(physical_device: Any) bool[source]¶
Whether
VK_KHR_external_memory_fdis exposed by the device.Gates the dma-buf zero-copy cross-device transfer path (D8 multi-GPU). The extension must also be enabled at logical-device creation to be usable; the probe only reports availability. Absent on this dev box -> the staging-copy floor is always chosen.
- simvx.graphics.gpu.capabilities.probe_dedicated_queue_families(physical_device: Any) tuple[int | None, int | None][source]¶
Locate dedicated compute and transfer queue families.
Returns
(dedicated_compute_qf, dedicated_transfer_qf):dedicated compute: a family with COMPUTE but not GRAPHICS (async compute),
dedicated transfer: a family with TRANSFER but neither GRAPHICS nor COMPUTE (DMA-only copy engine). COMPUTE/GRAPHICS families implicitly support transfer, so we want the genuinely transfer-only one.
Either is
Nonewhen the device exposes no such family (e.g. integrated GPUs with a single universal queue family).
- simvx.graphics.gpu.capabilities.probe_gpu_timing(physical_device: Any) bool[source]¶
Whether the device supports GPU timestamp queries (
timestampPeriod > 0).
- class simvx.graphics.gpu.capabilities.RenderCapabilities[source]¶
Immutable snapshot of host + GPU render capabilities.
Probed facts only: no policy, no derived “should we” decisions. Consumers (the renderer, the future threading/queue/multi-GPU paths) read these fields and decide. Build via :meth:
probeat init, or construct directly from scalar fields in tests.- free_threaded: bool¶
False
GIL is disabled at runtime (
not sys._is_gil_enabled()).
- gil_disabled_build: bool¶
False
Interpreter was built free-threaded (
Py_GIL_DISABLEDconfig var).
- physical_device_count: int¶
1
- device_group: bool¶
False
A linked device group with >1 physical device is available.
- external_memory_fd: bool¶
False
VK_KHR_external_memory_fdis available (probed) on the selected device.Availability only: it does not mean the extension was enabled at logical-device creation. Use :attr:
external_memory_fd_enabledto gate the dma-buf zero-copy path; this field reports whether enabling it is even possible.Falseon this dev box.
- external_memory_fd_enabled: bool¶
False
VK_KHR_external_memory_fdwas enabled at logical-device creation.This is the gate the D8 multi-GPU cross-device transfer reads to select the dma-buf zero-copy path (:mod:
simvx.graphics.gpu.multi_device): a probed-but- not-enabled extension cannot export/import fds, so DMABUF stays unselected and the always-available staging-copy floor is used until the rig opts in and the secondary + primary devices both enable it.Falseon this dev box (the single-GPU path never requests it), so the dma-buf raise is never reached.
- dedicated_compute_qf: int | None¶
None
- dedicated_transfer_qf: int | None¶
None
- gpu_timing: bool¶
False
- multi_draw_indirect: bool¶
False
- image_cube_array: bool¶
False
- texture_compression_bc: bool¶
False
- texture_compression_etc2: bool¶
False
- texture_compression_astc_ldr: bool¶
False
- limits: dict[str, int]¶
‘field(…)’
- meets(*, features: list[str] | None = None, limits: dict[str, int] | None = None) bool[source]¶
Predicate mirroring the web
Capabilities.meets()truth table.featuresare capability field names that must be truthy (e.g."multi_draw_indirect","free_threaded","gpu_timing").limitsmaps a GPU-limit key to a minimum required value; every requested limit must be present and>=the requested value. Empty requirements pass. An unknown feature name fails (a typo never silently passes), matching the webhas()semantics.
- classmethod probe(instance: Any, physical_device: Any) simvx.graphics.gpu.capabilities.RenderCapabilities[source]¶
Build a capability snapshot from live Vulkan handles + the host build.
Pure probing: all GPU access is delegated to the module-level
probe_*helpers so this stays the single Vulkan touch point.