PDA

View Full Version : Compute shader : barrier issue?



qnoper
11-22-2014, 10:27 AM
Hello there.

To begin, I am sorry for my english, but I am going to do the maximum to explain as good I can.

I am a beginner with Compute shader.
I tried to implement my own SSAO algorithm (I know it's not espacially the best method, but it's only to improve my level ^^.

So, I have one problem with barrier function. I think my problem is in rapport with dynamically uniform, but I don't know why it does not work.

I use a block with 16 x 16 threads and 20 x 20 shared value (cause I have an "extern radius" 2 in left, right, down and top).

It's my code.


#version 440 core

/* Uniform */
#define CONTEXT 0
#define MATRIX 1
#define MATERIAL 2
#define POINT_LIGHT 3

layout(local_size_x = 16, local_size_y = 16) in;

readonly layout(binding = 1, rgba32f) uniform image2D position;
readonly layout(binding = 2, rgba16_snorm) uniform image2D normal;
readonly layout(binding = 3, r32f) uniform image2D distSquare;

writeonly layout(binding = 4, r32f) uniform image2D AO;

struct sharedStruct
{
vec3 position;
float distSquare;
};

shared sharedStruct value[20][21];

void main(void)
{
float ao = 0.0;
ivec2 tID = ivec2(gl_LocalInvocationID.xy);

ivec2 texCoordSample = ivec2(gl_GlobalInvocationID.xy);

vec3 normal = imageLoad(normal, texCoordSample).xyz;

// To radius
// left down coin
if(tID.y < 2 && tID.x < 2)
{
value[tID.y][tID.x].position = imageLoad(position, texCoordSample + tID + ivec2(-2, -2)).xyz;
value[tID.y][tID.x].distSquare = imageLoad(distSquare, texCoordSample + tID + ivec2(-2, -2)).x;
}

// left top coin
else if(tID.y > 13 && tID.x < 2)
{
value[tID.y + 4][tID.x].position = imageLoad(position, texCoordSample + tID + ivec2(-2, 2)).xyz;
value[tID.y + 4][tID.x].distSquare = imageLoad(distSquare, texCoordSample + tID + ivec2(-2, 2)).x;
}

// right down coin
else if(tID.y < 2 && tID.x > 13)
{
value[tID.y][tID.x + 4].position = imageLoad(position, texCoordSample + tID + ivec2(2, -2)).xyz;
value[tID.y][tID.x + 4].distSquare = imageLoad(distSquare, texCoordSample + tID + ivec2(2, -2)).x;
}

// right top coin
else if(tID.y > 13 && tID.x > 13)
{
value[tID.y + 4][tID.x + 4].position = imageLoad(position, texCoordSample + tID + ivec2(2, 2)).xyz;
value[tID.y + 4][tID.x + 4].distSquare = imageLoad(distSquare, texCoordSample + tID + ivec2(2, 2)).x;
}

// down band without coins
else if(tID.y < 2)
{
value[tID.y][tID.x + 2].position = imageLoad(position, texCoordSample + tID + ivec2(0, -2)).xyz;
value[tID.y][tID.x + 2].distSquare = imageLoad(distSquare, texCoordSample + tID + ivec2(0, -2)).x;
}

// top band without coins
else if(tID.y > 13)
{
value[tID.y + 4][tID.x + 2].position = imageLoad(position, texCoordSample + tID + ivec2(0, 2)).xyz;
value[tID.y + 4][tID.x + 2].distSquare = imageLoad(distSquare, texCoordSample + tID + ivec2(0, 2)).x;
}

// left band without coins
else if(tID.x < 2)
{
value[tID.y + 2][tID.x].position = imageLoad(position, texCoordSample + tID + ivec2(-2, 0)).xyz;
value[tID.y + 2][tID.x].distSquare = imageLoad(distSquare, texCoordSample + tID + ivec2(-2, 0)).x;
}

// right band without coins
else if(tID.x > 13)
{
value[tID.y + 2][tID.x + 4].position = imageLoad(position, texCoordSample + tID + ivec2(2, 0)).xyz;
value[tID.y + 2][tID.x + 4].distSquare = imageLoad(distSquare, texCoordSample + tID + ivec2(2, 0)).x;
}

tID += ivec2(2, 2);

// These instruction works.
value[tID.y][tID.x].position = imageLoad(position, texCoordSample).xyz;
value[tID.y][tID.x].distSquare = imageLoad(distSquare, texCoordSample).x;

barrier();

for(int j = -2; j < 3; ++j)
{
for(int i = -2; i < 3; ++i)
{
ivec2 texCoordRay = tID + ivec2(i, j);

float c = dot(normal,
normalize(value[texCoordRay.y][texCoordRay.x].position - value[tID.y][tID.x].position));

// Out of hemisphere
if(c < 0.0)
c = -c;

if(value[texCoordRay.y][texCoordRay.x].distSquare < value[tID.y][tID.x].distSquare)
ao += c;
}
}

imageStore(AO, texCoordSample, vec4((1 - ao / 25), 0.0, 0.0, 0.0));
}

I don't have issue with these instructions

// These instruction works.
value[tID.y][tID.x].position = imageLoad(position, texCoordSample).xyz;
value[tID.y][tID.x].distSquare = imageLoad(distSquare, texCoordSample).x;

But a code above seem not synchronize because I have glitters...

Thanks to your help :).