如何在GLSL中使用Vulkan SPIR-V数据格式

如何在GLSL中使用Vulkan SPIR-V数据格式,glsl,vulkan,spir-v,Glsl,Vulkan,Spir V,SPIR-V允许非常高的性能 GLSL只有不指定位长度的 据我所知,为Vulkan编程着色器最方便的方法是在GLSL中编程,然后使用Vulkan SDK提供的编译器(glslc.exe)将文件转换为SPIR-V二进制文件 我的问题是,在使用glslc.exe编译着色器代码时,如何在GLSL中使用这些详细的数据格式,例如VK_FORMAT\u R4G4\u UNORM_PACK8(可在上面的SPIR-V链接中找到)。编译器是否允许使用特殊的数据类型?如果没有,是否有一种更高级的语言可以使用,然后编

SPIR-V允许非常高的性能

GLSL只有不指定位长度的

据我所知,为Vulkan编程着色器最方便的方法是在GLSL中编程,然后使用Vulkan SDK提供的编译器(glslc.exe)将文件转换为SPIR-V二进制文件

我的问题是,在使用glslc.exe编译着色器代码时,如何在GLSL中使用这些详细的数据格式,例如
VK_FORMAT\u R4G4\u UNORM_PACK8
(可在上面的SPIR-V链接中找到)。编译器是否允许使用特殊的数据类型?如果没有,是否有一种更高级的语言可以使用,然后编译成二进制

例如,如果这是图形管道中使用的属性描述:

struct Attributes {
   vec2 pos;
   char flags;
};

static inline std::array<VkVertexInputAttributeDescription, 3> getAttributeDescriptions() {
   std::array<VkVertexInputAttributeDescription, 3> attributeDescriptions{};
   attributeDescriptions[0].binding = 0;
   attributeDescriptions[0].location = 0;
   attributeDescriptions[0].format = VK_FORMAT_R32G32_SFLOAT;
   attributeDescriptions[0].offset = offsetof(Attributes, pos);

   attributeDescriptions[1].binding = 0;
   attributeDescriptions[1].location = 1;
   attributeDescriptions[1].format = VK_FORMAT_R4G4_UNORM_PACK8;
   attributeDescriptions[1].offset = offsetof(Attributes, flags);

return attributeDescriptions;
继续执行的GLSL着色器代码如下所示:

#version 450
#extension GL_ARB_separate_shader_objects : enable

//Instance Attributes
layout(location = 0) in vec2 pos;
layout(location = 1) in 4BitVec2DataType flags;         
//4BitVec2DataType is a placeholder for whatever GLSL's equivalent of SPIR-V's VK_FORMAT_R4G4_UNORM_PACK8 would be

void main() {
    ...
}
不,不会的。您将在着色器中收到一个
vec2
,因为顶点属性就是这样工作的。顶点格式并不意味着与数据格式完全匹配;数据将从该格式转换为着色器预期的位深度。无符号规范化值是浮点数据,因此2-vector UNORM映射到GLSL
vec2

顺便说一句,SPIR-V并没有改变这一点。着色器的输入大小不需要与给定的数据大小完全匹配;任何转换都只是烘焙到着色器中(这也是为什么顶点格式是管道的一部分的一部分)

该扩展在GLSL中提供了更大的灵活性,可以在缓冲区支持的接口块中创建异常大小的数据类型。但它们专门用于UBOs/SSBO格式的数据,而不是顶点格式。但是,此扩展需要SPV_KHR_16位存储和SPV_KHR_8位存储SPIR-V扩展

继续执行的GLSL着色器代码如下所示:

#version 450
#extension GL_ARB_separate_shader_objects : enable

//Instance Attributes
layout(location = 0) in vec2 pos;
layout(location = 1) in 4BitVec2DataType flags;         
//4BitVec2DataType is a placeholder for whatever GLSL's equivalent of SPIR-V's VK_FORMAT_R4G4_UNORM_PACK8 would be

void main() {
    ...
}
不,不会的。您将在着色器中收到一个
vec2
,因为顶点属性就是这样工作的。顶点格式并不意味着与数据格式完全匹配;数据将从该格式转换为着色器预期的位深度。无符号规范化值是浮点数据,因此2-vector UNORM映射到GLSL
vec2

顺便说一句,SPIR-V并没有改变这一点。着色器的输入大小不需要与给定的数据大小完全匹配;任何转换都只是烘焙到着色器中(这也是为什么顶点格式是管道的一部分的一部分)


该扩展在GLSL中提供了更大的灵活性,可以在缓冲区支持的接口块中创建异常大小的数据类型。但它们专门用于UBOs/SSBO格式的数据,而不是顶点格式。但是,此扩展需要SPV_KHR_16bit_存储和SPV_KHR_8bit_存储SPIR-V扩展。

由于在创建图形管道时只添加一次位大小,因此在该阶段之前,是否可以安全地假设不添加填充(用于对齐要求)?在中,它表示向量的对齐方式具有与其组件类型相同的标量对齐方式。这是否意味着,为了不统一,图形卡不会向变量添加填充。例如,它不会有两个32位向量,其中LSB设置为8个向量中的每一个4位provided@Ryoku:“为了非制服”在这种情况下是什么意思?如果您不是在谈论某种类型的缓冲区备份接口块,那么“对齐”是不相关的。在阅读Vulkan规范时,我发现有三种对齐方式:标量对齐、基对齐和扩展对齐。我之所以说制服,是因为我知道制服必须经过延伸的对齐,然后四舍五入到16的倍数。不过,我找不到其他路线何时使用的清晰信息。从您的回答来看,我们似乎将使用基本对齐,并且,与编译器一样,只要不影响可观察的行为,驱动程序就可以更改实现,在这种情况下,只要它接受8位,并在必要时单独提供4位。那么这些对齐都是如何对齐UBO或SSBO内部以及如何对应GLSL布局限定符的选项。@Andrea我不太确定,让我相信UBOs有特定规则的部分是标准缓冲区布局部分中的这一部分:“需要显式布局的OpTypeStruct的成员必须按照以下第一个匹配规则对齐。如果结构包含在多个存储类的指针类型中,则它必须满足用于引用它的每个存储类的要求。1.如果启用了scalarBlockLayout功能;每个成员都必须根据其标量对齐方式进行对齐。由于在创建图形管道时只添加一次位大小,因此可以安全地假设在该阶段之前(对于对齐要求)不会添加填充吗?在中,它表示向量的对齐方式具有与其组件类型相同的标量对齐方式。这是否意味着,为了不统一,图形卡不会向变量添加填充。例如,它不会有两个32位向量,其中LSB设置为8个向量中的每一个4位provided@Ryoku:“为了非制服”在这种情况下是什么意思?如果您不是在谈论某种类型的缓冲区备份接口块,那么“对齐”是不相关的。在阅读Vulkan规范时,我发现有三种对齐方式:标量对齐、基对齐和扩展对齐。我之所以说制服,是因为我知道制服必须经过延伸的对齐,然后四舍五入到16的倍数。不过,我找不到其他路线何时使用的清晰信息。从您的响应来看,我们似乎将使用基本对齐,并且与编译器一样,只要不影响可观察的行为,驱动程序就可以更改实现,在这种情况下,只要它接受8位并提供4位独立的