Ejemplo n.º 1
0
void
OSGLContext_x11::getGPUInfos(std::list<OpenGLRendererInfo>& renderers)
{
    const OSGLContext_glx_data* glxInfo = appPTR->getGLXData();

    assert(glxInfo);
    if (!glxInfo->_imp->MESA_query_renderer) {
        boost::scoped_ptr<OSGLContext_x11> context;
        try {
            context.reset( new OSGLContext_x11(FramebufferConfig(), GLVersion.major, GLVersion.minor, false, GLRendererID(), 0) );
        } catch (const std::exception& e) {
            std::cerr << e.what() << std::endl;

            return;
        }

        if ( !makeContextCurrent( context.get() ) ) {
            return;
        }

        try {
            OSGLContext::checkOpenGLVersion();
        } catch (const std::exception& e) {
            std::cerr << e.what() << std::endl;

            return;
        }

        OpenGLRendererInfo info;
        info.vendorName = std::string( (const char *) glGetString(GL_VENDOR) );
        info.rendererName = std::string( (const char *) glGetString(GL_RENDERER) );
        info.glVersionString = std::string( (const char *) glGetString(GL_VERSION) );
        glGetIntegerv(GL_MAX_TEXTURE_SIZE, &info.maxTextureSize);
        // We don't have any way to get memory size, set it to 0
        info.maxMemBytes = 0;
        info.rendererID.renderID = -1;
        renderers.push_back(info);
    } else {
        // Just use the first screen
        const int screen = 0;
        // The function QueryRendererIntegerMESA can return at most 3 values:  https://www.opengl.org/registry/specs/MESA/glx_query_renderer.txt
        unsigned int v[3];
        int renderer = 0;
        bool gotRenderer;
        do {
            gotRenderer = (bool)glxInfo->_imp->QueryRendererIntegerMESA(glxInfo->_imp->x11.display, screen, renderer, GLX_RENDERER_DEVICE_ID_MESA, v);
            if (gotRenderer) {
                int rendererID = v[0];
                if ( (unsigned int)rendererID == 0xFFFFFFFF ) {
                    gotRenderer = false;
                } else {
                    bool ok = glxInfo->_imp->QueryRendererIntegerMESA(glxInfo->_imp->x11.display, screen, renderer, GLX_RENDERER_ACCELERATED_MESA, v);
                    assert(ok);
                    if (!ok || !v[0]) {
                        ++renderer;
                        continue;
                    }


                    ok = glxInfo->_imp->QueryRendererIntegerMESA(glxInfo->_imp->x11.display, screen, renderer, GLX_RENDERER_OPENGL_COMPATIBILITY_PROFILE_VERSION_MESA, v);
                    assert(ok);
                    if (!ok) {
                        ++renderer;
                        continue;
                    }

                    int maxCompatGLVersionMajor = (int)v[0];
                    int maxCompatGLVersionMinor = (int)v[1];

                    ok = glxInfo->_imp->QueryRendererIntegerMESA(glxInfo->_imp->x11.display, screen, renderer,  GLX_RENDERER_OPENGL_CORE_PROFILE_VERSION_MESA, v);
                    assert(ok);
                    if (!ok) {
                        ++renderer;
                        continue;
                    }

                    int maxCoreGLVersionMajor = (int)v[0];
                    int maxCoreGLVersionMinor = (int)v[1];
                    const char* vendorIDStr = glxInfo->_imp->QueryRendererStringMesa(glxInfo->_imp->x11.display, screen, renderer, GLX_RENDERER_VENDOR_ID_MESA);
                    if (!vendorIDStr) {
                        ++renderer;
                        continue;
                    }
                    const char* deviceIDStr = glxInfo->_imp->QueryRendererStringMesa(glxInfo->_imp->x11.display, screen, renderer, GLX_RENDERER_DEVICE_ID_MESA);
                    if (!deviceIDStr) {
                        ++renderer;
                        continue;
                    }
                    std::string vendorID(vendorIDStr);
                    std::string deviceID(deviceIDStr);
                    std::stringstream ss;
                    ss << "Creating context for Device:" << deviceID << ", Vendor:" << vendorID << std::endl;
                    ss << "Max Compatibility OpenGL profile version: " << maxCompatGLVersionMajor << "." << maxCompatGLVersionMinor << std::endl;
                    ss << "Max Core OpenGL profile version: " << maxCoreGLVersionMajor << "." << maxCoreGLVersionMinor;
#ifdef DEBUG
                    std::cerr << ss.str() << std::endl;
#endif

                    OpenGLRendererInfo info;

                    ok = glxInfo->_imp->QueryRendererIntegerMESA(glxInfo->_imp->x11.display, screen, renderer, GLX_RENDERER_VIDEO_MEMORY_MESA, v);
                    assert(ok);
                    info.maxMemBytes = v[0] * 1e6;

                    // Now create a context with the renderer ID
                    boost::scoped_ptr<OSGLContext_x11> context;
                    try {
                        context.reset( new OSGLContext_x11(FramebufferConfig(), GLVersion.major, GLVersion.minor, false, GLRendererID( (int)renderer ), 0) );
                    } catch (const std::exception& e) {
#ifndef DEBUG
                        std::cerr << ss.str() << std::endl;
#endif
                        std::cerr << e.what() << std::endl;
                        ++renderer;
                        continue;
                    }

                    if ( !makeContextCurrent( context.get() ) ) {
                        ++renderer;
                        continue;
                    }

                    try {
                        OSGLContext::checkOpenGLVersion();
                    } catch (const std::exception& e) {
#ifndef DEBUG
                        std::cerr << ss.str() << std::endl;
#endif
                        std::cerr << e.what() << std::endl;
                        ++renderer;
                        continue;
                    }

                    info.rendererID.renderID = renderer;
                    info.vendorName = std::string( (const char *) glGetString(GL_VENDOR) );
                    info.rendererName = std::string( (const char *) glGetString(GL_RENDERER) );
                    info.glVersionString = std::string( (const char *) glGetString(GL_VERSION) );
                    glGetIntegerv(GL_MAX_TEXTURE_SIZE, &info.maxTextureSize);

                    renderers.push_back(info);

                    makeContextCurrent(0);
                }
            }
            ++renderer;
        } while (gotRenderer);
    }
} // OSGLContext_x11::getGPUInfos
Ejemplo n.º 2
0
void
OSGLContext_win::getGPUInfos(std::list<OpenGLRendererInfo>& renderers)
{

    const OSGLContext_wgl_data* wglInfo = appPTR->getWGLData();
    assert(wglInfo);
    if (!wglInfo) {
        return;
    }
    bool defaultFallback = false;
    if (wglInfo->NV_gpu_affinity) {
        // https://www.opengl.org/registry/specs/NV/gpu_affinity.txt
        std::vector<HGPUNV> gpuHandles;
        int gpuIndex = 0;
        HGPUNV gpuHandle;
        bool gotGPU = true;
        do {
            gotGPU = wglInfo->EnumGpusNV(gpuIndex, &gpuHandle);
            if (gotGPU) {
                gpuHandles.push_back(gpuHandle);
            }
            ++gpuIndex;
        } while (gotGPU);

        if (gpuHandles.empty()) {
            defaultFallback = true;
        }
        for (std::size_t i = 0; i < gpuHandles.size(); ++i) {
            OpenGLRendererInfo info;
            info.rendererID.rendererHandle = (void*)gpuHandles[i];

            boost::scoped_ptr<OSGLContext_win> context;
            try {

                GLRendererID gid;
                gid.rendererHandle = info.rendererID.rendererHandle;
                context.reset( new OSGLContext_win(FramebufferConfig(), appPTR->getOpenGLVersionMajor(), appPTR->getOpenGLVersionMinor(), false, gid, 0) );
            } catch (const std::exception& e) {
                continue;
            }

            if ( !makeContextCurrent( context.get() ) ) {
                continue;
            }

            try {
                OSGLContext::checkOpenGLVersion(true);
            } catch (const std::exception& e) {
                std::cerr << e.what() << std::endl;
                continue;
            }

            info.vendorName = std::string( (const char *) GL_GPU::GetString(GL_VENDOR) );
            info.rendererName = std::string( (const char *) GL_GPU::GetString(GL_RENDERER) );
            info.glVersionString = std::string( (const char *) GL_GPU::GetString(GL_VERSION) );
            info.glslVersionString = std::string( (const char*) GL_GPU::GetString(GL_SHADING_LANGUAGE_VERSION) );
            info.maxMemBytes = nvx_get_GPU_mem_info();
            GL_GPU::GetIntegerv(GL_MAX_TEXTURE_SIZE, &info.maxTextureSize);
            renderers.push_back(info);

            makeContextCurrent(0);
        }
    } else if (wglInfo->AMD_gpu_association && !isApplication32Bits()) {
        //https://www.opengl.org/registry/specs/AMD/wgl_gpu_association.txt
        UINT getGpuIDMaxCount = wglInfo->GetGpuIDAMD(0, 0);
        UINT maxCount = getGpuIDMaxCount;
        std::vector<UINT> gpuIDs(maxCount);
        if (maxCount == 0) {
            defaultFallback = true;
        } else {
            UINT gpuCount = wglInfo->GetGpuIDAMD(maxCount, &gpuIDs[0]);
            if (gpuCount > maxCount) {
                gpuIDs.resize(gpuCount);
            }
            for (UINT index = 0; index < gpuCount; ++index) {
                assert(index < gpuIDs.size());
                UINT gpuID = gpuIDs[index];

                OpenGLRendererInfo info;
                info.rendererName = GetGPUInfoAMDInternal_string(wglInfo, gpuID, WGL_GPU_RENDERER_STRING_AMD);
                if (info.rendererName.empty()) {
                    continue;
                }

                info.vendorName = GetGPUInfoAMDInternal_string(wglInfo, gpuID, WGL_GPU_VENDOR_AMD);
                if (info.vendorName.empty()) {
                    continue;
                }


                info.glVersionString = GetGPUInfoAMDInternal_string(wglInfo, gpuID, WGL_GPU_OPENGL_VERSION_STRING_AMD);
                if (info.glVersionString.empty()) {
                    continue;
                }

                // note: cannot retrieve GL_SHADING_LANGUAGE_VERSION

                info.maxMemBytes = 0;
                if (!isApplication32Bits()) {
                    int ramMB = 0;
                    // AMD drivers are f*** up in 32 bits, they read a wrong buffer size.
                    // It works fine in 64 bits mode
                    if (!GetGPUInfoAMDInternal_int(wglInfo, gpuID, WGL_GPU_RAM_AMD, &ramMB)) {
                        continue;
                    }
                    info.maxMemBytes = ramMB * 1e6;
                }

                info.rendererID.renderID = gpuID;
                
                boost::scoped_ptr<OSGLContext_win> context;

                GLRendererID gid;
                gid.renderID = info.rendererID.renderID;
                try {
                    context.reset( new OSGLContext_win(FramebufferConfig(), appPTR->getOpenGLVersionMajor(), appPTR->getOpenGLVersionMinor(), false, gid, 0) );
                } catch (const std::exception& e) {
                    continue;
                }

                if ( !makeContextCurrent( context.get() ) ) {
                    continue;
                }

                try {
                    OSGLContext::checkOpenGLVersion(true);
                } catch (const std::exception& e) {
                    std::cerr << e.what() << std::endl;
                    continue;
                }

                GL_GPU::GetIntegerv(GL_MAX_TEXTURE_SIZE, &info.maxTextureSize);
                renderers.push_back(info);
                
                makeContextCurrent(0);
            }
        }
    }

    if (renderers.empty()) {
        defaultFallback = true;
    }
    if (defaultFallback) {
        // No extension, use default
        boost::scoped_ptr<OSGLContext_win> context;
        try {
            context.reset( new OSGLContext_win(FramebufferConfig(), appPTR->getOpenGLVersionMajor(), appPTR->getOpenGLVersionMinor(), false, GLRendererID(), 0) );
        } catch (const std::exception& e) {
            std::cerr << e.what() << std::endl;

            return;
        }

        if ( !makeContextCurrent( context.get() ) ) {
            return;
        }

        try {
            OSGLContext::checkOpenGLVersion(true);
        } catch (const std::exception& e) {
            std::cerr << e.what() << std::endl;

            return;
        }

        OpenGLRendererInfo info;
        info.vendorName = std::string( (const char *) GL_GPU::GetString(GL_VENDOR) );
        info.rendererName = std::string( (const char *) GL_GPU::GetString(GL_RENDERER) );
        info.glVersionString = std::string( (const char *) GL_GPU::GetString(GL_VERSION) );
        info.glslVersionString = std::string( (const char *) GL_GPU::GetString(GL_SHADING_LANGUAGE_VERSION) );
        GL_GPU::GetIntegerv(GL_MAX_TEXTURE_SIZE, &info.maxTextureSize);
        // We don't have any way to get memory size, set it to 0
        info.maxMemBytes = nvx_get_GPU_mem_info();
        renderers.push_back(info);

        makeContextCurrent(0);
    }
} // OSGLContext_win::getGPUInfos