From 4e75d4456d61996772f7e113b73b07f2d5894a1b Mon Sep 17 00:00:00 2001 From: kuba Date: Tue, 6 Oct 2026 23:59:17 +0200 Subject: [PATCH] [Tests] Enable portable Vulkan devices and release fixture slabs --- .../Gpu/Vulkan/HeadlessVulkan.cs | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/tests/SharpEmu.Libs.Tests/Gpu/Vulkan/HeadlessVulkan.cs b/tests/SharpEmu.Libs.Tests/Gpu/Vulkan/HeadlessVulkan.cs index 5c3f36f..95c8133 100644 --- a/tests/SharpEmu.Libs.Tests/Gpu/Vulkan/HeadlessVulkan.cs +++ b/tests/SharpEmu.Libs.Tests/Gpu/Vulkan/HeadlessVulkan.cs @@ -161,6 +161,7 @@ internal sealed unsafe class HeadlessVulkan : IDisposable public void Dispose() { Vk.DeviceWaitIdle(Device); + _deviceInfo?.Slabs.Destroy(); Vk.DestroyDevice(Device, null); if (_debugUtils is { } debugUtils) { @@ -215,22 +216,33 @@ internal sealed unsafe class HeadlessVulkan : IDisposable var appInfo = new ApplicationInfo { SType = StructureType.ApplicationInfo, ApiVersion = apiVersion }; var validation = Environment.GetEnvironmentVariable(ValidationVariable) == "1"; var layers = validation ? SilkMarshal.StringArrayToPtr(new[] { "VK_LAYER_KHRONOS_validation" }) : 0; - var extensions = validation ? SilkMarshal.StringArrayToPtr(new[] { ExtDebugUtils.ExtensionName }) : 0; + uint instanceExtensionCount = 0; + vk.EnumerateInstanceExtensionProperties((byte*)null, &instanceExtensionCount, null); + var instanceExtensions = new ExtensionProperties[instanceExtensionCount]; + fixed (ExtensionProperties* pointer = instanceExtensions) + vk.EnumerateInstanceExtensionProperties((byte*)null, &instanceExtensionCount, pointer); + var portable = instanceExtensions.Any(extension => + SilkMarshal.PtrToString((nint)extension.ExtensionName) == "VK_KHR_portability_enumeration"); + var instanceNames = new List(); + if (validation) instanceNames.Add(ExtDebugUtils.ExtensionName); + if (portable) instanceNames.Add("VK_KHR_portability_enumeration"); + var extensions = instanceNames.Count != 0 ? SilkMarshal.StringArrayToPtr(instanceNames.ToArray()) : 0; var instanceInfo = new InstanceCreateInfo { SType = StructureType.InstanceCreateInfo, + Flags = portable ? InstanceCreateFlags.EnumeratePortabilityBitKhr : 0, PApplicationInfo = &appInfo, EnabledLayerCount = validation ? 1u : 0u, PpEnabledLayerNames = (byte**)layers, - EnabledExtensionCount = validation ? 1u : 0u, + EnabledExtensionCount = (uint)instanceNames.Count, PpEnabledExtensionNames = (byte**)extensions, }; var created = vk.CreateInstance(&instanceInfo, null, out var instance); if (validation) { SilkMarshal.Free(layers); - SilkMarshal.Free(extensions); } + if (extensions != 0) SilkMarshal.Free(extensions); if (created != Result.Success) { @@ -368,6 +380,7 @@ internal sealed unsafe class HeadlessVulkan : IDisposable vulkan13Features.PNext = &barycentricFeatures; } var extensionNames = new List(); + if (HasDeviceExtensions(vk, physical, ["VK_KHR_portability_subset"])) extensionNames.Add("VK_KHR_portability_subset"); if (dynamicRendering) extensionNames.AddRange(RenderingExtensionNames); if (barycentric) extensionNames.Add(barycentricExtension); const string fillRectangleExtension = "VK_NV_fill_rectangle";