如何强制OpenCL不重新排列结构?

时间:2015-11-10 10:51:10

标签: opengl opencl

我正在构建一个内核代码,用于捕获当前GL场景中的三角形 为此,我将顶点流与我的索引一起发送到内核代码。

这是我的内核条目的声明:

__kernel
void CaptureTriangles(
    const uint NumTriangles,
    const float16 WorldMatrix,
    __constant ushort3 *IndexDataBlock,
    __constant struct Vertex *DataBlock,
    __global struct Triangle *TriangleBuffer,
    __global uint *TriangleBufferCount)

Vertex结构定义如下:

struct Vertex
{
    float3  position;
    float3  normal;
    float   materialIndex;
}
__attribute__((packed));

现在,此流是通过GL创建的,以及数据的布局方式。

在获取三角形时,我在内核代码中执行以下操作:

const ushort3 idx = IndexDataBlock[get_global_id(0)];
const struct Vertex v0 = DataBlock[idx.x],
                    v1 = DataBlock[idx.y],
                    v2 = DataBlock[idx.z];

但似乎OpenCL继续将Vertex结构重新调整到它自己的内部要求,即使它被声明为__attribute((packed))。 因此,三角形永远不会被正确捕获。

__constant struct Vertex *DataBlock切换到__constant float *DataBlock并在内核代码中显式获取每个浮动修复了该问题。 因此,当通过float读取float时,这是有效的:

// __constant float *DataBlock
float4 p0 = (float4)(DataBlock[7 * idx.x + 0], DataBlock[7 * idx.x + 1], DataBlock[7 * idx.x + 2], 1.0f),
       p1 = (float4)(DataBlock[7 * idx.y + 0], DataBlock[7 * idx.y + 1], DataBlock[7 * idx.y + 2], 1.0f),
       p2 = (float4)(DataBlock[7 * idx.z + 0], DataBlock[7 * idx.z + 1], DataBlock[7 * idx.z + 2], 1.0f);

我宁愿使用struct Vertex语法来提高代码清晰度,有没有办法让OpenCL不重新对齐结构?

1 个答案:

答案 0 :(得分:3)

对于CL,cl_float3cl_float4的大小相等。但在您的情况下,您的GL代码会将真实float3值作为输出。

__attribute__((packed))无法解决您的问题,因为对于CL,结构已经打包,内部的元素大小不同。

我害怕你必须手动解析它。