C++ 布局说明符标量在EXT\u scalar\u block\u布局中有什么用途? 问题:

C++ 布局说明符标量在EXT\u scalar\u block\u布局中有什么用途? 问题:,c++,glsl,vulkan,C++,Glsl,Vulkan,当访问GL\U EXT\U scalar\U block\U布局中的存储缓冲区时,scalar布局说明符有什么用途?(例如,见下文) 标量的用例是什么 背景 我最近使用Vulkan和NVidias VkRayTracing扩展编程了一个简单的光线跟踪器,并且正在跟踪。在关于最近命中着色器的部分中,需要访问存储在存储缓冲区中的一些数据(使用标志vk::BufferUsageFlagBits::eStorageBuffer) 在着色器中,使用扩展名GL\u EXT\u scalar\u block\

当访问GL\U EXT\U scalar\U block\U布局中的存储缓冲区时,
scalar
布局说明符有什么用途?(例如,见下文)

标量的用例是什么

背景 我最近使用Vulkan和NVidias VkRayTracing扩展编程了一个简单的光线跟踪器,并且正在跟踪。在关于最近命中着色器的部分中,需要访问存储在存储缓冲区中的一些数据(使用标志
vk::BufferUsageFlagBits::eStorageBuffer

在着色器中,使用扩展名
GL\u EXT\u scalar\u block\u layout
,这些缓冲区的访问方式如下:

layout(binding = 4, set = 1, scalar) buffer Vertices { Vertex v[]; } vertices[];
当我第一次使用这段代码时,验证层告诉我像
Vertex
这样的结构有一个无效的布局,所以我更改了它们,使每个成员在16字节块上对齐:

struct Vertex {
    vec4 position;
    vec4 normal;
    vec4 texCoord;
};
使用C++中相应的结构:

#pragma pack(push, 1)
struct Vertex {
    glm::vec4 position_1unused;
    glm::vec4 normal_1unused;
    glm::vec4 texCoord_2unused;
};
#pragma pack(pop)
错误消失了,我得到了一个工作的光线跟踪器。但是我仍然不明白为什么这里使用
scalar
关键字。我发现在谈论GL\u EXT\u scalar\u block\u布局扩展,但我真的不明白。也许我只是不习惯glsl术语?我看不出我为什么要用这个


此外,我刚刚尝试删除标量,它仍然工作,没有任何区别、警告或错误。如果您对此主题有任何澄清或进一步的资料,我们将不胜感激。

std140和
std430
布局对对象的偏移/对齐大小进行了大量舍入
std140
基本上使任何非标量类型与
vec4
对齐
std430稍微放松了这一点,但它仍然会对
vec4
的对齐方式进行大量的取整

scalar
layout基本上是指按照对象的组件标量布局对象。聚合组件(向量、矩阵、数组和
struct
s)的任何内容都不会影响布局。特别是:

  • 所有类型的大小/对齐方式都仅限于它们实际使用的标量组件的最高对齐方式。因此,包含单个
    uint
    的结构的大小/对齐方式与
    uint
    的大小/对齐方式相同:4字节。在std140规则下,它的大小和对齐方式为16字节

    注意,这种布局,因为C和C++将能够创建映射规则,这些规则映射到GLSL。

  • 数组中元素的数组步长仅基于元素类型的大小/对齐方式(递归)。因此,
    uint
    的数组具有4字节的数组跨距;在
    std140
    规则下

  • 对齐和填充只对标量起作用。如果在
    std140/430
    中有一个包含
    uint
    后跟
    uvec2
    的结构,这将需要16个字节,在第一个
    uint
    之后有4个字节的填充。在
    scalar
    layout下,这样的结构只需要12个字节(与4个字节对齐),而
    uvec2
    在概念上没有对齐。因此,只有当标量较小时才存在填充,如
    uint16
    后跟
    uint


  • 在您展示的特定案例中,
    scalar
    布局是不必要的,因为您使用的所有类型都是
    vec4
    s.

    非常感谢calrifies。然后我可能错过了vulkan设置中的其他部分,因为验证层抱怨
    Vector
    的旧布局没有与16字节块对齐。但是,如果它是这样工作的,并且我理解为什么我很高兴:)在std430下,结构对齐不是等于它的任何成员的最大对齐吗?16字节的步幅是从哪里来的?