diff --git a/src/Magnum/Vk/Implementation/DeviceState.cpp b/src/Magnum/Vk/Implementation/DeviceState.cpp index 5b848d190..318d3c94c 100644 --- a/src/Magnum/Vk/Implementation/DeviceState.cpp +++ b/src/Magnum/Vk/Implementation/DeviceState.cpp @@ -42,7 +42,10 @@ using namespace Containers::Literals; DeviceState::DeviceState(Device& device, Containers::Array>& encounteredWorkarounds) { if(device.isVersionSupported(Version::Vk11)) { - getDeviceQueueImplementation = &Device::getQueueImplementation11; + if(device.properties().name().hasPrefix("SwiftShader"_s) && !Implementation::isDriverWorkaroundDisabled(encounteredWorkarounds, "swiftshader-crashy-getdevicequeue2"_s)) + getDeviceQueueImplementation = &Device::getQueueImplementationDefault; + else + getDeviceQueueImplementation = &Device::getQueueImplementation11; } else { getDeviceQueueImplementation = &Device::getQueueImplementationDefault; } diff --git a/src/Magnum/Vk/Implementation/DriverWorkaround.cpp b/src/Magnum/Vk/Implementation/DriverWorkaround.cpp index 1caf65fb5..b71314f47 100644 --- a/src/Magnum/Vk/Implementation/DriverWorkaround.cpp +++ b/src/Magnum/Vk/Implementation/DriverWorkaround.cpp @@ -39,6 +39,10 @@ using namespace Containers::Literals; /* Search the code for the following strings to see where they are implemented */ constexpr Containers::StringView KnownWorkarounds[]{ /* [workarounds] */ +/* SwiftShader on Android 29 image advertises Vulkan 1.1 but crashes inside + vkGetDeviceQueue2(). Using the Vulkan 1.0 entrypoint instead. */ +"swiftshader-crashy-getdevicequeue2"_s, + /* For layered image copies, SwiftShader (5.0? the version reporting is messy) expects the layer offsets/counts to be included as second/third dimension of the image offset/extent instead. Actually, having the Vulkan API contain diff --git a/src/Magnum/Vk/Test/DeviceVkTest.cpp b/src/Magnum/Vk/Test/DeviceVkTest.cpp index 1de614d5f..9d8e49dab 100644 --- a/src/Magnum/Vk/Test/DeviceVkTest.cpp +++ b/src/Magnum/Vk/Test/DeviceVkTest.cpp @@ -159,8 +159,13 @@ struct { Containers::Array args; const char* log; } ConstructWorkaroundsCommandLineData[] { - {"default", false, nullptr, - "Device: {}, Vulkan {}.{}{}\n" + {"default", false, + Containers::array({"", + /* Have to force version to 1.0 because on 1.1 SwiftShader requires + the "swiftshader-crashy-getdevicequeue2" workaround, they can't + be all disabled */ + "--magnum-vulkan-version", "1.0"}), + "Device: {}, Vulkan 1.0\n" "Device driver: {}, {}\n" "Using device driver workarounds:\n" " swiftshader-image-copy-extent-instead-of-layers\n" @@ -172,8 +177,12 @@ struct { ""}, {"disabled workarounds", true, Containers::array({"", + /* Have to force version to 1.0 because on 1.1 SwiftShader requires + the "swiftshader-crashy-getdevicequeue2" workaround, they can't + be all disabled */ + "--magnum-vulkan-version", "1.0", "--magnum-disable-workarounds", "swiftshader-image-copy-extent-instead-of-layers swiftshader-spirv-multi-entrypoint-conflicting-locations"}), - "Device: {}, Vulkan {}.{}{}\n" + "Device: {}, Vulkan 1.0\n" "Device driver: {}, {}\n"} }; @@ -872,13 +881,7 @@ void DeviceVkTest::constructWorkaroundsCommandLineDisable() { }; CORRADE_VERIFY(device.handle()); - - /** @todo cleanup when Debug::toString() or some similar utility exists */ - UnsignedInt major = versionMajor(deviceProperties.version()); - UnsignedInt minor = versionMinor(deviceProperties.version()); - UnsignedInt patch = versionPatch(deviceProperties.version()); - /* SwiftShader reports just 1.1 with no patch version, special-case that */ - CORRADE_COMPARE(out.str(), Utility::formatString(data.log, deviceProperties.name(), major, minor, patch ? Utility::formatString(".{}", patch) : "", deviceProperties.driverName(), deviceProperties.driverInfo())); + CORRADE_COMPARE(out.str(), Utility::formatString(data.log, deviceProperties.name(), deviceProperties.driverName(), deviceProperties.driverInfo())); } void DeviceVkTest::constructMultipleQueues() {