#version 310 es
#extension GL_OES_shader_image_atomic : require
layout(local_size_x = 1) in;

layout(r32ui, binding = 0) uniform highp uimage2D uImage;
layout(r32i, binding = 1) uniform highp iimage2D iImage;
layout(binding = 2, std430) buffer SSBO
{
    uint u32;
    int i32;
} ssbo;

void main()
{
    imageAtomicAdd(uImage, ivec2(1, 5), 1u);

    // Test that we do not invalidate OpImage variables which are loaded from UniformConstant
    // address space.
    imageStore(iImage, ivec2(1, 6), ivec4(imageAtomicAdd(uImage, ivec2(1, 5), 1u)));

    imageAtomicOr(uImage, ivec2(1, 5), 1u);
    imageAtomicXor(uImage, ivec2(1, 5), 1u);
    imageAtomicAnd(uImage, ivec2(1, 5), 1u);
    imageAtomicMin(uImage, ivec2(1, 5), 1u);
    imageAtomicMax(uImage, ivec2(1, 5), 1u);
    //imageAtomicExchange(uImage, ivec2(1, 5), 1u);
    imageAtomicCompSwap(uImage, ivec2(1, 5), 10u, 2u);

    imageAtomicAdd(iImage, ivec2(1, 6), 1);
    imageAtomicOr(iImage, ivec2(1, 6), 1);
    imageAtomicXor(iImage, ivec2(1, 6), 1);
    imageAtomicAnd(iImage, ivec2(1, 6), 1);
    imageAtomicMin(iImage, ivec2(1, 6), 1);
    imageAtomicMax(iImage, ivec2(1, 6), 1);
    //imageAtomicExchange(iImage, ivec2(1, 5), 1u);
    imageAtomicCompSwap(iImage, ivec2(1, 5), 10, 2);

    atomicAdd(ssbo.u32, 1u);
    atomicOr(ssbo.u32, 1u);
    atomicXor(ssbo.u32, 1u);
    atomicAnd(ssbo.u32, 1u);
    atomicMin(ssbo.u32, 1u);
    atomicMax(ssbo.u32, 1u);
    atomicExchange(ssbo.u32, 1u);
    atomicCompSwap(ssbo.u32, 10u, 2u);

    atomicAdd(ssbo.i32, 1);
    atomicOr(ssbo.i32, 1);
    atomicXor(ssbo.i32, 1);
    atomicAnd(ssbo.i32, 1);
    atomicMin(ssbo.i32, 1);
    atomicMax(ssbo.i32, 1);
    atomicExchange(ssbo.i32, 1);
    atomicCompSwap(ssbo.i32, 10, 2);
}