I am trying to write a basic program using Vulkan, but I keep getting a runtime error.
Exception thrown at 0x00007FFDC27A8DBE (vulkan-1.dll) in VulkanTest.exe: 0xC0000005: Access violation writing location 0x0000000000000000.
This seems to be a relatively common issue, resulting from a failure to initialize the arguments of the vkCreateInstance function. I have tried all of the solutions I found proposed to others, even initializing things I am fairly certain I don't need to, and I still haven't been able to solve the problem. The program is written in C using the MSVC compiler.
#include "stdio.h"
#include "SDL.h"
#include "vulkan\vulkan.h"
#include "System.h"
int main(int argc, char *argv[])
{
//Initialize SDL
if (SDL_Init(SDL_INIT_EVERYTHING) < 0)
{
printf("Error");
}
printf("Success");
//Initialize Vulkan
VkInstance VulkanInstance;
VkApplicationInfo VulkanApplicationInfo;
VulkanApplicationInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
VulkanApplicationInfo.pNext = 0;
VulkanApplicationInfo.pApplicationName = "VulkanTest";
VulkanApplicationInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
VulkanApplicationInfo.pEngineName = "VulkanTest";
VulkanApplicationInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0);
VulkanApplicationInfo.apiVersion = VK_API_VERSION_1_0;
VkInstanceCreateInfo VulkanCreateInfo = {0,0,0,0,0,0,0,0};
VulkanCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
VulkanCreateInfo.pNext = 0;
VulkanCreateInfo.pApplicationInfo = &VulkanApplicationInfo;
VulkanCreateInfo.enabledLayerCount = 1;
VulkanCreateInfo.ppEnabledLayerNames = "VK_LAYER_KHRONOS_validation";
vkEnumerateInstanceExtensionProperties(0, VulkanCreateInfo.enabledExtensionCount,
VulkanCreateInfo.ppEnabledExtensionNames);
//Create Vulkan Instance
if(vkCreateInstance(&VulkanCreateInfo, 0, &VulkanInstance) != VK_SUCCESS)
{
printf("Vulkan instance was not created");
}
//Create SDL Window
SDL_Window* window;
window = SDL_CreateWindow("VulkanTest", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 0, 0, SDL_WINDOW_VULKAN || SDL_WINDOW_FULLSCREEN_DESKTOP);
SDL_Delay(10000);
return 0;
}
Are you sure the call to vkCreateInstance()
is what is crashing? I have not tried to debug the code you have shown (that is your job), but just looking at the calls that the code is making, it should be the call to vkEnumerateInstanceExtensionProperties()
that is crashing (if it even compiles at all!).
The 2nd parameter of vkEnumerateInstanceExtensionProperties()
expects a uint32_t*
pointer, but you are passing in a uint32_t
value (VulkanCreateInfo.enabledExtensionCount
) that has been initialized to 0. So, that would make the pPropertyCount
parameter be a NULL pointer (if it even compiles).
You are passing VulkanCreateInfo.ppEnabledExtensionNames
in the 3rd parameter (if that even compiles), and ppEnabledExtensionNames
has been initialized to NULL. Per the documentation for vkEnumerateInstanceExtensionProperties()
:
If
pProperties
is NULL, then the number of extensions properties available is returned inpPropertyCount
. Otherwise,pPropertyCount
must point to a variable set by the user to the number of elements in thepProperties
array, and on return the variable is overwritten with the number of structures actually written topProperties
.
Since pPropertCount
is NULL, vkEnumerateInstanceExtensionProperties()
has nowhere to write the property count to! That would certainly cause an Access Violation trying to write to address 0x0000000000000000.
The documentation clears states:
pPropertyCount
must be a valid pointer to auint32_t
value
On top of that, your call to vkEnumerateInstanceExtensionProperties()
is just logically wrong anyway, because the 3rd parameter expects a pointer to an array of VkExtensionProperties
structs, but VulkanCreateInfo.ppEnabledExtensionNames
is a pointer to an array of const char*
UTF-8 strings instead.
In other words, you should not be using vkEnumerateInstanceExtensionProperties()
to initialize criteria for the call to vkCreateInstance()
. You are completely misusing vkEnumerateInstanceExtensionProperties()
. You probably meant to use SDL_Vulkan_GetInstanceExtensions()
instead, eg:
uint32_t ExtensionCount = 0;
if (!SDL_Vulkan_GetInstanceExtensions(NULL, &ExtensionCount, NULL))
{
...
}
const char **ExtensionNames = (const char **) SDL_malloc(sizeof(const char *) * ExtensionCount);
if (!ExtensionNames)
{
...
}
if (!SDL_Vulkan_GetInstanceExtensions(NULL, &ExtensionCount, ExtensionNames))
{
SDL_free(ExtensionNames);
...
}
VulkanCreateInfo.enabledExtensionCount = ExtensionCount;
VulkanCreateInfo.ppEnabledExtensionNames = ExtensionNames;
if (vkCreateInstance(&VulkanCreateInfo, 0, &VulkanInstance) != VK_SUCCESS)
{
...
}
SDL_free(ExtensionNames);
...
User contributions licensed under CC BY-SA 3.0