我试图了解OpenCL生态系统以及vulkan如何发挥作用.
鉴于:
OpenCL如何与vulkan相关?我知道OpenCL是更高级别并抽象设备,但是它(或可能)内部使用Vulkan吗?(而不是依赖供应商特定的驱动程序)
Vulkan被宣传为计算和图形API,但是我发现计算部分的资源非常少 - 为什么呢?
Vulkan比OpenGL具有性能优势.Vulkan与OpenCl的情况是否相同?(OpenCL因为比CUDA慢而臭名昭着)
SYCL内部使用OpenCL还是使用vulkan?或者它既不使用,而是依赖于低级别,供应商特定的apis来实现?
我正在尝试使用 glslang 将 glsl 着色器代码编译为 SPIR-V 二进制文件。glslang 项目可以在这里找到:
https://github.com/KhronosGroup/glslang
它可以通过在命令行中手动运行 glslangValidator.exe 来很好地工作。但我想使用 C++ 接口。
我已经按照 github 页面上的描述构建了项目,现在我正在努力解决如何实际使用该界面的问题。
我宁愿不在我的解决方案中实际包含任何项目(我正在使用 Visual Studio),而是链接使用它所需的 .lib 和标头。我只是找不到我需要链接哪些。github页面只提到ShaderLang.h和StandAlone.cpp,这是不够的。
有人可以解释如何设置一个可以使用 glslang 的项目吗?我只需要它来将 glsl 着色器代码编译为 SPIR-V 二进制文件(带有有关着色器编译的调试信息)。我认为对于已经做过或有更多经验的人来说,这将是一个非常简单的问题。
这是我能想出的(最简单的)实例化着色器,它基本上只是转换了一堆2D基元:
#version 400
#extension GL_ARB_draw_instanced : enable
#extension GL_ARB_shading_language_420pack : enable
layout(std140, binding = 0) uniform VConstants {
vec4 vfuniforms[48];
};
in vec4 pos;
void main() {
gl_Position = vec4(0.0,0,0.0,1);
gl_Position.x = dot(pos, vfuniforms[int(float(gl_InstanceID) * 2.0)]);
gl_Position.y = dot(pos, vfuniforms[int(float(gl_InstanceID) * 2.0 + 1.0)]);
}
Run Code Online (Sandbox Code Playgroud)
如果我尝试使用Vulkan SDK附带的glslangValidator将其编译为SPIR-V,我会得到:
WARNING: 0:2: '#extension' : extension not supported: GL_ARB_draw_instanced
ERROR: 0:14: 'gl_InstanceID' : undeclared identifier
ERROR: 1 compilation errors. No code generated.
Run Code Online (Sandbox Code Playgroud)
如果我删除该#extension GL_ARB_draw_instanced行,我仍然会收到gl_InstanceID错误.是否可以编写实例化GLSL并将它们编译为SPIR-V?如果是这样,我做错了什么?
我正在尝试使用 SPIR-V专门化常量来定义统一块中数组的大小。
#version 460 core
layout(constant_id = 0) const uint count = 0;
layout(binding = 0) uniform Uniform
{
vec4 foo[count];
uint bar[count];
};
void main() {}
Run Code Online (Sandbox Code Playgroud)
count = 0在着色器中声明 时,编译失败并显示:
array size must be a positive integer
Run Code Online (Sandbox Code Playgroud)
当count = 1特化为 5 时,代码可以编译,但在运行时链接失败,并抱怨别名:
error: different uniforms (named Uniform.foo[4] and Uniform.bar[3]) sharing the same offset within a uniform block (named Uniform) between shaders
error: different uniforms (named Uniform.foo[3] and Uniform.bar[2]) sharing the same offset within a …Run Code Online (Sandbox Code Playgroud) 有没有办法为 Vulkan 自动编译 OpenGL 着色器?问题出在制服上。
'non-opaque uniforms outside a block' : not allowed when using GLSL for Vulkan
Run Code Online (Sandbox Code Playgroud)
我试过为 OpenGL 编译,然后用 spirv-cross 反编译--vulkan-semantics,但它仍然有非不透明的制服。
spirv-cross 似乎只有用于为 OpenGL 编译 Vulkan 着色器的工具。
[--glsl-emit-push-constant-as-ubo]
[--glsl-emit-ubo-as-plain-uniforms]
Run Code Online (Sandbox Code Playgroud) 可以有一个专门化常量数组,这样 glsl 代码看起来类似于以下内容:
layout(constant_id = 0) const vec2 arr[2] = vec2[] (
vec2(2.0f, 2.0f),
vec2(4.0f, 4.0f)
);
Run Code Online (Sandbox Code Playgroud)
或者,或者:
layout(constant_id = 0) const float arr[4] = float[] (
2.0f, 2.0f,
4.0f, 4.0f
);
Run Code Online (Sandbox Code Playgroud)
据我所知,可以使用的专门化常量的数量没有限制,所以感觉很奇怪,这是不可能的,但是当我尝试上述操作时,SPIR-V 编译器通知我“constant_id”只能应用于标量。目前,我使用统一缓冲区来提供数据,但我想消除后备缓冲区以及在绘制之前绑定缓冲区的需要,并允许系统在管道创建期间优化代码(如果可能)。
我对在一组Vulkan计算着色器中实现特定算法感兴趣.该算法在一个点使用clz()函数.我希望我的NVIDIA GPU可能为这个功能提供硬件支持; CUDA显然使用clz指令,而clz()也在OpenCL 1.2中.所以我不想写自己的clz().有没有办法让我以CUDA或OpenCL的方式调用函数?
我想我可以尝试将一个OpenCL内核编译成SPIR-V并在Vulkan中使用它,但我不认为Vulkan会对此感到高兴......?
我的另一个想法是,也许我可以翻译一个包含对SPIR-V程序集的clz()调用的非常简单的OpenCL内核,对我的GLSL着色器执行相同操作,然后手动破解clz()调用,因为它出现在内核汇编代码中,进入着色器的汇编代码.但我对SPIR-V的细节一无所知,或者说Vulkan可能对计算着色器可能使用的各种SPIR-V指令有什么限制,所以我几乎不知道这是否真的有用.
似乎在某个时间点 Nvidia 有一个扩展,允许OpenGL 1.1 的半浮点值,但显然从那时起*世界的一半已经在某个时候被现代 GLSL 规范回收了。
今天,我可以使用16位漂浮在CUDA点值没有问题,不应该有硬件支持NVIDIA以支持16位浮点数的问题,他们似乎支持他们HLSL和赫克甚至似乎矛盾的支持,他们在HLSL交叉编译到SPIR-V 而 GLSL 不适用于 Nvidia。似乎 SPIR-V 具有支持 16 位浮点所需的所有原语,而不管主要扩展(KHR),因此似乎没有理由禁止我使用它们。
我不确定为什么尽管有 Nvidia 卡,但我无法利用 16 位浮点运算,而且如果我想利用它,显然我不得不完全使用 AMD或切换 API。当然必须有某种方法来实际使用真正的 16 位浮点值吗?
我不是在询问主机到设备分配的缓冲区(IE 顶点缓冲区)。是的,您可以将它们分配为具有 KHR 扩展名的 16 位浮点数,并且没有太大问题,但在实际着色器中,使用 16 位浮点数而不是强制为 32 位浮点数的 16 位浮点数是我所担心的。
在我在OpenGL中使用的几何着色器中,在开头设置一个变量,然后在不重置它的情况下发出顶点,但是在vulkan中,如果我不写入每个EmitVertex()代码之间的变量将无法正常工作.
我在glsl规范中找不到任何相关内容,是否有规则,第一种情况恰好起作用?有什么变化转移到spirv?
我正在尝试将 spirv 与OpenGL一起使用。之前在我的着色器中,我必须gl_VertexID计算矩形的 uv,现在我将其替换为gl_VertexIndex.
如果我使用gl_VertexID的代码工作,如果我用gl_VertexIndex在spirv与vulkan代码的作品,但如果我用gl_VertexIndex用的OpenGL的gl_VertexIndex始终0。
这是我正在使用的测试绘制命令:
glDrawArraysInstancedBaseInstance(GL_TRIANGLES, 0, 6, 1, 2);
Run Code Online (Sandbox Code Playgroud)
不应该gl_VertexIndex从0到5吗?