标签: vulkan

使用多个索引渲染网格

我有一些顶点数据.位置,法线,纹理坐标.我可能从.obj文件或其他格式加载它.也许我正在画一个立方体.但是每个顶点数据都有自己的索引.我可以使用OpenGL/Direct3D渲染这个网格数据吗?

opengl direct3d opengl-es webgl vulkan

54
推荐指数
2
解决办法
1万
查看次数

我应该在统一缓冲区或着色器存储缓冲区对象中使用`vec3`吗?

vec3类型是一个非常好的类型.它只需要3个浮点数,我的数据只需要3个浮点数.我想在UBO和/或SSBO的结构中使用一个:

layout(std140) uniform UBO
{
  vec4 data1;
  vec3 data2;
  float data3;
};

layout(std430) buffer SSBO
{
  vec4 data1;
  vec3 data2;
  float data3;
};
Run Code Online (Sandbox Code Playgroud)

然后,在我的C或C++代码中,我可以这样做来创建匹配的数据结构:

struct UBO
{
  vector4 data1;
  vector3 data2;
  float data3;
};

struct SSBO
{
  vector4 data1;
  vector3 data2;
  float data3;
};
Run Code Online (Sandbox Code Playgroud)

这是一个好主意吗?

opengl opengl-es glsl vulkan

28
推荐指数
1
解决办法
4507
查看次数

OpenCL,Vulkan,Sycl

我试图了解OpenCL生态系统以及vulkan如何发挥作用.

  • 我知道OpenCL是一个执行gpus和cpu代码的框架 - 使用可以编译为SPIR的内核
  • Vulkan也可以用作使用相同SPIR语言的计算API
  • SYCL是一个新规范,允许编写opencl代码作为符合c ++ 14的适当标准.我的理解是,该规范还没有自由实现.

鉴于:

  • OpenCL如何与vulkan相关?我知道OpenCL是更高级别并抽象设备,但是它(或可能)内部使用Vulkan吗?(而不是依赖供应商特定的驱动程序)

  • Vulkan被宣传为计算和图形API,但是我发现计算部分的资源非常少 - 为什么呢?

  • Vulkan比OpenGL具有性能优势.Vulkan与OpenCl的情况是否相同?(OpenCL因为比CUDA慢而臭名昭着)

  • SYCL内部使用OpenCL还是使用vulkan?或者它既不使用,而是依赖于低级别,供应商特定的apis来实现?

opencl vulkan spir-v

27
推荐指数
2
解决办法
1万
查看次数

Vulkan:vk*CreateInfo结构中的sType有什么意义?

vk*CreateInfo新的Vulkan API中的所有create info structs()中,总有一个.sType成员.如果价值只能是一件事,为什么会这样?此外,Vulkan规范非常明确,您只能将vk*CreateInfo结构用作其相应vkCreate*函数的参数.这似乎有点多余.我可以看到,如果驱动程序将此结构直接传递给GPU,您可能需要它(我确实注意到它始终是第一个成员).但对于应用程序而言,这似乎是一个非常糟糕的想法,因为如果驱动程序这样做,应用程序将更不容易出错,并且在结构中添加int似乎不是一个计算效率极低的操作.我只是不明白为什么它存在.

TL; DR
    为什么vk*CreateInfo结构有.sType成员?

c specifications vulkan

23
推荐指数
1
解决办法
1607
查看次数

Vulkan中命令缓冲区之间的同步

有几种方法可以处理Vulkan中的同步.这就是我理解的方式:

  • Fences是GPU到CPU的同步.
  • 信号量是GPU到GPU的同步,它们用于同步队列提交(在相同或不同的队列上).
  • 事件更通用,在CPU和GPU上重置和检查.
  • 障碍用于命令缓冲区内的同步.

在我的情况下,我有两个命令缓冲区.我希望第二个命令缓冲区在第一个命令缓冲区之后执行.

submitInfo.pCommandBuffers = &firstCommandBuffer;
vkQueueSubmit(queue, 1, &submitInfo, VK_NULL_HANDLE);

// wait for first command buffer to finish
submitInfo.pCommandBuffers = &secondCommandBuffer;
vkQueueSubmit(queue, 1, &submitInfo, VK_NULL_HANDLE);
Run Code Online (Sandbox Code Playgroud)

什么样的同步最适合这个?如果我使用的vkQueueWaitIdle(queue)),是与使用栅栏相同的东西,或者我应该使用事件或信号量?

如果我同时向队列发送多个命令缓冲区:

std::vector<VkCommandBuffer> submitCmdBuffers = {
        firstCommandBuffer,
        secondCommandBuffer
    };
    submitInfo.commandBufferCount = submitCmdBuffers.size();
    submitInfo.pCommandBuffers = submitCmdBuffers.data();
Run Code Online (Sandbox Code Playgroud)

还有一种方法可以在第一个和第二个之间同步吗?

c++ synchronization gpu vulkan

23
推荐指数
2
解决办法
2644
查看次数

什么是GPU上的连贯内存?

我曾经偶然发现一个术语"非连贯"和"连贯"的记忆

与图形编程相关的技术论文.我一直在寻找一个简单而明确的解释,但是发现了这种类型的"硬核"论文.我很高兴收到外行人的样式答案,关于GPU体系结构实际上是什么连贯的内存以及它是如何实现的与其他(可能不相干)的内存类型进行比较.

gpu gpgpu gpu-programming vulkan

20
推荐指数
2
解决办法
3299
查看次数

为什么在使用信号量时每个swapchain命令缓冲区都需要VkFence?

我正在使用交换链的3个图像和VkCommandBuffer每个交换链图像的一个(CB).GPU同步由两个信号量完成,一个用于presentation_finished,一个用于rendering_finished.目前的模式是VK_PRESENT_MODE_MAILBOX_KHR(快速概述).

现在,当我在不等待任何CB围栏的情况下运行我的示例时,验证层会在第二次使用任何交换链图像时立即报告此错误:

vkBeginCommandBuffer()在活动CB完成之前调用它.您必须在此电话前检查CB围栏.

乍一看,这对我来说似乎是合理的,因为处理来自CB的命令可能还没有完成.但我想的越多,我就会得出结论,这根本不应该发生.

我目前的理解是,当vkAcquireImageKHR返回特定的图像索引时,它意味着返回的图像必须通过渲染完成.

那是因为我在渲染结束时将rendering_finished信号量传递vkQueueSubmit给要发信号,并vkQueuePresentKHR在呈现图像之前等待它发出信号.

规格VkQueuePresentInfoKHR说:

pWaitSemaphores,如果不是VK_NULL_HANDLE,则是VkSemaphore带有waitSemaphoreCount条目的对象数组,并指定在发出当前请求之前要等待的信号量

含义:我永远不会出现任何没有渲染渲染的图像,因此一旦图像出现,相关的CB就不能再使用了.

第二个信号量presentation_finished由信号通知vkAqcuireImageKHR并传递给它vkQueueSubmit(开始渲染).这意味着任何图像的渲染都不会早于演示引擎允许的开始.

总结:vkQueuePresentKHR在完成图像渲染之前不会发出当前请求,并且vkAcquireImageKHR阻止直到图像可用并且永远不会返回当前获取的图像.

我错过了什么使围栏成为必要?


我已经包含了一个最小的代码示例,其中仅包含概念上重要的部分来说明问题.

VkImage[] swapchain_images;
VkCommandBuffer[] command_buffers;

VkSemaphore rendering_finished;
VkSemaphore presentation_finished;

void RenderLoop()
{
    /* Acquire an image from the swapchain. Block until one is available.
       Signal presentation_finished when we are allowed to render …
Run Code Online (Sandbox Code Playgroud)

c++ vulkan

19
推荐指数
1
解决办法
1590
查看次数

什么是vulkan的"推力常数"?

我查看了一堆关于推送常量的教程,暗示可能的好处,但我从未见过,即使在Vulkan文档中,实际上是什么"推动常数"......我不明白他们应该是什么,以及推动常数的目的是什么.我能找到的最接近的是这篇文章,遗憾的是它不会问它们是什么,但是它们和另一个概念之间有什么不同,并没有帮助我.

什么是推动常数,它为什么存在以及它用于什么?它的名字来自哪里?

vulkan

18
推荐指数
1
解决办法
5006
查看次数

多GPU编程如何与Vulkan一起使用?

在Vulkan中使用多GPU会不会像制作许多命令队列那样在它们之间划分命令缓冲区?

有两个问题:

  1. 在OpenGL中,我们使用GLEW来获取函数.拥有超过1个GPU,每个GPU都有自己的驱动程序.我们如何使用Vulkan?
  2. 框架的一部分是用GPU生成的,而其他GPU是用其他GPU生成的,例如使用Intel GPU来渲染UI和AMD或Nvidia GPU以在labtops中渲染游戏画面?或者是否会在GPU中生成帧并在另一个GPU中生成下一帧?

gpu multi-gpu vulkan

17
推荐指数
2
解决办法
7958
查看次数

映射 GPU 内存时应该使用 volatile 吗?

OpenGL 和 Vulkan 都允许分别使用glMapBuffer和获取指向部分 GPU 内存的指针vkMapMemory。他们都给void*映射的内存一个。要将其内容解释为某些数据,必须将其强制转换为适当的类型。最简单的示例可能是转换为 afloat*以将内存解释为浮点数或向量或类似数组。

似乎任何类型的内存映射在 C++ 中都是未定义的行为,因为它没有内存映射的概念。但是,这并不是真正的问题,因为该主题超出了 C++ 标准的范围。但是,仍然存在一个问题volatile

在链接的问题中,指针被额外标记为volatile因为它指向的内存内容可以以编译器在编译期间无法预料的方式进行修改。这似乎是合理的,尽管我很少看到人们volatile在这种情况下使用(更广泛地说,这个关键字现在似乎很少使用)。

同时在这个问题中,答案似乎是使用volatile是不必要的。这是因为他们所说的内存是映射使用的mmap,然后msync可以被视为修改内存,这类似于在 Vulkan 或 OpenGL 中显式刷新它。恐怕这不适用于 OpenGL 和 Vulkan。

如果内存被映射为未映射GL_MAP_FLUSH_EXPLICIT_BIT或根本VK_MEMORY_PROPERTY_HOST_COHERENT_BIT不需要刷新,则内存内容会自动更新。即使通过使用手动刷新内存,vkFlushMappedMemoryRanges或者glFlushMappedBufferRange这些函数实际上都没有将映射指针作为参数,因此编译器也不可能知道它们修改了映射内存的内容。

因此,是否有必要将指向映射 GPU 内存的指针标记为volatile?我知道从技术上讲这都是未定义的行为,但我问的是在实际硬件中实际需要什么。

顺便说一下,无论是Vulkan 规范还是OpenGL 规范都没有提到volatile限定符。

编辑:将内存标记为volatile会导致性能开销吗?

c++ opengl gpu volatile vulkan

17
推荐指数
1
解决办法
451
查看次数