gpt4 book ai didi

c - Vulkan API 和 C - 查询物理设备属性导致段错误

转载 作者:行者123 更新时间:2023-11-30 16:06:42 27 4
gpt4 key购买 nike

这是主要的调用函数

void createVulkanContext()
{
queueFamilyCount = 0;

populatePhysicalDevice(&instance, &physicalDevice);
physicalDeviceTest(&physicalDevice); // This one works fine

populateQueueFamilies(physicalDevice, &queueFamilyIndicesList, &queueFamilyCount, surface);
physicalDeviceTest(&physicalDevice); // This one causes segfault
}

这是查询函数

void physicalDeviceTest(VkPhysicalDevice* gPhysicalDevice)
{

printf("%p\n", gPhysicalDevice);

VkPhysicalDeviceProperties pdProp;
vkGetPhysicalDeviceProperties(*gPhysicalDevice, &pdProp);

printf("%u\n", pdProp.deviceID);
printf("%s\n", pdProp.deviceName);
printf("%u\n", pdProp.apiVersion);
printf("%u\n", pdProp.driverVersion);
printf("%u\n", pdProp.vendorID);
}

打印这个

0x55555555a1e8
26958
Unknown AMD GPU
4198513
8388708
4098
0x55555555a1e8

这是gdb回溯结果

Thread 1 "VulkanApp1090" received signal SIGSEGV, Segmentation fault.
0x00007ffff7f63467 in vkGetPhysicalDeviceProperties () from /usr/lib/libvulkan.so.1
(gdb) backtrace
#0 0x00007ffff7f63467 in vkGetPhysicalDeviceProperties () from /usr/lib/libvulkan.so.1
#1 0x0000555555555602 in physicalDeviceTest (gPhysicalDevice=0x55555555a1e8 <physicalDevice>)

据我所知,这不应该发生,因为 populateQueueFamilies(physicalDevice, &queueFamilyIndi​​cesList ...) 函数并没有真正更改按值传递的 physicalDevice 变量.

<小时/>

完整代码

typedef struct QueueFamilyIndices
{
int graphicsFamilySupportQueueIndex;
int computeFamilySupportQueueIndex;
int transferFamilySupportQueueIndex;
int sparsebindingFamilySupportQueueIndex;
int protectedFamilySupportQueueIndex;
int presentFamilySupportQueueIndex;

} QueueFamilyIndices;


VkInstance instance;

VkPhysicalDevice physicalDevice;
VkDevice logicalDevice;

QueueFamilyIndices* queueFamilyIndicesList;
QueueFamilyIndices selectedQueueFamilyIndex;
uint32_t queueFamilyCount;

VkQueue graphicsQueue;
VkSurfaceKHR surface;


void populateQueueFamilyQueueIndices(VkQueueFamilyProperties gQueueFamilyProperties,
uint32_t gQueueFamilyIndex,
QueueFamilyIndices* gQueueFamilyIndices)
{
gQueueFamilyIndices->graphicsFamilySupportQueueIndex = -1;
gQueueFamilyIndices->computeFamilySupportQueueIndex = -1;
gQueueFamilyIndices->transferFamilySupportQueueIndex = -1;
gQueueFamilyIndices->sparsebindingFamilySupportQueueIndex = -1;
gQueueFamilyIndices->protectedFamilySupportQueueIndex = -1;

if (gQueueFamilyProperties.queueFlags & VK_QUEUE_GRAPHICS_BIT)
{
gQueueFamilyIndices->graphicsFamilySupportQueueIndex = gQueueFamilyIndex;
}
if (gQueueFamilyProperties.queueFlags & VK_QUEUE_COMPUTE_BIT)
{
gQueueFamilyIndices->computeFamilySupportQueueIndex = gQueueFamilyIndex;
}
if (gQueueFamilyProperties.queueFlags & VK_QUEUE_TRANSFER_BIT)
{
gQueueFamilyIndices->transferFamilySupportQueueIndex = gQueueFamilyIndex;
}
if (gQueueFamilyProperties.queueFlags & VK_QUEUE_SPARSE_BINDING_BIT)
{
gQueueFamilyIndices->sparsebindingFamilySupportQueueIndex = gQueueFamilyIndex;
}
if (gQueueFamilyProperties.queueFlags & VK_QUEUE_PROTECTED_BIT)
{
gQueueFamilyIndices->protectedFamilySupportQueueIndex = gQueueFamilyIndex;
}
}


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

uint32_t queueFamilyCount;
vkGetPhysicalDeviceQueueFamilyProperties(gPhysicalDevice, &queueFamilyCount, VK_NULL_HANDLE);

VkQueueFamilyProperties queueFamilies[queueFamilyCount];
vkGetPhysicalDeviceQueueFamilyProperties(gPhysicalDevice, &queueFamilyCount, queueFamilies);

VkBool32 presentFamilySupported;

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

for (uint32_t i = 0; i < queueFamilyCount; ++i)
{
QueueFamilyIndices gQueueFamilyIndices;

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

presentFamilySupported = false;

vkGetPhysicalDeviceSurfaceSupportKHR(gPhysicalDevice, i, surface, &presentFamilySupported);
gQueueFamilyIndices.presentFamilySupportQueueIndex = presentFamilySupported ? i : -1;

gQueueFamilyIndicesList[i] = malloc(sizeof(QueueFamilyIndices));
*gQueueFamilyIndicesList[i] = gQueueFamilyIndices;
}

*gQueueFamilyCount = queueFamilyCount;
}

void physicalDeviceTest(VkPhysicalDevice* gPhysicalDevice)
{

printf("%p\n", gPhysicalDevice);

VkPhysicalDeviceProperties pdProp;
vkGetPhysicalDeviceProperties(*gPhysicalDevice, &pdProp);

printf("%u\n", pdProp.deviceID);
printf("%s\n", pdProp.deviceName);
printf("%u\n", pdProp.apiVersion);
printf("%u\n", pdProp.driverVersion);
printf("%u\n", pdProp.vendorID);
}

void createVulkanContext()
{
queueFamilyCount = 0;

populatePhysicalDevice(&instance, &physicalDevice);
physicalDeviceTest(&physicalDevice); // This one works fine

populateQueueFamilies(physicalDevice, &queueFamilyIndicesList, &queueFamilyCount, surface);
physicalDeviceTest(&physicalDevice); // This one causes segfault
}

多一点诊断让我思考

      gQueueFamilyIndicesList[i]  = malloc(sizeof(QueueFamilyIndices));
*gQueueFamilyIndicesList[i] = gQueueFamilyIndices;

因为注释掉它们可以修复段错误。

<小时/>

TL;DR

再次调用同一函数(physicalDeviceTest)会导致段错误

void createVulkanContext()
{
queueFamilyCount = 0;

populatePhysicalDevice(&instance, &physicalDevice);
physicalDeviceTest(&physicalDevice); // This one works fine

populateQueueFamilies(physicalDevice, &queueFamilyIndicesList, &queueFamilyCount, surface);
physicalDeviceTest(&physicalDevice); // This one causes segfault
}

可能是由于这些电话

      gQueueFamilyIndicesList[i]  = malloc(sizeof(QueueFamilyIndices));
*gQueueFamilyIndicesList[i] = gQueueFamilyIndices;

在函数populateQueueFamilies中,尽管我不确定为什么或如何。

最佳答案

想通了。

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

现在可以正确分配内存并指向列表中的第一个内存块。

像这样取消引用和等同

(*gQueueFamilyIndicesList)[i] = gQueueFamilyIndices;

现在就像我期望的那样工作。

gQueueFamilyIndi​​cesList 周围的括号很重要,因为 [] 运算符优先于 *

*gQueueFamilyIndi​​cesList[i] = *(*(gQueueFamilyIndi​​cesList + i))

(*gQueueFamilyIndi​​cesList)[i] = *((*gQueueFamilyIndi​​cesList) + i)

关于c - Vulkan API 和 C - 查询物理设备属性导致段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59876663/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com