#c #opengl-es #compute-shader
Вопрос:
Я экспериментирую с вычислительными шейдерами. Что я хочу сделать, так это отправить данные arr1 для вычисления переменной шейдера shader_arr1 [], сделать все ее элементы 1 и прочитать этот результат обратно на сторону процессора в переменной arr2 []. Однако, запустив следующую программу, я получаю то же начальное значение arr1[]{1,2,3,4,5,6,7} в arr2 [], ничего не изменилось. Не могли бы вы сказать мне, какую часть я делаю неправильно?
GLuint program = glCreateProgram();
GLuint computeShader = glCreateShader(GL_COMPUTE_SHADER);
const GLchar* const shaderSrc = {
"#version 310 esn"
"n"
"layout (local_size_x = 1) in;n"
"layout(std430, binding = 0) writeonly buffer SSBO {n"
" int shader_arr1[];n"
"};n"
"void main(void)n"
"{n"
" shader_arr1[gl_GlobalInvocationID.x] = 1;n"
"}n"
};
glShaderSource(computeShader, 1, amp;shaderSrc, NULL);
glCompileShader(computeShader);
int resu<
glGetShaderiv(computeShader, GL_COMPILE_STATUS, amp;result);
if(result == GL_FALSE){
int length;
glGetShaderiv(computeShader, GL_INFO_LOG_LENGTH, amp;length);
char* message = static_cast<char*>(malloc(length));
glGetShaderInfoLog(computeShader, length, amp;length, message);
__android_log_print(ANDROID_LOG_INFO, "MyLog", "Shader Compile Error: %s", message);
free(message);
}
GL_CALL(glAttachShader(program, computeShader));
GL_CALL(glLinkProgram(program));
GL_CALL(glValidateProgram(program));
GL_CALL(glUseProgram(program));
GLuint buff1Id, buff2Id;
glGenBuffers(1, amp;buff1Id);
glGenBuffers(1, amp;buff2Id);
GLint arr1[7] = {1, 2, 3, 4, 5, 6, 7};
GLint arr2[7];
glBindBuffer(GL_SHADER_STORAGE_BUFFER, buff1Id);
//glBindBuffer(GL_SHADER_STORAGE_BUFFER, buff2Id);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER,0, buff1Id);
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(arr1), arr1, GL_DYNAMIC_DRAW);
//glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(arr2), arr2, GL_DYNAMIC_DRAW);
GL_CALL(glDispatchCompute(1, 1, 1));
GL_CALL(glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT));
// GL_CALL(glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, buff2Id));
// GL_CALL(glBindBuffer(GL_SHADER_STORAGE_BUFFER, buff2Id));
GLint* data = static_cast<GLint*>(glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 7,GL_MAP_READ_BIT));
for(int i = 0; i < 7; i) {
arr2[i] = data[i];
__android_log_print(ANDROID_LOG_INFO, "MyLog", "Num %d", arr2[i]);
}
glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
Комментарии:
1. Примечание сбоку. Вы должны использовать необработанные строки C 11 для кода шейдера.
2. Да, раньше я так и делал.
Ответ №1:
Я исправил код. Это рабочая версия программы
GLuint program = glCreateProgram();
GLuint computeShader = glCreateShader(GL_COMPUTE_SHADER);
const GLchar* const shaderSrc = {
"#version 310 esn"
"n"
"layout (local_size_x = 1) in;n"
"layout(std430, binding = 0) writeonly buffer SSBO1 {n"
" int shader_arr1[];n"
"};n"
"void main(void)n"
"{n"
" shader_arr1[gl_GlobalInvocationID.x] = 1;n"
"}n"
};
glShaderSource(computeShader, 1, amp;shaderSrc, NULL);
glCompileShader(computeShader);
int resu<
glGetShaderiv(computeShader, GL_COMPILE_STATUS, amp;result);
if(result == GL_FALSE){
int length;
glGetShaderiv(computeShader, GL_INFO_LOG_LENGTH, amp;length);
char* message = static_cast<char*>(malloc(length));
glGetShaderInfoLog(computeShader, length, amp;length, message);
__android_log_print(ANDROID_LOG_INFO, "MyLog", "Shader Compile Error: %s", message);
free(message);
}
GL_CALL(glAttachShader(program, computeShader));
GL_CALL(glLinkProgram(program));
GL_CALL(glValidateProgram(program));
GL_CALL(glUseProgram(program));
GLuint buff1Id, buff2Id;
GL_CALL(glGenBuffers(1, amp;buff1Id));
GL_CALL(glGenBuffers(1, amp;buff2Id));
GLint arr1[7] = {1, 2, 3, 4, 5, 6, 7};
GLint arr2[7];
GL_CALL(glBindBuffer(GL_SHADER_STORAGE_BUFFER, buff1Id));
GL_CALL(glBindBufferBase(GL_SHADER_STORAGE_BUFFER,0, buff1Id));
GL_CALL(glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(arr1), arr1, GL_DYNAMIC_DRAW));
GL_CALL(glDispatchCompute(7, 1, 1));
GL_CALL(glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT));
GL_CALL(glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0));
GL_CALL(glBindBuffer(GL_SHADER_STORAGE_BUFFER, buff1Id));
GL_CALL(glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, buff1Id));
GLint* data = static_cast<GLint*>(glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, sizeof(GLint) * 7,GL_MAP_READ_BIT));
for(int i = 0; i < 7; i) {
arr2[i] = data[i];
__android_log_print(ANDROID_LOG_INFO, "MyLog", "Num %d", arr2[i]);
}
glUnmapBuffer(GL_SHADER_STORAGE_BUFFER