22 if(m_image.pixels.size() == 0)
27 GLenum data_type= GL_UNSIGNED_BYTE;
28 GLenum data_format= GL_RGBA;
29 if(m_image.channels == 1)
31 else if(m_image.channels == 2)
33 else if(m_image.channels == 3)
36 glGenTextures(1, &m_texture);
37 glBindTexture(GL_TEXTURE_2D, m_texture);
38 glTexImage2D(GL_TEXTURE_2D, 0,
39 GL_RGBA8, m_image.width, m_image.height, 0,
40 data_format, data_type, m_image.data());
43 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
46 glGenBuffers(1, &m_histogram);
47 glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_histogram);
48 glBufferData(GL_SHADER_STORAGE_BUFFER,
sizeof(
int) * 16,
nullptr, GL_STATIC_COPY);
50 m_program=
read_program(
"gkit2_tutos/M2/histogram1.glsl");
53 glGetProgramiv(m_program, GL_COMPUTE_WORK_GROUP_SIZE, m_threads);
56 glGenQueries(1, &m_time_query);
60 auto start= std::chrono::high_resolution_clock::now();
62 int histogram[16]= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
63 for(
unsigned y= 0; y < m_image.height; y++)
64 for(
unsigned x= 0; x < m_image.width; x++)
66 unsigned offset= m_image.offset(x, y);
67 int r= m_image.pixels[offset];
68 int g= m_image.pixels[offset+1];
69 int b= m_image.pixels[offset+2];
70 int bin= 15 * (r+g+b) / (255*3);
74 auto stop= std::chrono::high_resolution_clock::now();
75 int cpu_time= std::chrono::duration_cast<std::chrono::microseconds>(stop - start).count();
77 for(
int i= 0; i < 16; i++)
78 printf(
"bin %d: %d pixels, %d%%\n", i, histogram[i], 100*histogram[i] / (m_image.width * m_image.height));
80 printf(
"cpu %dus\n", cpu_time);
98 glClear(GL_COLOR_BUFFER_BIT);
100 glUseProgram(m_program);
103 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_histogram);
105 glClearBufferData(GL_SHADER_STORAGE_BUFFER, GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT, 0);
108 glBindImageTexture(0, m_texture, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA8);
110 program_uniform(m_program,
"image", 0);
112 int nx= m_image.width / m_threads[0];
113 int ny= m_image.height / m_threads[1];
117 glBeginQuery(GL_TIME_ELAPSED, m_time_query);
121 glDispatchCompute(nx, ny, 1);
124 glMemoryBarrier(GL_ALL_BARRIER_BITS);
126 glEndQuery(GL_TIME_ELAPSED);
133 glGenBuffers(1, &buffer);
134 glBindBuffer(GL_COPY_READ_BUFFER, buffer);
135 glBufferData(GL_COPY_READ_BUFFER,
sizeof(
int) * 16,
nullptr, GL_DYNAMIC_READ);
138 glCopyBufferSubData(GL_SHADER_STORAGE_BUFFER, GL_COPY_READ_BUFFER, 0, 0,
sizeof(
int) * 16);
141 glGetBufferSubData(GL_COPY_READ_BUFFER, 0,
sizeof(
int) * 16, histogram);
144 glDeleteBuffers(1, &buffer);
147 for(
int i= 0; i < 16; i++)
148 printf(
"bin %d: %d pixels, %d%%\n", i, histogram[i], 100*histogram[i] / (m_image.width * m_image.height));
150 printf(
"\n%dx%d groups, %d threads\n", nx, ny, nx*ny*m_threads[0]*m_threads[1]);
154 glGetQueryObjecti64v(m_time_query, GL_QUERY_RESULT, &gpu_time);
156 printf(
"gpu %02dms %03dus\n\n",
int(gpu_time / 1000000),
int((gpu_time / 1000) % 1000));