Расширение семафора временной шкалы Vulkan не может быть включено - PullRequest
0 голосов
/ 09 марта 2020

Я занимался этим в течение большей части сегодняшнего дня, и я нахожусь в конце своего ума.

Я использую Vulkan SDK 1.2.131.2

У меня есть RTX 2080 Ti.

У меня Windows 10 Образование, версия 1909, сборка 18363.657.

Я использую Vulkan.hpp вместо Vulkan.h напрямую.

Вот где я указываю версию API, которую я использую:

appInfo.apiVersion = VK_API_VERSION_1_2;

Это соответствующая часть кода, которая создает устройство:

// bla bla
const std::vector<const char*> deviceExtensions = {
    VK_KHR_SWAPCHAIN_EXTENSION_NAME,
    VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME,
    VK_NV_RAY_TRACING_EXTENSION_NAME
};

deviceCreateInfo.enabledExtensionCount = static_cast<uint32_t>(deviceExtensions.size());
deviceCreateInfo.ppEnabledExtensionNames = deviceExtensions.data();

m_logicalDevice = m_physicalDevice.createDeviceUnique(deviceCreateInfo);

Я использую следующие уровни проверки:

"VK_LAYER_LUNARG_api_dump"
"VK_LAYER_KHRONOS_validation"

Вот как я позже пытаюсь создать семафор временной шкалы:

vk::UniqueSemaphore VulkanContext::createTimelineSemaphore(const uint32_t initialValue) const {
    vk::SemaphoreTypeCreateInfo timelineCreateInfo;
    timelineCreateInfo.semaphoreType = vk::SemaphoreType::eTimeline;
    timelineCreateInfo.initialValue = initialValue;

    vk::SemaphoreCreateInfo createInfo;
    createInfo.pNext = &timelineCreateInfo;

    return m_logicalDevice->createSemaphoreUnique(createInfo);
}

Я получаю следующую ошибку:

vkCreateSemaphore(device, pCreateInfo, pAllocator, pSemaphore) returns VkResultVkCreateSemaphore: timelineSemaphore feature is not enabled, can not create timeline semaphores The Vulkan spec states: If the timelineSemaphore feature is not enabled, semaphoreType must not equal VK_SEMAPHORE_TYPE_TIMELINE (https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID-VkSemaphoreTypeCreateInfo-timelineSemaphore-03252)

Это еще более раздражает, потому что семафоры временной шкалы должны быть частью ядра Vulkan 1.2, но я получаю ту же ошибку, даже если опускаю ее из списка расширений. Расширение Swapchain работает, и у меня не было времени, чтобы проверить, включено ли расширение трассировки лучей.

Становится еще глупее, потому что следующее сообщение говорит мне:

VK_SUCCESS (0):
device:                         VkDevice = 0000023AA29BD8B0
pCreateInfo:                    const VkSemaphoreCreateInfo* = 0000008D145ED538:
    sType:                          VkStructureType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO (9)
    pNext:                          VkSemaphoreTypeCreateInfo = 0000008D145ED4F8:
        sType:                          VkStructureType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO (1000207002)
        pNext:                          const void* = NULL
        semaphoreType:                  VkSemaphoreType = VK_SEMAPHORE_TYPE_TIMELINE (1)
        initialValue:                   uint64_t = 0
    flags:                          VkSemaphoreCreateFlags = 0
pAllocator:                     const VkAllocationCallbacks* = NULL
pSemaphore:                     VkSemaphore* = AA989B000000001E

I понятия не имею, создает ли это семафор временной шкалы или просто создает обычный двоичный.

Когда я позже использую его для отправки в очередь передачи:

vk::CommandBufferBeginInfo beginInfo;
transferCmdBuffer->begin(beginInfo);
object->recordUploadToGPU(*transferCmdBuffer);
transferCmdBuffer->end();

vk::TimelineSemaphoreSubmitInfo timelineSubmitInfo;
timelineSubmitInfo.signalSemaphoreValueCount = 1;
timelineSubmitInfo.pSignalSemaphoreValues = &signalValue;

vk::SubmitInfo submitInfo;
submitInfo.pNext = &timelineSubmitInfo;
submitInfo.signalSemaphoreCount = 1;
submitInfo.pSignalSemaphores = &signalSemaphore;
submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = &*transferCmdBuffer;

vkCtx.m_transferQueue.submit(submitInfo, nullptr);

Я получаю эту ошибку здесь:

vkQueueSubmit(queue, submitCount, pSubmits, fence) returns VkResultVkQueueSubmit: VkQueue 0x23aa2539500[] contains timeline sempahore VkSemaphore 0xaa989b000000001e[] that sets its wait value with a margin greater than maxTimelineSemaphoreValueDifference The Vulkan spec states: For each element of pSignalSemaphores created with a VkSemaphoreType of VK_SEMAPHORE_TYPE_TIMELINE the corresponding element of VkTimelineSemaphoreSubmitInfo::pSignalSemaphoreValues must have a value which does not differ from the current value of the semaphore or the value of any outstanding semaphore wait or signal operation on that semaphore by more than maxTimelineSemaphoreValueDifference. (https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID-VkSubmitInfo-pSignalSemaphores-03244)

И просто для дальнейшей насмешки, это следующая строка:

VK_SUCCESS (0):
queue:                          VkQueue = 0000023AA2539500
submitCount:                    uint32_t = 1
pSubmits:                       const VkSubmitInfo* = 0000008D145ED370
    pSubmits[0]:                    const VkSubmitInfo = 0000008D145ED370:
        sType:                          VkStructureType = VK_STRUCTURE_TYPE_SUBMIT_INFO (4)
        pNext:                          VkTimelineSemaphoreSubmitInfo = 0000008D145ED318:
            sType:                          VkStructureType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO (1000207003)
            pNext:                          const void* = NULL
            waitSemaphoreValueCount:        uint32_t = 0
            pWaitSemaphoreValues:           const uint64_t* = NULL
            signalSemaphoreValueCount:      uint32_t = 1
            pSignalSemaphoreValues:         const uint64_t* = 0000008D145ED740
                pSignalSemaphoreValues[0]:      const uint64_t = 1
        waitSemaphoreCount:             uint32_t = 0
        pWaitSemaphores:                const VkSemaphore* = NULL
        pWaitDstStageMask:              const VkPipelineStageFlags* = NULL
        commandBufferCount:             uint32_t = 1
        pCommandBuffers:                const VkCommandBuffer* = 0000008D145EF408
            pCommandBuffers[0]:             const VkCommandBuffer = 0000023AA9CEC8E0
        signalSemaphoreCount:           uint32_t = 1
        pSignalSemaphores:              const VkSemaphore* = 0000008D145EF430
            pSignalSemaphores[0]:           const VkSemaphore = AA989B000000001E
fence:                          VkFence = 0000000000000000

Я также пробовал с VK_API_VERSION_1_1 и VK_API_VERSION_1_0, как с включением, так и без расширение явно, ни одно из них не работает.

Дампы из уровня проверки VK_LAYER_LUNARG_api_dump, в то время как уровень проверки VK_LAYER_KHRONOS_validation является тем, который извергает ошибки. Кажется, они не согласны.

Итак, что дает?

Чем я сегодня глуп?

РЕДАКТИРОВАТЬ:

Вот пример, который вы должен быть в состоянии запустить себя. Я думаю, что сделал это как можно меньше:

#include <vulkan/vulkan.hpp>
#include <iostream>

VKAPI_ATTR VkBool32 VKAPI_CALL debugCallback(
    VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
    VkDebugUtilsMessageTypeFlagsEXT messageType,
    const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,
    void* pUserData) {

    std::cerr << pCallbackData->pMessage << std::endl;

    return VK_FALSE;
};

int main() {
    vk::ApplicationInfo appInfo;
    appInfo.apiVersion = VK_API_VERSION_1_2;

    vk::InstanceCreateInfo instanceCreateInfo;
    instanceCreateInfo.pApplicationInfo = &appInfo;

    std::vector<const char*> extensions;

    extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);

    instanceCreateInfo.enabledExtensionCount = static_cast<uint32_t>(extensions.size());
    instanceCreateInfo.ppEnabledExtensionNames = extensions.data();

    const std::vector<const char*> validationLayers = {
        "VK_LAYER_LUNARG_api_dump",
        "VK_LAYER_KHRONOS_validation"
    };

    instanceCreateInfo.enabledLayerCount = static_cast<uint32_t>(validationLayers.size());
    instanceCreateInfo.ppEnabledLayerNames = validationLayers.data();

    vk::DebugUtilsMessengerCreateInfoEXT debugCreateInfo;
    debugCreateInfo.messageSeverity =
        vk::DebugUtilsMessageSeverityFlagBitsEXT::eInfo |
        vk::DebugUtilsMessageSeverityFlagBitsEXT::eVerbose |
        vk::DebugUtilsMessageSeverityFlagBitsEXT::eWarning |
        vk::DebugUtilsMessageSeverityFlagBitsEXT::eError;
    debugCreateInfo.messageType =
        vk::DebugUtilsMessageTypeFlagBitsEXT::eGeneral |
        vk::DebugUtilsMessageTypeFlagBitsEXT::eValidation |
        vk::DebugUtilsMessageTypeFlagBitsEXT::ePerformance;
    debugCreateInfo.pfnUserCallback = debugCallback;

    instanceCreateInfo.pNext = &debugCreateInfo;

    vk::Instance m_instance = vk::createInstance(instanceCreateInfo);
    vk::DispatchLoaderDynamic m_loader = vk::DispatchLoaderDynamic(m_instance, vkGetInstanceProcAddr);
    vk::DebugUtilsMessengerEXT m_debugMessenger = m_instance.createDebugUtilsMessengerEXT(debugCreateInfo, nullptr, m_loader);

    vk::PhysicalDevice m_physicalDevice = m_instance.enumeratePhysicalDevices()[0];

    std::vector<vk::DeviceQueueCreateInfo> queueCreateInfos;

    vk::DeviceQueueCreateInfo queueInfo;
    queueInfo.queueFamilyIndex = 0;
    queueInfo.queueCount = 1;
    queueCreateInfos.push_back(queueInfo);

    vk::PhysicalDeviceFeatures deviceFeatures;

    vk::DeviceCreateInfo deviceCreateInfo;
    deviceCreateInfo.pQueueCreateInfos = queueCreateInfos.data();
    deviceCreateInfo.queueCreateInfoCount = static_cast<uint32_t>(queueCreateInfos.size());
    deviceCreateInfo.pEnabledFeatures = &deviceFeatures;

    // This part can be omitted from here...
    const std::vector<const char*> deviceExtensions = {
        VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME
    };

    deviceCreateInfo.enabledExtensionCount = static_cast<uint32_t>(deviceExtensions.size());
    deviceCreateInfo.ppEnabledExtensionNames = deviceExtensions.data();
    // ...to here. It doesn't work either way.

    vk::Device m_logicalDevice = m_physicalDevice.createDevice(deviceCreateInfo);

    vk::SemaphoreTypeCreateInfo timelineCreateInfo;
    timelineCreateInfo.semaphoreType = vk::SemaphoreType::eTimeline;
    timelineCreateInfo.initialValue = 0;

    vk::SemaphoreCreateInfo semaphoreCreateInfo;
    semaphoreCreateInfo.pNext = &timelineCreateInfo;

    m_logicalDevice.createSemaphore(semaphoreCreateInfo);
}

1 Ответ

0 голосов
/ 09 марта 2020

Функция также должна быть включена явно:

vk::PhysicalDeviceTimelineSemaphoreFeatures timelineSemaphore;
timelineSemaphore.timelineSemaphore = true;

vk::PhysicalDeviceFeatures2 deviceFeatures;
deviceFeatures.pNext = &timelineSemaphore;

vk::DeviceCreateInfo deviceCreateInfo;
deviceCreateInfo.pNext = &deviceFeatures;
...