Solved About buffer for compute shader
-
Good day!
I try to create a program for compute shader use.
A program is being created. When the program is running, an error occurs on the last line in Qt5Guid.dll.
How to create a GL_SHADER_STORAGE_BUFFER buffer correctly?//my code ```QOpenGLBuffer data_buffer(QOpenGLBuffer::VertexBuffer), //QOpenGLExtraFunctions QOpenGLFunctions_4_5_Core gl; void wgl::initializeGL() { initializeOpenGLFunctions(); gl.initializeOpenGLFunctions(); data_buffer.create(); data_buffer.setUsagePattern(QOpenGLBuffer::StaticDraw); data_buffer.bind(); data_buffer.allocate(inpb, sizeof(inpb)); gl.glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, data_buffer.bufferId());
-
@TCH2019 said in About buffer for compute shader:
data_buffer.allocate(inpb, sizeof(inpb));
Is this really what you want to do? allocate the sizeof(void*)?
-
@TCH2019 said in About buffer for compute shader:
gl.initializeOpenGLFunctions();should be more like
gl = context()->versionFunctions<QOpenGLFunctions_4_5_Core>();
as to SSBO, same question here so +1 from me.
-
no, inpb is defined as a static array:
QVector3D inpb[100]; -
@Dariusz
Thank! Managed to go much further.
But not so simple!
But now, after executing the function gl->glDispatchCompute() is getting error 1282 - wrong buffer ;+(QOpenGLFunctions_4_3_Core *gl; QOpenGLShaderProgram compute; QOpenGLBuffer data_buffer(QOpenGLBuffer::VertexBuffer); QVector3D inpb[100]; void wgl::initializeGL() { initializeOpenGLFunctions(); gl = new QOpenGLFunctions_4_3_Core(); gl=context()->versionFunctions<QOpenGLFunctions_4_3_Core>(); compute.addShaderFromSourceFile(QOpenGLShader::Compute, "comupe.shgl"); compute.link(); compute.bind(); data_buffer.create(); data_buffer.setUsagePattern(QOpenGLBuffer::StaticDraw); data_buffer.bind(); data_buffer.allocate(inpb, sizeof(inpb)); gl->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, data_buffer.bufferId()); eRRoR(); compute.enableAttributeArray("data"); compute.setAttributeArray("data", inpb,0); logg = compute.log(); if (!(logg == "")) { QMessageBox mymess; mymess.setWindowTitle(QStringLiteral("Shader error: ")); mymess.setText(logg); mymess.exec(); exit(0); }; gl->glDispatchCompute(5, 1, 1); eRRoR(); gl->glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT); eRRoR(); ... }
-
Have a nice day to everyone who is interested in the topic!
Everything worked, but there are nuances.
In order for the compute shader to work properly, the data must be loaded immediately before the calculations.
After the calculations, the result must be forcibly read from the video memory.Test program code:
QOpenGLShaderProgram program; QOpenGLBuffer SSBO; //QOpenGLExtraFunctions QOpenGLFunctions_4_3_Core * gl; // Test buffers float bbb[20]; void wgl::initializeGL() { initializeOpenGLFunctions(); gl = context()->versionFunctions<QOpenGLFunctions_4_3_Core>(); eRRoR(); // Compute shader init program.addShaderFromSourceFile(QOpenGLShader::Compute, "comp.sh"); res = program.link(); res = program.bind(); // SSBO init buffer SSBO.create(); SSBO.bind(); SSBO.setUsagePattern(QOpenGLBuffer::DynamicCopy); gl->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, SSBO.bufferId()); //SSBO.bufferId()); eRRoR(); // Multi use compute shader for (int i=1; i<10; i++){ // The data in the SSBO buffer should be placed strictly before the calculations // and updated every time as the calculations are started. //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! SSBO.allocate(bbb, sizeof(bbb)); gl->glDispatchCompute(5, 1, 1); // Запуск вычислений eRRoR(); gl->glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT); // Ожидание окончания вычислений eRRoR(); // Result read memcpy(bbb, SSBO.map(QOpenGLBuffer::ReadWrite), sizeof(bbb)); } SSBO.release(); program.release(); ....
-
@TCH2019 Thanks a lot! You code was very helpful for me.
I checked this too, and it's not required to upload strictly before computing and download strictly after computing. All you need - to use SSBO.bind before and SSBO.release after any operation with SSBO, such as SSBO.allocate and SSBO.map.Because - as I found in QOpenGLBuffer sources - they don't do it in SSBO.allocate and map, but it's required by OpenGL.
I put whole example here: https://github.com/perevalovds/qtcomputeshader