Files
DroidDeck/tools/linuxfs/xclipse-layer/gen_device_chain.py
T
Stefan Zijlstra 6fcc11ab80 Xclipse layer: copy any device-chain structure the headers define
The chain copy that clears the emulated textureCompressionBC only knew a
handful of structure sizes, so a valid chain such as
VkPhysicalDeviceTimelineSemaphoreFeatures -> VkPhysicalDeviceFeatures2 was
passed on unchanged and the compat layer refused the bit. Size every
structure that may extend VkDeviceCreateInfo from a table generated from the
Vulkan registry (gen_device_chain.py, Vulkan-Headers 1.3.275, the headers
the build compiles with), and copy onto the heap instead of a fixed buffer.
Only a structure newer than those headers still passes the chain unchanged.

Add a regression test that runs the layer between a simulated loader and a
mock driver: the timeline-semaphore chain, pEnabledFeatures, an unknown
structure, the caller's structures left untouched, per-device YCbCr sampler
tracking with handle reuse, and the KHR calibrated-timestamp forwarding. CI
installs libvulkan-dev for it.
2026-10-12 07:32:52 +02:00

44 lines
1.9 KiB
Python
Executable File

#!/usr/bin/env python3
"""Generate device_chain.inc: the structures a VkDeviceCreateInfo chain may hold, with their sizes.
The Xclipse layer copies the chain ahead of the VkPhysicalDeviceFeatures2 it edits, and copying a
structure needs its size. Run against the Vulkan-Headers release the build compiles with (Ubuntu
24.04's libvulkan-dev is 1.3.275):
gen_device_chain.py Vulkan-Headers/registry/vk.xml Vulkan-Headers/include/vulkan/vulkan_core.h
"""
import re
import sys
import xml.etree.ElementTree as ElementTree
from pathlib import Path
def main(registry, core_header, output):
core = Path(core_header).read_text()
root = ElementTree.parse(registry).getroot()
entries = []
for struct in root.iter("type"):
if struct.get("category") != "struct" or struct.get("alias"):
continue
if "VkDeviceCreateInfo" not in (struct.get("structextends") or "").split(","):
continue
name = struct.get("name")
stype = next((member.get("values") for member in struct.findall("member")
if member.findtext("name") == "sType"), None)
# Platform and provisional structures live outside vulkan_core.h; the layer never builds them.
if not stype or not re.search(r"\}\s*" + re.escape(name) + r"\s*;", core):
continue
entries.append((stype, name))
version = re.search(r"#define VK_HEADER_VERSION (\d+)", core).group(1)
lines = ["/* Generated by gen_device_chain.py from Vulkan-Headers 1.3.%s; do not edit. */" % version]
lines += ["DEVICE_CHAIN(%s, %s)" % entry for entry in sorted(entries)]
Path(output).write_text("\n".join(lines) + "\n")
print("%d structures" % len(entries))
if __name__ == "__main__":
if len(sys.argv) not in (3, 4):
sys.exit(__doc__)
main(sys.argv[1], sys.argv[2], sys.argv[3] if len(sys.argv) == 4 else
Path(__file__).with_name("device_chain.inc"))