Ejemplo n.º 1
0
QByteArray UINVControl::GetNVEDID(Display *XDisplay, int Screen)
{
    if (!NVControlAvailable(XDisplay))
        return QByteArray();

    QMutexLocker locker(gNVCtrlLock);
    QByteArray result;

    if (!XNVCTRLIsNvScreen(XDisplay, Screen))
    {
        LOG(VB_GENERAL, LOG_ERR, QString("NV-CONTROL is not available on screen %1 of display '%2'")
            .arg(Screen).arg(XDisplayName(NULL)));
        return result;
    }

    int displays = 0;
    Bool ok = XNVCTRLQueryAttribute(XDisplay, Screen, 0, NV_CTRL_CONNECTED_DISPLAYS, &displays);
    if (ok != True)
    {
        LOG(VB_GENERAL, LOG_ERR, "Failed to retrieve display list");
        return result;
    }

    int displaycount = ListDisplays(displays);
    if (displaycount != 1)
    {
        LOG(VB_GENERAL, LOG_WARNING, "There is more than one physical display attached to this screen. Ignoring EDID");
        return result;
    }

    int edid = NV_CTRL_EDID_AVAILABLE_FALSE;
    ok = XNVCTRLQueryAttribute(XDisplay, Screen, displays, NV_CTRL_EDID_AVAILABLE, &edid);
    if (ok != True)
    {
        LOG(VB_GENERAL, LOG_INFO, "Failed to check EDID_AVAILABLE attribute");
        return result;
    }

    if (edid != NV_CTRL_EDID_AVAILABLE_TRUE)
    {
        LOG(VB_GENERAL, LOG_INFO, "EDID not available");
        return result;
    }

    unsigned char* data = NULL;
    int datalength = 0;

    ok = XNVCTRLQueryBinaryData(XDisplay, Screen, displays, NV_CTRL_BINARY_DATA_EDID, &data, &datalength);

    if (ok != True)
    {
        LOG(VB_GENERAL, LOG_INFO, QString("EDID not available on screen %1 of display '%2'")
            .arg(Screen).arg(XDisplayName(NULL)));
        return result;
    }

    result = QByteArray((const char*)data, datalength);
    delete data;
    return result;
}
Ejemplo n.º 2
0
/*
 * nv-control-screen.h - trivial helper for NV-CONTROL sample clients: use
 * the default screen if it is an NVIDIA X screen.  If it isn't, then look
 * for the first NVIDIA X screen.  Abort if no NVIDIA X screens are found.
 */
static inline int GetNvXScreen(Display *dpy) {
  int defaultScreen, screen;

  defaultScreen = DefaultScreen(dpy);

  if (XNVCTRLIsNvScreen(dpy, defaultScreen)) {
    return defaultScreen;
  }

  for (screen = 0; screen < ScreenCount(dpy); screen++) {
    if (XNVCTRLIsNvScreen(dpy, screen)) {
      printf("Default X screen %d is not an NVIDIA X screen.  "
	     "Using X screen %d instead.\n",
	     defaultScreen, screen);
      return screen;
    }
  }

  fprintf(stderr, "Unable to find any NVIDIA X screens; aborting.\n");
  return -1;
}
Ejemplo n.º 3
0
int CheckNVOpenGLSyncToVBlank(void)
{
    MythXDisplay *d = OpenMythXDisplay();
    if (!d)
        return -1;

    Display *dpy = d->GetDisplay();
    int screen   = d->GetScreen();

    if (!XNVCTRLIsNvScreen(dpy, screen))
    {
        delete d;
        return -1;
    }

    int major, minor;
    if (!XNVCTRLQueryVersion(dpy, &major, &minor))
        return -1;

    int sync = NV_CTRL_SYNC_TO_VBLANK_OFF;
    if (!XNVCTRLQueryAttribute(dpy, screen, 0, NV_CTRL_SYNC_TO_VBLANK, &sync))
    {
        delete d;
        return -1;
    }

    if (!sync)
    {
        LOG(VB_GENERAL, LOG_WARNING, LOC + "OpenGL Sync to VBlank is disabled.");
        LOG(VB_GENERAL, LOG_WARNING, LOC + "For best results enable this in NVidia settings or try running:");
        LOG(VB_GENERAL, LOG_WARNING, LOC + "nvidia-settings -a \"SyncToVBlank=1\"");
    }

    if (!sync && getenv("__GL_SYNC_TO_VBLANK"))
    {
        LOG(VB_GENERAL, LOG_INFO, LOC +
            "OpenGL Sync to VBlank enabled via __GL_SYNC_TO_VBLANK.");
        sync = 1;
    }
    else if (!sync)
    {
        LOG(VB_GENERAL, LOG_WARNING, LOC +
            "Alternatively try setting the '__GL_SYNC_TO_VBLANK' environment variable.");
    }

    return sync;
}
Ejemplo n.º 4
0
egl::Error DisplayGLX::getNVIDIADriverVersion(std::string *version) const
{
    *version = "";

    int eventBase = 0;
    int errorBase = 0;
    if (XNVCTRLQueryExtension(mXDisplay, &eventBase, &errorBase))
    {
        int screenCount = ScreenCount(mXDisplay);
        for (int screen = 0; screen < screenCount; ++screen)
        {
            char *buffer = nullptr;
            if (XNVCTRLIsNvScreen(mXDisplay, screen) &&
                XNVCTRLQueryStringAttribute(mXDisplay, screen, 0,
                                            NV_CTRL_STRING_NVIDIA_DRIVER_VERSION, &buffer))
            {
                *version = buffer;
                XFree(buffer);
            }
        }
    }

    return egl::Error(EGL_SUCCESS);
}
Ejemplo n.º 5
0
// this function does some checks
int nvidia_gpu_init(Display * dpy, int screen) {

	int event_base, error_base;

    int ret = XNVCTRLQueryExtension(dpy, &event_base, &error_base);
    if (ret != True) {
        fprintf(stderr, "The NV-CONTROL X extension does not exist on '%s'.\n",
                XDisplayName(NULL));
        return 0;
    }

	if(!XNVCTRLIsNvScreen(dpy, screen)) {
		fprintf(stderr, "Screen %d does not support the NV-Control extension\n", screen);
		return 0;
	}

	int max;
	ret = XNVCTRLQueryAttribute(dpy, screen, 0, NV_CTRL_GPU_CORE_THRESHOLD, &max);
	if(ret) {
		nvidia_gpu_max_temperature = max;
	}
	
	return 1;
}
Ejemplo n.º 6
0
static void
hwloc_gl_query_devices(struct hwloc_gl_backend_data_s *data)
{
  int err;
  unsigned i,j;

  /* mark the number of display as 0 in case we fail below,
   * so that we don't try again later.
   */
  data->nr_display = 0;

  for (i = 0; i < HWLOC_GL_SERVER_MAX; ++i) {
    Display* display;
    char displayName[10];
    int opcode, event, error;

    /* open X server */
    snprintf(displayName, sizeof(displayName), ":%u", i);
    display = XOpenDisplay(displayName);
    if (!display)
      continue;

    /* Check for NV-CONTROL extension (it's per server) */
    if(!XQueryExtension(display, "NV-CONTROL", &opcode, &event, &error)) {
      XCloseDisplay(display);
      continue;
    }

    for (j = 0; j < (unsigned) ScreenCount(display) && j < HWLOC_GL_SCREEN_MAX; j++) {
      struct hwloc_gl_display_info_s *info = &data->display[data->nr_display];
      const int screen = j;
      unsigned int *ptr_binary_data;
      int data_length;
      int gpu_number;
      int nv_ctrl_pci_bus;
      int nv_ctrl_pci_device;
      int nv_ctrl_pci_domain;
      int nv_ctrl_pci_func;
      char *productname;

      /* the server supports NV-CONTROL but it may contain non-NVIDIA screen that don't support it */
      if (!XNVCTRLIsNvScreen(display, screen))
        continue;

      /* Gets the GPU number attached to the default screen. */
      /* For further details, see the <NVCtrl/NVCtrlLib.h> */
      err = XNVCTRLQueryTargetBinaryData (display, NV_CTRL_TARGET_TYPE_X_SCREEN, screen, 0,
                                          NV_CTRL_BINARY_DATA_GPUS_USED_BY_XSCREEN,
                                          (unsigned char **) &ptr_binary_data, &data_length);
      if (!err)
        continue;

      gpu_number = ptr_binary_data[1];
      free(ptr_binary_data);

#ifdef NV_CTRL_PCI_DOMAIN
      /* Gets the ID's of the GPU defined by gpu_number
       * For further details, see the <NVCtrl/NVCtrlLib.h> */
      err = XNVCTRLQueryTargetAttribute(display, NV_CTRL_TARGET_TYPE_GPU, gpu_number, 0,
                                        NV_CTRL_PCI_DOMAIN, &nv_ctrl_pci_domain);
      if (!err)
        continue;
#else
      nv_ctrl_pci_domain = 0;
#endif

      err = XNVCTRLQueryTargetAttribute(display, NV_CTRL_TARGET_TYPE_GPU, gpu_number, 0,
                                        NV_CTRL_PCI_BUS, &nv_ctrl_pci_bus);
      if (!err)
        continue;

      err = XNVCTRLQueryTargetAttribute(display, NV_CTRL_TARGET_TYPE_GPU, gpu_number, 0,
                                        NV_CTRL_PCI_DEVICE, &nv_ctrl_pci_device);
      if (!err)
        continue;

      err = XNVCTRLQueryTargetAttribute(display, NV_CTRL_TARGET_TYPE_GPU, gpu_number, 0,
                                        NV_CTRL_PCI_FUNCTION, &nv_ctrl_pci_func);
      if (!err)
        continue;

      productname = NULL;
      err = XNVCTRLQueryTargetStringAttribute(display, NV_CTRL_TARGET_TYPE_GPU, gpu_number, 0,
                                              NV_CTRL_STRING_PRODUCT_NAME, &productname);

      snprintf(info->name, sizeof(info->name), ":%u.%u", i, j);
      info->port = i;
      info->device = j;
      info->pcidomain = nv_ctrl_pci_domain;
      info->pcibus = nv_ctrl_pci_bus;
      info->pcidevice = nv_ctrl_pci_device;
      info->pcifunc = nv_ctrl_pci_func;
      info->productname = productname;

      hwloc_debug("GL device %s (product %s) on PCI 0000:%02x:%02x.%u\n", info->name, productname,
		  nv_ctrl_pci_domain, nv_ctrl_pci_bus, nv_ctrl_pci_device, nv_ctrl_pci_func);

      /* validate this device */
      data->nr_display++;
    }
    XCloseDisplay(display);
  }
}
Ejemplo n.º 7
0
int GetNvidiaRates(t_screenrate& screenmap)
{
#ifdef USING_XRANDR

    MythXDisplay *d = OpenMythXDisplay();
    if (!d)
    {
        return -1;
    }
    Display *dpy;
    bool ret;
    int screen, display_devices, mask, major, minor, len, j;
    char *str, *start;
    int nDisplayDevice;
    
    char *pMetaModes, *pModeLines[8], *tmp, *modeString;
    char *modeLine, *modeName;
    int MetaModeLen, ModeLineLen[8];
    int thisMask;
    int id;
    int twinview =  0;
    map<int, map<int,bool> > maprate;

    memset(pModeLines, 0, sizeof(pModeLines));
    memset(ModeLineLen, 0, sizeof(ModeLineLen));

    /*
     * Open a display connection, and make sure the NV-CONTROL X
     * extension is present on the screen we want to use.
     */

    dpy = d->GetDisplay();    
    screen = d->GetScreen();

    if (!XNVCTRLIsNvScreen(dpy, screen))
    {
        LOG(VB_PLAYBACK, LOG_INFO,
            QString("The NV-CONTROL X extension is not available on screen %1 "
                    "of '%2'.")
                .arg(screen) .arg(XDisplayName(NULL)));
        delete d;
        return -1;
    }

    ret = XNVCTRLQueryVersion(dpy, &major, &minor);
    if (ret != True)
    {
        LOG(VB_PLAYBACK, LOG_INFO,
            QString("The NV-CONTROL X extension does not exist on '%1'.")
                .arg(XDisplayName(NULL)));
        delete d;
        return -1;
    }

    ret = XNVCTRLQueryAttribute(dpy, screen, 0, NV_CTRL_DYNAMIC_TWINVIEW, &twinview);

    if (!ret)
    {
        LOG(VB_PLAYBACK, LOG_ERR,
             "Failed to query if Dynamic Twinview is enabled");
        XCloseDisplay(dpy);
        return -1;
    }
    if (!twinview)
    {
        LOG(VB_PLAYBACK, LOG_ERR, "Dynamic Twinview not enabled, ignoring");
        delete d;
        return 0;
    }

    /*
     * query the connected display devices on this X screen and print
     * basic information about each X screen
     */

    ret = XNVCTRLQueryAttribute(dpy, screen, 0,
                                NV_CTRL_CONNECTED_DISPLAYS, &display_devices);

    if (!ret)
    {
        LOG(VB_PLAYBACK, LOG_ERR,
            "Failed to query the enabled Display Devices.");
        delete d;
        return -1;
    }

    /* first, we query the MetaModes on this X screen */

    ret = XNVCTRLQueryBinaryData(dpy, screen, 0, // n/a
                           NV_CTRL_BINARY_DATA_METAMODES,
                           (unsigned char **)&pMetaModes, &MetaModeLen);
    if (!ret)
    {
        LOG(VB_PLAYBACK, LOG_ERR,
            "Failed to query the metamode on selected display device.");
        delete d;
        return -1;
    }

    /*
     * then, we query the ModeLines for each display device on
     * this X screen; we'll need these later
     */

    nDisplayDevice = 0;

    for (mask = 1; mask < (1 << 24); mask <<= 1)
    {
        if (!(display_devices & mask)) continue;

        ret = XNVCTRLQueryBinaryData(dpy, screen, mask,
                               NV_CTRL_BINARY_DATA_MODELINES,
                               (unsigned char **)&str, &len);
        if (!ret)
        {
            LOG(VB_PLAYBACK, LOG_ERR,
               "Unknown error. Failed to query the enabled Display Devices.");
            // Free Memory currently allocated
            for (j=0; j < nDisplayDevice; ++j)
            {
                free(pModeLines[j]);
            }
            delete d;
            return -1;
        }

        pModeLines[nDisplayDevice] = str;
        ModeLineLen[nDisplayDevice] = len;

        nDisplayDevice++;
    }

    /* now, parse each MetaMode */
    str = start = pMetaModes;

    for (j = 0; j < MetaModeLen - 1; ++j)
    {
        /*
         * if we found the end of a line, treat the string from
         * start to str[j] as a MetaMode
         */

        if ((str[j] == '\0') && (str[j+1] != '\0'))
        {
            id = extract_id_string(start);
            /*
             * the MetaMode may be preceded with "token=value"
             * pairs, separated by the main MetaMode with "::"; if
             * "::" exists in the string, skip past it
             */

            tmp = strstr(start, "::");
            if (tmp)
            {
                tmp += 2;
            }
            else
            {
                tmp = start;
            }

            /* split the MetaMode string by comma */

            char *strtok_state = NULL;
            for (modeString = strtok_r(tmp, ",", &strtok_state);
                 modeString;
                 modeString = strtok_r(NULL, ",", &strtok_state))
            {
                /*
                 * retrieve the modeName and display device mask
                 * for this segment of the Metamode
                 */

                parse_mode_string(modeString, &modeName, &thisMask);

                /* lookup the modeline that matches */
                nDisplayDevice = 0;
                if (thisMask)
                {
                    for (mask = 1; mask < (1 << 24); mask <<= 1)
                    {
                        if (!(display_devices & mask)) continue;
                        if (thisMask & mask) break;
                        nDisplayDevice++;
                    }
                }

                modeLine = find_modeline(modeName,
                                         pModeLines[nDisplayDevice],
                                         ModeLineLen[nDisplayDevice]);

                if (modeLine && !modeline_is_interlaced(modeLine))
                {
                    int w, h, vfl, hfl, i, irate;
                    double dcl, r;
                    char *buf[256];
                    uint64_t key, key2;

                    // skip name
                    tmp = strchr(modeLine, '"');
                    tmp = strchr(tmp+1, '"') +1 ;
                    while (*tmp == ' ')
                        tmp++;
                    i = 0;
                    for (modeString = strtok_r(tmp, " ", &strtok_state);
                         modeString;
                         modeString = strtok_r(NULL, " ", &strtok_state))
                    {
                        buf[i++] = modeString;
                    }
                    w = strtol(buf[1], NULL, 10);
                    h = strtol(buf[5], NULL, 10);
                    vfl = strtol(buf[8], NULL, 10);
                    hfl = strtol(buf[4], NULL, 10);
                    h = strtol(buf[5], NULL, 10);
                    istringstream istr(buf[0]);
                    istr.imbue(locale("C"));
                    istr >> dcl;
                    r = (dcl * 1000000.0) / (vfl * hfl);
                    irate = (int) round(r * 1000.0);
                    key = DisplayResScreen::CalcKey(w, h, (double) id);
                    key2 = DisplayResScreen::CalcKey(w, h, 0.0);
                    // We need to eliminate duplicates, giving priority to the first entries found
                    if (maprate.find(key2) == maprate.end())
                    {
                        // First time we see this resolution, create a map for it
                        maprate[key2] = map<int, bool>();
                    }
                    if ((maprate[key2].find(irate) == maprate[key2].end()) &&
                        (screenmap.find(key) == screenmap.end()))
                    {
                        screenmap[key] = r;
                        maprate[key2][irate] = true;
                    }
                }
                free(modeName);
            }

            /* move to the next MetaMode */
            start = &str[j+1];
        }
Ejemplo n.º 8
0
int main(void)
{
    Display *dpy;
    Bool ret;
    int event_base, error_base, major, minor, screens, i;
    char *str;
        
    /*
     * open a connection to the X server indicated by the DISPLAY
     * environment variable
     */
    
    dpy = XOpenDisplay(NULL);
    if (!dpy) {
        fprintf(stderr, "Cannot open display '%s'.\n", XDisplayName(NULL));
        return 1;
    }
    
    /*
     * check if the NV-CONTROL X extension is present on this X server
     */

    ret = XNVCTRLQueryExtension(dpy, &event_base, &error_base);
    if (ret != True) {
        fprintf(stderr, "The NV-CONTROL X extension does not exist on '%s'.\n",
                XDisplayName(NULL));
        return 1;
    }

    /*
     * query the major and minor extension version
     */

    ret = XNVCTRLQueryVersion(dpy, &major, &minor);
    if (ret != True) {
        fprintf(stderr, "The NV-CONTROL X extension does not exist on '%s'.\n",
                XDisplayName(NULL));
        return 1;
    }

    /*
     * print statistics thus far
     */

    printf("NV-CONTROL X extension present\n");
    printf("  version        : %d.%d\n", major, minor);
    printf("  event base     : %d\n", event_base);
    printf("  error base     : %d\n", error_base);
    
    /*
     * loop over each screen, and determine if each screen is
     * controlled by the NVIDIA X driver (and thus supports the
     * NV-CONTROL X extension); then, query the string attributes on
     * the screen.
     */

    screens = ScreenCount(dpy);
    for (i = 0; i < screens; i++) {
        if (XNVCTRLIsNvScreen(dpy, i)) {
            printf("Screen %d supports the NV-CONTROL X extension\n", i);

            ret = XNVCTRLQueryStringAttribute(dpy, i,
                                              0, /* XXX not curently used */
                                              NV_CTRL_STRING_PRODUCT_NAME,
                                              &str);
            if (ret) {
                printf("  GPU            : %s\n", str);
                XFree(str);
            }
            
            ret = XNVCTRLQueryStringAttribute(dpy, i,
                                              0, /* XXX not curently used */
                                              NV_CTRL_STRING_VBIOS_VERSION,
                                              &str);
            
            if (ret) {
                printf("  VideoBIOS      : %s\n", str);
                XFree(str);
            }

            ret = XNVCTRLQueryStringAttribute(dpy, i,
                                              0, /* XXX not curently used */
                                              NV_CTRL_STRING_NVIDIA_DRIVER_VERSION,
                                              &str);

            if (ret) {
                printf("  Driver version : %s\n", str);
                XFree(str);
            }
        }
    }

    /*
     * print attribute permission and type information.
     */

    printf("Attributes (Integers):\n");
    for (i = 0; i < NV_CTRL_LAST_ATTRIBUTE; i++) {
        const char *name = attr2str(i, attr_int_table);
        if (name) {
            NVCTRLAttributePermissionsRec perms;

            printf("  (%3d) [Perms: ", i);

            memset(&perms, 0, sizeof(NVCTRLAttributePermissionsRec));

            XNVCTRLQueryAttributePermissions(dpy, i, &perms);
            print_perms(&perms);
            printf("] [ ");
            printf("%-32s", GetAttrTypeName(perms.type));
            printf("] - %s\n", name);
        }
    }

    printf("Attributes (Strings):\n");
    for (i = 0; i < NV_CTRL_STRING_LAST_ATTRIBUTE; i++) {
        const char *name = attr2str(i, attr_str_table);
        if (name) {
            NVCTRLAttributePermissionsRec perms;

            printf("  (%3d) [Perms: ", i);

            memset(&perms, 0, sizeof(NVCTRLAttributePermissionsRec));

            XNVCTRLQueryStringAttributePermissions(dpy, i, &perms);
            print_perms(&perms);
            printf("] [ ");
            printf("%-32s", GetAttrTypeName(perms.type));
            printf("] - %s\n", name);
        }
    }

    printf("Attributes (Binary Data):\n");
    for (i = 0; i < NV_CTRL_BINARY_DATA_LAST_ATTRIBUTE; i++) {
        const char *name = attr2str(i, attr_bin_table);
        if (name) {
            NVCTRLAttributePermissionsRec perms;

            printf("  (%3d) [Perms: ", i);

            memset(&perms, 0, sizeof(NVCTRLAttributePermissionsRec));

            XNVCTRLQueryBinaryDataAttributePermissions(dpy, i, &perms);
            print_perms(&perms);
            printf("] [ ");
            printf("%-32s", GetAttrTypeName(perms.type));
            printf("] - %s\n", name);
        }
    }

    printf("Attributes (String Operations):\n");
    for (i = 0; i < NV_CTRL_STRING_OPERATION_LAST_ATTRIBUTE; i++) {
        const char *name = attr2str(i, attr_strop_table);
        if (name) {
            NVCTRLAttributePermissionsRec perms;

            printf("  (%3d) [Perms: ", i);

            memset(&perms, 0, sizeof(NVCTRLAttributePermissionsRec));

            XNVCTRLQueryStringOperationAttributePermissions(dpy, i, &perms);
            print_perms(&perms);
            printf("] [ ");
            printf("%-32s", GetAttrTypeName(perms.type));
            printf("] - %s\n", name);
        }
    }

    /*
     * close the display connection
     */

    XCloseDisplay(dpy);

    return 0;
}
Ejemplo n.º 9
0
static int
hwloc_gl_discover(struct hwloc_backend *backend)
{
  struct hwloc_topology *topology = backend->topology;
  unsigned i, res = 0;
  int err;

  if (!(hwloc_topology_get_flags(topology) & (HWLOC_TOPOLOGY_FLAG_IO_DEVICES|HWLOC_TOPOLOGY_FLAG_WHOLE_IO)))
    return 0;

  if (!hwloc_topology_is_thissystem(topology)) {
    hwloc_debug("%s", "\nno GL detection (not thissystem)\n");
    return 0;
  }

  for (i = 0; i < HWLOC_GL_SERVER_MAX; ++i) {
    Display* display;
    char displayName[10];
    int opcode, event, error;
    unsigned j;

    /* open X server */
    snprintf(displayName, sizeof(displayName), ":%u", i);
    display = XOpenDisplay(displayName);
    if (!display)
      continue;

    /* Check for NV-CONTROL extension (it's per server) */
    if(!XQueryExtension(display, "NV-CONTROL", &opcode, &event, &error)) {
      XCloseDisplay(display);
      continue;
    }

    for (j = 0; j < (unsigned) ScreenCount(display) && j < HWLOC_GL_SCREEN_MAX; j++) {
      hwloc_obj_t osdev, parent;
      const int screen = j;
      unsigned int *ptr_binary_data;
      int data_length;
      int gpu_number;
      int nv_ctrl_pci_bus;
      int nv_ctrl_pci_device;
      int nv_ctrl_pci_domain;
      int nv_ctrl_pci_func;
      char *productname;
      char name[64];

      /* the server supports NV-CONTROL but it may contain non-NVIDIA screen that don't support it */
      if (!XNVCTRLIsNvScreen(display, screen))
        continue;

      /* Gets the GPU number attached to the default screen. */
      /* For further details, see the <NVCtrl/NVCtrlLib.h> */
      err = XNVCTRLQueryTargetBinaryData (display, NV_CTRL_TARGET_TYPE_X_SCREEN, screen, 0,
                                          NV_CTRL_BINARY_DATA_GPUS_USED_BY_XSCREEN,
                                          (unsigned char **) &ptr_binary_data, &data_length);
      if (!err)
        continue;

      gpu_number = ptr_binary_data[1];
      free(ptr_binary_data);

#ifdef NV_CTRL_PCI_DOMAIN
      /* Gets the ID's of the GPU defined by gpu_number
       * For further details, see the <NVCtrl/NVCtrlLib.h> */
      err = XNVCTRLQueryTargetAttribute(display, NV_CTRL_TARGET_TYPE_GPU, gpu_number, 0,
                                        NV_CTRL_PCI_DOMAIN, &nv_ctrl_pci_domain);
      if (!err)
        continue;
#else
      nv_ctrl_pci_domain = 0;
#endif

      err = XNVCTRLQueryTargetAttribute(display, NV_CTRL_TARGET_TYPE_GPU, gpu_number, 0,
                                        NV_CTRL_PCI_BUS, &nv_ctrl_pci_bus);
      if (!err)
        continue;

      err = XNVCTRLQueryTargetAttribute(display, NV_CTRL_TARGET_TYPE_GPU, gpu_number, 0,
                                        NV_CTRL_PCI_DEVICE, &nv_ctrl_pci_device);
      if (!err)
        continue;

      err = XNVCTRLQueryTargetAttribute(display, NV_CTRL_TARGET_TYPE_GPU, gpu_number, 0,
                                        NV_CTRL_PCI_FUNCTION, &nv_ctrl_pci_func);
      if (!err)
        continue;

      productname = NULL;
      err = XNVCTRLQueryTargetStringAttribute(display, NV_CTRL_TARGET_TYPE_GPU, gpu_number, 0,
                                              NV_CTRL_STRING_PRODUCT_NAME, &productname);

      snprintf(name, sizeof(name), ":%u.%u", i, j);

      osdev = hwloc_alloc_setup_object(HWLOC_OBJ_OS_DEVICE, -1);
      osdev->name = strdup(name);
      osdev->logical_index = -1;
      osdev->attr->osdev.type = HWLOC_OBJ_OSDEV_GPU;
      hwloc_obj_add_info(osdev, "Backend", "GL");
      hwloc_obj_add_info(osdev, "GPUVendor", "NVIDIA Corporation");
      if (productname)
	hwloc_obj_add_info(osdev, "GPUModel", productname);

      parent = hwloc_pci_belowroot_find_by_busid(topology, nv_ctrl_pci_domain, nv_ctrl_pci_bus, nv_ctrl_pci_device, nv_ctrl_pci_func);
      if (!parent)
	parent = hwloc_pci_find_busid_parent(topology, nv_ctrl_pci_domain, nv_ctrl_pci_bus, nv_ctrl_pci_device, nv_ctrl_pci_func);
      if (!parent)
	parent = hwloc_get_root_obj(topology);

      hwloc_insert_object_by_parent(topology, parent, osdev);

      hwloc_debug("GL device %s (product %s) on PCI 0000:%02x:%02x.%u\n", name, productname,
		  nv_ctrl_pci_domain, nv_ctrl_pci_bus, nv_ctrl_pci_device, nv_ctrl_pci_func);
      res++;
    }
    XCloseDisplay(display);
  }

  return res;
}
Ejemplo n.º 10
0
void UINVControl::InitialiseMetaModes(Display *XDisplay, int Screen)
{
    if (!NVControlAvailable(XDisplay))
        return;

    QMutexLocker locker(gNVCtrlLock);

    gMetaModeMap.clear();

    if (!XNVCTRLIsNvScreen(XDisplay, Screen))
    {
        LOG(VB_GENERAL, LOG_ERR, QString("NV-CONTROL is not available on screen %1 of display '%2'")
            .arg(Screen).arg(XDisplayName(NULL)));
        return;
    }

    int displays = 0;
    Bool ok = XNVCTRLQueryAttribute(XDisplay, Screen, 0, NV_CTRL_CONNECTED_DISPLAYS, &displays);
    if (ok != True)
    {
        LOG(VB_GENERAL, LOG_ERR, "Failed to retrieve display list");
        return;
    }

    int displaycount = ListDisplays(displays);
    if (displaycount != 1)
    {
        LOG(VB_GENERAL, LOG_WARNING, "There is more than one physical display attached to this screen. Ignoring metamodes");
        return;
    }

    // retrieve a list of refresh rates by mode name
    QMap<QString,double> rates;
    QStringList interlacedrates;

    unsigned char* modelines = NULL;
    int modelinelength = 0;
    if (XNVCTRLQueryBinaryData(XDisplay, Screen, displays, NV_CTRL_BINARY_DATA_MODELINES, &modelines, &modelinelength))
    {
        QByteArray data((const char*)modelines, modelinelength);
        QList<QByteArray> lines = data.split('\0');
        foreach (QByteArray line, lines)
        {
            QString modeline = QString::fromLatin1(line.data()).simplified();

            LOG(VB_GUI, LOG_DEBUG, QString("Modeline: %1").arg(modeline));

            QStringList parts = modeline.split("::", QString::SkipEmptyParts);
            if (parts.size() < 1)
                continue;

            modeline = parts.last();
            parts = modeline.split(" ", QString::SkipEmptyParts);
            if (parts.size() < 10)
                continue;

            QString name = parts[0].replace("\"", "");
            double rate = parts[5].toInt() * parts[9].toInt();
            double clock = parts[1].toDouble();
            if (rate > 0.0 && clock > 0.0f)
            {
                rate = (clock * 1000000) / rate;
                bool interlaced = false;
                if (modeline.contains("interlace", Qt::CaseInsensitive))
                {
                    rate *= 2.0f;
                    interlaced = true;
                }
                if (rate > 20.0f && rate < 121.0f)
                {
                    rates.insert(name, rate);
                    if (interlaced)
                        interlacedrates.append(name);
                }
            }
        }
Ejemplo n.º 11
0
/*
================
Sys_GetVideoRam
returns in megabytes
open your own display connection for the query and close it
using the one shared with GLimp_Init is not stable
================
*/
int Sys_GetVideoRam( void ) {
#ifdef USE_SDL
	return 128;
#else
	static int run_once = 0;
	int major, minor, value;
	Display *l_dpy;
	int l_scrnum;

	if ( run_once ) {
		return run_once;
	}

	if ( sys_videoRam.GetInteger() ) {
		run_once = sys_videoRam.GetInteger();
		return sys_videoRam.GetInteger();
	}

	// try a few strategies to guess the amount of video ram
	common->Printf( "guessing video ram ( use +set sys_videoRam to force ) ..\n" );
	if ( !GLimp_OpenDisplay( ) ) {
		run_once = 64;
		return run_once;
	}

	l_dpy = dpy;
	l_scrnum = scrnum;
	// go for nvidia ext first
	if ( XNVCTRLQueryVersion( l_dpy, &major, &minor ) ) {
		common->Printf( "found XNVCtrl extension %d.%d\n", major, minor );
		if ( XNVCTRLIsNvScreen( l_dpy, l_scrnum ) ) {
			if ( XNVCTRLQueryAttribute( l_dpy, l_scrnum, 0, NV_CTRL_VIDEO_RAM, &value ) ) {
				run_once = value / 1024;
				return run_once;
			} else {
				common->Printf( "XNVCtrlQueryAttribute NV_CTRL_VIDEO_RAM failed\n" );
			}
		} else {
			common->Printf( "default screen %d is not controlled by NVIDIA driver\n", l_scrnum );
		}
	}
	// try ATI /proc read ( for the lack of a better option )
	int fd;
	if ( ( fd = open( "/proc/dri/0/umm", O_RDONLY ) ) != -1 ) {
		int len;
		char umm_buf[ 1024 ];
		char *line;
		if ( ( len = read( fd, umm_buf, 1024 ) ) != -1 ) {
			// should be way enough to get the full file
			// grab "free  LFB = " line and "free  Inv = " lines
			umm_buf[ len-1 ] = '\0';
			line = umm_buf;
			line = strtok( umm_buf, "\n" );
			int total = 0;
			while ( line ) {
				if ( strlen( line ) >= 13 && strstr( line, "max   LFB =" ) == line ) {
					total += atoi( line + 12 );
				} else if ( strlen( line ) >= 13 && strstr( line, "max   Inv =" ) == line ) {
					total += atoi( line + 12 );
				}
				line = strtok( NULL, "\n" );
			}
			if ( total ) {
				run_once = total / 1048576;
				// round to the lower 16Mb
				run_once &= ~15;
				return run_once;
			}
		} else {
			common->Printf( "read /proc/dri/0/umm failed: %s\n", strerror( errno ) );
		}
	}
	common->Printf( "guess failed, return default low-end VRAM setting ( 64MB VRAM )\n" );
	run_once = 64;
	return run_once;
#endif
}