【发布时间】:2016-06-20 23:06:41
【问题描述】:
我一直在使用 GL3.3 编写一些东西,它采用统一缓冲区,并使用其中的信息在片段着色器中选择精灵图块。它在我的台式机上运行,配备 Nvidia GTX780,但我的基于 AMD 的笔记本电脑 (A6-4455M) 存在一些问题。两者都在最新(或最近)的驱动程序上。
回到代码,首先建立一个uniform buffer,由两个uint和一个uint数组组成。然后它们被填充,并在着色器中访问。起初我在笔记本电脑上遇到了一个 GL 错误,因为我没有分配足够的空间,但是考虑到填充的临时更改已经解决了这个问题,现在数据实际上正在被缓冲。
前两个 uint 没问题。我还在着色器中得到了一些可读的数组,只有一个问题;数据乘以四!目前数组只是一些测试数据,初始化为其索引,所以 spriteArr[1] == 1,spriteArr[34] == 34,等等。但是,在着色器中访问它, spriteArr[10] 给出 40。这一直到 spriteArr[143] == 572。除此之外,还有别的东西。我不知道这是为什么,但它似乎是一个不正确的偏移量。
我正在使用共享统一布局,并从 GL 本身获取统一偏移量,所以它们应该是正确的。我确实注意到 AMD 卡上的偏移量要大得多,好像它增加了更多的填充。它们在台式机上总是 0,4,8,而在笔记本电脑上总是 0,16,32。
如果有什么不同,还有另一个 UBO(绑定点 0),用于视图和投影矩阵。这些按预期工作。但是它不用于片段着色器。它也是在此 UBO 之前创建的。
UBO初始化代码:
GLuint spriteUBO;
glGenBuffers(1, &spriteUBO);
glBindBuffer(GL_UNIFORM_BUFFER, spriteUBO);
unsigned maxsize = (2 + 576 + 24) * sizeof(GLuint);
/*Bad I know, but temporary. AMD's driver adds 24 bytes of padding. Nvidias has none.
Not the cause of this problem. At least ensures we have enough allocated. */
glBufferData(GL_UNIFORM_BUFFER, maxsize, NULL, GL_STATIC_DRAW);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
//Set binding point
GLuint spriteUBOIndex = glGetUniformBlockIndex(programID, "SpriteMatchData");
glUniformBlockBinding(programID, spriteUBOIndex, 1);
static const GLchar *unames[] =
{
"width", "height",
//"size",
"spriteArr"
};
GLuint uindices[3];
GLint offsets[3];
glGetUniformIndices(programID,3,unames,uindices);
glGetActiveUniformsiv(programID, 3, uindices, GL_UNIFORM_OFFSET, offsets);
//buffer stuff
glBindBufferBase(GL_UNIFORM_BUFFER, 1, spriteUBO);
glBufferSubData(GL_UNIFORM_BUFFER,offsets[0], sizeof(GLuint), tm.getWidth());
glBufferSubData(GL_UNIFORM_BUFFER, offsets[1], sizeof(GLuint), tm.getHeight());
glBufferSubData(GL_UNIFORM_BUFFER, offsets[2], tm.getTileCount() * sizeof(GLuint), tm.getSpriteArray());
片段着色器:
layout (shared) uniform SpriteMatchData{
uint width, height;
uint spriteArr[576];};
然后我用这样的方式对数组进行实验:
if(spriteArr[10] == uint(40))
{
debug_colour = vec4(0.0,1.0,0.0,0.0);//green
}
else
{
debug_colour = vec4(1.0,0.0,0.0,0.0); //red
}
在这种情况下,debug_colour 变为绿色。
有什么办法可以用两个系统都可以的东西来解决这个问题吗?为什么 AMD 驱动程序处理这个问题的方式如此不同?会不会是它处理统一 uint 数组的方式的错误?
【问题讨论】: