Remove requirement for memory_priority extension

This commit is contained in:
Bailey Harrison 2023-03-20 14:25:22 +00:00
parent 36727d8d5e
commit 3bf0f1511e
4 changed files with 76 additions and 14 deletions

View File

@ -3,6 +3,7 @@
#include "resource_manager.hpp"
#include "gfx.hpp"
#include "gfx_device.hpp"
#include <glm/mat4x4.hpp>

View File

@ -559,10 +559,10 @@ namespace engine {
};
DeviceRequirements deviceRequirements{};
deviceRequirements.requiredExtensions = { VK_KHR_SWAPCHAIN_EXTENSION_NAME, VK_EXT_MEMORY_PRIORITY_EXTENSION_NAME };
deviceRequirements.requiredExtensions = { VK_KHR_SWAPCHAIN_EXTENSION_NAME };
deviceRequirements.optionalExtensions = { VK_EXT_MEMORY_PRIORITY_EXTENSION_NAME };
deviceRequirements.requiredFeatures.samplerAnisotropy = VK_TRUE;
deviceRequirements.requiredFeatures.fillModeNonSolid = VK_TRUE;
deviceRequirements.memoryPriorityFeature = VK_TRUE;
deviceRequirements.formats.push_back(
FormatRequirements{
.format = VK_FORMAT_R8G8B8A8_SRGB,
@ -678,7 +678,7 @@ namespace engine {
/* create a global descriptor pool */
std::vector<VkDescriptorPoolSize> poolSizes{};
poolSizes.emplace_back(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 100); // purposely low limit
poolSizes.emplace_back(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 100u); // purposely low limit
VkDescriptorPoolCreateInfo descriptorPoolInfo{};
descriptorPoolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
@ -740,12 +740,15 @@ namespace engine {
res = vkResetFences(pimpl->device.device, 1, &frameData.renderFence);
VKCHECK(res);
if (pimpl->device.queues.transferQueues.size() < 2) throw std::runtime_error("Need at least 2 transfer queues!");
uint32_t transferQueueIndex = 0;
if (pimpl->device.queues.transferQueues.size() >= 2) {
transferQueueIndex = 1;
}
/* first empty the descriptor buffer write queue */
auto& writeQueue = pimpl->descriptorBufferWriteQueues[currentFrameIndex];
if (writeQueue.empty() == false) {
LOG_TRACE("write queue size: {}", writeQueue.size());
// LOG_TRACE("write queue size: {}", writeQueue.size());
// vkQueueWaitIdle(pimpl->device.queues.drawQueues[0]);
}
for (gfx::DescriptorBuffer* buffer : writeQueue) {
@ -761,7 +764,7 @@ namespace engine {
res = vkAllocateCommandBuffers(pimpl->device.device, &allocInfo, &commandBuffer);
assert(res == VK_SUCCESS);
LOG_TRACE(" write command buffer: {}", (void*)commandBuffer);
// LOG_TRACE(" write command buffer: {}", (void*)commandBuffer);
VkCommandBufferBeginInfo beginInfo{};
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
@ -813,7 +816,7 @@ namespace engine {
submitInfo.waitSemaphoreCount = 0;
submitInfo.pWaitSemaphores = nullptr;
res = vkQueueSubmit(pimpl->device.queues.transferQueues[1], 1, &submitInfo, VK_NULL_HANDLE);
res = vkQueueSubmit(pimpl->device.queues.transferQueues[transferQueueIndex], 1, &submitInfo, VK_NULL_HANDLE);
assert(res == VK_SUCCESS);
}

View File

@ -37,16 +37,24 @@ namespace engine {
res = vkEnumeratePhysicalDevices(instance, &physDeviceCount, physicalDevices.data());
assert(res == VK_SUCCESS);
std::vector<VkExtensionProperties> availableExtensions{};
for (VkPhysicalDevice physDev : physicalDevices) {
// first, check extension support
availableExtensions.clear();
uint32_t extensionCount;
res = vkEnumerateDeviceExtensionProperties(physDev, nullptr, &extensionCount, nullptr);
assert(res == VK_SUCCESS);
availableExtensions.resize(extensionCount);
std::vector<VkExtensionProperties> availableExtensions(extensionCount);
res = vkEnumerateDeviceExtensionProperties(physDev, nullptr, &extensionCount, availableExtensions.data());
assert(res == VK_SUCCESS);
for (const VkExtensionProperties& ext : availableExtensions) {
LOG_TRACE("extension: {}", ext.extensionName);
}
bool foundRequiredExtensions = true;
for (const char* extToFind : requirements.requiredExtensions) {
bool extFound = false;
@ -190,8 +198,40 @@ namespace engine {
if (requirements.requiredFeatures.inheritedQueries == VK_TRUE)
if (devFeatures.features.inheritedQueries == VK_FALSE) continue;
if (requirements.memoryPriorityFeature == VK_TRUE)
if (memoryPriorityFeatures.memoryPriority == VK_FALSE) continue;
/* check the memory priority extension was even requested */
bool memoryPriorityRequired = false;
for (const char* ext : requirements.requiredExtensions) {
if (strcmp(ext, VK_EXT_MEMORY_PRIORITY_EXTENSION_NAME) == 0) {
memoryPriorityRequired = true;
break;
}
}
if (memoryPriorityRequired) {
if (memoryPriorityFeatures.memoryPriority == VK_FALSE) {
throw std::runtime_error("Required device feature 'memoryPriority' not found, but extension was");
} else {
d.memoryPriorityFeature = true;
}
} else {
// see if memoryPriority was optionally requested */
for (const char* optExt : requirements.optionalExtensions) {
if (strcmp(optExt, VK_EXT_MEMORY_PRIORITY_EXTENSION_NAME) == 0) {
for (const VkExtensionProperties& extAvail : availableExtensions) {
if (strcmp(extAvail.extensionName, VK_EXT_MEMORY_PRIORITY_EXTENSION_NAME) == 0) {
if (memoryPriorityFeatures.memoryPriority == VK_TRUE) {
d.memoryPriorityFeature = true;
} else {
throw std::runtime_error("Optional device extension 'VK_EXT_memory_priority' found, but feature wasn't");
}
break; // |
} // |
} // V
// <--------------------
break; // |
} // |
} // V
// <--------------------
}
}
bool formatsSupported = true;
@ -305,12 +345,22 @@ namespace engine {
/* set enabled features */
VkPhysicalDeviceMemoryPriorityFeaturesEXT memoryPriorityFeaturesToEnable{};
memoryPriorityFeaturesToEnable.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PRIORITY_FEATURES_EXT;
memoryPriorityFeaturesToEnable.memoryPriority = requirements.memoryPriorityFeature;
memoryPriorityFeaturesToEnable.memoryPriority = d.memoryPriorityFeature ? VK_TRUE : VK_FALSE;
VkPhysicalDeviceFeatures2 featuresToEnable{};
featuresToEnable.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
featuresToEnable.pNext = &memoryPriorityFeaturesToEnable;
featuresToEnable.features = requirements.requiredFeatures;
/* get list of extensions to enable */
std::vector<const char*> extensionsToEnable{};
for (const VkExtensionProperties& availableExt : availableExtensions) {
if ( std::find(requirements.optionalExtensions.begin(), requirements.optionalExtensions.end(),
std::string(availableExt.extensionName)) != requirements.optionalExtensions.end()) {
extensionsToEnable.push_back(availableExt.extensionName);
}
}
extensionsToEnable.insert(extensionsToEnable.end(), requirements.requiredExtensions.begin(), requirements.requiredExtensions.end());
/* create device now */
VkDeviceCreateInfo deviceCreateInfo{
.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
@ -320,8 +370,8 @@ namespace engine {
.pQueueCreateInfos = queueCreateInfos.data(),
.enabledLayerCount = 0, // deprecated and ignored
.ppEnabledLayerNames = nullptr, // deprecated and ignored
.enabledExtensionCount = static_cast<uint32_t>(requirements.requiredExtensions.size()),
.ppEnabledExtensionNames = requirements.requiredExtensions.data(),
.enabledExtensionCount = static_cast<uint32_t>(extensionsToEnable.size()),
.ppEnabledExtensionNames = extensionsToEnable.data(),
.pEnabledFeatures = nullptr,
};
@ -332,6 +382,12 @@ namespace engine {
volkLoadDevice(d.device);
/* get list of extensions enabled */
d.enabledExtensions.clear();
for (const char* ext : extensionsToEnable) {
// must be copied into std::strings
d.enabledExtensions.emplace_back(ext);
}
if (transferFamily != graphicsFamily) {
vkGetDeviceQueue(d.device, graphicsFamily, 0, &d.queues.presentQueue);

View File

@ -1,6 +1,7 @@
#pragma once
#include <vector>
#include <string>
#include <volk.h>
@ -13,17 +14,18 @@ namespace engine {
struct DeviceRequirements {
std::vector<const char*> requiredExtensions;
std::vector<const char*> optionalExtensions;
VkPhysicalDeviceFeatures requiredFeatures;
VkBool32 memoryPriorityFeature;
std::vector<FormatRequirements> formats{};
};
struct Device {
VkDevice device = VK_NULL_HANDLE;
VkPhysicalDevice physicalDevice = VK_NULL_HANDLE;
std::vector<std::string> enabledExtensions{};
VkPhysicalDeviceProperties properties{};
VkPhysicalDeviceFeatures features{};
bool memoryPriorityFeature = false;
struct DeviceQueues {
VkQueue presentQueue = VK_NULL_HANDLE;
std::vector<VkQueue> drawQueues{};