// cc -Wall -Wextra -g -std=c99 -lglut -lGLEW -lGL test_debug.c -o test_debug
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <GL/glew.h>
#include <GL/gl.h>
#include <GL/freeglut.h>
struct State
{
GLuint buffers[2];
GLuint shader_program;
} state;
void debug
(GLenum source,
GLenum type,
GLuint id,
GLenum severity,
GLsizei length,
const GLchar* message,
GLvoid* userParams)
{
printf("DEBUG: %s\n", message);
}
char *read_file(char *filename)
{
FILE* fp = fopen(filename, "r");
assert(fp);
fseek(fp, 0, SEEK_END);
long size = ftell(fp);
fseek(fp, 0, SEEK_SET);
char * data = malloc(sizeof(char) * size + 1);
size_t r = fread(data, sizeof(char), size, fp);
assert(r == size);
data[size] = '\0';
fclose(fp);
return data;
}
void init2()
{
// Compute shader creation
GLuint compute_shader = glCreateShader(GL_COMPUTE_SHADER);
const GLchar * csSrc = read_file("test.cs");
GLint size = strlen(csSrc);
glShaderSource(compute_shader, 1, &csSrc, &size);
glCompileShader(compute_shader);
// link of program
state.shader_program = glCreateProgram();
glAttachShader(state.shader_program, compute_shader);
glLinkProgram(state.shader_program);
// Display errors
char infoLog[10000];
glGetProgramInfoLog(state.shader_program, sizeof(infoLog), NULL, infoLog);
printf("%s\n", infoLog);
// buffer creation (input and output)
glGenBuffers(2, state.buffers);
// fill the input buffer with numbers
float data[32];
for(unsigned int i = 0; i < 32; ++i)
data[i] = i;
glBindBuffer( GL_SHADER_STORAGE_BUFFER, state.buffers[0] );
glBufferData( GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_DYNAMIC_DRAW );
// resize the output buffer
glBindBuffer(GL_SHADER_STORAGE_BUFFER, state.buffers[1]);
// XXX depending of the choice I use, I got right/wrong results
//GLenum choice = GL_STATIC_DRAW; // NO
//GLenum choice = GL_STATIC_READ; // NO
//GLenum choice = GL_STATIC_COPY; // NO
//GLenum choice = GL_DYNAMIC_DRAW; // NO
//GLenum choice = GL_DYNAMIC_READ; // YES
//GLenum choice = GL_DYNAMIC_COPY; // YES
//GLenum choice = GL_STREAM_DRAW; // NO
GLenum choice = GL_STREAM_READ; // YES
//GLenum choice = GL_STREAM_COPY; // YES
glBufferData( GL_SHADER_STORAGE_BUFFER, sizeof(data), NULL, choice);
glMemoryBarrier(GL_ALL_BARRIER_BITS);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
}
void renderScene2()
{
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, state.buffers[0]);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, state.buffers[1]);
glUseProgram(state.shader_program);
// Ugly memory sync because I don't know what I'm doing, I want to be sure that all my data are sent
glMemoryBarrier(GL_ALL_BARRIER_BITS);
glDispatchCompute(1, 1, 1);
// Ugly memory sync because I don't know what I'm doing, I want to bu sure that my shader correctly modified the data
glMemoryBarrier(GL_ALL_BARRIER_BITS);
glUseProgram(0);
// Get the resul0t back
float result[32];
// Ugly init of the result vector for debug
for(unsigned int i = 0; i < 32; ++i)
result[i] = -2;
glBindBuffer(GL_SHADER_STORAGE_BUFFER, state.buffers[1]);
glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, sizeof(result), result);
// Get and display the results
for(unsigned int i = 0; i < 32; ++i)
printf("%f\n", result[i]);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
}
int main(int argc, char **argv) {
// init GLUT and create Window
glutInit(&argc, argv);
//glutInitContextVersion(4, 3);
glutInitContextFlags(GLUT_CORE_PROFILE | GLUT_DEBUG);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowSize(800, 600);
glutCreateWindow("Instance Test");
// C'est pour glew, pour recuperer toutes les extensions
glewInit();
glEnable(GL_DEBUG_OUTPUT);
glDebugMessageCallback(&debug, NULL);
printf("VERSION: %s\n", glGetString(GL_VERSION));
printf("RENDERER: %s\n", glGetString(GL_RENDERER));
printf("VENDOR: %s\n", glGetString(GL_VENDOR));
GLint mcsms;
glGetIntegerv(GL_MAX_COMPUTE_SHARED_MEMORY_SIZE, &mcsms);
printf("GL_MAX_COMPUTE_SHARED_MEMORY_SIZE: %d\n", mcsms);
glutDisplayFunc(renderScene2);
init2();
renderScene2();
//glutMainLoop();
return 0;
}