如何在 GLSL 中使用 Vulkan SPIR-V 数据格式
How to Use Vulkan SPIR-V Data Formats in GLSL
SPIR-V 允许非常 verbose data formats.
GLSL只有basic data types (Chapter 4)没有指定位长
据我所知,为 Vulkan 着色器编程最方便的方法是在 GLSL 中对其进行编程,然后使用 Vulkan SDK 提供的编译器 (glslc.exe) 将文件转换为 SPIR-V二进制。
我的问题是如何在 GLSL 中使用 VK_FORMAT_R4G4_UNORM_PACK8
(在上面的 SPIR-V link 中找到)这些冗长的数据格式,同时使用 glslc.exe 编译我们的着色器代码。是否有编译器允许的特殊数据类型?如果没有,是否有一种可以使用的替代高级语言,然后编译成二进制文件?
例如,如果这是图形管道中使用的属性描述:
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() {
...
}
The proceeding GLSL shader code would look something like this:
不,不会。您会在着色器中收到一个 vec2
,因为这就是顶点属性 工作 的方式。顶点格式并不意味着与数据格式完全匹配;数据将从该格式转换为着色器预期的位深度。无符号归一化值是浮点数据,因此 2 向量 UNORM 映射到 GLSL vec2
.
顺便说一句,SPIR-V 不会改变这个。着色器的输入大小不需要与给定的数据大小完全匹配;任何转换都只是烘焙到着色器中(这也是为什么顶点格式是管道的 部分 的部分原因)。
GL_EXT_shader_16bit_storage 扩展在 GLSL 中提供了更大的灵活性,可以在缓冲区支持的接口块中创建异常大小的数据类型。但这些专门用于 UBOs/SSBOs 中的数据,而不是顶点格式。但是,此扩展需要 SPV_KHR_16bit_storage 和 SPV_KHR_8bit_storage SPIR-V 扩展。
SPIR-V 允许非常 verbose data formats.
GLSL只有basic data types (Chapter 4)没有指定位长
据我所知,为 Vulkan 着色器编程最方便的方法是在 GLSL 中对其进行编程,然后使用 Vulkan SDK 提供的编译器 (glslc.exe) 将文件转换为 SPIR-V二进制。
我的问题是如何在 GLSL 中使用 VK_FORMAT_R4G4_UNORM_PACK8
(在上面的 SPIR-V link 中找到)这些冗长的数据格式,同时使用 glslc.exe 编译我们的着色器代码。是否有编译器允许的特殊数据类型?如果没有,是否有一种可以使用的替代高级语言,然后编译成二进制文件?
例如,如果这是图形管道中使用的属性描述:
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() {
...
}
The proceeding GLSL shader code would look something like this:
不,不会。您会在着色器中收到一个 vec2
,因为这就是顶点属性 工作 的方式。顶点格式并不意味着与数据格式完全匹配;数据将从该格式转换为着色器预期的位深度。无符号归一化值是浮点数据,因此 2 向量 UNORM 映射到 GLSL vec2
.
顺便说一句,SPIR-V 不会改变这个。着色器的输入大小不需要与给定的数据大小完全匹配;任何转换都只是烘焙到着色器中(这也是为什么顶点格式是管道的 部分 的部分原因)。
GL_EXT_shader_16bit_storage 扩展在 GLSL 中提供了更大的灵活性,可以在缓冲区支持的接口块中创建异常大小的数据类型。但这些专门用于 UBOs/SSBOs 中的数据,而不是顶点格式。但是,此扩展需要 SPV_KHR_16bit_storage 和 SPV_KHR_8bit_storage SPIR-V 扩展。