Значение указателя VkSurfaceKHR изменяется после вызова функции без каких-либо явных назначений - PullRequest
0 голосов
/ 26 января 2020

Это сокращенное сообщение об ошибке из проверочных слоев Vulkan

Invalid VkSurfaceKHR Object 0x1000000002.
Objects: 1
        [0] 0x1000000002, type: 1000000000, name: NULL

, выданное этой функцией

populateQueueFamilies(&physicalDevice, &queueFamilyIndicesList, &queueFamilyCount, &surface);

Теперь этого не должно произойти, потому что

populatePhysicalDevice(&instance, &physicalDevice, &surface);
populateQueueFamilies(&physicalDevice, &queueFamilyIndicesList, &queueFamilyCount, &surface);

функция до того, как она также использует переменную surface и не выдает никаких ошибок!

Я заглянул в некоторые функции печати, чтобы посмотреть, не так ли что-то с переменной, и вуаля


  printf("%p\n", surface); // prints - 0x10000000001

  populatePhysicalDevice(&instance, &physicalDevice, &surface);

  printf("%p\n", surface); // prints - 0x10000000002

  populateQueueFamilies(&physicalDevice, &queueFamilyIndicesList, &queueFamilyCount, &surface);

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

Но я не думаю, что это происходит здесь, потому что единственная функция, которая касается surface var внутри populateQueueFamilies, это вот это:

void populateSwapchainSupportDetails(SwapchainSupportDetails* gSwapchainSupportDetails,
                                     VkPhysicalDevice*        gPhysicalDevice,
                                     VkSurfaceKHR*            gSurface)
{

  VkSurfaceCapabilitiesKHR lCapabilities;
  uint32_t                 formatCount;
  uint32_t                 presentModeCount;

  vkGetPhysicalDeviceSurfaceCapabilitiesKHR(*gPhysicalDevice, *gSurface, &lCapabilities);

  uint32_t gFormatCount;
  vkGetPhysicalDeviceSurfaceFormatsKHR(*gPhysicalDevice, *gSurface, &gFormatCount, VK_NULL_HANDLE);

  VkSurfaceFormatKHR lFormats[gFormatCount];
  if (gFormatCount != 0)
    {
      vkGetPhysicalDeviceSurfaceFormatsKHR(*gPhysicalDevice, *gSurface, &gFormatCount, lFormats);
    }

  uint32_t gPresentModeCount;

  vkGetPhysicalDeviceSurfacePresentModesKHR(*gPhysicalDevice, *gSurface, &gPresentModeCount, VK_NULL_HANDLE);

  VkPresentModeKHR lPresentModes[gPresentModeCount];
  if (gPresentModeCount != 0)
    {
      vkGetPhysicalDeviceSurfacePresentModesKHR(
          *gPhysicalDevice, *gSurface, &gPresentModeCount, lPresentModes);
    }

  gSwapchainSupportDetails->capabilities     = lCapabilities;
  gSwapchainSupportDetails->formatCount      = gFormatCount;
  gSwapchainSupportDetails->presentModeCount = gPresentModeCount;

  gSwapchainSupportDetails->formats = malloc(sizeof(lFormats));
  memcpy(gSwapchainSupportDetails->formats, lFormats, sizeof(lFormats));

  gSwapchainSupportDetails->formats = malloc(sizeof(lPresentModes));
  memcpy(gSwapchainSupportDetails->formats, lPresentModes, sizeof(lPresentModes));

Есть временное исправление, которое работает:

VkSurfaceKHR surface1 = surface;
VkSurfaceKHR surface2 = surface;

и передача каждого surface(number) различным функциям.

1 Ответ

0 голосов
/ 27 января 2020

О, мальчик, это было интересное путешествие, которое закончилось тем, что я был полностью взорван; Проще говоря - отсутствие гениальности.

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

Я получил это с помощью valgrind.

Я запустил его с помощью этой команды

valgrind\
       --leak-check=full\
       --leak-resolution=high\
       --show-leak-kinds=all\
       --xtree-leak=yes\
       --track-origins=yes\
       --show-mismatched-frees=yes\

Это дало мне много сообщений, вот их сокращенная версия

Invalid write of size 8
    at <someaddress>: populateQueueFamilies ()
...
...
Invalid write of size 8
    at <someaddress>: populateQueueFamilies ()
...
...
Invalid write of size 8
    at <someaddress>: populateQueueFamilies ()
...
...

Неправильная запись означает, что я пишу в недопустимую область памяти. Гугл говорит мне, что сообщение об ошибке почти всегда возникает из-за неправильного использования malloc.

Это была моя populateQueueFamilies функция

void populateQueueFamilies(const VkPhysicalDevice* gPhysicalDevice,
                           const VkSurfaceKHR*     surface,
                           uint32_t*               gQueueFamilyCount,
                           QueueFamilyIndices**    gQueueFamilyIndicesList)
{

  uint32_t lQueueFamilyCount;
  vkGetPhysicalDeviceQueueFamilyProperties(*gPhysicalDevice, &lQueueFamilyCount, VK_NULL_HANDLE);

  VkQueueFamilyProperties lQueueFamilies[lQueueFamilyCount];
  vkGetPhysicalDeviceQueueFamilyProperties(*gPhysicalDevice, &lQueueFamilyCount, lQueueFamilies);

  VkBool32 presentFamilySupported;

  (*gQueueFamilyIndicesList) = malloc(sizeof(*lQueueFamilies) * lQueueFamilyCount);

  for (int i = 0; i < lQueueFamilyCount; ++i)
    {
      QueueFamilyIndices gQueueFamilyIndices;

      populateQueueFamilyQueueIndices(lQueueFamilies[i], i, &gQueueFamilyIndices);

      presentFamilySupported = false;
      vkGetPhysicalDeviceSurfaceSupportKHR(*gPhysicalDevice, i, *surface, &presentFamilySupported);

      gQueueFamilyIndices.presentFamilySupportQueueIndex = presentFamilySupported ? i : -1;

      (*gQueueFamilyIndicesList)[i] = gQueueFamilyIndices;
    }

  *gQueueFamilyCount = lQueueFamilyCount;
}

Там эта строка

(*gQueueFamilyIndicesList) = malloc(sizeof(*lQueueFamilies) * lQueueFamilyCount);

Я подумал: «Да, мне нужен размер для хранения информации из этого lQueueFamilies массива», и я выделил память для хранения информации в *lQueueFamilies раз больше.

НО это неправильно !

Мне нужно было

(*gQueueFamilyIndicesList) = malloc(sizeof(QueueFamilyIndices) * lQueueFamilyCount);

, потому что мне нужно было gQueueFamilyIndicesList для хранения конкретной c информации из VkQueueFamilyProperties, а не самой структуры.

Я не знаю, как я это пропустил. Спасибо @krOoze за предложение использовать const и @solidpixel, чтобы предположить, что это может быть поврежденное повреждение памяти, что и было.

...