这是来自 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);
我知道当您将局部变量的地址分配给指针时会发生此类问题。
但我不认为这就是这里发生的事情,因为唯一接触 populateQueueFamilies
内的 surface
var 的函数是这个:
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;
并将每个表面(数字)
传递给不同的函数。
最佳答案
天哪,这是一次有趣的旅程,最终让我完全被震撼了;简单地说 - 缺乏天才。
经过一段时间的寻找,尝试调试一些东西,我最终发现了一个非常非常的愚蠢错误,它导致了各种各样的问题。
我通过使用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
来存储来自 VkQueueFamilyProperties
的特定信息,而不是结构本身。
我不知道我是怎么错过的。感谢 @krOoze 建议使用 const 和 @solidpixel 来建议这可能是内存损坏,事实确实如此。
关于c++ - VkSurfaceKHR 指针的值在函数调用后发生变化,无需任何显式赋值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59917462/