- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
这是主要的调用函数
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, &queueFamilyIndicesList ...)
函数并没有真正更改按值传递的 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;
现在就像我期望的那样工作。
gQueueFamilyIndicesList
周围的括号很重要,因为 []
运算符优先于 *
。
*gQueueFamilyIndicesList[i]
= *(*(gQueueFamilyIndicesList + i))
和
(*gQueueFamilyIndicesList)[i]
= *((*gQueueFamilyIndicesList) + i)
关于c - Vulkan API 和 C - 查询物理设备属性导致段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59876663/
我想知道为什么可以在 VkPipelineLayoutCreateInfo 中指定多个描述符集布局,因为一个已经包含所有绑定(bind)。 最佳答案 描述符集布局描述了单个描述符集的布局。但是一个管道
我试图了解整个 L1/L2 冲洗是如何工作的。假设我有一个像这样的计算着色器 layout(std430, set = 0, binding = 2) buffer Particles{ Pa
Vulkan 旨在为用户提供精简和明确的内容,但队列是此规则的一个很大异常(exception):队列可能由驱动程序复用,并且使用一个系列的多个队列是否会提高性能并不总是很明显。 在驱动程序更新之一之
来自与 vkCmdPipelineBarrier 相关的规范: If no memory barriers are specified, then the first access scope inc
Vulkan 是否提供绘制基本图元的功能?点、线、矩形、实心矩形、圆角矩形、实心圆角矩形、圆、实心圆等。 ? 我认为没有任何 VkCmdDraw* 命令可以提供此功能。如果这是真的,需要做些什么来绘制
我正在尝试进行一个模拟,该模拟涉及渲染前的两个计算步骤。我目前有一个计算基础物理的计算管道,然后是一个图形管道。我希望能够添加第二个计算着色器以在第一个计算着色器之后运行。 首先,Vulkan 中是否
取消映射后可以刷新内存范围吗? 乍一看好像不对,因为函数叫vkFlushMappedMemoryRanges() ,但是 the documentation似乎暗示内存已准备好刷新,即使在未映射之后:
Vulkan 是否支持保存流水线阶段的顶点输出?我一直在寻找,但找不到任何示例或引用资料,也许其他人不知道? 最佳答案 Transform Feedback 在最初的 Vulkan 版本中没有被削减,
我有多个具有不同纹理/管道构造的网格,例如深度测试/混合函数以使用 vulkan 进行渲染。在性能方面呈现它们的最佳实践是什么。 一种选择是为 n 个网格创建 n 个具有 n 个线程的命令缓冲区,它们
我正在开发一个使用 Vulkan 的 C++ 应用程序。我如何获得支持的扩展集? 像std::set get_supported_extensions()这样的签名会很理想。 最佳答案 vkEnume
我正在开发一个使用 Vulkan 的 C++ 应用程序。我如何获得支持的扩展集? 像std::set get_supported_extensions()这样的签名会很理想。 最佳答案 vkEnume
正在处理 Vulkan 三角形渲染代码,我想将渲染图像保存到文件而不是渲染到窗口。 那么我应该什么时候读取帧缓冲区以及如何编写在文件中。我想需要将原始 RGBA 格式的像素转换为某种已知的 BMP 或
Vulkan 规范(1.0.12)在第 2.4 节介绍了 VkDeviceSize: With few exceptions, Vulkan uses the standard C types for
即使实例在 Vulkan 中创建失败,我是否应该销毁它? 哪个是正确的: 1: VkResult Result = vkCreateInstance( info, NULL, instance );
我开始学习 Vulkan,想知道 VkCreate[...] 函数是否将结构中指向的资源复制到他自己的缓冲区中。 为了澄清我的问题,在这段代码中我加载了 斯皮尔 将着色器放入我自己的 mkShader
Khronos 刚刚发布了他们的新内存模型扩展,但还没有进行非正式讨论、示例实现等,所以我对基本细节感到困惑。 https://www.khronos.org/blog/vulkan-has-just
SubpassInput 由片段着色器隐式寻址。我想用我自己的纹理坐标来处理输入。类似于 texture(sampler, texCoord) 最佳答案 这是不可能的。如果您想在着色器内对图像进行采样
有没有办法从实例中获取对象类型枚举器(vk::ObjectType dor vulkan.hpp 和 VkObjectType for vulkan)? 例如假设我们有 3 个对象: vk::Devi
我的着色器索引到采样器和图像,但是当我从图像中采样时(如果我在着色器中采样,我只会得到错误)我得到一个错误: Descriptor in binding #0 index 0 requires FLO
我想到了以下场景,但我不知道它是否有效: 在程序的开头创建一个VkCommandPool,并从中分配一个VkCommandBuffer。 在渲染循环中,将命令记录到 VkCommandBuffer(隐
我是一名优秀的程序员,十分优秀!