Vulkan vkCreateInstance - расположение записи нарушения доступа 0x0000000000000000 - PullRequest
1 голос
/ 21 марта 2020

Я пытаюсь написать основную c программу с использованием Vulkan, но продолжаю получать ошибку времени выполнения.

Exception thrown at 0x00007FFDC27A8DBE (vulkan-1.dll) in VulkanTest.exe: 0xC0000005: Access violation writing location 0x0000000000000000.

Это, кажется, довольно распространенная проблема, возникающая в результате сбоя при инициализации аргументы функции vkCreateInstance. Я перепробовал все решения, которые я нашел, предложенные другим, даже инициализируя то, что, я уверен, мне не нужно, и я до сих пор не смог решить проблему. Программа написана на C с использованием компилятора MSV C.

#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;
}

1 Ответ

2 голосов
/ 21 марта 2020

Вы уверены, что звонок на vkCreateInstance() вызывает сбой? Я не пытался отлаживать код, который вы показали (это ваша работа), но просто глядя на вызовы, которые делает код, это должен быть вызов vkEnumerateInstanceExtensionProperties(), который дает сбой (если он вообще компилируется! ).

2-й параметр vkEnumerateInstanceExtensionProperties() ожидает указатель uint32_t*, но вы передаете значение uint32_t (VulkanCreateInfo.enabledExtensionCount), которое было инициализировано равным 0. Таким образом, это сделает Параметр pPropertyCount будет указателем NULL (если он даже компилируется).

Вы передаете VulkanCreateInfo.ppEnabledExtensionNames в 3-м параметре (если он даже компилируется), и ppEnabledExtensionNames был инициализирован в NULL. Согласно документации для vkEnumerateInstanceExtensionProperties():

Если pProperties равен NULL, то число доступных свойств расширений возвращается в pPropertyCount. В противном случае pPropertyCount должен указывать на переменную, установленную пользователем на количество элементов в массиве pProperties, а при возврате переменная перезаписывается с количеством структур, фактически записанным в pProperties .

Поскольку pPropertCount имеет значение NULL, vkEnumerateInstanceExtensionProperties() некуда записать счетчик свойств! Это, безусловно, приведет к нарушению прав доступа при попытке записи по адресу 0x0000000000000000.

Документация очищает состояния:

pPropertyCount должно быть действительным указателем на uint32_t значение

Кроме того, ваш вызов vkEnumerateInstanceExtensionProperties() в любом случае просто логически неверен, поскольку третий параметр ожидает указатель на массив структур VkExtensionProperties, но VulkanCreateInfo.ppEnabledExtensionNames это указатель на массив const char* строк UTF-8 вместо этого.

Другими словами, вам не следует использовать vkEnumerateInstanceExtensionProperties() для инициализации критериев вызова vkCreateInstance(). Вы совершенно неправильно используете vkEnumerateInstanceExtensionProperties(). Вы, вероятно, хотели использовать SDL_Vulkan_GetInstanceExtensions() вместо этого, например:

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);
...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...