No output from validation layers

At the point of creating an instance I have “VK_LAYER_LUNARG_standard_validation” as a layer in my Instance creation structure and “VK_EXT_debug_utils” in my extensions. I’ve got a valid debug messenger (copied verbatim from vulcan-tutorial). I just can’t get any output at all. I’ve tried everything. A lot of examples appear to be out of date quoting “VK_LAYER_KHRONOS_validation” as the validation layer however that is not available. my version is 1.2.148.1 which is only a few week old. I’m pretty sure I’ve not missed anything. I’ve tried several different ways to initiate an error but it just throws exceptions at that point. I’m basically going through the tutorial and so far I’m understanding it well, I have a genuine error later in my code that I need the validation layer to advise on but just can’t get them working. Please help.

You don’t have to configure the validation layer in your application, it is much easier to use the VK_INSTANCE_LAYERS environment variable, see the SDK page on layer configuration for details.

Also, VK_LAYER_KHRONOS_validation is the current validation layer and materials referencing VK_LAYER_LUNARG_standard_validation or even individual validation layers are the ones that are out of date :wink:

Hey there.
Try this: set up a debug callback for Vulkan debug messages:

VKAPI_ATTR VkBool32 VKAPI_CALL vulkan_debug_message_callback(VkDebugReportFlagsEXT flags,
                                                             VkDebugReportObjectTypeEXT object_type,
                                                             std::uint64_t object, std::size_t location,
                                                             std::int32_t message_code, const char *layer_prefix,
                                                             const char *message, void *user_data) {
    cout << message << endl;
    return VK_FALSE;
}

and set up the debug message callback like this:

VkDebugReportCallbackCreateInfoEXT debugReportCreateInfo = {};
debugReportCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT;
debugReportCreateInfo.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT;
debugReportCreateInfo.pfnCallback = (PFN_vkDebugReportCallbackEXT)debugMessageCallback;

// We have to explicitly load this function.
PFN_vkCreateDebugReportCallbackEXT vkCreateDebugReportCallbackEXT = reinterpret_cast<PFN_vkCreateDebugReportCallbackEXT>(vkGetInstanceProcAddr(instance, "vkCreateDebugReportCallbackEXT"));

assert(vkCreateDebugReportCallbackEXT);
assert(vkCreateDebugReportCallbackEXT(instance, &debugReportCreateInfo, nullptr, &debugReportCallback) == VK_SUCCESS);

But you must also make sure the instance extension is available:

void create_instance_extensions_cache() {
    // First ask Vulkan how many instance extensions are available on the system.
    if (vkEnumerateInstanceExtensionProperties(nullptr, &m_available_instance_extensions, nullptr) != VK_SUCCESS) {
        throw std::runtime_error("Error: vkEnumerateInstanceExtensionProperties failed!");
    }

    if (m_available_instance_extensions == 0) {
        // It should be a very rare case that no instance extensions are available at all. Still we have to consider
        // this!
        throw std::runtime_error("Error: No Vulkan instance extensions available!");
    } else {
        // Preallocate memory for extension properties.
        m_instance_extensions_cache.resize(m_available_instance_extensions);

        // Get the information about the available instance extensions.
        if (vkEnumerateInstanceExtensionProperties(nullptr, &m_available_instance_extensions,
                                                   m_instance_extensions_cache.data())) {
            throw std::runtime_error("Error: vkEnumerateInstanceExtensionProperties failed!");
        }
    }
}


bool has_instance_extension(const std::string &instance_extension_name) {
    assert(!instance_extension_name.empty());

    if (m_instance_extensions_cache.empty()) {
        create_instance_extensions_cache();
    }

    // Loop through all available instance extensions and search for the requested one.
    auto result =
        std::find_if(m_instance_extensions_cache.begin(), m_instance_extensions_cache.end(),
                     [&](const VkExtensionProperties &instance_extension) {
                         // Compare the name of the current instance extension with the requested one.
                         return (strcmp(instance_extension.extensionName, instance_extension_name.c_str()) == 0);
                     });

    // True if instance extension was found and is supported!
    return result != m_instance_extensions_cache.end();
}

So make sure you put the setup code in an if(has_instance_extension(VK_EXT_DEBUG_REPORT_EXTENSION_NAME)) {...} block.

Hope this helps.
Feel free to ask about the code.

best regards,
Johannes

Thanks y’all. I got this working. It’s strange but when I enumerated my layers originally VK_LAYER_KHRONOS_validation was not present. I updated to the newest SDK and now it is present.
Anyway I’m happy I’ve resolved my error and am cracking on with the triangle tutorial. Thanks for all your help.

Hey there,
nice to hear you got it working.
Adam Sawicki points our in his talk on youtube that you should update your Vulkan SDK, Graphics drivers and Windows/Platform SDK at least every month:

They contain so many changes and bug fixes…

best regards,
Johannes

Yes, but then there’s…

This serves to discourage devs and users from updating their graphics drivers very often. If this is not the behavior the vendors want, they really need to help solve this problem.

Or maybe developers could avoid having nearly 100,000 pipelines in the first place with different shader code among them. I thought deferred rendering and uber-shaders were supposed to eliminate this sort of explosion of shaders that need to be built.

Yes, the ideal scenario of having only a handful of different shaders is not going to happen in reality, but there’s a lot of room between 20 and 100,000. And all of those pipeline bindings during rendering can’t be good for performance.

I’m not sure why. On current GPUs, warp/wavefront occupancy drives the perf of many shaders, and that’s a function of register count incl interpolators. Having a bunch of code baked in that you’re not using is not a good idea. And deferred has its own set of problems.

(NOTE: Here I assume you mean ubershaders in the “one linked shader to rule them all” sense [dynamic branches based on uniforms)], not in the “unified shader source” iteratively compiled to produce many linked shaders sense [static branches based on constants]).