我想在计算着色器中计算一些值,并将它们返回到CPU端的堆分配缓冲区。
我用我的计算着色器发送了一个名为“input_buffer”的数组中的5个浮点数到GPU,我想在该数组中将所有值乘以3和6。
问题是我不能填充我的输出缓冲区,即使我绑定它正确的相应绑定索引在我的计算着色器代码。
这是我的密码--〉
const char* compute_shader = "\n" \
"#version 430 core\n" \
"layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n" \
"layout(std430, binding = 0) buffer input_layout\n" \
"{\n" \
" float Elements[];\n" \
"};\n" \
"layout(std430, binding = 1) buffer output_layout\n" \
"{\n" \
" float Elements2[];\n" \
"};\n" \
"void main()\n" \
"{\n" \
" const uint idx = gl_GlobalInvocationID.x;\n" \
" Elements2[idx] = Elements[idx] * 3.0f;\n" \
" Elements[idx] = Elements[idx] * 6.0f;\n" \
"}\n" \
"\n";
uint32_t shader = CreateShader(compute_shader);
glUseProgram(shader);
//int len = width * height;
int len = 5;
float* input_buffer = new float[len];
float* output_buffer = new float[len];
for (size_t idx = 0; idx < len; idx++)
{
input_buffer[idx] = 65.0f;
output_buffer[idx] = -1001.0f;
}
GLuint SSBO; //Shader Storage Buffer Object
glGenBuffers(1, &SSBO);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, SSBO);
glBufferData(GL_SHADER_STORAGE_BUFFER, len * sizeof(float), (GLvoid*)input_buffer, GL_DYNAMIC_COPY);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, SSBO);
GLuint SSBO2;
glGenBuffers(1, &SSBO2);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, SSBO2);
glBufferData(GL_SHADER_STORAGE_BUFFER, len * sizeof(float), (GLvoid*)output_buffer, GL_DYNAMIC_COPY);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, SSBO2);
glUseProgram(shader);
glDispatchCompute(len, 1, 1);
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT | GL_BUFFER_UPDATE_BARRIER_BIT);
float* dummy_out = nullptr;
dummy_out = (float*)glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_READ_WRITE);
printf("\nInput Buffer: ");
for (int idx = 0; idx < len; idx++)
{
printf("%f ", input_buffer[idx]);
}
printf("\n");
printf("\nOutput Buffer: ");
for (int idx = 0; idx < len; idx++)
{
printf("%f ", output_buffer[idx]);
}
printf("\n");
if (nullptr != dummy_out)
{
printf("\nDummy_Output: ");
for (int idx = 0; idx < len; idx++)
{
printf("%f ", dummy_out[idx]);
}
printf("\n");
}
glDeleteProgram(shader);
delete[] input_buffer, output_buffer, dummy_out;
输出为--〉
OpenGL Version: 4.3.0 - Build 31.0.101.2114
Input Buffer: 50.000000 50.000000 50.000000 50.000000 50.000000
Output Buffer: -1001.000000 -1001.000000 -1001.000000 -1001.000000 -1001.000000
Dummy_Output: 150.000000 150.000000 150.000000 150.000000 150.000000
为什么我看不到我的缓冲区“output_buffer”的变化?有没有什么方法可以专门填充它?这就是我需要的。
我尝试了其他Glenum标志来获取数据。
1条答案
按热度按时间wlwcrazw1#
你似乎误解了OpenGL中缓冲区的工作原理。缓冲区包含了传递给
glBufferData
的数组的副本,它们没有在缓冲区和数组之间建立任何连接。因此,当缓冲区被更改时,这些更改不会反映在原始数组中。如果您希望在CPU端使用GPU生成的数据,则必须使用
glGetBufferSubData
读回缓冲区内容,例如:另请注意,您可能需要在着色器执行后添加内存屏障,以确保GPU在阅读回内容之前已经完成。