I've converted your Java code to C++, and oddly enough I get even worse results than you
The editor seems to have eaten the tabs, but it compiles/runs.
[source=c++]#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <cstdio>
static const char *shaderSource = "#version 430\n"
"\n"
"layout(std430, binding = 0) buffer Data{\n"
" int data[];\n"
"} dataBuffer;\n"
"\n"
"layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
"\n"
"void main(){\n"
" int offset = int(gl_GlobalInvocationID.x);\n"
" dataBuffer.data[offset]++;\n"
"}\n"
;
#define CHECK() \
{ \
GLenum err; \
while ((err = glGetError()) != GL_NO_ERROR) { \
printf("GL ERROR: 0x%x\n", err); \
} \
}
int main()
{
if ( !glfwInit() )
{
return -1;
}
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_COMPAT_PROFILE);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 4);
GLFWwindow *window = glfwCreateWindow(640, 480, "Compute", nullptr, nullptr);
if ( window == nullptr )
{
return -1;
}
glfwMakeContextCurrent(window);
if ( glewInit() != GLEW_OK )
{
return -1;
}
GLuint buffer;
glGenBuffers(1, &buffer); //Different in Java.
glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer);
glBufferStorage(GL_SHADER_STORAGE_BUFFER, 4, nullptr, GL_MAP_WRITE_BIT | GL_MAP_READ_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT); //Create 4-byte buffer.
//Map 4-byte buffer. Different in Java. The returned pointer is wrapped in a ByteBuffer.
int *mappedBuffer = (int *)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 4, GL_MAP_WRITE_BIT | GL_MAP_READ_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
int computeShader = glCreateShader(GL_COMPUTE_SHADER);
glShaderSource(computeShader, 1, &shaderSource, nullptr);
glCompileShader(computeShader);
GLint status;
glGetShaderiv(computeShader, GL_COMPILE_STATUS, &status);
if ( status != GL_TRUE )
{
printf("COMPILE FAILED\n");
return -1;
}
CHECK();
int computeShaderProgram = glCreateProgram();
glAttachShader(computeShaderProgram, computeShader);
glLinkProgram(computeShaderProgram);
CHECK();
int passes = 0;
int fails = 0;
while ( !glfwWindowShouldClose(window) )
{
glfwPollEvents();
*mappedBuffer = 0;
//Execute compute shader
glUseProgram(computeShaderProgram);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, buffer);
glDispatchCompute(1, 1, 1);
//Wait for the compute shader to finish. Warn if an error occurs.
GLsync syncObject = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
int waitResult = glClientWaitSync(syncObject, 0, 1000*1000*1000);
if(waitResult == GL_WAIT_FAILED || waitResult == GL_TIMEOUT_EXPIRED){
printf("WAIT FAILED!!!\n");
}
glDeleteSync(syncObject);
//Read back result from the buffer.
int result = *mappedBuffer; //Get int from index 0
//Update statistics
if(result == 1){
passes++;
}else{
fails++;
}
//Print out the statistics every 1 000 run
if((passes + fails) % 1000 == 0){
printf("Correct result: %d\n", passes);
printf("Wrong result: %d\n", fails);
printf("Correct percentage: %.6f%%", 100 * (double)passes/(passes + fails));
printf("\n"); //new line
glClear(GL_COLOR_BUFFER_BIT);
glfwSwapBuffers(window);
}
}
glDeleteShader(computeShader);
glDeleteProgram(computeShaderProgram);
glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
glDeleteBuffers(1, &buffer);
glfwDestroyWindow(window);
glfwTerminate();
return 0;
}[/source]
I'm pretty sure I've converted it properly. Anyhow, what I'm seeing is it works perfectly up until I swap buffers. After that, the value in the mapped buffer is always 0. I have an AMD Radeon HD 6870 with latest Catalyst 14.7 beta drivers.