AMD GPU Services 5.1.1
The AMD GPU Services (AGS) library provides game and application developers with the ability to query information about installed AMD GPUs and their driver, in …
The AMD GPU Services (AGS) library provides game and application developers with the ability to query information about installed AMD GPUs and their driver, in …
Due to architectural differences between Zen and our previous processor architecture, Bulldozer, developers need to take care when using the Windows® APIs for processor and core enumeration. …
The AMD GCN Vulkan extensions allow developers to get access to some additional functionalities offered by the GCN architecture which are not currently exposed in the Vulkan API. One of these is the ability to access the barycentric coordinates at the fragment-shader level.
Thanks (again!) Before we dive into a run over the release notes for the 1.0.2 release of Radeon GPU Profiler, we’d like to thank everyone …
Understanding the instruction-level capabilities of any processor is a worthwhile endeavour for any developer writing code for it, even if the instructions that get executed …
An important part of learning the Vulkan API – just like any other API – is to understand what types of objects are defined in it, what they represent and how they relate to each other. To help with this, we’ve created a diagram that shows all of the Vulkan objects and some of their relationships, especially the order in which you create one from another.
Summary In this blog post we are announcing the open-source availability of the Radeon™ ProRender renderer, an implementation of the Radeon ProRender API. We will give …
Introduction and thanks Effective GPU performance analysis is a more complex proposition for developers today than it ever has been, especially given developments in how …
TressFX 4 introduces a number of improvements. This blog post focuses on three of these, all of which are tied to simulation: Bone-based skinning Signed distance …
Full application control over GPU memory is one of the major differentiating features of the newer explicit graphics APIs such as Vulkan® and Direct3D® 12. …
We are excited to announce the release of Compressonator V2.6. This version contains several new features and optimizations, including: Adaptive Format Conversion for general transcoding operations …
When getting a new piece of hardware, the first step is to install the driver. You can see how to install them for the Radeon …
In this blog we will go through the installation process of the driver for your new Radeon Vega Frontier card. We will go through the …
When using a compute shader, it is important to consider the impact of thread group size on performance. Limited register space, memory latency and SIMD occupancy each affect shader performance in different ways. This article discusses potential performance issues, and techniques and optimizations that can dramatically increase performance if correctly applied.
The AMD Developer Tools team is thrilled to announce the availability of the AMD plugin for Microsoft’s PIX for Windows tool. PIX is a performance …
A new version of the CodeXL open-source developer tool is out! Here are the major new features in this release: CPU Profiling Support for AMD …
When it comes to multi-GPU (mGPU), most developers immediately think of complicated Crossfire setups with two or more GPUs and how to make their game …
Introduction Shortly after our Capsaicin and Cream event at GDC this year where we unveiled Radeon RX Vega, we hosted a developer-focused event designed to …
BC6 HDR Compression The BC6H codec has been improved and now offers better quality then previous releases, along with support for both 16 bit Half …
This article explains how to use Radeon GPU Analyzer (RGA) to produce a live VGPR analysis report for your shaders and kernels. Basic RGA usage …
I’m Mike Schmit, Director of Software Engineering with the Radeon Technologies Group at AMD. I’m leading the development of a new open-source 360-degree video-stitching framework …
AMD LiquidVR MultiView Rendering in Serious Sam VR with the GPU Services (AGS) Library AMD’s MultiView Rendering feature reduces the number of duplicated object draw …
In 2016, AMD brought TrueAudio Next to GameSoundCon. GameSoundCon was held Sept 27-28 at the Millennium Biltmore Hotel in Los Angeles. GameSoundCon caters to game …
Budgeting, measuring and debugging video memory usage is essential for the successful release of game titles on Windows. As a developer, this can be efficiently achieved with the …
Another year, another Game Developer Conference! GDC is held earlier this year (27 February – 3 March 2017) which is leaving even less time for …
With the launch of AGS 5.0 developers now have access to the shader compiler control API. Here’s a quick summary of the how and why…. Background …
There are many games out there taking place in vast environments. The basic building block of every environment is height-field based terrain – there’s no …
Understanding concurrency (and what breaks it) is extremely important when optimizing for modern GPUs. Modern APIs like DirectX® 12 or Vulkan™ provide the ability to …
Summary Many Gaming and workstation laptops are available with both (1) integrated power saving and (2) discrete high performance graphics devices. Unfortunately, 3D intensive application …
This post is taking a look at some of the interesting bits of helping id Software with their DOOM® Vulkan™ effort, from the perspective of …
This blog is guest authored by Croteam developer Karlo Jez and he will be giving us a detailed look at how Affinity Multi-GPU support was …
When opening a 64-bit crash dump you will find that you will not necessarily get a sensible call stack. This is because 64-bit crash dumps …
Vulkan™’s barrier system is unique as it not only requires you to provide what resources are transitioning, but also specify a source and destination pipeline …
This is the third post in the follow up series to my prior GDC talk on Variable Dynamic Range. Prior posts covered dithering, today’s topic …
Virtual desktop infrastructure systems and cloud gaming are increasingly gaining popularity thanks to an ever more improved internet infrastructure. This gives more flexibility to the …
As noted in my previous blog, new innovations in virtual reality have spearheaded a renewed interest in audio processing, and many new as well as …
This week marks the last in the series of our regular Warhammer Wednesday blog posts. We’d like to extent our thanks to Creative Assembly’s Lead …
Audio Must be Consistent With What You See Virtual reality demands a new way of thinking about audio processing. In the many years of history …
Happy Warhammer Wednesday! This week Creative Assembly’s Lead Graphics Programmer Tamas Rabel talks about how Total War: Warhammer utilized asynchronous compute to extract some extra …
It’s Wednesday, so we’re continuing with our series on Total War: Warhammer. Here’s Tamas Rabel again with some juicy details about how Creative Assembly brought …
A new release of the CodeXL open-source developer tool is out! Here’s the hot new stuff in this release: New platforms support Support Linux systems …
We’re back again on this fine Warhammer Wednesday with more from Tamas Rabel, Lead Graphics Programmer on the Total War series. In last week’s post …
For the next few weeks we’ll be having a regular feature on GPUOpen that we’ve affectionately dubbed “Warhammer Wednesdays”. We’re extremely lucky to have Tamas Rabel, …
Game engines do most of their shading work per-pixel or per-fragment. But there is another alternative that has been popular in film for decades: object …
EDIT: 2016/08/08 – Added section on Targeting Low-Memory GPUs This post serves as a guide on how to best use the various Memory Heaps and …
Before Direct3D® 12 and Vulkan™, resources were bound to shaders through a “slot” system. Some of you might remember when hardware did have only very …
Multi-GPU systems are much more common than you might think. Most of the time, when someone mentions mGPU, you think about high-end gaming machines with …
Compressonator is a set of tools to allow artists and developers to more easily create compressed texture image assets and easily visualize the quality impact …
Prior to explicit graphics APIs a lot of draw-time validation was performed to ensure that resources were synchronized and everything set up correctly. A side-effect of this robustness …
Direct3D® 12 and Vulkan™ significantly reduce CPU overhead and provide new tools to better use the GPU. For instance, one common use case for the …
As promised, we’re back and today I’m going to cover how to get resources to and from the GPU. In the last post, we learned …
A new CodeXL release is out! For the first time the AMD Developer Tools group worked on this release on the CodeXL GitHub public repository, …
Today, we are excited to announce that we are releasing an update for ShadowFX that adds support for DirectX® 12. Features Different shadowing modes Union of …
Achieving high performance from your Graphics or GPU Compute applications can sometimes be a difficult task. There are many things that a shader or kernel …
The GCN architecture contains a lot of functionality in the shader cores which is not currently exposed in current APIs like Vulkan™ or Direct3D® 12. One …
A Complete Tool to Transform Your Desktop Appearance After introducing our Display Output Post Processing (DOPP) technology, we are introducing a new tool to change …
Compaction is a basic building block of many algorithms – for instance, filtering out invisible triangles as seen in Optimizing the Graphics Pipeline with Compute. …
We are releasing TressFX 3.1. Our biggest update in this release is a new order-independent transparency (OIT) option we call “ShortCut”. We’ve also addressed some of …
Today’s update for GeometryFX introduces cluster culling. Previously, GeometryFX worked on a per-triangle level only. With cluster culling, GeometryFX is able to reject large chunks …
Full-speed, out-of-order rasterization If you’re familiar with graphics APIs, you’re certainly aware of the API ordering guarantees. At their core, these guarantees mean that if …
A New Milestone After the success of the first version, FireRays is moving to another major milestone. We are open sourcing the entire library which …
Last week, we organized a two hours-long talk at University of Lodz in Poland where we discussed the most common mistakes we come across in Vulkan applications. Dominik Witczak, …
We are very pleased to be announcing that AMD is open-sourcing one of our most popular tools and SDKs. Compressonator (previously released as AMD Compress …
Gaming at optimal performance and quality at high screen resolutions can sometimes be a demanding task for a single GPU. 4K monitors are becoming mainstream and gamers …
If you have supported Crossfire™ or Eyefinity™ in your previous titles, then you have probably already used our AMD GPU Services (AGS) library. A lot of …
Resource creation and management has changed dramatically in Direct3D® and Vulkan™ compared to previous APIs. In older APIs, memory is managed transparently by the driver. …
CodeXL major release 2.0 is out! It is chock-full of new features and a drastic change in the CodeXL development model: CodeXL is now open …
The prior post in this series established a base technique for adding grain, and now this post is going to look at very subtle changes to …
Welcome back to our performance & optimization series. Today, we’ll be looking more closely at shaders. On the surface, it may look as if they …
This is the first of a series of posts expanding on the ideas presented at GDC in the Advanced Techniques and Optimization of VDR Color …
The Game Developer Conference 2016 was an event of epic proportions. Presentations, tutorials, round-tables, and the show floor are only one part of the story …
This post describes how GCN hardware coalesces memory operations to minimize traffic throughout the memory hierarchy. The post uses the term “invocation” to describe one …
Bandwidth is always a scarce resource on a GPU. On one hand, hardware has made dramatic improvements with the introduction of ever faster memory standards …
Vulkan™ provides unprecedented control to developers over generating graphics and compute workloads for a wide range of hardware, from tiny embedded processors to high-end workstation GPUs with wildly different …
The Game Developer Conference 2016 (GDC16) is held March 14-18 in the Moscone Center in San Francisco. This is the most important event for game developers, …
Welcome back to our DX12 series! Let’s dive into one of the hottest topics right away: synchronization, that is, barriers and fences! Barriers A barrier is …
Vulkan™ is a high performance, low overhead graphics API designed to allow advanced applications to drive modern GPUs to their fullest capacity. Where traditional APIs …
Imagine that you were asked one day to design an API with bleeding-edge graphics hardware in mind. It would need to be as efficient as …
Hello and welcome to our series of blog posts covering performance advice for Direct3D® 12 & Vulkan™. You may have seen the #DX12PerfTweets on Twitter, and …
For GPU-side dynamically generated data structures which need 3D spherical mappings, two of the most useful mappings are cubemaps and octahedral maps. This post explores …
I have met enough game developers in my professional life to know that these guys are among the smartest people on the planet. Those particular individuals will go …
About CodeXL Analyzer CLI CodeXL Analyzer CLI is an offline compiler and performance analysis tool for OpenCL™ kernels, DirectX® shaders and OpenGL® shaders. Using CodeXL …
GPU PerfStudio supports DirectX® 12 on Windows® 10 PCs. The current tool set for DirectX 12 comprises of an API Trace, a new GPU Trace …
Today we’re going to take a look at how asynchronous compute can help you to get the maximum out of a GPU. I’ll be explaining …
What’s New With the recent adoption of new APIs such as DirectX® 12 and Vulkan™, we are seeing renewed interest in an older tool. AMD …
A typical problem with MSAA Resolve mixed with HDR is that a single sample with a large HDR value can over-power all other samples, resulting …
Vulkan™ provides unprecedented control to developers over generating graphics and compute workloads for a wide range of hardware, from tiny embedded processors to high-end workstation GPUs with wildly different architectures. As usual, with great power comes great responsibility, and making sure that your application runs correctly on all these possible target platforms it is crucial to follow all the rules of the API specification even if some level of violation of these rules, either intentional or accidental, seem to not cause any issues on a particular hardware and driver implementation.
Traditional graphics APIs try to solve this issue by defining a set of illegal API usage conditions that are required to be caught by driver implementations and reported to the application through some sort of error reporting mechanism. The problem with this approach is that even though these errors generated in response to incorrect API usage are extremely valuable during the development of an application, checking for all of these error conditions costs significant CPU time spent in the driver that provides no value when running a released application that is known to use the API correctly. Not to mention the fact that practice reveals some driver implementations are less pedantic about certain rules established by the API specifications than others, and thus relying on testing on a particular implementation and observing no problems could still lead to portability issues when the same application is ran against other driver implementations.
Unlike traditional graphics APIs, Vulkan groups possible error scenarios into two distinct buckets:
While many of the Vulkan API commands do return a result code in the form of one of the constants of the VkResult
enumeration, these result codes are only used to indicate run-time errors and status information about certain operations or objects, but do not report information about respecting valid usage conditions. This allows release builds of applications to run at maximum performance because the driver implementations don’t have to spend precious CPU cycles on checking for the potential violation of specification rules as that’s anyways unnecessary in case of applications that are known to use the API correctly.
As driver implementations aren’t checking valid usage conditions and expect that all inputs coming from the application to be valid according to the specification, running applications that use the API incorrectly may result in unexpected behavior, including corrupted rendering or even application crashes. Often the consequences of passing invalid parameters to an API command might only manifest when executing latter commands.
We already acknowledged that not having to check for valid API usage for release builds of applications that are known to behave correctly from the point of view of the Vulkan API specification has great benefits, but it’s still very important to be able to identify incorrect API usage during the development of an application because finding the mistake we made that results in the weird corruption we see or the mysterious crash we can’t explain is not trivial to debug without a hint about where we should look for the error.
In order to provide a solution for this, Vulkan comes with a set of validation and debug layers as part of the Vulkan SDK. At the time of writing the SDK includes almost a dozen layers dedicated for validating certain aspects of API usage and providing debugging tools to developers like an API call dumper. When any subset of these layers are enabled they insert themselves automatically into the call-chain of every Vulkan API call issued by the application to perform their job. A detailed description of the individual layers is outside of the scope of this article but curious readers can find more information here.
The benefit of validation layers compared to the approach taken by traditional APIs is that applications only have to spend time on extensive error checking when explicitly requested, during development and typically when using debug builds of the application. This fits naturally in the general pay for what you use principle of the Vulkan API. Additionally, as the official validation layers coming with the SDK are maintained centrally and work equivalently across driver implementations, this approach doesn’t suffer from the fragmentation issues often seen in the error checking behavior of traditional APIs thus developers can be confident that the same validation errors are going to be reported in all cases, indifferent of the driver implementation the application is ran against.
What’s even better, the validation layers aren’t just looking for violations of the allowed API usage, but can also report warnings about potential incorrect or dangerous use of the API, and are even capable of reporting performance warnings that allow developers to identify places where the API is used correctly but isn’t used in the most efficient way. Examples of such potential performance warnings are binding resources that aren’t actually used or using a sub-optimal layout for an image.
Application developers willing to validate their API usage during development are going to be primarily interested in VK_LAYER_LUNARG_standard_validation
that bulks all standard validation layers in a big meta-layer. Enabling this layer ensures that all official validation layers will going to be keen on trying to catch any mistake the application makes in the use of Vulkan. In order to report the caught violations of valid API usage to the application the validation layers expose the VK_EXT_debug_report
instance extension that allows feeding the detected validation errors and warnings to application-provided callbacks. We are going to present the basic usage of this extension in this article but more information is available in the Vulkan Registry.
We recommend that all applications should enable and use the validation layers in their debug builds in order to make sure their applications are always respecting valid API usage and thus are going to be portable across the wide range of Vulkan driver implementations.
The following code snippet shows a typical C++ example of how applications should enable the VK_LAYER_LUNARG_standard_validation
layer and the VK_EXT_debug_report
extension at instance creation time in their debug builds:
std::vector enabledInstanceLayers;
std::vector enabledInstanceExtensions;
#ifdef MY_DEBUG_BUILD_MACRO
/* Enable validation layers in debug builds to detect validation errors */
enabledInstanceLayers.push_back("VK_LAYER_LUNARG_standard_validation");
#endif
/* Enable instance extensions used in all build types */
enabledInstanceExtensions.push_back("VK_KHR_surface");
...
#ifdef MY_DEBUG_BUILD_MACRO
/* Enable debug report extension in debug builds to be able to consume validation errors */
enabledInstanceExtensions.push_back("VK_EXT_debug_report");
#endif
/* Setup instance creation information */
VkInstanceCreateInfo instanceCreateInfo = {};
...
instanceCreateInfo.enabledLayerCount = static_cast<uint32_t>(enabledInstanceLayers.size());
instanceCreateInfo.ppEnabledLayerNames = &enabledInstanceLayers[0];
instanceCreateInfo.enabledExtensionCount = static_cast<uint32_t>(enabledInstanceExtensions.size());
instanceCreateInfo.ppEnabledExtensionNames = &enabledInstanceExtensions[0];
/* Create the instance */
VkInstance instance = VK_NULL_HANDLE;
VkResult result = vkCreateInstance(&instanceCreateInfo, nullptr, &instance);
Editor’s Note: Based on your input I’ve replaced the use of the NDEBUG
macro to indicate code that is meant to be built only in debug versions of the application and now the code examples refer to a custom macro called MY_DEBUG_BUILD_MACRO
that you should replace with the debug build macro used by your project or compiler toolchain.
Of course, a resilient application should first check for the presence of the used instance layers and extensions before passing them to vkCreateInstance
by using the vkEnumerateInstanceLayerProperties
and vkEnumerateInstanceExtensionProperties
commands, respectively. After a successful instance creation the validation layers are active for the instance and the debug report extension is available for use.
As the VK_EXT_debug_report
instance extension is not a core feature, the addresses of its entry points have to be acquired through the use of the vkGetInstanceProcAddr
command as shown in the code snippet below:
#ifdef MY_DEBUG_BUILD_MACRO
/* Load VK_EXT_debug_report entry points in debug builds */
PFN_vkCreateDebugReportCallbackEXT vkCreateDebugReportCallbackEXT =
reinterpret_cast<PFN_vkCreateDebugReportCallbackEXT>
(vkGetInstanceProcAddr(instance, "vkCreateDebugReportCallbackEXT"));
PFN_vkDebugReportMessageEXT vkDebugReportMessageEXT =
reinterpret_cast<PFN_vkDebugReportMessageEXT>
(vkGetInstanceProcAddr(instance, "vkDebugReportMessageEXT"));
PFN_vkDestroyDebugReportCallbackEXT vkDestroyDebugReportCallbackEXT =
reinterpret_cast<PFN_vkDestroyDebugReportCallbackEXT>
(vkGetInstanceProcAddr(instance, "vkDestroyDebugReportCallbackEXT"));
#endif
We’ll talk about each individual entry point of the extension separately, but first let’s take a look at how an application-provided debug report callback should look like and what behavior it should follow. The application can register any number of debug report callbacks, they only need to match the signature defined by PFN_vkDebugReportCallbackEXT
. A sample debug report callback that simply directs all incoming debug messages to stderr
is presented below:
VKAPI_ATTR VkBool32 VKAPI_CALL MyDebugReportCallback(
VkDebugReportFlagsEXT flags,
VkDebugReportObjectTypeEXT objectType,
uint64_t object,
size_t location,
int32_t messageCode,
const char* pLayerPrefix,
const char* pMessage,
void* pUserData)
{
std::cerr << pMessage << std::endl;
return VK_FALSE;
}
The parameters passed to the callback provide information about where and what type of validation event has triggered the call, like the type of the event (error, warning, performance warning, etc.), the type and handle of the object being created or manipulated by the command triggering the call, the code and text message describing the event, and there’s even a parameter to supply application-specific user data to the callback which is provided when registering the callback. By putting a breakpoint in the callback, developers can also have access to the complete callstack to more accurately determine the location of the offending API call.
The return value of the callback is a Boolean that indicates to the validation layers whether the API call that triggered the debug report callback should be aborted or not. However, developers have to be aware that in case an error is reported by one of the validation layers it’s an indication that something invalid was being attempted by the application thus any operation following the error might result in undefined behavior or even a crash. As such, it’s advised that developers stop at the first error and try to resolve that before making any assumptions about the behavior of subsequent operations. Think about validation errors in the same way like errors reported by compilers: often subsequent errors are just consequences of the first one.
When registering our debug report callback, we can specify what type of events we want to get notification about. Typically we’re interested in errors, warnings, and performance warnings; the following code snipped registers our callback with such a configuration:
#ifdef MY_DEBUG_BUILD_MACRO
/* Setup callback creation information */
VkDebugReportCallbackCreateInfoEXT callbackCreateInfo;
callbackCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
callbackCreateInfo.pNext = nullptr;
callbackCreateInfo.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT |
VK_DEBUG_REPORT_WARNING_BIT_EXT |
VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT;
callbackCreateInfo.pfnCallback = &MyDebugReportCallback;
callbackCreateInfo.pUserData = nullptr;
/* Register the callback */
VkDebugReportCallbackEXT callback;
VkResult result = vkCreateDebugReportCallbackEXT(instance, &callbackCreateInfo, nullptr, &callback);
#endif
An already registered callback can then be unregistered by destroying the callback object just like any other API object using the corresponding destroy command, vkDestroyDebugReportCallbackEXT
. Developers should make sure to unregister their debug report callbacks before destroying the instance, otherwise they going to be notified about their misbehavior through any debug report callback that’s registered to receive errors.
The last remaining entry point of the debug report extension that we didn’t discuss yet, vkDebugReportMessageEXT
can be used to generate debug report messages from application code. This can be useful to mark certain points of the execution of the application or to report application specific information to the same stream where the validation messages are fed.
Update: Since version 1.0.13 of the Vulkan API specification and the Vulkan SDK device layers have been deprecated so the instructions related to enabling the validation layers at the device level have been removed accordingly.
The recommended way to validate an application is the approach presented so far, because it allows developers to enable validation based on the type of the build, as presented, based on some application setting, or through any other mechanism. Additionally, the debug report callback enables fine grained control over which validation events should be captured and how.
However, in some cases it’s possible that modifying or rebuilding the application to enable validation programatically is not viable or convenient. This includes cases like validating release builds of applications that don’t reproduce the issue in debug builds, or validating third-party applications or libraries that we cannot rebuild because of lack of access to the source code.
There’s a solution even for situations like this, as layers can also be enabled through the environment variable VK_INSTANCE_LAYERS
. This variable accepts a list of layer names to enable separated by semicolons (Windows) or colons (Linux). The following command enables all standard validation layers on Windows:
> set VK_INSTANCE_LAYERS=VK_LAYER_LUNARG_standard_validation
When enabling validation through this approach, besides setting the environment variable to activate the layers, the reporting mechanism must be configured for each layer via a settings file, otherwise the activated layers will produce no output. This settings file must be named vk_layer_settings.txt
and must be located in the working directory of the application or in the directory specified using the VK_LAYER_SETTINGS_PATH
environment variable. A sample layer settings file is provided as part of the Vulkan SDK under the config
folder which will simply output all error, warning, and performance warning messages to stdout
, if used, but can be easily changed to output a different subset of the validation messages and can be redirected to files instead of console output (which may be necessary to capture the output of applications without a console). The sample settings file contains instructions about how to change the various configuration options.
While getting familiar with the Vulkan API may seem a bit involving at the beginning, as due to its nature it has a steeper learning curve than traditional APIs, the validation layers make it much easier to catch any mistakes, and they also provide a lot of additional useful information beyond just reporting basic errors. While using the validation layers does not completely eliminate the need to test your application on multiple platforms, it minimizes the chances of any portability issues resulting from incorrect API usage.
In addition to that, the official loader and validation layers are all available open-source on Github. So in case you find any errors that aren’t currently caught by any of the validation layers then don’t hesitate: contribute!
Don’t forget: validate your application before the users validate it for you!
Other Vulkan related blogs on GPUOpen
there is type error
enabledInstanceExtensions.push_back(“VK_KHR_swapchain”);
should be
enabledDeviceExtensions.push_back(“VK_KHR_swapchain”);
That’s is what I needed ! The examples available today at GitHub are so messy and so big that miss entirely the point about validation !
Thanks for putting it in simple and direct way !
What library is the implementation of vkCreateDebugReportCallbackEXT(..)? I’m getting an unresolved external symbol error on that function when I add it to my program. My program is linking vulkan-1.lib
The implementation is part of the validation layer library (or any other library implementing VK_EXT_debug_report). You need to acquire those function pointers using vkGetInstanceProcAddr as shown in the post, you don’t link to those at build time.
I have the same problem.
Craig: the solution was in the article but escaped my notice too. You have to get the function pointers manually. Those function prototypes in vulkan.h are not for calling, apparently (nice bit of misdirection there)
/* Load VK_EXT_debug_report entry points in debug builds */
PFN_vkCreateDebugReportCallbackEXT vkCreateDebugReportCallbackEXT =
reinterpret_cast
(vkGetInstanceProcAddr(instance, “vkCreateDebugReportCallbackEXT”));
PFN_vkDebugReportMessageEXT vkDebugReportMessageEXT =
reinterpret_cast
(vkGetInstanceProcAddr(instance, “vkDebugReportMessageEXT”));
PFN_vkDestroyDebugReportCallbackEXT vkDestroyDebugReportCallbackEXT =
reinterpret_cast
(vkGetInstanceProcAddr(instance, “vkDestroyDebugReportCallbackEXT”));