Skip to content

Commit eefbee0

Browse files
committed
GPU Vulkan Display: Improve requesting device features
1 parent 5b7951f commit eefbee0

2 files changed

Lines changed: 25 additions & 9 deletions

File tree

‎GPU/GPUTracking/display/backend/GPUDisplayBackendVulkan.cxx‎

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -273,13 +273,29 @@ static inline void clearVector(T& v, S func, bool downsize = true)
273273

274274
// ---------------------------- VULKAN DEVICE MANAGEMENT ----------------------------
275275

276-
double GPUDisplayBackendVulkan::checkDevice(vk::PhysicalDevice device, const std::vector<const char*>& reqDeviceExtensions, bool silent)
276+
static bool hasFeatures(const vk::PhysicalDeviceFeatures& available, const vk::PhysicalDeviceFeatures& required) // The struct consists only of VkBool32 members
277+
{
278+
static_assert(sizeof(vk::PhysicalDeviceFeatures) % sizeof(vk::Bool32) == 0);
279+
const vk::Bool32* a = reinterpret_cast<const vk::Bool32*>(&available);
280+
const vk::Bool32* r = reinterpret_cast<const vk::Bool32*>(&required);
281+
for (size_t i = 0; i < sizeof(vk::PhysicalDeviceFeatures) / sizeof(vk::Bool32); i++) {
282+
if (r[i] && !a[i]) {
283+
return false;
284+
}
285+
}
286+
return true;
287+
}
288+
289+
double GPUDisplayBackendVulkan::checkDevice(vk::PhysicalDevice device, const std::vector<const char*>& reqDeviceExtensions, const vk::PhysicalDeviceFeatures& reqDeviceFeatures, bool silent)
277290
{
278291
double score = -1.;
279292
vk::PhysicalDeviceProperties deviceProperties = device.getProperties();
280293
vk::PhysicalDeviceFeatures deviceFeatures = device.getFeatures();
281294
vk::PhysicalDeviceMemoryProperties memoryProperties = device.getMemoryProperties();
282-
if (!deviceFeatures.geometryShader || !deviceFeatures.wideLines || !deviceFeatures.largePoints) {
295+
if (!hasFeatures(deviceFeatures, reqDeviceFeatures)) {
296+
if (!silent) {
297+
GPUInfo("%s ignored due to missing features", &deviceProperties.deviceName[0]);
298+
}
283299
return (-1);
284300
}
285301

@@ -431,8 +447,9 @@ void GPUDisplayBackendVulkan::createDevice()
431447
throw std::runtime_error("Frontend does not provide Vulkan surface");
432448
}
433449

434-
const std::vector<const char*> reqDeviceExtensions = {
435-
VK_KHR_SWAPCHAIN_EXTENSION_NAME};
450+
const std::vector<const char*> reqDeviceExtensions = {VK_KHR_SWAPCHAIN_EXTENSION_NAME};
451+
vk::PhysicalDeviceFeatures reqDeviceFeatures{};
452+
reqDeviceFeatures.geometryShader = reqDeviceFeatures.wideLines = reqDeviceFeatures.largePoints = VK_TRUE;
436453

437454
mPhysicalDevice = VkPhysicalDevice(VK_NULL_HANDLE);
438455
std::vector<vk::PhysicalDevice> devices = mInstance.enumeratePhysicalDevices();
@@ -441,7 +458,7 @@ void GPUDisplayBackendVulkan::createDevice()
441458
}
442459
double bestScore = -1.;
443460
for (uint32_t i = 0; i < devices.size(); i++) {
444-
double score = checkDevice(devices[i], reqDeviceExtensions);
461+
double score = checkDevice(devices[i], reqDeviceExtensions, reqDeviceFeatures);
445462
if (mDisplay->GetProcessingSettings().debugLevel >= 2) {
446463
vk::PhysicalDeviceProperties deviceProperties = devices[i].getProperties();
447464
GPUInfo("Available Vulkan device %d: %s - Score %f", i, &deviceProperties.deviceName[0], score);
@@ -460,13 +477,12 @@ void GPUDisplayBackendVulkan::createDevice()
460477
if (!mPhysicalDevice) {
461478
throw std::runtime_error("All available Vulkan devices unsuited");
462479
}
463-
if (checkDevice(mPhysicalDevice, reqDeviceExtensions, true) <= 0) {
480+
if (checkDevice(mPhysicalDevice, reqDeviceExtensions, reqDeviceFeatures, true) <= 0) {
464481
throw std::runtime_error("Selected vulkan device is incompatible");
465482
}
466483

467484
updateSwapChainDetails(mPhysicalDevice);
468485
vk::PhysicalDeviceProperties deviceProperties = mPhysicalDevice.getProperties();
469-
vk::PhysicalDeviceFeatures deviceFeatures = mPhysicalDevice.getFeatures();
470486
vk::FormatProperties depth32FormatProperties = mPhysicalDevice.getFormatProperties(vk::Format::eD32Sfloat);
471487
vk::FormatProperties depth64FormatProperties = mPhysicalDevice.getFormatProperties(vk::Format::eD32SfloatS8Uint);
472488
GPUInfo("Using physical Vulkan device %s", &deviceProperties.deviceName[0]);
@@ -486,7 +502,7 @@ void GPUDisplayBackendVulkan::createDevice()
486502
vk::DeviceCreateInfo deviceCreateInfo{};
487503
deviceCreateInfo.pQueueCreateInfos = &queueCreateInfo;
488504
deviceCreateInfo.queueCreateInfoCount = 1;
489-
deviceCreateInfo.pEnabledFeatures = &deviceFeatures;
505+
deviceCreateInfo.pEnabledFeatures = &reqDeviceFeatures;
490506
deviceCreateInfo.enabledExtensionCount = static_cast<uint32_t>(reqDeviceExtensions.size());
491507
deviceCreateInfo.ppEnabledExtensionNames = reqDeviceExtensions.data();
492508
mDevice = mPhysicalDevice.createDevice(deviceCreateInfo, nullptr);

‎GPU/GPUTracking/display/backend/GPUDisplayBackendVulkan.h‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ class GPUDisplayBackendVulkan : public GPUDisplayBackend
8383
float getYFactor() const override { return -1.0f; }
8484
int32_t getMaxMSAA() const override { return mMaxMSAAsupported; }
8585

86-
double checkDevice(vk::PhysicalDevice device, const std::vector<const char*>& reqDeviceExtensions, bool silent = false);
86+
double checkDevice(vk::PhysicalDevice device, const std::vector<const char*>& reqDeviceExtensions, const vk::PhysicalDeviceFeatures& reqDeviceFeatures, bool silent = false);
8787
vk::Extent2D chooseSwapExtent(const vk::SurfaceCapabilitiesKHR& capabilities);
8888
void transitionImageLayout(vk::CommandBuffer commandBuffer, vk::Image image, vk::Format format, vk::ImageLayout oldLayout, vk::ImageLayout newLayout);
8989
VulkanBuffer createBuffer(size_t size, const void* srcData = nullptr, vk::BufferUsageFlags type = vk::BufferUsageFlagBits::eVertexBuffer, int32_t deviceMemory = 1);

0 commit comments

Comments
 (0)