Compute shader runs more than once?!

Started by
24 comments, last by theagentd 9 years, 7 months ago

I've converted your Java code to C++, and oddly enough I get even worse results than you tongue.png

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.
Advertisement

Does the Java program I uploaded work on your AMD card? That'd rule out a lot of things. I could imagine that the C++ compiler optimizes the loop you have since it assumes that the value of *mappedBuffer does not change inside the loop or something like that... Anyway, it'd be nice to know if my Java version works, as that program worked perfectly fine on my HD7790.

I tried downloading it, but it said too many people had downloaded it :P

I'm unsure what that means... Hopefully it'll clear up once some time has passed?

Same problem with your Java program, but I'm tempted to put this down to a driver bug. I can't see anything wrong with the code, and it doesn't make sense that it doesn't work after doing a swap buffers.

Yeah, that's basically what this all boils down to. I've given up on reporting bugs to Nvidia as I never get any kind of response or feedback at all, so I'll just wait until the next driver comes out...

This topic is closed to new replies.

Advertisement