1

の他の投稿は、GLSL スピンロックの種類に関する一般的な情報を収集することを目的としていますが、残念ながら何も得られておらず、問題も解決していません。したがって、具体的な質問です。以下に示す最小限の例に問題を減らしました。

些細な問題で、ロックの画面サイズのテクスチャと色のテクスチャが作成されます。パス 1 では、色はすべてゼロに設定されます (シェーダー 1)。パス 2 では、2 つの三角形が描画され、ジオメトリ シェーダーによって 4 倍になり、わずかにオフセットされます (シェーダー 2)。フラグメント シェーダーは、テクスチャの色をアトミックにインクリメントします。パス 3 では、色が視覚化されます (シェーダー 3)。

シェーダー 1:

//Vertex
#version 440
uniform mat4 mat_P;
in vec4 _vec_vert_a;
void main(void) {
    gl_Position = mat_P*_vec_vert_a;
}

//Fragment
#version 440
layout(rgba32f) coherent uniform image2D img0;
void main(void) {
    imageStore(img0,ivec2(gl_FragCoord.xy),vec4(0.0,0.0,0.0,1.0));
    discard;
}

シェーダー 2:

//Vertex
#version 440
in vec4 _vec_vert_a;
out vec4 vert_vg;
void main(void) {
    vert_vg = _vec_vert_a;
}

//Geometry
#version 440
#define REPS 4
layout(triangles) in;
layout(triangle_strip,max_vertices=3*REPS) out;
uniform mat4 mat_P;
in vec4 vert_vg[3];
void main(void) {
    for (int rep=0;rep<REPS;++rep) {
        for (int i=0;i<3;++i) {
            vec4 vert = vert_vg[i];
            vert.xy += vec2(5.0*rep);
            gl_Position = mat_P*vert; EmitVertex();
        }
        EndPrimitive();
    }
}

//Fragment
#version 440
layout(rgba32f) coherent uniform image2D img0;
layout(r32ui) coherent uniform uimage2D img1;
void main(void) {
    ivec2 coord = ivec2(gl_FragCoord.xy);
    bool have_written = false;
    do {
        bool can_write = (imageAtomicExchange(img1,coord,1u)!=1u);
        if (can_write) {
            vec4 data = imageLoad(img0,coord);
            data.xyz += vec3(1.0,0.0,0.0);
            imageStore(img0,coord,data);
            memoryBarrier();
            imageAtomicExchange(img1,coord,0);
            have_written = true;
        }
    } while (!have_written);
    discard;
}

シェーダー 3:

//Vertex
#version 440
uniform mat4 mat_P;
in vec4 _vec_vert_a;
void main(void) {
    gl_Position = mat_P*_vec_vert_a;
}

#version 440
layout(rgba32f) coherent uniform image2D img0;
void main(void) {
    vec4 data = imageLoad(img0,ivec2(gl_FragCoord.xy));
    gl_FragData[0] = vec4(data.rgb/4.0, 1.0); //tonemap
}

メインループ:

  1. シェーダー 1 を有効にする
  2. フルスクリーン クワッドをレンダリングする
  3. glMemoryBarrier(GL_ALL_BARRIER_BITS);

  4. シェーダー 2 を有効にする

  5. 2 つの小さな三角形をレンダリングする
  6. glMemoryBarrier(GL_ALL_BARRIER_BITS);

  7. シェーダー 3 を有効にする

  8. フルスクリーン クワッドをレンダリングする

手順 3 と 6 で、GL_SHADER_IMAGE_ACCESS_BARRIER_BIT を使用できた[と思う]ことに注意してください。念のため、私は保守的です。

視覚化された色は、時間の経過とともにジッターし、ほとんどの場合かなり小さいです。これは、原子性が発生していないことを示しています。誰かがこの手順を正気でチェックできますか? 何か不足していますか?

編集:このページから、使用discardするとフラグメントで画像のロード/ストアが未定義になる可能性があることがわかりました。破棄を削除しましたが、問題は引き続き発生します。また、初期のフラグメント テストを強制するも見つかりましlayout(early_fragment_tests) in;た (どちらも役に立ちませんでした)。

4

1 に答える 1