1

頂点とインデックスを読み取るために opencl-opengl 相互運用性を使用する OpenCL カーネルを作成しましたが、インデックスで特定の頂点を取得するために単純なポインターの追加を行っているだけなので、おそらくこれは重要ではありません。

uint pos = (index + base)*stride;

ここでは絶対位置をバイト単位で計算しています。この例では、pos は 28,643,328 で、ストライドは 28、インデックス = 0、ベース = 1,022,976 です。まあ、それは正しいようです。

残念ながら、vload3offset パラメータはバイト単位の絶対アドレスとして計算されないため、直接使用することはできません。posだから私はポインタに追加するだけですvoid* vertices_gl

void* new_addr = vertices_gl+pos;

new_addr私の例では = 0x2f90000 であり、これが奇妙な部分の始まりです。

vertices_gl= 0x303f000


結果 ( new_addr) は 0x4B90000 (0x303f000 + 28,643,328) になります。

アドレス vertices_gl が 716,800 (0xAF000) 減少する理由がわかりません


GPU をターゲットにしています: AMD Radeon HD5830

Ps: 疑問に思っている人のために、私はこれらの値を取得するために printf を使用しています :) (CodeXL を動作させることができませんでした)

4

1 に答える 1

5

ポインターのポインター演算はありませんvoid*。ポインターを使用char*して、バイト単位のポインター計算を実行します。

または、それよりもはるかに優れています。ポインターが指している実際の型を使用し、オフセットを乗算しないでください。vertex[index+base]28バイトのデータを含む型への想定vertexポイントを書くだけです。

パフォーマンスに関する考慮事項:合体メモリ アクセスのために、頂点属性を 2 の累乗に合わせます。つまり、各頂点エントリの後に 4 バイトのパディングを追加します。これを自動的に行うにはfloat8、アトリビュートがすべて浮動小数点値の場合に頂点タイプとして使用します。位置データや法線データなどを扱うことを想定しているため、便利でわかりやすい方法で両方のベクトルをカプセル化するカスタム構造体を作成することをお勧めします。

// Defining a type for the vertex data. This is 32 bytes large.
// You can share this code in a header for inclusion in both OpenCL and C / C++!
typedef struct {
    float4 pos;
    float4 normal;
} VertexData;

// Example kernel
__kernel void computeNormalKernel(__global VertexData *vertex, uint base) {
    uint index = get_global_id(0);
    VertexData thisVertex = vertex[index+base];   // It can't be simpler!
    thisVertex.normal = computeNormal(...);       // Like you'd do it in C / C++!
    vertex[index+base] = thisVertex;              // Of couse also when writing
}

float4注: s の1 つを a に変更しただけでは、このコードは 28 のストライドでは機能しません。メモリの 4 つのフロートも消費するfloat3ためです。float3ただし、パディングを追加しない次のように書くこともできます (ただし、これはメモリ アクセス帯域幅にペナルティを課すことに注意してください)。

typedef struct {
    float pos[4];
    float normal[3];  // Assuming you want 3 floats here
} VertexData;
于 2013-06-16T23:09:05.603 に答える