Segmentation fault calling QOpenGLContext::create()
-
Good day to all! I am trying to run a computational shader on OpenGL 4.3 in a Qt console application. I read about the context and format, and even found the same topic - https://forum.qt.io/topic/52688/console-application-with-opengl/2 - however, that code cannot be executed, because when calling '.create()' for any object, a segfault occurs.
No matter what I did, I couldn't get around this problem.
I am grateful in advance for any help! -
Please provide a minimal compilable example to reproduce the problem. Also your environment would be interesting.
-
@Christian-Ehrlicher , In general, a minimal example is given by the link I gave (for this, actually), but here is my code:
.pro file:
QT += gui CONFIG += c++11 console CONFIG -= app_bundle # You can make your code fail to compile if it uses deprecated APIs. # In order to do so, uncomment the following line. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 SOURCES += \ main.cpp # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target
main.cpp:
#include <QOpenGLShaderProgram> #include <QGuiApplication> #include <QSurfaceFormat> #include <QOpenGLContext> #include <QOffscreenSurface> #include <QOpenGLFunctions_4_3_Core> #include <QDebug> //void compute(); int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); QSurfaceFormat format; format.setVersion(4, 3); format.setProfile(QSurfaceFormat::CoreProfile); //QSurfaceFormat::setDefaultFormat(format); QOpenGLContext context; context.setFormat(format); context.create(); QOffscreenSurface surface; surface.create(); context.makeCurrent(&surface); QOpenGLFunctions_4_3_Core *fun = context.versionFunctions<QOpenGLFunctions_4_3_Core>();// context.functions(); //QOpenGLFunctions *fun = context.functions(); fun->initializeOpenGLFunctions(); QOpenGLShaderProgram m_program; QOpenGLShader cShader(QOpenGLShader::Compute); cShader.compileSourceFile("/GA_comp_shader.glsl"); m_program.addShader(&cShader); if ( !m_program.link() ) { qWarning( "Error: unable to link a shader program." ); } else {qWarning( "Able to link a shader program." );} GLuint m_GA_uniform_pop_size = m_program.uniformLocation("pop_size"); GLuint m_GA_uniform_A = m_program.uniformLocation("A"); GLuint m_GA_uniform_B = m_program.uniformLocation("B"); GLuint m_GA_uniform_C = m_program.uniformLocation("C"); GLuint m_GA_uniform_D = m_program.uniformLocation("D"); GLuint m_GA_uniform_E = m_program.uniformLocation("E"); int popul_size = 1000; QVector<float> population(popul_size); for (int i = 0; i < popul_size; i++) { population[i] = i; } QVector<float> fitness(popul_size); GLuint bufObjHandles[2]; fun->glGenBuffers(2, bufObjHandles); fun->glBindBuffer(GL_SHADER_STORAGE_BUFFER, bufObjHandles[0]); fun->glBufferData(GL_SHADER_STORAGE_BUFFER, population.size() * sizeof(float), population.data(), GL_DYNAMIC_DRAW); fun->glBindBuffer(GL_SHADER_STORAGE_BUFFER, bufObjHandles[1]); fun->glBufferData(GL_SHADER_STORAGE_BUFFER, fitness.size() * sizeof(float), fitness.data(), GL_DYNAMIC_DRAW); fun->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, bufObjHandles[0]); fun->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, bufObjHandles[1]); int pop_size = 500; float A = 1.05; float B = -3.1; float C = 1.05; float D = 10; float E = 2; if ( !m_program.bind() ) qWarning( "Error: unable to bind a shader program." ); m_program.setUniformValue(m_GA_uniform_pop_size, pop_size); m_program.setUniformValue(m_GA_uniform_A, A); m_program.setUniformValue(m_GA_uniform_B, B); m_program.setUniformValue(m_GA_uniform_C, C); m_program.setUniformValue(m_GA_uniform_D, D); m_program.setUniformValue(m_GA_uniform_E, E); fun->glDispatchCompute(256,1,1); fun->glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT); float *result = (float*)fun->glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, pop_size*sizeof(float), GL_MAP_READ_BIT); m_program.release(); return a.exec(); }
-
@Christian-Ehrlicher , Oh, and the shader, of course:
#version 430 core layout (local_size_x = 128, local_size_y = 1, local_size_z = 1) in; uniform float pop_size; uniform float A; uniform float B; uniform float C; uniform float D; uniform float E; layout (std430, binding = 0) buffer Individuals { float individuals[]; }; layout (std430, binding = 1) buffer FitnessValues { float fitnessValues[]; }; void main() { uint gid = gl_GlobalInvocationID.x; float individual = individuals[gid]; // Calculate the fitness value for the current individual float fitness; for (int i = 0; i < 10000; i++) { fitness = (i + 1358/145.548) * A * individual + sqrt(abs(B)*individual) / sqrt(abs(C)*individual) - pow(sqrt(abs(D)*individual), sqrt(sqrt(sqrt(sqrt(sqrt(sqrt(E))))))); fitness = (i/2 + 98641/14524.285548) * A * individual + sqrt(abs(B)*individual) / sqrt(abs(C)*individual) - pow(sqrt(abs(D)*individual), sqrt(sqrt(sqrt(sqrt(sqrt(sqrt(E))))))); fitness = (i*1.5 - 13/1.548) * A * individual + sqrt(abs(B)*individual) / sqrt(abs(C)*individual) - pow(sqrt(abs(D)*individual), sqrt(sqrt(sqrt(sqrt(sqrt(sqrt(E))))))); } fitnessValues[gid] = fitness; }
This code is definitely working, because everything starts in QWidgets and is considered correct, but nothing wants to work in the console application :)
-
@RoApPr You need at least a QGuiApplication because e.g. QOpenGLContext is in QtGui.
-
@Christian-Ehrlicher , I not completely understand - i MUST to create graphical window before using my code block? And there is no way to bypass the restriction?
-
@RoApPr said in Segmentation fault calling QOpenGLContext::create():
i MUST to create graphical window before using my code block
No, you need to create an QGuiApplication instance.