Skip to main content
Up and Coming
October 25, 2014

Linux SDK with mesa

I understand that officially it's experimental and only tested with nvidia.

In fact it does not work with mesa and I am interested why.

Running stuff doesn't show much:
./OculusWorldDemo_x86_64_Debug
Debug: [NetClient] Connected to a server running version 1.1.0 (my version=1.1.0)
Debug: GL_VERSION: 3.0 Mesa 10.4.0-devel (git-cfcd190)
Debug: GL_VERSION: 3.0 Mesa 10.4.0-devel (git-cfcd190)
X Error of failed request: GLXBadDrawable
Major opcode of failed request: 155 (GLX)
Minor opcode of failed request: 29 (X_GLXGetDrawableAttributes)
Serial number of failed request: 56
Current serial number in output stream: 56

and looking at it in a debugger and reading some code still doesn't make it obvious what the actual problem is.

It's clear that this happens because some unsupported opengl functionality is used. But the files in LibOVR/Src/CAPI/GL/ aren't nice to read completely through and I haven't found this anywhere, so a quick question:

What opengl extensions are required to use the sdk and the demos?
Does anyone happen to know which of those are missing in mesa, maybe they can be implemented in a timely manner?
If it's known what the missing functionality is, can the SDK easily be patched for a temporary workaround (e.g. if it is some synchronization, just don't use it)?

    14 replies

    Up and Coming
    October 30, 2014
    "haagch" wrote:

    The callback branch doesn't compile:
    /home/chris/build/oculus-rift-sdk-jherico-git/src/OculusSDK/Samples/CommonSrc/Platform/Linux_Platform.cpp: In member function 'virtual ovrRenderAPIConfig OVR::Render::GL::Linux::RenderDevice::Get_ovrRenderAPIConfig() const':
    /home/chris/build/oculus-rift-sdk-jherico-git/src/OculusSDK/Samples/CommonSrc/Platform/Linux_Platform.cpp:952:13: error: 'ovrGLConfigData' has no member named 'Win'
    cfg.OGL.Win = Win;
    ^
    /home/chris/build/oculus-rift-sdk-jherico-git/src/OculusSDK/Samples/CommonSrc/Platform/Linux_Platform.cpp:953:13: error: 'ovrGLConfigData' has no member named 'Disp'
    cfg.OGL.Disp = Disp;
    ^
    Samples/CommonSrc/CMakeFiles/CommonSrc.dir/build.make:261: recipe for target 'Samples/CommonSrc/CMakeFiles/CommonSrc.dir/Platform/Linux_Platform.cpp.o' failed

    But removing the two offending lines for now "fixes" that.


    You should not remove them. They are just conditionally compiled, and you have to define OVR_OS_LINUX.
    John Tsiombikas webpage - blog - youtube channel
    Inspiring
    October 30, 2014
    "nuclear" wrote:
    You should not remove them. They are just conditionally compiled, and you have to define OVR_OS_LINUX.


    The point is he's building my branch of the LibOVR project, which no longer defines Disp and Win in the OpenGL rendering config (regardless of OS). I've updated LibOVR, but not the samples, so the samples will not work at all.
    Brad Davis - Developer for High Fidelity Co-author of Oculus Rift in Action
    haagchAuthor
    Up and Coming
    November 9, 2014
    So glewExperimental is not something that should be used - or so I have been told. And it may or may not creates this errors. So removing it and printing the version
    diff --git a/examples/cpp/common/GlfwApp.cpp b/examples/cpp/common/GlfwApp.cpp
    index 6034336..79096e5 100644
    --- a/examples/cpp/common/GlfwApp.cpp
    +++ b/examples/cpp/common/GlfwApp.cpp
    @@ -166,10 +166,11 @@ void GlfwApp::onCreate() {
    // Initialize the OpenGL bindings
    // For some reason we have to set this experminetal flag to properly
    // init GLEW if we use a core context.
    - glewExperimental = GL_TRUE;
    + //glewExperimental = GL_TRUE;
    if (0 != glewInit()) {
    FAIL("Failed to initialize GLEW");
    }
    + printf("Initialized OpenGL version: %s\n", glGetString(GL_VERSION));
    glGetError();
    #ifdef RIFT_DEBUG
    GL_CHECK_ERROR;

    prints
    Initialized OpenGL version: 3.3 (Core Profile) Mesa 10.4.0-devel (git-971dc2c)

    But it segfaults:
    #0  0x0000000000000000 in ?? ()
    No symbol table info available.
    #1 0x00000000004a7b21 in gl::FrameBuffer::FrameBuffer (this=0x13a5800) at /home/chris/build/OculusRiftInAction/libraries/gl/GlFrameBuffer.h:35
    No locals.
    #2 0x00000000004ab5bf in gl::TFrameBufferWrapper<3553u, 32856u, 33191u>::init (this=0x7fffffffd280, size=...) at /home/chris/build/OculusRiftInAction/libraries/gl/GlFrameBuffer.h:124
    No locals.
    #3 0x00000000004a9105 in HelloRift::initGl()::{lambda(ovrEyeType)#1}::operator()(ovrEyeType) const (__closure=0x7fffffffcfd0, eye=ovrEye_Left) at /home/chris/build/OculusRiftInAction/examples/cpp/Example_2_4_HelloRift.cpp:149
    eyeArgs = @0x7fffffffd200: {projection = {value = {{{data = {1, 0, 0, 0}, {{x = 1, r = 1, s = 1}, {y = 0, g = 0, t = 0}, {z = 0, b = 0, p = 0}, {w = 0, a = 0, q = 0}}}}, {{data = {0, 1, 0, 0}, {{x = 0, r = 0, s = 0}, {y = 1, g = 1, t = 1}, {z = 0, b = 0, p = 0}, {w = 0, a = 0, q = 0}}}}, {{
    data = {0, 0, 1, 0}, {{x = 0, r = 0, s = 0}, {y = 0, g = 0, t = 0}, {z = 1, b = 1, p = 1}, {w = 0, a = 0, q = 0}}}}, {{data = {0, 0, 0, 1}, {{x = 0, r = 0, s = 0}, {y = 0, g = 0, t = 0}, {z = 0, b = 0, p = 0}, {w = 1, a = 1, q = 1}}}}}}, viewOffset = {value = {{{data = {1, 0, 0, 0}, {
    {x = 1, r = 1, s = 1}, {y = 0, g = 0, t = 0}, {z = 0, b = 0, p = 0}, {w = 0, a = 0, q = 0}}}}, {{data = {0, 1, 0, 0}, {{x = 0, r = 0, s = 0}, {y = 1, g = 1, t = 1}, {z = 0, b = 0, p = 0}, {w = 0, a = 0, q = 0}}}}, {{data = {0, 0, 1, 0}, {{x = 0, r = 0, s = 0}, {y = 0, g = 0,
    t = 0}, {z = 1, b = 1, p = 1}, {w = 0, a = 0, q = 0}}}}, {{data = {0, 0, 0, 1}, {{x = 0, r = 0, s = 0}, {y = 0, g = 0, t = 0}, {z = 0, b = 0, p = 0}, {w = 1, a = 1, q = 1}}}}}}, framebuffer = {frameBuffer = std::shared_ptr (empty) 0x0, color = std::shared_ptr (empty) 0x0,
    depth = std::shared_ptr (empty) 0x0, size = {{x = 1182, r = 1182, s = 1182}, {y = 1461, g = 1461, t = 1461}}}}
    eyeTextureHeader = @0x7fffffffd380: {API = ovrRenderAPI_OpenGL, TextureSize = {w = 1182, h = 1461}, RenderViewport = {Pos = {x = 0, y = 0}, Size = {w = 1182, h = 1461}}}
    this = 0x7fffffffd1b0
    eyeFovPorts = @0x7fffffffd010: {{UpTan = 1.32928634, DownTan = 1.32928634, LeftTan = 1.05865765, RightTan = 1.09236801}, {UpTan = -nan(0x7fd040), DownTan = 4.59163468e-41, LeftTan = -7.2322215e+33, RightTan = 4.59163468e-41}}
    #4 0x00000000004ab99c in for_each_eye<HelloRift::initGl()::{lambda(ovrEyeType)#1}>(HelloRift::initGl()::{lambda(ovrEyeType)#1}) (function=...) at /home/chris/build/OculusRiftInAction/examples/cpp/common/Rift.h:326
    eye = ovrEye_Left
    #5 0x00000000004a936e in HelloRift::initGl (this=0x7fffffffd1b0) at /home/chris/build/OculusRiftInAction/examples/cpp/Example_2_4_HelloRift.cpp:151
    distortionCaps = 0
    eyeFovPorts = {{UpTan = 1.32928634, DownTan = 1.32928634, LeftTan = 1.05865765, RightTan = 1.09236801}, {UpTan = -nan(0x7fd040), DownTan = 4.59163468e-41, LeftTan = -7.2322215e+33, RightTan = 4.59163468e-41}}
    cfg = {Config = {Header = {API = 8722464, RTSize = {w = 1, h = 8444300}, Multisample = 0}, PlatformData = {4294955120, 32767, 4155654654, 32767, 8444184, 0, 8444296, 0, 8722464, 0, 4160712904, 0, 4294955168, 32767, 4155648100, 32767}}, OGL = {Header = {API = 8722464, RTSize = {w = 1,
    h = 8444300}, Multisample = 0}, ContextData = 0x7fffffffd070, ContextSwitch = 0x7ffff7b241fe <OVR::LocklessUpdater<OVR::CAPI::FrameTimeManager::Timing, OVR::CAPI::FrameTimeManager::Timing>::SetState(OVR::CAPI::FrameTimeManager::Timing const&)+208>, SwapBuffers = 0x80d918}}
    eyeRenderDescs = {{Eye = (unknown: 8443160), Fov = {UpTan = 0, DownTan = -nan(0x7fffff), LeftTan = 0, RightTan = 1.2222732e-38}, DistortedViewport = {Pos = {x = 0, y = 8443160}, Size = {w = 0, h = -12064}}, PixelsPerTanAngleAtCenter = {x = 4.59163468e-41, y = -7.23693248e+33},
    HmdToEyeViewOffset = {x = 4.59163468e-41, y = 8.96831017e-43, z = 8.96831017e-43}}, {Eye = (unknown: 8442800), Fov = {UpTan = 0, DownTan = 1.18308827e-38, LeftTan = 0, RightTan = 8.96831017e-43}, DistortedViewport = {Pos = {x = 0, y = 0}, Size = {w = 0, h = 4880000}},
    PixelsPerTanAngleAtCenter = {x = 0, y = -nan(0x7fd110)}, HmdToEyeViewOffset = {x = 4.59163468e-41, y = -7.38575392e+33, z = 4.59163468e-41}}}
    configResult = 32767
    #6 0x00000000004d28b6 in GlfwApp::run (this=0x7fffffffd1b0) at /home/chris/build/OculusRiftInAction/examples/cpp/common/GlfwApp.cpp:320
    framecount = 32767
    start = 4880000
    #7 0x00000000004a7855 in main (argc=1, argv=0x7fffffffd598) at /home/chris/build/OculusRiftInAction/examples/cpp/Example_2_4_HelloRift.cpp:283
    No locals.


    So this is the segfault:
    OculusRiftInAction/libraries/gl/GlFrameBuffer.h:35 is "glGenFramebuffers(1, &frameBuffer);"

    (gdb) print glGenFramebuffers
    $1 = {<text variable, no debug info>} 0x7ffff6aff980 <glGenFramebuffersEXT>

    So it's not a null pointer. But it's a glGenFramebuffersEXT instead of glGenFramebuffers. Weird. I tried changing this, but it didn't change anything:
    diff --git a/LibOVR/Src/CAPI/GL/CAPI_GL_Util.cpp b/LibOVR/Src/CAPI/GL/CAPI_GL_Util.cpp
    index 964e22e..a43b110 100644
    --- a/LibOVR/Src/CAPI/GL/CAPI_GL_Util.cpp
    +++ b/LibOVR/Src/CAPI/GL/CAPI_GL_Util.cpp
    @@ -224,7 +224,7 @@ void InitGLExtensions()
    #endif

    glGetStringi = (PFNGLGETSTRINGIPROC) GetFunction("glGetStringi");
    - glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC) GetFunction("glGenFramebuffersEXT");
    + glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC) GetFunction("glGenFramebuffers");
    glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC) GetFunction("glDeleteFramebuffersEXT");
    glEnablei = (PFNGLENABLEIPROC) GetFunction("glEnableIndexedEXT");
    glDisablei = (PFNGLDISABLEIPROC) GetFunction("glDisableIndexedEXT");
    diff --git a/Samples/CommonSrc/Render/Render_GL_Device.cpp b/Samples/CommonSrc/Render/Render_GL_Device.cpp
    index 64da492..c3c6d19 100644
    --- a/Samples/CommonSrc/Render/Render_GL_Device.cpp
    +++ b/Samples/CommonSrc/Render/Render_GL_Device.cpp
    @@ -119,7 +119,7 @@ void InitGLExtensions()
    #endif

    glGetStringi = (PFNGLGETSTRINGIPROC) GetFunction("glGetStringi");
    - glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC) GetFunction("glGenFramebuffersEXT");
    + glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC) GetFunction("glGenFramebuffers");
    glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC) GetFunction("glDeleteFramebuffersEXT");
    glDeleteShader = (PFNGLDELETESHADERPROC) GetFunction("glDeleteShader");
    glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC) GetFunction("glCheckFramebufferStatusEXT");


    This was on intel.
    On radeonsi it first segfaults in the same file in GL_CHECK_ERROR. Yes, segfault. Commenting it out results in the same segfault than above.
       virtual ~FrameBuffer() {
    if (frameBuffer) {
    glDeleteFramebuffers(1, &frameBuffer);
    //GL_CHECK_ERROR;
    }
    }


    So first question: Is it normal that glGenFramebuffers is <glGenFramebuffersEXT>?
    Participant
    November 9, 2014
    "haagch" wrote:
    If it's known what the missing functionality is, can the SDK easily be patched for a temporary workaround (e.g. if it is some synchronization, just don't use it)?

    Client side distortion appears to be working, as far as I can tell, if you just want to program for the rift on linux right now.