并发SSBO读数在片段着色器中出现故障

时间:2018-11-11 16:17:15

标签: multithreading opengl graphics glsl gpu

主要修改:

我有一个着色器设置SSBO的值:

#version 430

//Input variables
in vec3 f_pos;
in vec3 f_norm;
in vec3 f_uv;

struct Voxel_Node
{
    vec4 color;
    vec4 normal;
    uint children[8];
};
//Buffer for the rest of the tree
layout(std430, binding = 0) buffer tree_buffer
{
    uint t_index;
    uint pad1;
    uint pad2;
    uint pad3;
    Voxel_Node tree[];
};

void main()
{
    tree[0].children[7] = 1;
    tree[1].children[0] = 2;
    tree[2].children[7] = 3;
    tree[3].children[0] = 4;
    tree[4].children[7] = 5;

    tree[0].normal = vec4(0,0,1,1);
    tree[1].normal = vec4(0,1,0,1);
    tree[2].normal = vec4(0,1,1,1);
    tree[3].normal = vec4(1,0,0,1);
    tree[4].normal = vec4(1,0,1,1);
    tree[5].normal = vec4(1,1,0,1);
}

从SSBO中读取一个着色器:

#version 430
#pragma optimize (off)

in vec2 f_coord;

out vec4 fragment_color;

struct Voxel_Node
{
    vec4 color;
    vec4 normal;
    uint children[8];
};
//Buffer for the rest of the tree
layout(std430, binding = 0) buffer tree_buffer
{
    uint t_index;
    uint pad1;
    uint pad2;
    uint pad3;
    Voxel_Node tree[];
};


void main()
{
    fragment_color = vec4(tree[1].children[0]);
    int pls = int(tree[1].children[0]);
    //set 1
    fragment_color = vec4(pls);         //white
    //fragment_color = vec4(pls-1);     //white
    //fragment_color = vec4(pls-2);     //black
    //fragment_color = vec4(pls)/2.f;   //grey

    //Set 2
    fragment_color = tree[pls].normal;      //blue
    //fragment_color = tree[pls+2].normal;  //cyan
    //fragment_color = tree[2].normal;      //cyan
}

有2组测试。首先,注释掉tree[value].normal块。

因此片段的颜色取决于pls的值。一次只能将2个块之一取消,并且每个块中只有一行。右边的值是测试的结果颜色。

第一个测试块成功完成,所有这些都是预期的输出。对于第二个测试块,第一个输出应为蓝色,而secddn输出不应为青色。

根据这些测试,第一组测试读取的pls值为2,第二组读取的pls值为0。

除了尝试读取SSBO的内容外,没有其他逻辑,什么可能导致这种行为?

编辑:

我认为可能是由于这个原因,但我不确定:

https://www.khronos.org/opengl/wiki/Memory_Model#Incoherent_memory_access

更新:

将SSBO设置为恒定大小可以解决此问题,但是我宁愿能够使用不同大小的ssbo。

coherent layout(std430, binding = 0) buffer tree_buffer
{
    uint t_index;
    uint pad1;
    uint pad2;
    uint pad3;
    Voxel_Node tree[8];
};

将代码修改为上述结果会带来预期的行为

0 个答案:

没有答案
相关问题