OpenGL统一缓冲区std140布局,驱动程序错误或我误解了规范? [英] OpenGL Uniform Buffer std140 layout, a driver bug or did I misunderstand the specification?

查看:636
本文介绍了OpenGL统一缓冲区std140布局,驱动程序错误或我误解了规范?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

OpenGL规范存在(或这是一个错误?)...指的是std140的布局,带有共享的统一缓冲区,它指出:

The OpenGL specification lies (or is this a bug?)... Referring to the layout for std140, with shared uniform buffers, it states:

"GLSL编译器使用Tabl e L-1中显示的规则集来 符合std140标准的统一块中的布局成员.的偏移量 区块中的成员是根据 块中的先前成员(在变量中之前声明的成员 问题),以及起始偏移量.第一个的起始偏移 成员始终为零.

"The set of rules shown in Tabl e L-1 are used by the GLSL compiler to layout members in a std140-qualified uniform block. The offsets of members in the block are accumulated based on the sizes of the previous members in the block (those declared before the variable in question), and the starting offset. The starting offset of the first member is always zero.

标量变量类型(bool,int,uint,float)-标量的大小 基本机器类型"

Scalar variable type (bool, int, uint, float) - Size of the scalar in basic machine types"

( http://www.opengl-redbook.com/appendices/AppL.pdf )

因此,有了这些信息,我在着色器中设置了一个统一的块,如下所示:

So, armed with this information, I setup a uniform block in my shader that looks something like this:

// Spotlight.

layout (std140) uniform Spotlight
{
    float Light_Intensity;
    vec4  Light_Ambient;
    vec3  Light_Position;   
};

...只是发现它不适用于我在CPU端设置的后续std140布局.也就是说,前4个字节是浮点数(GLfloat的机器标量类型的大小),后16个字节是vec4,随后的12个字节是vec3(最后留有4个字节以考虑该规则一个vec3确实是一个vec4).

... only to discover it doesn't work with the subsequent std140 layout I setup on the CPU side. That is the first 4 bytes are a float (size of the machine scalar type for GLfloat), the next 16 bytes are a vec4 and the following 12 bytes are a vec3 (with 4 bytes left over on the end to take account of the rule that a vec3 is really a vec4).

当我更改CPU端以将浮点数指定为与vec4相同的大小(即16字节),并按此假设进行偏移量和缓冲区大小时,着色器将按预期工作.

When I change the CPU side to specify a float as being the same size as a vec4, i.e. 16 bytes, and do my offsets and buffer size making this assumption, the shader works as intended.

因此,在这种情况下规范要么错误,要么我误解了标量"的含义,或者ATI出现了驱动程序错误.谁能揭开这个谜底?

So, either the spec is wrong or I've misunderstood the meaning of "scalar" in this context, or ATI have a driver bug. Can anyone shed any light on this mystery?

推荐答案

您链接到的PDF不是不是

That PDF you linked to is not the OpenGL specification. I don't know where you got it from, but that is certainly not the full list of rules. Always check your sources; the spec is not as unreadable as many claim it to be.

是的,基本类型的变量的 size 与基本计算机类型的大小相同(即:4个字节).但是,单独的大小并不能确定变量的位置.

Yes, the size of variables of basic types is the same size as the basic machine type (ie: 4 bytes). But size alone does not determine the position of the variable.

每种类型都有一个基本对齐方式,无论该类型在统一块中的什么位置,其总字节偏移量必须都适合该对齐方式. vec4的基本对齐方式是4 *其基本类型的对齐方式(即:float).因此vec4的基本对齐方式为16.

Each type has a base alignment, and no matter where that type is found in a uniform block, it's overall byte offset must fit that alignment. The base alignment of a vec4 is 4 * the alignment of its basic type (ie: float). So the base alignment of a vec4 is 16.

因为Light_Intensity在4个字节后结束,所以编译器必须插入12个字节的填充,因为Light_Ambient 不能在4字节边界上.它必须在16字节的边界上,因此编译器使用12字节的空白空间.

Because Light_Intensity ends after 4 bytes, the compiler must insert 12 bytes of padding, because Light_Ambient cannot be on a 4-byte boundary. It must be on a 16-byte boundary, so the compiler uses 12 bytes of empty space.

ATI确实在std140布局周围存在一些驱动程序错误,但这不是其中之一.

ATI does have a few driver bugs around std140 layout, but this isn't one of them.

作为一般规则,我喜欢将填充明确地放入结构中,并且避免使用vec3(因为它具有16个字节的对齐方式).通常,这样做可以减少编译器错误,也可以避免误解内容的去向以及它们实际占用的空间.

As a general rule, I like to explicitly put padding into my structures, and I avoid vec3 (because it has 16 byte alignment). Doing these generally cuts down on compiler bugs as well as accidental misunderstanding about where things go and how much room they actually take.

这篇关于OpenGL统一缓冲区std140布局,驱动程序错误或我误解了规范?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆