假设我有以下顶点着色器代码:
#version 330
uniform mat4 ProjectionMatrix, CameraMatrix, SingleModelMatrix;
uniform uint SingleModel;
layout (std140) uniform ModelBlock {
mat4 ModelMatrices[128];
};
void main(void) {
... something that uses ModelMatrices
}
如果在我的程序中,我为代表上述着色器的程序对象发出以下 OpenGL 调用:
getUniformBlockParameter(GL_UNIFORM_BLOCK_DATA_SIZE)
我使用 Intel HD Graphics 4000 卡发现以下内容:
GLUniformBlock[
name: ModelBlock,
blockSize: 8192,
buffer: java.nio.HeapByteBuffer[pos=0 lim=8192 cap=8192],
metadata: {
ModelMatrices=GLUniformBlockAttributeMetadata[
name: ModelMatrices,
offset: 0,
arrayStride: 64,
matrixStride: 16,
matrixOrder: 0
]},
uniforms: GLUniformInterface[
uniforms: {
ModelMatrices=GLUFloatMat4 [
name:ModelMatrices,
idx:2,
loc:-1,
size:128,
glType:8b5c]
}
]
]
我应该如何解释blockSize
参数?OpenGL 3 sdk 文档 指出:
如果 pname 是
GL_UNIFORM_BLOCK_DATA_SIZE
,则返回与实现相关的最小总缓冲区对象大小(以基本机器单位为单位),用于保存由 uniformBlockIndex 标识的统一块中的所有活动统一。既不保证也不期望给定的实现会将统一值安排为紧密包装在缓冲区对象中。对此的例外是 std140 统一块布局,它保证特定的打包行为并且不需要应用程序查询偏移量和步幅。在这种情况下,仍然可以查询最小大小,即使它只是基于统一块声明预先确定的。
那么在这种情况下,我应该如何测量 8192 中的数字blockSize
?在float
s? 在byte
s?
如果我计算数字,一个 4x4 矩阵mat4
制服共有 16 个float
分量,适合 64 bytes
,所以至少我需要大约16 x 4 x 128
字节来存储 128 个矩阵,这确实是8192
.
那么为什么硬件还要求数组步长为 64( ? ),矩阵步长bytes
为 16( ?),但只请求 8192 个字节?bytes
不应该getUniformBlockParameter(GL_UNIFORM_BLOCK_DATA_SIZE)
为对齐/填充目的请求更多空间吗?