2

我正在尝试使用嵌套结构来模拟 GLSL 中的多态性之类的东西。

struct Primitve{
   Sphere s;
   Plane p;
   Triangle t;
   int type;
};

整数类型指定了这个原语的真正含义。通过这种方式,我可以将所有原语放在一个数组中。一个缺点是内存的浪费。

所以我的问题是关于“打包”布局类型。当我使用这种类型创建着色器存储缓冲区时

layout(packed) buffer PrimitiveBuffer{
   Primitive primitives[];
};

是否会通过不为根本不使用的成员分配数据来优化此数据块?Wiki 对打包布局说:“此外,如果实现发现块的成员不影响着色器的结果,则可以对其进行优化。”

我是正确的还是由于对齐限制而仅涉及划桨?

4

2 回答 2

2

编译器可以优化元素吗?是的。吗?仅当它可以静态确定它们未使用时。

考虑这个函数:

void ProcessPrimitive(int index)
{
  if(primitives[index].type == 0)
  {
    primitives[index].s ...
  }
  else if(primitives[index].type == 1)
  {
    primitives[index].p ...
  }
  else
  {
    primitives[index].t ...
  }
}

编译器如何知道,对于特定索引,该type字段将是什么?它怎么知道一个特定的索引将是一个球体或其他什么?它不能。因此,它无法优化任何东西。

如果你想节省空间,你将不得不自己实现数据转换。因此,您必须在 Primitive 中存储通用的信息“浮点数”,可以根据类型字段将其转换为 Sphere/etc。

于 2013-03-18T02:02:21.880 回答
1

这取决于您是否要在多个着色器程序之间共享缓冲区。

如果你不这样做,你可以使用一个打包的内存布局,基本上告诉你的实现:“这个块中的任何变量,没有使用(因为不影响着色器阶段的结果)可能会被优化掉。”

但请记住,在这种情况下,您必须显式查询块内成员的位置。

最后,由您的 GLSL 实现来找出“不影响着色器的结果”的内容。我想你必须做一些分析。

于 2013-03-17T19:46:15.530 回答