假设我有以下顶点着色器代码:
#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)
我使用英特尔高清显卡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 docs表示:
如果pname为
GL_UNIFORM_BLOCK_DATA_SIZE
,则返回由uniformBlockIndex标识的统一块中保存所有活动制服所需的与实现相关的最小总缓冲区对象大小,以基本机器单位。既不保证也不期望给定的实现将在缓冲区对象中紧密打包的统一值排列。例外情况是std140统一块布局,它保证了特定的打包行为,并且不需要应用程序查询偏移和步幅。在这种情况下,仍然可以查询最小大小,即使它是根据统一块声明预先确定的。
那么在这种情况下,我应该如何衡量blockSize
中的8192号码?在float
s?在byte
s?
如果我使用数字,则4x4矩阵mat4
制服总共有16个float
个组件,这些组件适合64个bytes
,所以至少我需要16 x 4 x 128
1}}字节来存储128个矩阵,确实是8192
。
为什么硬件也要求64(bytes
?)的数组步幅和16(bytes
?)的矩阵步幅,但只请求8192个字节? getUniformBlockParameter(GL_UNIFORM_BLOCK_DATA_SIZE)
不应该为对齐/填充目的请求更多空间吗?
答案 0 :(得分:4)
数组步长是从一个数组元素的开头到下一个数组元素的开头的字节偏移量。在这种情况下,数组元素是mat4
s,其大小为 64字节。因此,阵列步幅尽可能小。
矩阵步幅是从一列/一行矩阵数据到下一行的字节偏移量。每个mat4
的列或行大小为vec4
,这意味着它的大小为 16字节。再次,矩阵列/行紧密包装。
所以8KiB是这种存储的预期大小。
话虽如此,这完全无关紧要。你根本不应该费心去查询这些东西。通过使用std140
布局,您已经强制 OpenGL采用特定布局。一个特别需要mat4
s具有64字节的数组步长并且具有16字节的矩阵步长。你不必要求实现这个;它是标准的必需。
您只需要询问您是使用shared
还是packed
。