Пример #1
0
EGLBoolean
drm_terminate(_EGLDriver *drv, _EGLDisplay *dpy)
{
	struct drm_device *dev = lookup_drm_device(dpy);
	struct drm_screen *screen;
	int i = 0;

	_eglReleaseDisplayResources(drv, dpy);
	_eglCleanupDisplay(dpy);

	drmFreeVersion(dev->version);

	for (i = 0; i < dev->count_screens; i++) {
		screen = dev->screens[i];

		if (screen->shown)
			drm_takedown_shown_screen(dpy, screen);

		drmModeFreeProperty(screen->dpms);
		drmModeFreeConnector(screen->connector);
		_eglDestroyScreen(&screen->base);
		dev->screens[i] = NULL;
	}

	dev->screen->destroy(dev->screen);
	dev->winsys = NULL;

	drmClose(dev->drmFD);

	dev->api->destroy(dev->api);
	free(dev);
	dpy->DriverData = NULL;

	return EGL_TRUE;
}
Пример #2
0
drm_public struct fd_device * fd_device_new(int fd)
{
	struct fd_device *dev;
	drmVersionPtr version;

	/* figure out if we are kgsl or msm drm driver: */
	version = drmGetVersion(fd);
	if (!version) {
		ERROR_MSG("cannot get version: %s", strerror(errno));
		return NULL;
	}

	if (!strcmp(version->name, "kgsl")) {
		DEBUG_MSG("kgsl DRM device");
		dev = kgsl_device_new(fd);
	} else if (!strcmp(version->name, "msm")) {
		DEBUG_MSG("msm DRM device");
		dev = msm_device_new(fd);
	} else {
		ERROR_MSG("unknown device: %s", version->name);
		dev = NULL;
	}
	drmFreeVersion(version);

	if (!dev)
		return NULL;

	atomic_set(&dev->refcnt, 1);
	dev->fd = fd;
	dev->handle_table = drmHashCreate();
	dev->name_table = drmHashCreate();
	init_cache_buckets(dev);

	return dev;
}
Пример #3
0
/* This is actually the entrypoint to the entire driver,
 * called by the target bootstrap code.
 */
struct svga_winsys_screen *
svga_drm_winsys_screen_create(int fd)
{
   struct vmw_winsys_screen *vws;
   struct dri1_api_version drm_ver;
   drmVersionPtr ver;

   ver = drmGetVersion(fd);
   if (ver == NULL)
      return NULL;

   drm_ver.major = ver->version_major;
   drm_ver.minor = ver->version_minor;
   drm_ver.patch_level = 0; /* ??? */

   drmFreeVersion(ver);
   if (!vmw_dri1_check_version(&drm_ver, &drm_required,
			       &drm_compat, "vmwgfx drm driver"))
      return NULL;

   vws = vmw_winsys_create(fd);
   if (!vws)
      goto out_no_vws;

   /* XXX do this properly */
   vws->base.surface_from_handle = vws->base.have_gb_objects ?
      vmw_drm_gb_surface_from_handle : vmw_drm_surface_from_handle;
   vws->base.surface_get_handle = vmw_drm_surface_get_handle;

   return &vws->base;

out_no_vws:
   return NULL;
}
Пример #4
0
/* Find the index of a compatible DRM device. */
static int get_device_index(void) {
  char buf[32];
  drmVersionPtr ver;

  int index = 0;
  int fd;
  bool found = false;

  while (!found) {
    snprintf(buf, sizeof(buf), "/dev/dri/card%d", index);

    fd = open(buf, O_RDWR);
    if (fd == -1) break;

    ver = drmGetVersion(fd);

    if (strcmp("exynos", ver->name) == 0)
      found = true;
    else
      ++index;

    drmFreeVersion(ver);
    close(fd);
  }

  return (found ? index : -1);
}
Пример #5
0
static Bool
vmw_screen_init(CustomizerPtr cust, int fd)
{
    struct vmw_customizer *vmw = vmw_customizer(cust);
    drmVersionPtr ver;

    vmw->fd = fd;
    ver = drmGetVersion(fd);
    if (ver == NULL ||
            (ver->version_major == 1 && ver->version_minor < 1)) {
        cust->swap_throttling = TRUE;
        cust->dirty_throttling = TRUE;
        cust->winsys_context_throttle = vmw_context_no_throttle;
    } else {
        cust->swap_throttling = TRUE;
        cust->dirty_throttling = FALSE;
        cust->winsys_context_throttle = vmw_context_throttle;
        debug_printf("%s: Enabling kernel throttling.\n", __func__);
    }

    if (ver)
        drmFreeVersion(ver);

    vmw_screen_cursor_init(vmw);



    /* if gallium is used then we don't need to do anything more. */
    if (xorg_has_gallium(vmw->pScrn))
        return TRUE;

    vmw_video_init(vmw);

    return TRUE;
}
Пример #6
0
/* Find the index of a compatible DRM device. */
static int exynos_get_device_index(void)
{
   drmVersionPtr ver;
   char buf[32]       = {0};
   int index          = 0;
   bool found         = false;

   while (!found)
   {
      int fd;

      snprintf(buf, sizeof(buf), "/dev/dri/card%d", index);

      fd = open(buf, O_RDWR);
      if (fd < 0) break;

      ver = drmGetVersion(fd);

      if (string_is_equal(ver->name, "exynos"))
         found = true;
      else
         ++index;

      drmFreeVersion(ver);
      close(fd);
   }

   if (!found)
      return -1;
   return index;
}
Пример #7
0
char *
loader_get_driver_for_fd(int fd, unsigned driver_types)
{
   int vendor_id, chip_id, i, j;
   char *driver = NULL;

   if (!driver_types)
      driver_types = _LOADER_GALLIUM | _LOADER_DRI;

   if (!loader_get_pci_id_for_fd(fd, &vendor_id, &chip_id)) {

#ifndef __NOT_HAVE_DRM_H
      /* fallback to drmGetVersion(): */
      drmVersionPtr version = drmGetVersion(fd);

      if (!version) {
         log_(_LOADER_WARNING, "failed to get driver name for fd %d\n", fd);
         return NULL;
      }

      driver = strndup(version->name, version->name_len);
      log_(_LOADER_INFO, "using driver %s for %d\n", driver, fd);

      drmFreeVersion(version);
#endif

      return driver;
   }

   for (i = 0; driver_map[i].driver; i++) {
      if (vendor_id != driver_map[i].vendor_id)
         continue;

      if (!(driver_types & driver_map[i].driver_types))
         continue;

      if (driver_map[i].predicate && !driver_map[i].predicate(fd))
         continue;

      if (driver_map[i].num_chips_ids == -1) {
         driver = strdup(driver_map[i].driver);
         goto out;
      }

      for (j = 0; j < driver_map[i].num_chips_ids; j++)
         if (driver_map[i].chip_ids[j] == chip_id) {
            driver = strdup(driver_map[i].driver);
            goto out;
         }
   }

out:
   log_(driver ? _LOADER_DEBUG : _LOADER_WARNING,
         "pci id for fd %d: %04x:%04x, driver %s\n",
         fd, vendor_id, chip_id, driver);
   return driver;
}
/** As long as we are using our fake DRI driver inside of Mesa, we only want
 *  to implement the minimum here to make Mesa load it. */
Bool VBOXDRIScreenInit(ScrnInfoPtr pScrn, ScreenPtr pScreen, VBOXPtr pVBox)
{
    DRI2InfoRec DRI2Info;
    unsigned i;

    memset(&DRI2Info, 0, sizeof(DRI2Info));
    pVBox->drmFD = -1;
    for (i = 0; i < RT_ELEMENTS(devicePaths); ++i)
    {
        int fd = open(devicePaths[i], O_RDWR);
        if (fd >= 0)
        {
            drmVersionPtr pVersion = drmGetVersion(fd);
            if (   pVersion
                && pVersion->name_len
                && !strcmp(pVersion->name, VBOX_DRM_DRIVER_NAME)
                && drmSetMaster(fd) == 0)
            {
                TRACE_LOG("Opened drm device %s\n", devicePaths[i]);
                DRI2Info.deviceName = devicePaths[i];
                /* Keep the driver open and hope that the path won't change. */
                pVBox->drmFD = fd;
                drmFreeVersion(pVersion);
                break;
            }
            close(fd);
            drmFreeVersion(pVersion);
        }
    }
    if (!DRI2Info.deviceName)
        return FALSE;
    DRI2Info.version = 3;
    DRI2Info.fd = pVBox->drmFD;
    DRI2Info.driverName = VBOX_DRI_DRIVER_NAME;
    DRI2Info.CopyRegion = VBOXDRICopyRegion;
    DRI2Info.Wait = NULL;
    DRI2Info.CreateBuffer = VBOXDRICreateBuffer;
    DRI2Info.DestroyBuffer = VBOXDRIDestroyBuffer;
    return DRI2ScreenInit(pScreen, &DRI2Info);
}
Пример #9
0
/* Print AMD devices information */
static void amdgpu_print_devices()
{
	int i;
	drmDevicePtr device;

	/* Open the first AMD devcie to print driver information. */
	if (drm_amdgpu[0] >=0) {
		/* Display AMD driver version information.*/
		drmVersionPtr retval = drmGetVersion(drm_amdgpu[0]);

		if (retval == NULL) {
			perror("Cannot get version for AMDGPU device");
			return;
		}

		printf("Driver name: %s, Date: %s, Description: %s.\n",
			retval->name, retval->date, retval->desc);
		drmFreeVersion(retval);
	}

	/* Display information of AMD devices */
	printf("Devices:\n");
	for (i = 0; i < MAX_CARDS_SUPPORTED && drm_amdgpu[i] >=0; i++)
		if (drmGetDevice2(drm_amdgpu[i],
			DRM_DEVICE_GET_PCI_REVISION,
			&device) == 0) {
			if (device->bustype == DRM_BUS_PCI) {
				printf("PCI ");
				printf(" domain:%04x",
					device->businfo.pci->domain);
				printf(" bus:%02x",
					device->businfo.pci->bus);
				printf(" device:%02x",
					device->businfo.pci->dev);
				printf(" function:%01x",
					device->businfo.pci->func);
				printf(" vendor_id:%04x",
					device->deviceinfo.pci->vendor_id);
				printf(" device_id:%04x",
					device->deviceinfo.pci->device_id);
				printf(" subvendor_id:%04x",
					device->deviceinfo.pci->subvendor_id);
				printf(" subdevice_id:%04x",
					device->deviceinfo.pci->subdevice_id);
				printf(" revision_id:%02x",
					device->deviceinfo.pci->revision_id);
				printf("\n");
			}
			drmFreeDevice(&device);
		}
}
Пример #10
0
/**
 * DRI2
 */
static __DRIscreen *
dri2CreateNewScreen(int scrn, int fd,
                    const __DRIextension **extensions,
                    const __DRIconfig ***driver_configs, void *data)
{
    static const __DRIextension *emptyExtensionList[] = { NULL };
    __DRIscreen *psp;
    drmVersionPtr version;

    if (driDriverAPI.InitScreen2 == NULL)
        return NULL;

    psp = calloc(1, sizeof(*psp));
    if (!psp)
        return NULL;

    setupLoaderExtensions(psp, extensions);

    version = drmGetVersion(fd);
    if (version) {
        psp->drm_version.major = version->version_major;
        psp->drm_version.minor = version->version_minor;
        psp->drm_version.patch = version->version_patchlevel;
        drmFreeVersion(version);
    }

    psp->extensions = emptyExtensionList;
    psp->fd = fd;
    psp->myNum = scrn;
    psp->dri2.enabled = GL_TRUE;

    psp->DriverAPI = driDriverAPI;
    psp->api_mask = (1 << __DRI_API_OPENGL);
    *driver_configs = driDriverAPI.InitScreen2(psp);
    if (*driver_configs == NULL) {
        free(psp);
        return NULL;
    }

    psp->DriverAPI = driDriverAPI;
    psp->loaderPrivate = data;

    driParseOptionInfo(&psp->optionInfo, __dri2ConfigOptions,
                       __dri2NConfigOptions);
    driParseConfigFiles(&psp->optionCache, &psp->optionInfo, psp->myNum,
                        "dri2");

    return psp;
}
Пример #11
0
struct fd_device * fd_device_new(int fd)
{
	struct fd_device *dev;
	drmVersionPtr version;

	/* figure out if we are kgsl or msm drm driver: */
	version = drmGetVersion(fd);
	if (!version) {
		ERROR_MSG("cannot get version: %s", strerror(errno));
		return NULL;
	}

	if (!strcmp(version->name, "msm")) {
		DEBUG_MSG("msm DRM device");
		if (version->version_major != 1) {
			ERROR_MSG("unsupported version: %u.%u.%u", version->version_major,
				version->version_minor, version->version_patchlevel);
			dev = NULL;
			goto out;
		}

		dev = msm_device_new(fd);
		dev->version = version->version_minor;
#if HAVE_FREEDRENO_KGSL
	} else if (!strcmp(version->name, "kgsl")) {
		DEBUG_MSG("kgsl DRM device");
		dev = kgsl_device_new(fd);
#endif
	} else {
		ERROR_MSG("unknown device: %s", version->name);
		dev = NULL;
	}

out:
	drmFreeVersion(version);

	if (!dev)
		return NULL;

	p_atomic_set(&dev->refcnt, 1);
	dev->fd = fd;
	dev->handle_table = _mesa_hash_table_create(NULL, u32_hash, u32_equals);
	dev->name_table = _mesa_hash_table_create(NULL, u32_hash, u32_equals);
	fd_bo_cache_init(&dev->bo_cache, FALSE);
	fd_bo_cache_init(&dev->ring_cache, TRUE);

	return dev;
}
static Bool has_kernel_mode_setting(const struct pci_device *dev)
{
	char id[20];
	int ret, fd;

	snprintf(id, sizeof(id),
		 "pci:%04x:%02x:%02x.%d",
		 dev->domain, dev->bus, dev->dev, dev->func);

	ret = drmCheckModesettingSupported(id);
	if (ret) {
		if (xf86LoadKernelModule("i915"))
			ret = drmCheckModesettingSupported(id);
		if (ret)
			return FALSE;
		/* Be nice to the user and load fbcon too */
		(void)xf86LoadKernelModule("fbcon");
	}

	/* Confirm that this is a i915.ko device with GEM/KMS enabled */
	ret = FALSE;
	fd = drmOpen(NULL, id);
	if (fd != -1) {
		drmVersionPtr version = drmGetVersion(fd);
		if (version) {
			ret = strcmp ("i915", version->name) == 0;
			drmFreeVersion(version);
		}
		if (ret) {
			struct drm_i915_getparam gp;
			gp.param = I915_PARAM_HAS_GEM;
			gp.value = &ret;
			if (drmIoctl(fd, DRM_IOCTL_I915_GETPARAM, &gp))
				ret = FALSE;
		}
		if (ret) {
			struct drm_mode_card_res res;

			memset(&res, 0, sizeof(res));
			if (drmIoctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &res))
				ret = FALSE;
		}
		close(fd);
	}

	return ret;
}
/*
 * Create the driver for a DRM fd.
 */
static struct gralloc_drm_drv_t *
init_drv_from_fd(int fd)
{
	struct gralloc_drm_drv_t *drv = NULL;
	drmVersionPtr version;

	/* get the kernel module name */
	version = drmGetVersion(fd);
	if (!version) {
		LOGE("invalid DRM fd");
		return NULL;
	}

	if (version->name) {
#ifdef ENABLE_PIPE
		drv = gralloc_drm_drv_create_for_pipe(fd, version->name);
#endif

#ifdef ENABLE_INTEL
		if (!drv && !strcmp(version->name, "i915"))
			drv = gralloc_drm_drv_create_for_intel(fd);
#endif
#ifdef ENABLE_OMAP
		if (!drv && !strcmp(version->name, "omapdrm"))
			drv = gralloc_drm_drv_create_for_omap(fd);
#endif
#ifdef ENABLE_RADEON
		if (!drv && !strcmp(version->name, "radeon"))
			drv = gralloc_drm_drv_create_for_radeon(fd);
#endif
#ifdef ENABLE_NOUVEAU
		if (!drv && !strcmp(version->name, "nouveau"))
			drv = gralloc_drm_drv_create_for_nouveau(fd);
#endif
	}

	if (!drv) {
		LOGE("unsupported driver: %s", (version->name) ?
				version->name : "NULL");
	}

	drmFreeVersion(version);

	return drv;
}
Пример #14
0
static void getversion(int fd)
{
    drmVersionPtr version;
    
    version = drmGetVersion(fd);
    if (version) {
	printf( "Name: %s\n", version->name ? version->name : "?" );
	printf( "    Version: %d.%d.%d\n",
		version->version_major,
		version->version_minor,
		version->version_patchlevel );
	printf( "    Date: %s\n", version->date ? version->date : "?" );
	printf( "    Desc: %s\n", version->desc ? version->desc : "?" );
	drmFreeVersion(version);
    } else {
	printf( "No driver available\n" );
    }
}
Пример #15
0
drm_public int drm_tegra_new(struct drm_tegra **drmp, int fd)
{
	bool supported = false;
	drmVersionPtr version;

	version = drmGetVersion(fd);
	if (!version)
		return -ENOMEM;

	if (!strncmp(version->name, "tegra", version->name_len))
		supported = true;

	drmFreeVersion(version);

	if (!supported)
		return -ENOTSUP;

	return drm_tegra_wrap(drmp, fd, false);
}
Пример #16
0
static void
log_drm_version (GstKMSSink * self)
{
#ifndef GST_DISABLE_GST_DEBUG
  drmVersion *v;

  v = drmGetVersion (self->fd);
  if (v) {
    GST_INFO_OBJECT (self, "DRM v%d.%d.%d [%s — %s — %s]", v->version_major,
        v->version_minor, v->version_patchlevel, GST_STR_NULL (v->name),
        GST_STR_NULL (v->desc), GST_STR_NULL (v->date));
    drmFreeVersion (v);
  } else {
    GST_WARNING_OBJECT (self, "could not get driver information: %s",
        GST_STR_NULL (self->devname));
  }
#endif
  return;
}
Пример #17
0
static gboolean
device_open (Device *device)
{
  gboolean ret = FALSE;

  device->fd = open ("/dev/dri/card0", O_RDWR);
  if (device->fd < 0)
    {
      g_warning ("Unable to open DRI device");
      goto out;
    }

  ret = TRUE;

  drmVersionPtr version = drmGetVersion (device->fd);
  g_print ("Driver name: %s\n", version->name);
  drmFreeVersion (version);

 out:
  return ret;
}
Пример #18
0
int main(int argc, char *argv[])
{
	struct etna_device *dev;

	drmVersionPtr version;
	int fd, ret = 0;

	fd = open(argv[1], O_RDWR);
	if (fd < 0)
		return 1;

	version = drmGetVersion(fd);
	if (version) {
		printf("Version: %d.%d.%d\n", version->version_major,
		       version->version_minor, version->version_patchlevel);
		printf("  Name: %s\n", version->name);
		printf("  Date: %s\n", version->date);
		printf("  Description: %s\n", version->desc);
		drmFreeVersion(version);
	}

	dev = etna_device_new(fd);
	if (!dev) {
		ret = 2;
		goto out;
	}

	test_cache(dev);
	test_size_rounding(dev);

	etna_device_del(dev);

out:
	close(fd);

	return ret;
}
Пример #19
0
int main(int argc, char *argv[])
{
	struct drm_tegra *tegra;
	drmVersionPtr version;
	const char *device;
	int err, fd;

	if (argc < 2)
		device = default_device;
	else
		device = argv[1];

	fd = open(device, O_RDWR);
	if (fd < 0)
		return 1;

	version = drmGetVersion(fd);
	if (version) {
		printf("Version: %d.%d.%d\n", version->version_major,
		       version->version_minor, version->version_patchlevel);
		printf("  Name: %s\n", version->name);
		printf("  Date: %s\n", version->date);
		printf("  Description: %s\n", version->desc);

		drmFreeVersion(version);
	}

	err = drm_tegra_new(&tegra, fd);
	if (err < 0)
		return 1;

	drm_tegra_close(tegra);
	close(fd);

	return 0;
}
Пример #20
0
/**
 * This is the first entrypoint in the driver called by the DRI driver loader
 * after dlopen()ing it.
 *
 * It's used to create global state for the driver across contexts on the same
 * Display.
 */
static __DRIscreen *
driCreateNewScreen2(int scrn, int fd,
                    const __DRIextension **extensions,
                    const __DRIextension **driver_extensions,
                    const __DRIconfig ***driver_configs, void *data)
{
    static const __DRIextension *emptyExtensionList[] = { NULL };
    __DRIscreen *psp;

    psp = calloc(1, sizeof(*psp));
    if (!psp)
	return NULL;

    /* By default, use the global driDriverAPI symbol (non-megadrivers). */
    psp->driver = globalDriverAPI;

    /* If the driver exposes its vtable through its extensions list
     * (megadrivers), use that instead.
     */
    if (driver_extensions) {
       for (int i = 0; driver_extensions[i]; i++) {
          if (strcmp(driver_extensions[i]->name, __DRI_DRIVER_VTABLE) == 0) {
             psp->driver =
                ((__DRIDriverVtableExtension *)driver_extensions[i])->vtable;
          }
       }
    }

    setupLoaderExtensions(psp, extensions);

#ifndef __NOT_HAVE_DRM_H
    if (fd != -1) {
       drmVersionPtr version = drmGetVersion(fd);
       if (version) {
          psp->drm_version.major = version->version_major;
          psp->drm_version.minor = version->version_minor;
          psp->drm_version.patch = version->version_patchlevel;
          drmFreeVersion(version);
       }
    }
#endif

    psp->loaderPrivate = data;

    psp->extensions = emptyExtensionList;
    psp->fd = fd;
    psp->myNum = scrn;

    *driver_configs = psp->driver->InitScreen(psp);
    if (*driver_configs == NULL) {
	free(psp);
	return NULL;
    }

    int gl_version_override = _mesa_get_gl_version_override();
    if (gl_version_override >= 31) {
       psp->max_gl_core_version = MAX2(psp->max_gl_core_version,
                                       gl_version_override);
    } else {
       psp->max_gl_compat_version = MAX2(psp->max_gl_compat_version,
                                         gl_version_override);
    }

    psp->api_mask = (1 << __DRI_API_OPENGL);
    if (psp->max_gl_core_version > 0)
       psp->api_mask |= (1 << __DRI_API_OPENGL_CORE);
    if (psp->max_gl_es1_version > 0)
       psp->api_mask |= (1 << __DRI_API_GLES);
    if (psp->max_gl_es2_version > 0)
       psp->api_mask |= (1 << __DRI_API_GLES2);
    if (psp->max_gl_es2_version >= 30)
       psp->api_mask |= (1 << __DRI_API_GLES3);

    driParseOptionInfo(&psp->optionInfo, __dri2ConfigOptions);
    driParseConfigFiles(&psp->optionCache, &psp->optionInfo, psp->myNum, "dri2");


    return psp;
}
Пример #21
0
/**
 * Perform the required libGL-side initialization and call the client-side
 * driver's \c __driCreateNewScreen function.
 * 
 * \param dpy    Display pointer.
 * \param scrn   Screen number on the display.
 * \param psc    DRI screen information.
 * \param driDpy DRI display information.
 * \param createNewScreen  Pointer to the client-side driver's
 *               \c __driCreateNewScreen function.
 * \returns A pointer to the \c __DRIscreen structure returned by
 *          the client-side driver on success, or \c NULL on failure.
 */
static void *
CallCreateNewScreen(Display *dpy, int scrn, struct dri_screen *psc,
                    struct dri_display * driDpy)
{
   void *psp = NULL;
   drm_handle_t hSAREA;
   drmAddress pSAREA = MAP_FAILED;
   char *BusID;
   __DRIversion ddx_version;
   __DRIversion dri_version;
   __DRIversion drm_version;
   __DRIframebuffer framebuffer;
   int fd = -1;
   int status;

   drm_magic_t magic;
   drmVersionPtr version;
   int newlyopened;
   char *driverName;
   drm_handle_t hFB;
   int junk;
   const __DRIconfig **driver_configs;
   struct glx_config *visual, *configs = NULL, *visuals = NULL;

   /* DRI protocol version. */
   dri_version.major = driDpy->driMajor;
   dri_version.minor = driDpy->driMinor;
   dri_version.patch = driDpy->driPatch;

   framebuffer.base = MAP_FAILED;
   framebuffer.dev_priv = NULL;
   framebuffer.size = 0;

   if (!XF86DRIOpenConnection(dpy, scrn, &hSAREA, &BusID)) {
      ErrorMessageF("XF86DRIOpenConnection failed\n");
      goto handle_error;
   }

   fd = drmOpenOnce(NULL, BusID, &newlyopened);

   free(BusID);                /* No longer needed */

   if (fd < 0) {
      ErrorMessageF("drmOpenOnce failed (%s)\n", strerror(-fd));
      goto handle_error;
   }

   if (drmGetMagic(fd, &magic)) {
      ErrorMessageF("drmGetMagic failed\n");
      goto handle_error;
   }

   version = drmGetVersion(fd);
   if (version) {
      drm_version.major = version->version_major;
      drm_version.minor = version->version_minor;
      drm_version.patch = version->version_patchlevel;
      drmFreeVersion(version);
   }
   else {
      drm_version.major = -1;
      drm_version.minor = -1;
      drm_version.patch = -1;
   }

   if (newlyopened && !XF86DRIAuthConnection(dpy, scrn, magic)) {
      ErrorMessageF("XF86DRIAuthConnection failed\n");
      goto handle_error;
   }

   /* Get device name (like "radeon") and the ddx version numbers.
    * We'll check the version in each DRI driver's "createNewScreen"
    * function. */
   if (!XF86DRIGetClientDriverName(dpy, scrn,
                                   &ddx_version.major,
                                   &ddx_version.minor,
                                   &ddx_version.patch, &driverName)) {
      ErrorMessageF("XF86DRIGetClientDriverName failed\n");
      goto handle_error;
   }

   free(driverName);           /* No longer needed. */

   /*
    * Get device-specific info.  pDevPriv will point to a struct
    * (such as DRIRADEONRec in xfree86/driver/ati/radeon_dri.h) that
    * has information about the screen size, depth, pitch, ancilliary
    * buffers, DRM mmap handles, etc.
    */
   if (!XF86DRIGetDeviceInfo(dpy, scrn, &hFB, &junk,
                             &framebuffer.size, &framebuffer.stride,
                             &framebuffer.dev_priv_size,
                             &framebuffer.dev_priv)) {
      ErrorMessageF("XF86DRIGetDeviceInfo failed\n");
      goto handle_error;
   }

   framebuffer.width = DisplayWidth(dpy, scrn);
   framebuffer.height = DisplayHeight(dpy, scrn);

   /* Map the framebuffer region. */
   status = drmMap(fd, hFB, framebuffer.size,
                   (drmAddressPtr) & framebuffer.base);
   if (status != 0) {
      ErrorMessageF("drmMap of framebuffer failed (%s)\n", strerror(-status));
      goto handle_error;
   }

   /* Map the SAREA region.  Further mmap regions may be setup in
    * each DRI driver's "createNewScreen" function.
    */
   status = drmMap(fd, hSAREA, SAREA_MAX, &pSAREA);
   if (status != 0) {
      ErrorMessageF("drmMap of SAREA failed (%s)\n", strerror(-status));
      goto handle_error;
   }

   psp = (*psc->legacy->createNewScreen) (scrn,
                                          &ddx_version,
                                          &dri_version,
                                          &drm_version,
                                          &framebuffer,
                                          pSAREA,
                                          fd,
                                          loader_extensions,
                                          &driver_configs, psc);

   if (psp == NULL) {
      ErrorMessageF("Calling driver entry point failed\n");
      goto handle_error;
   }

   configs = driConvertConfigs(psc->core, psc->base.configs, driver_configs);
   visuals = driConvertConfigs(psc->core, psc->base.visuals, driver_configs);

   if (!configs || !visuals)
       goto handle_error;

   glx_config_destroy_list(psc->base.configs);
   psc->base.configs = configs;
   glx_config_destroy_list(psc->base.visuals);
   psc->base.visuals = visuals;

   psc->driver_configs = driver_configs;

   /* Visuals with depth != screen depth are subject to automatic compositing
    * in the X server, so DRI1 can't render to them properly. Mark them as
    * non-conformant to prevent apps from picking them up accidentally.
    */
   for (visual = psc->base.visuals; visual; visual = visual->next) {
      XVisualInfo template;
Пример #22
0
Bool
I810DRIScreenInit(ScreenPtr pScreen)
{
   ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
   I810Ptr pI810 = I810PTR(pScrn);
   DRIInfoPtr pDRIInfo;
   I810DRIPtr pI810DRI;
   unsigned long tom;
   drm_handle_t agpHandle;
   drm_handle_t dcacheHandle;
   int sysmem_size = 0;
   int back_size = 0;
   unsigned int pitch_idx = 0;
   int bufs;
   int width = pScrn->displayWidth * pI810->cpp;
   int i;

   /* Hardware 3D rendering only implemented for 16bpp */
   /* And it only works for 5:6:5 (Mark) */
   if (pScrn->depth != 16)
      return FALSE;

   /* Check that the DRI, and DRM modules have been loaded by testing
    * for known symbols in each module. */
   if (!xf86LoaderCheckSymbol("drmAvailable"))
      return FALSE;
   if (!xf86LoaderCheckSymbol("DRIQueryVersion")) {
      xf86DrvMsg(pScreen->myNum, X_ERROR,
		 "[dri] I810DRIScreenInit failed (libdri.a too old)\n");
      return FALSE;
   }

   /* adjust width first */
#define Elements(x) sizeof(x)/sizeof(*x)
   for (pitch_idx = 0; pitch_idx < Elements(i810_pitches); pitch_idx++)
      if (width <= i810_pitches[pitch_idx])
	 break;

   if (pitch_idx == Elements(i810_pitches)) {
      xf86DrvMsg(pScrn->scrnIndex, X_INFO,
		 "[dri] Couldn't find depth/back buffer pitch");
      DRICloseScreen(pScreen);
      return FALSE;
   } else {
      /* for tiled memory to work, the buffer needs to have the
       * number of lines as a multiple of 16 (the tile size),
       *  - airlied */
      int lines = (pScrn->virtualY + 15) / 16 * 16;
      back_size = i810_pitches[pitch_idx] * lines;
      back_size = ((back_size + 4096 - 1) / 4096) * 4096;
   }

   pScrn->displayWidth = i810_pitches[pitch_idx] / pI810->cpp;

   /* Check the DRI version */
   {
      int major, minor, patch;

      DRIQueryVersion(&major, &minor, &patch);
      if (major != DRIINFO_MAJOR_VERSION || minor < DRIINFO_MINOR_VERSION) {
	 xf86DrvMsg(pScreen->myNum, X_ERROR,
		    "[dri] I810DRIScreenInit failed because of a version mismatch.\n"
		    "[dri] libdri version is %d.%d.%d bug version %d.%d.x is needed.\n"
		    "[dri] Disabling DRI.\n", major, minor, patch,
                    DRIINFO_MAJOR_VERSION, DRIINFO_MINOR_VERSION);
	 return FALSE;
      }
   }

   pDRIInfo = DRICreateInfoRec();
   if (!pDRIInfo) {
      xf86DrvMsg(pScreen->myNum, X_ERROR,
		 "[dri] DRICreateInfoRec failed.  Disabling DRI.\n");
      return FALSE;
   }

/*     pDRIInfo->wrap.ValidateTree = 0;    */
/*     pDRIInfo->wrap.PostValidateTree = 0;    */

   pI810->pDRIInfo = pDRIInfo;
   pI810->LockHeld = 0;

   pDRIInfo->drmDriverName = I810KernelDriverName;
   pDRIInfo->clientDriverName = I810ClientDriverName;
   if (xf86LoaderCheckSymbol("DRICreatePCIBusID")) {
      pDRIInfo->busIdString = DRICreatePCIBusID(pI810->PciInfo);
   } else {
      pDRIInfo->busIdString = malloc(64);
      if (pDRIInfo->busIdString)
	 sprintf(pDRIInfo->busIdString, "PCI:%d:%d:%d",
		 ((pI810->PciInfo->domain << 8) | pI810->PciInfo->bus),
		 pI810->PciInfo->dev, pI810->PciInfo->func
		);
   }
   if (!pDRIInfo->busIdString) {
      DRIDestroyInfoRec(pI810->pDRIInfo);
      pI810->pDRIInfo = NULL;
      return FALSE;
   }
   pDRIInfo->ddxDriverMajorVersion = I810_MAJOR_VERSION;
   pDRIInfo->ddxDriverMinorVersion = I810_MINOR_VERSION;
   pDRIInfo->ddxDriverPatchVersion = I810_PATCHLEVEL;
   pDRIInfo->frameBufferPhysicalAddress = (pointer) pI810->LinearAddr;
   pDRIInfo->frameBufferSize = (((pScrn->displayWidth *
				  pScrn->virtualY * pI810->cpp) +
				 4096 - 1) / 4096) * 4096;

   pDRIInfo->frameBufferStride = pScrn->displayWidth * pI810->cpp;
   pDRIInfo->ddxDrawableTableEntry = I810_MAX_DRAWABLES;

   if (SAREA_MAX_DRAWABLES < I810_MAX_DRAWABLES)
      pDRIInfo->maxDrawableTableEntry = SAREA_MAX_DRAWABLES;
   else
      pDRIInfo->maxDrawableTableEntry = I810_MAX_DRAWABLES;

   /* For now the mapping works by using a fixed size defined
    * in the SAREA header
    */
   if (sizeof(XF86DRISAREARec) + sizeof(I810SAREARec) > SAREA_MAX) {
      xf86DrvMsg(pScreen->myNum, X_ERROR,
		 "[dri] Data does not fit in SAREA\n");
      return FALSE;
   }
   pDRIInfo->SAREASize = SAREA_MAX;

   if (!(pI810DRI = (I810DRIPtr) calloc(sizeof(I810DRIRec), 1))) {
      DRIDestroyInfoRec(pI810->pDRIInfo);
      pI810->pDRIInfo = NULL;
      return FALSE;
   }
   pDRIInfo->devPrivate = pI810DRI;
   pDRIInfo->devPrivateSize = sizeof(I810DRIRec);
   pDRIInfo->contextSize = sizeof(I810DRIContextRec);

   pDRIInfo->CreateContext = I810CreateContext;
   pDRIInfo->DestroyContext = I810DestroyContext;
   pDRIInfo->SwapContext = I810DRISwapContext;
   pDRIInfo->InitBuffers = I810DRIInitBuffers;
   pDRIInfo->MoveBuffers = I810DRIMoveBuffers;
   pDRIInfo->bufferRequests = DRI_ALL_WINDOWS;
   pDRIInfo->TransitionTo2d = I810DRITransitionTo2d;
   pDRIInfo->TransitionTo3d = I810DRITransitionTo3d;
   pDRIInfo->TransitionSingleToMulti3D = I810DRITransitionSingleToMulti3d;
   pDRIInfo->TransitionMultiToSingle3D = I810DRITransitionMultiToSingle3d;

   pDRIInfo->createDummyCtx = TRUE;
   pDRIInfo->createDummyCtxPriv = FALSE;

   /* This adds the framebuffer as a drm map *before* we have asked agp
    * to allocate it.  Scary stuff, hold on...
    */
   if (!DRIScreenInit(pScreen, pDRIInfo, &pI810->drmSubFD)) {
      xf86DrvMsg(pScreen->myNum, X_ERROR,
		 "[dri] DRIScreenInit failed.  Disabling DRI.\n");
      free(pDRIInfo->devPrivate);
      pDRIInfo->devPrivate = NULL;
      DRIDestroyInfoRec(pI810->pDRIInfo);
      pI810->pDRIInfo = NULL;
      return FALSE;
   }

   /* Check the i810 DRM versioning */
   {
      drmVersionPtr version;

      /* Check the DRM lib version.
       * drmGetLibVersion was not supported in version 1.0, so check for
       * symbol first to avoid possible crash or hang.
       */
      if (xf86LoaderCheckSymbol("drmGetLibVersion")) {
	 version = drmGetLibVersion(pI810->drmSubFD);
      } else
      {
	 /* drmlib version 1.0.0 didn't have the drmGetLibVersion
	  * entry point.  Fake it by allocating a version record
	  * via drmGetVersion and changing it to version 1.0.0
	  */
	 version = drmGetVersion(pI810->drmSubFD);
	 version->version_major = 1;
	 version->version_minor = 0;
	 version->version_patchlevel = 0;
      }

#define REQ_MAJ 1
#define REQ_MIN 1
      if (version) {
	 if (version->version_major != REQ_MAJ ||
	     version->version_minor < REQ_MIN) {
	    /* incompatible drm library version */
	    xf86DrvMsg(pScreen->myNum, X_ERROR,
		       "[dri] I810DRIScreenInit failed because of a version mismatch.\n"
		       "[dri] libdrm.a module version is %d.%d.%d but version %d.%d.x is needed.\n"
		       "[dri] Disabling DRI.\n",
		       version->version_major,
		       version->version_minor, version->version_patchlevel,
		       REQ_MAJ, REQ_MIN);
	    drmFreeVersion(version);
	    I810DRICloseScreen(pScreen);
	    return FALSE;
	 }
	 drmFreeVersion(version);
      }

      /* Check the i810 DRM version */
      version = drmGetVersion(pI810->drmSubFD);
      if (version) {
	i810_drm_version = (version->version_major<<16) |
	                    version->version_minor;
	 if (version->version_major != 1 || version->version_minor < 2) {
	    /* incompatible drm version */
	    xf86DrvMsg(pScreen->myNum, X_ERROR,
		       "[dri] I810DRIScreenInit failed because of a version mismatch.\n"
		       "[dri] i810.o kernel module version is %d.%d.%d but version 1.2.0 or greater is needed.\n"
		       "[dri] Disabling DRI.\n",
		       version->version_major,
		       version->version_minor, version->version_patchlevel);
	    I810DRICloseScreen(pScreen);
	    drmFreeVersion(version);
	    return FALSE;
	 }
         pI810->drmMinor = version->version_minor;
	 drmFreeVersion(version);
      }
   }

   pI810DRI->regsSize = I810_REG_SIZE;
   if (drmAddMap(pI810->drmSubFD, (drm_handle_t) pI810->MMIOAddr,
		 pI810DRI->regsSize, DRM_REGISTERS, 0,
		 (drmAddress) &pI810DRI->regs) < 0) {
      xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] drmAddMap(regs) failed\n");
      DRICloseScreen(pScreen);
      return FALSE;
   }
   xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Registers = 0x%08x\n",
	      (int)pI810DRI->regs);

   pI810->backHandle = DRM_AGP_NO_HANDLE;
   pI810->zHandle = DRM_AGP_NO_HANDLE;
   pI810->cursorHandle = DRM_AGP_NO_HANDLE;
   pI810->xvmcHandle = DRM_AGP_NO_HANDLE;
   pI810->sysmemHandle = DRM_AGP_NO_HANDLE;
   pI810->agpAcquired = FALSE;
   pI810->dcacheHandle = DRM_AGP_NO_HANDLE;

   /* Agp Support - Need this just to get the framebuffer.
    */
   if (drmAgpAcquire(pI810->drmSubFD) < 0) {
      xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] drmAgpAquire failed\n");
      DRICloseScreen(pScreen);
      return FALSE;
   }
   pI810->agpAcquired = TRUE;

   if (drmAgpEnable(pI810->drmSubFD, 0) < 0) {
      xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] drmAgpEnable failed\n");
      DRICloseScreen(pScreen);
      return FALSE;
   }

   memset(&pI810->DcacheMem, 0, sizeof(I810MemRange));
   memset(&pI810->BackBuffer, 0, sizeof(I810MemRange));
   memset(&pI810->DepthBuffer, 0, sizeof(I810MemRange));
   pI810->CursorPhysical = 0;
   pI810->CursorARGBPhysical = 0;

   /* Dcache - half the speed of normal ram, but has use as a Z buffer
    * under the DRI.
    */

   drmAgpAlloc(pI810->drmSubFD, 4096 * 1024, 1, NULL,
	       (drmAddress) &dcacheHandle);
   pI810->dcacheHandle = dcacheHandle;

   xf86DrvMsg(pScreen->myNum, X_INFO, "[agp] dcacheHandle : 0x%x\n",
	      (int)dcacheHandle);

   sysmem_size = pScrn->videoRam * 1024;
   if (dcacheHandle != DRM_AGP_NO_HANDLE) {
      if (back_size > 4 * 1024 * 1024) {
	 xf86DrvMsg(pScreen->myNum, X_INFO,
		    "[dri] Backsize is larger then 4 meg\n");
	 sysmem_size = sysmem_size - 2 * back_size;
	 drmAgpFree(pI810->drmSubFD, dcacheHandle);
	 pI810->dcacheHandle = dcacheHandle = DRM_AGP_NO_HANDLE;
      } else {
	 sysmem_size = sysmem_size - back_size;
      }
   } else {
      sysmem_size = sysmem_size - 2 * back_size;
   }

   /* Max size is 48 without XvMC, 41 with 6 surfaces, 40 with 7 surfaces */
   if (pI810->numSurfaces && (pI810->numSurfaces == 6)) {
      if (sysmem_size > (pI810->FbMapSize - 7 * 1024 * 1024)) {
	 sysmem_size = (pI810->FbMapSize - 7 * 1024 * 1024);
	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
		    "User requested more memory then fits in the agp aperture\n"
		    "Truncating to %d bytes of memory\n", sysmem_size);
      }
   }
   if (pI810->numSurfaces && (pI810->numSurfaces == 7)) {
      if (sysmem_size > (pI810->FbMapSize - 8 * 1024 * 1024)) {
	 sysmem_size = (pI810->FbMapSize - 8 * 1024 * 1024);
	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
		    "User requested more memory then fits in the agp aperture\n"
		    "Truncating to %d bytes of memory\n", sysmem_size);
      }
   }

   if (sysmem_size > pI810->FbMapSize) {
      sysmem_size = pI810->FbMapSize;

      xf86DrvMsg(pScrn->scrnIndex, X_INFO,
		 "[dri] User requested more memory then fits in the agp"
		 " aperture\n\tTruncating to %d bytes of memory\n",
		 sysmem_size);
   }

   sysmem_size -= 4096;			/* remove 4k for the hw cursor */
   sysmem_size -= 16384;		/* remove 16k for the ARGB hw cursor */

   pI810->SysMem.Start = 0;
   pI810->SysMem.Size = sysmem_size;
   pI810->SysMem.End = sysmem_size;
   tom = sysmem_size;

   pI810->SavedSysMem = pI810->SysMem;

   if (dcacheHandle != DRM_AGP_NO_HANDLE) {
      if (drmAgpBind(pI810->drmSubFD, dcacheHandle, pI810->DepthOffset) == 0) {
	 memset(&pI810->DcacheMem, 0, sizeof(I810MemRange));
	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
		    "[agp] GART: Found 4096K Z buffer memory\n");
	 pI810->DcacheMem.Start = pI810->DepthOffset;
	 pI810->DcacheMem.Size = 1024 * 4096;
	 pI810->DcacheMem.End =
	       pI810->DcacheMem.Start + pI810->DcacheMem.Size;
	 if (!I810AllocLow
	     (&(pI810->DepthBuffer), &(pI810->DcacheMem), back_size)) {
	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
		       "[agp] Depth buffer allocation failed\n");
	    DRICloseScreen(pScreen);
	    return FALSE;
	 }
      } else {
	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
		    "[agp] GART: dcache bind failed\n");
	 drmAgpFree(pI810->drmSubFD, dcacheHandle);
	 pI810->dcacheHandle = dcacheHandle = DRM_AGP_NO_HANDLE;
      }
   } else {
      xf86DrvMsg(pScrn->scrnIndex, X_INFO,
		 "[agp] GART: no dcache memory found\n");
   }

   drmAgpAlloc(pI810->drmSubFD, back_size, 0, NULL,
	       (drmAddress) &agpHandle);
   pI810->backHandle = agpHandle;

   if (agpHandle != DRM_AGP_NO_HANDLE) {
      if (drmAgpBind(pI810->drmSubFD, agpHandle, pI810->BackOffset) == 0) {
	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
		    "[agp] Bound backbuffer memory\n");

	 pI810->BackBuffer.Start = pI810->BackOffset;
	 pI810->BackBuffer.Size = back_size;
	 pI810->BackBuffer.End = (pI810->BackBuffer.Start +
				  pI810->BackBuffer.Size);
      } else {
	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
		    "[agp] Unable to bind backbuffer.  Disabling DRI.\n");
	 DRICloseScreen(pScreen);
	 return FALSE;
      }
   } else {
      xf86DrvMsg(pScrn->scrnIndex, X_INFO,
		 "[dri] Unable to allocate backbuffer memory.  Disabling DRI.\n");
      DRICloseScreen(pScreen);
      return FALSE;
   }

   if (dcacheHandle == DRM_AGP_NO_HANDLE) {
     drmAgpAlloc(pI810->drmSubFD, back_size, 0, NULL,
		 (drmAddress) &agpHandle);

      pI810->zHandle = agpHandle;

      if (agpHandle != DRM_AGP_NO_HANDLE) {
	 if (drmAgpBind(pI810->drmSubFD, agpHandle, pI810->DepthOffset) == 0) {
	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
		       "[agp] Bound depthbuffer memory\n");
	    pI810->DepthBuffer.Start = pI810->DepthOffset;
	    pI810->DepthBuffer.Size = back_size;
	    pI810->DepthBuffer.End = (pI810->DepthBuffer.Start +
				      pI810->DepthBuffer.Size);
	 } else {
	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
		       "[agp] Unable to bind depthbuffer.  Disabling DRI.\n");
	    DRICloseScreen(pScreen);
	    return FALSE;
	 }
      } else {
	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
		    "[agp] Unable to allocate depthbuffer memory.  Disabling DRI.\n");
	 DRICloseScreen(pScreen);
	 return FALSE;
      }
   }

   /* Now allocate and bind the agp space.  This memory will include the
    * regular framebuffer as well as texture memory.
    */
   drmAgpAlloc(pI810->drmSubFD, sysmem_size, 0, NULL,
	       (drmAddress)&agpHandle);
   pI810->sysmemHandle = agpHandle;

   if (agpHandle != DRM_AGP_NO_HANDLE) {
      if (drmAgpBind(pI810->drmSubFD, agpHandle, 0) == 0) {
	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
		   "[agp] Bound System Texture Memory\n");
      } else {
          xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] Unable to bind system texture memory. Disabling DRI.\n");
	  DRICloseScreen(pScreen);
	  return FALSE;
      }
   } else {
      xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] Unable to allocate system texture memory. Disabling DRI.\n");
      DRICloseScreen(pScreen);
      return FALSE;
   }

/* Allocate 7 or 8MB for XvMC this is setup as follows to best use tiled
   regions and required surface pitches. (Numbers are adjusted if the
   AGP region is only 32MB
   For numSurfaces == 6
   44 - 48MB = 4MB Fence, 8 Tiles wide
   43 - 44MB = 1MB Fence, 8 Tiles wide
   42 - 43MB = 1MB Fence, 4 Tiles wide
   41 - 42MB = 1MB Fence, 4 Tiles wide
   For numSurfaces == 7
   44 - 48MB   = 4MB Fence, 8 Tiles wide
   43 - 44MB   = 1MB Fence, 8 Tiles wide
   42.5 - 43MB = 0.5MB Fence, 8 Tiles wide
   42 - 42.5MB = 0.5MB Fence, 4 Tiles wide
   40 - 42MB   = 2MB Fence, 4 Tiles wide
 */
   if (pI810->numSurfaces) {
      if (pI810->numSurfaces == 6) {
	 pI810->MC.Size = 7 * 1024 * 1024;
	 pI810->MC.Start = pI810->FbMapSize - 7 * 1024 * 1024;

      }
      if (pI810->numSurfaces == 7) {
	 pI810->MC.Size = 8 * 1024 * 1024;
	 pI810->MC.Start = pI810->FbMapSize - 8 * 1024 * 1024;
      }
      drmAgpAlloc(pI810->drmSubFD, pI810->MC.Size, 0, NULL,
		  (drmAddress) &agpHandle);

      pI810->xvmcHandle = agpHandle;

      if (agpHandle != DRM_AGP_NO_HANDLE) {
	 if (drmAgpBind(pI810->drmSubFD, agpHandle, pI810->MC.Start) == 0) {
	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
		       "GART: Allocated 7MB for HWMC\n");
	    pI810->MC.End = pI810->MC.Start + pI810->MC.Size;
	 } else {
	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "GART: HWMC bind failed\n");
	    pI810->MC.Start = 0;
	    pI810->MC.Size = 0;
	    pI810->MC.End = 0;
	 }
      } else {
	 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "GART: HWMC alloc failed\n");
	 pI810->MC.Start = 0;
	 pI810->MC.Size = 0;
	 pI810->MC.End = 0;
      }
      pI810->xvmcContext = 0;
   }

   drmAgpAlloc(pI810->drmSubFD, 4096, 2,
	       (unsigned long *)&pI810->CursorPhysical,
	       (drmAddress) &agpHandle);

   pI810->cursorHandle = agpHandle;

   if (agpHandle != DRM_AGP_NO_HANDLE) {
      tom = sysmem_size;

      if (drmAgpBind(pI810->drmSubFD, agpHandle, tom) == 0) {
	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
		    "[agp] GART: Allocated 4K for mouse cursor image\n");
	 pI810->CursorStart = tom;
	 tom += 4096;
      } else {
	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
		    "[agp] GART: cursor bind failed\n");
	 pI810->CursorPhysical = 0;
      }
   } else {
      xf86DrvMsg(pScrn->scrnIndex, X_INFO,
		 "[agp] GART: cursor alloc failed\n");
      pI810->CursorPhysical = 0;
   }

   drmAgpAlloc(pI810->drmSubFD, 16384, 2,
	       (unsigned long *)&pI810->CursorARGBPhysical,
	       (drmAddress) &agpHandle);

   pI810->cursorARGBHandle = agpHandle;

   if (agpHandle != DRM_AGP_NO_HANDLE) {
      if (drmAgpBind(pI810->drmSubFD, agpHandle, tom) == 0) {
	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
		    "[agp] GART: Allocated 16K for ARGB mouse cursor image\n");
	 pI810->CursorARGBStart = tom;
	 tom += 16384;
      } else {
	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
		    "[agp] GART: ARGB cursor bind failed\n");
	 pI810->CursorARGBPhysical = 0;
      }
   } else {
      xf86DrvMsg(pScrn->scrnIndex, X_INFO,
		 "[agp] GART: ARGB cursor alloc failed\n");
      pI810->CursorARGBPhysical = 0;
   }

   /* Steal some of the excess cursor space for the overlay regs.
    */
   pI810->OverlayPhysical = pI810->CursorPhysical + 1024;
   pI810->OverlayStart = pI810->CursorStart + 1024;

   I810SetTiledMemory(pScrn, 1,
		      pI810->DepthBuffer.Start,
		      i810_pitches[pitch_idx], 8 * 1024 * 1024);

   I810SetTiledMemory(pScrn, 2,
		      pI810->BackBuffer.Start,
		      i810_pitches[pitch_idx], 8 * 1024 * 1024);

   /* These are for HWMC surfaces */
   if (pI810->numSurfaces == 6) {
      I810SetTiledMemory(pScrn, 3, pI810->MC.Start, 512, 1024 * 1024);

      I810SetTiledMemory(pScrn, 4,
			 pI810->MC.Start + 1024 * 1024, 512, 1024 * 1024);

      I810SetTiledMemory(pScrn, 5,
			 pI810->MC.Start + 1024 * 1024 * 2,
			 1024, 1024 * 1024);

      I810SetTiledMemory(pScrn, 6,
			 pI810->MC.Start + 1024 * 1024 * 3,
			 1024, 4 * 1024 * 1024);
   }
   if (pI810->numSurfaces == 7) {
      I810SetTiledMemory(pScrn, 3, pI810->MC.Start, 512, 2 * 1024 * 1024);

      I810SetTiledMemory(pScrn, 4,
			 pI810->MC.Start + 2 * 1024 * 1024, 512, 512 * 1024);

      I810SetTiledMemory(pScrn, 5,
			 pI810->MC.Start + 2 * 1024 * 1024 + 512 * 1024,
			 1024, 512 * 1024);

      I810SetTiledMemory(pScrn, 6,
			 pI810->MC.Start + 3 * 1024 * 1024,
			 1024, 1 * 1024 * 1024);

      I810SetTiledMemory(pScrn, 7,
			 pI810->MC.Start + 4 * 1024 * 1024,
			 1024, 4 * 1024 * 1024);

   }

   pI810->auxPitch = i810_pitches[pitch_idx];
   pI810->auxPitchBits = i810_pitch_flags[pitch_idx];
   pI810->SavedDcacheMem = pI810->DcacheMem;
   pI810DRI->backbufferSize = pI810->BackBuffer.Size;

   if (drmAddMap(pI810->drmSubFD, (drm_handle_t) pI810->BackBuffer.Start,
		 pI810->BackBuffer.Size, DRM_AGP, 0,
		 (drmAddress) &pI810DRI->backbuffer) < 0) {
      xf86DrvMsg(pScreen->myNum, X_ERROR,
		 "[drm] drmAddMap(backbuffer) failed.  Disabling DRI\n");
      DRICloseScreen(pScreen);
      return FALSE;
   }

   pI810DRI->depthbufferSize = pI810->DepthBuffer.Size;
   if (drmAddMap(pI810->drmSubFD, (drm_handle_t) pI810->DepthBuffer.Start,
		 pI810->DepthBuffer.Size, DRM_AGP, 0,
		 (drmAddress) &pI810DRI->depthbuffer) < 0) {
      xf86DrvMsg(pScreen->myNum, X_ERROR,
		 "[drm] drmAddMap(depthbuffer) failed.  Disabling DRI.\n");
      DRICloseScreen(pScreen);
      return FALSE;
   }

   /* Allocate FrontBuffer etc. */
   if (!I810AllocateFront(pScrn)) {
      DRICloseScreen(pScreen);
      return FALSE;
   }

   /* Allocate buffer memory */
   I810AllocHigh(&(pI810->BufferMem), &(pI810->SysMem),
		 I810_DMA_BUF_NR * I810_DMA_BUF_SZ);

   xf86DrvMsg(pScreen->myNum, X_INFO, "[dri] Buffer map : %lx\n",
	      pI810->BufferMem.Start);

   if (pI810->BufferMem.Start == 0 ||
       pI810->BufferMem.End - pI810->BufferMem.Start >
       I810_DMA_BUF_NR * I810_DMA_BUF_SZ) {
      xf86DrvMsg(pScreen->myNum, X_ERROR,
		 "[dri] Not enough memory for dma buffers.  Disabling DRI.\n");
      DRICloseScreen(pScreen);
      return FALSE;
   }
   if (drmAddMap(pI810->drmSubFD, (drm_handle_t) pI810->BufferMem.Start,
		 pI810->BufferMem.Size, DRM_AGP, 0,
		 (drmAddress) &pI810->buffer_map) < 0) {
      xf86DrvMsg(pScreen->myNum, X_ERROR,
		 "[drm] drmAddMap(buffer_map) failed.  Disabling DRI.\n");
      DRICloseScreen(pScreen);
      return FALSE;
   }

   pI810DRI->agp_buffers = pI810->buffer_map;
   pI810DRI->agp_buf_size = pI810->BufferMem.Size;

   if (drmAddMap(pI810->drmSubFD, (drm_handle_t) pI810->LpRing->mem.Start,
		 pI810->LpRing->mem.Size, DRM_AGP, 0,
		 (drmAddress) &pI810->ring_map) < 0) {
      xf86DrvMsg(pScreen->myNum, X_ERROR,
		 "[drm] drmAddMap(ring_map) failed.  Disabling DRI.\n");
      DRICloseScreen(pScreen);
      return FALSE;
   }

   /* Use the rest of memory for textures. */
   pI810DRI->textureSize = pI810->SysMem.Size;

   i = mylog2(pI810DRI->textureSize / I810_NR_TEX_REGIONS);

   if (i < I810_LOG_MIN_TEX_REGION_SIZE)
      i = I810_LOG_MIN_TEX_REGION_SIZE;

   pI810DRI->logTextureGranularity = i;
   pI810DRI->textureSize = (pI810DRI->textureSize >> i) << i;	/* truncate */

   if (pI810DRI->textureSize < 512 * 1024) {
      xf86DrvMsg(pScreen->myNum, X_ERROR,
		 "[drm] Less then 512k memory left for textures.  Disabling DRI.\n");
      DRICloseScreen(pScreen);
      return FALSE;
   }

   if (!I810AllocLow(&(pI810->TexMem), &(pI810->SysMem), pI810DRI->textureSize)) {
      xf86DrvMsg(pScrn->scrnIndex, X_INFO,
		 "[agp] Texure memory allocation failed\n");
      DRICloseScreen(pScreen);
      return FALSE;
   }

   if (drmAddMap(pI810->drmSubFD, (drm_handle_t) pI810->TexMem.Start,
		 pI810->TexMem.Size, DRM_AGP, 0,
		 (drmAddress) &pI810DRI->textures) < 0) {
      xf86DrvMsg(pScreen->myNum, X_ERROR,
		 "[drm] drmAddMap(textures) failed.  Disabling DRI.\n");
      DRICloseScreen(pScreen);
      return FALSE;
   }

   if ((bufs = drmAddBufs(pI810->drmSubFD,
			  I810_DMA_BUF_NR,
			  I810_DMA_BUF_SZ,
			  DRM_AGP_BUFFER, pI810->BufferMem.Start)) <= 0) {
      xf86DrvMsg(pScrn->scrnIndex, X_INFO,
		 "[drm] failure adding %d %d byte DMA buffers.  Disabling DRI.\n",
		 I810_DMA_BUF_NR, I810_DMA_BUF_SZ);
      DRICloseScreen(pScreen);
      return FALSE;
   }

   xf86DrvMsg(pScrn->scrnIndex, X_INFO,
	      "[drm] added %d %d byte DMA buffers\n", bufs, I810_DMA_BUF_SZ);

   I810InitDma(pScrn);

   /* Okay now initialize the dma engine */

   if (!pI810DRI->irq) {
      pI810DRI->irq = drmGetInterruptFromBusID(pI810->drmSubFD,
					       ((pI810->PciInfo->domain << 8) |
						pI810->PciInfo->bus),
					       pI810->PciInfo->dev,
					       pI810->PciInfo->func
					       );
      if ((drmCtlInstHandler(pI810->drmSubFD, pI810DRI->irq)) != 0) {
	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
		    "[drm] failure adding irq handler, there is a device "
		    "already using that irq\n Consider rearranging your "
		    "PCI cards.  Disabling DRI.\n");
	 DRICloseScreen(pScreen);
	 return FALSE;
      }
   }

   xf86DrvMsg(pScrn->scrnIndex, X_INFO,
	      "[drm] dma control initialized, using IRQ %d\n", pI810DRI->irq);

   pI810DRI->deviceID = pI810->PciInfo->device_id;
   pI810DRI->width = pScrn->virtualX;
   pI810DRI->height = pScrn->virtualY;
   pI810DRI->mem = pScrn->videoRam * 1024;
   pI810DRI->cpp = pI810->cpp;

   pI810DRI->fbOffset = pI810->FrontBuffer.Start;
   pI810DRI->fbStride = pI810->auxPitch;

   pI810DRI->bitsPerPixel = pScrn->bitsPerPixel;

   pI810DRI->textureOffset = pI810->TexMem.Start;

   pI810DRI->backOffset = pI810->BackBuffer.Start;
   pI810DRI->depthOffset = pI810->DepthBuffer.Start;

   pI810DRI->ringOffset = pI810->LpRing->mem.Start;
   pI810DRI->ringSize = pI810->LpRing->mem.Size;

   pI810DRI->auxPitch = pI810->auxPitch;
   pI810DRI->auxPitchBits = pI810->auxPitchBits;
   pI810DRI->sarea_priv_offset = sizeof(XF86DRISAREARec);

   xf86DrvMsg(pScrn->scrnIndex, X_INFO,
	      "[dri] visual configs initialized.\n");
   pI810->pDRIInfo->driverSwapMethod = DRI_HIDE_X_CONTEXT;

   return TRUE;
}
Пример #23
0
unsigned int init_pci(unsigned char bus, const unsigned char forcemem) {

	int ret = pci_system_init();
	if (ret)
		die(_("Failed to init pciaccess"));

	struct pci_id_match match;

	match.vendor_id = 0x1002;
	match.device_id = PCI_MATCH_ANY;
	match.subvendor_id = PCI_MATCH_ANY;
	match.subdevice_id = PCI_MATCH_ANY;
	match.device_class = 0;
	match.device_class_mask = 0;
	match.match_data = 0;

	struct pci_device_iterator *iter = pci_id_match_iterator_create(&match);
	struct pci_device *dev = NULL;
	char busid[32];

	while ((dev = pci_device_next(iter))) {
		pci_device_probe(dev);
		if ((dev->device_class & 0x00ffff00) != 0x00030000 &&
			(dev->device_class & 0x00ffff00) != 0x00038000)
			continue;
		snprintf(busid, sizeof(busid), "pci:%04x:%02x:%02x.%u",
				dev->domain, dev->bus, dev->dev, dev->func);
		if (!bus || bus == dev->bus)
			break;
	}

	pci_iterator_destroy(iter);

	if (!dev)
		die(_("Can't find Radeon cards"));

	const unsigned int device_id = dev->device_id;
	int reg = 2;
	if (getfamily(device_id) >= BONAIRE)
		reg = 5;

	if (!dev->regions[reg].size) die(_("Can't get the register area size"));

//	printf("Found area %p, size %lu\n", area, dev->regions[reg].size);

	// DRM support for VRAM
	drm_fd = drmOpen(NULL, busid);
	if (drm_fd >= 0) {
		drmVersionPtr ver = drmGetVersion(drm_fd);
		if (strcmp(ver->name, "radeon") != 0 && strcmp(ver->name, "amdgpu") != 0) {
			close(drm_fd);
			drm_fd = -1;
		}
		strcpy(drm_name, ver->name);
		drmFreeVersion(ver);
	}
	if (drm_fd < 0 && access("/dev/ati/card0", F_OK) == 0) // fglrx path
		drm_fd = open("/dev/ati/card0", O_RDWR);

	use_ioctl = 0;
	if (drm_fd >= 0) {
		authenticate_drm(drm_fd);
		uint32_t rreg = 0x8010;
		use_ioctl = get_drm_value(drm_fd, RADEON_INFO_READ_REG, &rreg);
	}

	if (forcemem) {
		printf(_("Forcing the /dev/mem path.\n"));
		use_ioctl = 0;
	}

	if (!use_ioctl) {
		int mem = open("/dev/mem", O_RDONLY);
		if (mem < 0) die(_("Cannot access GPU registers, are you root?"));

		area = mmap(NULL, MMAP_SIZE, PROT_READ, MAP_PRIVATE, mem,
				dev->regions[reg].base_addr + 0x8000);
		if (area == MAP_FAILED) die(_("mmap failed"));
	}

	bits.vram = 0;
	if (drm_fd < 0) {
		printf(_("Failed to open DRM node, no VRAM support.\n"));
	} else {
		drmDropMaster(drm_fd);
		drmVersionPtr ver = drmGetVersion(drm_fd);

/*		printf("Version %u.%u.%u, name %s\n",
			ver->version_major,
			ver->version_minor,
			ver->version_patchlevel,
			ver->name);*/

		if (ver->version_major < 2 ||
			(ver->version_major == 2 && ver->version_minor < 36)) {
			printf(_("Kernel too old for VRAM reporting.\n"));
			drmFreeVersion(ver);
			goto out;
		}
		drmFreeVersion(ver);

		// No version indicator, so we need to test once
		// We use different codepaths for radeon and amdgpu
		// We store vram_size and check below if the ret value is sane
		if (strcmp(drm_name, "radeon") == 0) {
			struct drm_radeon_gem_info gem;

			ret = drmCommandWriteRead(drm_fd, DRM_RADEON_GEM_INFO,
							&gem, sizeof(gem));
			vramsize = gem.vram_size;
		} else if (strcmp(drm_name, "amdgpu") == 0) {
#ifdef ENABLE_AMDGPU
			struct drm_amdgpu_info_vram_gtt vram_gtt = {};

			struct drm_amdgpu_info request;
			memset(&request, 0, sizeof(request));
			request.return_pointer = (unsigned long) &vram_gtt;
			request.return_size = sizeof(vram_gtt);
			request.query = AMDGPU_INFO_VRAM_GTT;

			ret = drmCommandWrite(drm_fd, DRM_AMDGPU_INFO,
						&request, sizeof(request));
			vramsize = vram_gtt.vram_size;
#else
			printf(_("amdgpu DRM driver is used, but amdgpu VRAM size reporting is not enabled\n"));
#endif
		}
		if (ret) {
			printf(_("Failed to get VRAM size, error %d\n"),
				ret);
			goto out;
		}

		ret = getvram();
		if (ret == 0) {
			if (strcmp(drm_name, "amdgpu") == 0) {
#ifndef ENABLE_AMDGPU
				printf(_("amdgpu DRM driver is used, but amdgpu VRAM usage reporting is not enabled\n"));
#endif
			}
			printf(_("Failed to get VRAM usage, kernel likely too old\n"));
			goto out;
		}

		bits.vram = 1;
	}

	out:

	pci_system_cleanup();

	return device_id;
}
/* Helper function to do the ioctls needed for setup and init. */
static boolean do_winsys_init(struct radeon_drm_winsys *ws)
{
    struct drm_radeon_gem_info gem_info;
    int retval;
    drmVersionPtr version;

    memset(&gem_info, 0, sizeof(gem_info));

    /* We do things in a specific order here.
     *
     * DRM version first. We need to be sure we're running on a KMS chipset.
     * This is also for some features.
     *
     * Then, the PCI ID. This is essential and should return usable numbers
     * for all Radeons. If this fails, we probably got handed an FD for some
     * non-Radeon card.
     *
     * The GEM info is actually bogus on the kernel side, as well as our side
     * (see radeon_gem_info_ioctl in radeon_gem.c) but that's alright because
     * we don't actually use the info for anything yet.
     *
     * The GB and Z pipe requests should always succeed, but they might not
     * return sensical values for all chipsets, but that's alright because
     * the pipe drivers already know that.
     */

    /* Get DRM version. */
    version = drmGetVersion(ws->fd);
    if (version->version_major != 2 ||
        version->version_minor < 3) {
        fprintf(stderr, "%s: DRM version is %d.%d.%d but this driver is "
                "only compatible with 2.3.x (kernel 2.6.34) or later.\n",
                __FUNCTION__,
                version->version_major,
                version->version_minor,
                version->version_patchlevel);
        drmFreeVersion(version);
        return FALSE;
    }

    ws->info.drm_major = version->version_major;
    ws->info.drm_minor = version->version_minor;
    ws->info.drm_patchlevel = version->version_patchlevel;
    drmFreeVersion(version);

    /* Get PCI ID. */
    if (!radeon_get_drm_value(ws->fd, RADEON_INFO_DEVICE_ID, "PCI ID",
                              &ws->info.pci_id))
        return FALSE;

    /* Check PCI ID. */
    switch (ws->info.pci_id) {
#define CHIPSET(pci_id, name, family) case pci_id:
#include "pci_ids/r300_pci_ids.h"
#undef CHIPSET
        ws->gen = R300;
        break;

#define CHIPSET(pci_id, name, family) case pci_id:
#include "pci_ids/r600_pci_ids.h"
#undef CHIPSET
        ws->gen = R600;
        break;

#define CHIPSET(pci_id, name, family) case pci_id:
#include "pci_ids/radeonsi_pci_ids.h"
#undef CHIPSET
        ws->gen = SI;
        break;

    default:
        fprintf(stderr, "radeon: Invalid PCI ID.\n");
        return FALSE;
    }

    /* Get GEM info. */
    retval = drmCommandWriteRead(ws->fd, DRM_RADEON_GEM_INFO,
            &gem_info, sizeof(gem_info));
    if (retval) {
        fprintf(stderr, "radeon: Failed to get MM info, error number %d\n",
                retval);
        return FALSE;
    }
    ws->info.gart_size = gem_info.gart_size;
    ws->info.vram_size = gem_info.vram_size;

    ws->num_cpus = sysconf(_SC_NPROCESSORS_ONLN);

    /* Generation-specific queries. */
    if (ws->gen == R300) {
        if (!radeon_get_drm_value(ws->fd, RADEON_INFO_NUM_GB_PIPES,
                                  "GB pipe count",
                                  &ws->info.r300_num_gb_pipes))
            return FALSE;

        if (!radeon_get_drm_value(ws->fd, RADEON_INFO_NUM_Z_PIPES,
                                  "Z pipe count",
                                  &ws->info.r300_num_z_pipes))
            return FALSE;
    }
    else if (ws->gen >= R600) {
        if (ws->info.drm_minor >= 9 &&
            !radeon_get_drm_value(ws->fd, RADEON_INFO_NUM_BACKENDS,
                                  "num backends",
                                  &ws->info.r600_num_backends))
            return FALSE;

        /* get the GPU counter frequency, failure is not fatal */
        radeon_get_drm_value(ws->fd, RADEON_INFO_CLOCK_CRYSTAL_FREQ, NULL,
                             &ws->info.r600_clock_crystal_freq);

        radeon_get_drm_value(ws->fd, RADEON_INFO_TILING_CONFIG, NULL,
                             &ws->info.r600_tiling_config);

        if (ws->info.drm_minor >= 11) {
            radeon_get_drm_value(ws->fd, RADEON_INFO_NUM_TILE_PIPES, NULL,
                                 &ws->info.r600_num_tile_pipes);

            if (radeon_get_drm_value(ws->fd, RADEON_INFO_BACKEND_MAP, NULL,
                                      &ws->info.r600_backend_map))
                ws->info.r600_backend_map_valid = TRUE;
        }

        ws->info.r600_virtual_address = FALSE;
        if (ws->info.drm_minor >= 13) {
            ws->info.r600_virtual_address = TRUE;
            if (!radeon_get_drm_value(ws->fd, RADEON_INFO_VA_START, NULL,
                                      &ws->info.r600_va_start))
                ws->info.r600_virtual_address = FALSE;
            if (!radeon_get_drm_value(ws->fd, RADEON_INFO_IB_VM_MAX_SIZE, NULL,
                                      &ws->info.r600_ib_vm_max_size))
                ws->info.r600_virtual_address = FALSE;
        }
        /* Remove this line once the virtual address space feature is fixed. */
        if (ws->gen == R600 && !debug_get_bool_option("RADEON_VA", FALSE))
            ws->info.r600_virtual_address = FALSE;
    }

    /* Get max pipes, this is only needed for compute shaders.  All evergreen+
     * chips have at least 2 pipes, so we use 2 as a default. */
    ws->info.r600_max_pipes = 2;
    radeon_get_drm_value(ws->fd, RADEON_INFO_MAX_PIPES, NULL,
                         &ws->info.r600_max_pipes);

    return TRUE;
}
Пример #25
0
/**
 * DRI2
 */
static __DRIscreen *
dri2CreateNewScreen(int scrn, int fd, unsigned int sarea_handle,
		    const __DRIextension **extensions,
		    const __DRIconfig ***driver_configs, void *data)
{
#ifdef TTM_API
    static const __DRIextension *emptyExtensionList[] = { NULL };
    __DRIscreen *psp;
    unsigned int *p;
    drmVersionPtr version;

    if (driDriverAPI.InitScreen2 == NULL)
        return NULL;

    psp = _mesa_malloc(sizeof(*psp));
    if (!psp)
	return NULL;

    setupLoaderExtensions(psp, extensions);

    version = drmGetVersion(fd);
    if (version) {
	psp->drm_version.major = version->version_major;
	psp->drm_version.minor = version->version_minor;
	psp->drm_version.patch = version->version_patchlevel;
	drmFreeVersion(version);
    }

    psp->extensions = emptyExtensionList;
    psp->fd = fd;
    psp->myNum = scrn;
    psp->dri2.enabled = GL_TRUE;

    if (drmBOReference(psp->fd, sarea_handle, &psp->dri2.sareaBO)) {
	fprintf(stderr, "Failed to reference DRI2 sarea BO\n");
	_mesa_free(psp);
	return NULL;
    }

    if (drmBOMap(psp->fd, &psp->dri2.sareaBO,
		 DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0, &psp->dri2.sarea)) {
	drmBOUnreference(psp->fd, &psp->dri2.sareaBO);
	_mesa_free(psp);
	return NULL;
    }

    p = psp->dri2.sarea;
    while (DRI2_SAREA_BLOCK_TYPE(*p)) {
	switch (DRI2_SAREA_BLOCK_TYPE(*p)) {
	case DRI2_SAREA_BLOCK_LOCK:
	    psp->dri2.lock = (__DRILock *) p;
	    break;
	case DRI2_SAREA_BLOCK_EVENT_BUFFER:
	    psp->dri2.buffer = (__DRIEventBuffer *) p;
	    break;
	}
	p = DRI2_SAREA_BLOCK_NEXT(p);
    }

    psp->lock = (drmLock *) &psp->dri2.lock->lock;

    psp->DriverAPI = driDriverAPI;
    *driver_configs = driDriverAPI.InitScreen2(psp);
    if (*driver_configs == NULL) {
	drmBOUnmap(psp->fd, &psp->dri2.sareaBO);
	drmBOUnreference(psp->fd, &psp->dri2.sareaBO);
	_mesa_free(psp);
	return NULL;
    }

    psp->DriverAPI = driDriverAPI;

    return psp;
#else
    return NULL;
#endif
}
Пример #26
0
boolean
vmw_ioctl_init(struct vmw_winsys_screen *vws)
{
   struct drm_vmw_getparam_arg gp_arg;
   struct drm_vmw_get_3d_cap_arg cap_arg;
   unsigned int size;
   int ret;
   uint32_t *cap_buffer;
   drmVersionPtr version;
   boolean have_drm_2_5;

   VMW_FUNC;

   version = drmGetVersion(vws->ioctl.drm_fd);
   if (!version)
      goto out_no_version;

   have_drm_2_5 = version->version_major > 2 ||
      (version->version_major == 2 && version->version_minor > 4);
   vws->ioctl.have_drm_2_6 = version->version_major > 2 ||
      (version->version_major == 2 && version->version_minor > 5);

   memset(&gp_arg, 0, sizeof(gp_arg));
   gp_arg.param = DRM_VMW_PARAM_3D;
   ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_GET_PARAM,
			     &gp_arg, sizeof(gp_arg));
   if (ret || gp_arg.value == 0) {
      vmw_error("No 3D enabled (%i, %s).\n", ret, strerror(-ret));
      goto out_no_3d;
   }

   memset(&gp_arg, 0, sizeof(gp_arg));
   gp_arg.param = DRM_VMW_PARAM_FIFO_HW_VERSION;
   ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_GET_PARAM,
			     &gp_arg, sizeof(gp_arg));
   if (ret) {
      vmw_error("Failed to get fifo hw version (%i, %s).\n",
                ret, strerror(-ret));
      goto out_no_3d;
   }
   vws->ioctl.hwversion = gp_arg.value;

   memset(&gp_arg, 0, sizeof(gp_arg));
   gp_arg.param = DRM_VMW_PARAM_HW_CAPS;
   ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_GET_PARAM,
                             &gp_arg, sizeof(gp_arg));
   if (ret)
      vws->base.have_gb_objects = FALSE;
   else
      vws->base.have_gb_objects =
         !!(gp_arg.value & (uint64_t) SVGA_CAP_GBOBJECTS);
   
   if (vws->base.have_gb_objects && !have_drm_2_5)
      goto out_no_3d;

   if (vws->base.have_gb_objects) {
      memset(&gp_arg, 0, sizeof(gp_arg));
      gp_arg.param = DRM_VMW_PARAM_3D_CAPS_SIZE;
      ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_GET_PARAM,
                                &gp_arg, sizeof(gp_arg));
      if (ret)
         size = SVGA_FIFO_3D_CAPS_SIZE * sizeof(uint32_t);
      else
         size = gp_arg.value;
   
      if (vws->base.have_gb_objects)
         vws->ioctl.num_cap_3d = size / sizeof(uint32_t);
      else
         vws->ioctl.num_cap_3d = SVGA3D_DEVCAP_MAX;


      memset(&gp_arg, 0, sizeof(gp_arg));
      gp_arg.param = DRM_VMW_PARAM_MAX_MOB_MEMORY;
      ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_GET_PARAM,
                                &gp_arg, sizeof(gp_arg));
      if (ret) {
         /* Just guess a large enough value. */
         vws->ioctl.max_mob_memory = 256*1024*1024;
      } else {
         vws->ioctl.max_mob_memory = gp_arg.value;
      }

      memset(&gp_arg, 0, sizeof(gp_arg));
      gp_arg.param = DRM_VMW_PARAM_MAX_MOB_SIZE;
      ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_GET_PARAM,
                                &gp_arg, sizeof(gp_arg));

      if (ret || gp_arg.value == 0) {
           vws->ioctl.max_texture_size = VMW_MAX_DEFAULT_TEXTURE_SIZE;
      } else {
           vws->ioctl.max_texture_size = gp_arg.value;
      }

      /* Never early flush surfaces, mobs do accounting. */
      vws->ioctl.max_surface_memory = -1;
   } else {
      vws->ioctl.num_cap_3d = SVGA3D_DEVCAP_MAX;

      memset(&gp_arg, 0, sizeof(gp_arg));
      gp_arg.param = DRM_VMW_PARAM_MAX_SURF_MEMORY;
      if (have_drm_2_5)
         ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_GET_PARAM,
                                   &gp_arg, sizeof(gp_arg));
      if (!have_drm_2_5 || ret) {
         /* Just guess a large enough value, around 800mb. */
         vws->ioctl.max_surface_memory = 0x30000000;
      } else {
         vws->ioctl.max_surface_memory = gp_arg.value;
      }

      vws->ioctl.max_texture_size = VMW_MAX_DEFAULT_TEXTURE_SIZE;

      size = SVGA_FIFO_3D_CAPS_SIZE * sizeof(uint32_t);
   }

   cap_buffer = calloc(1, size);
   if (!cap_buffer) {
      debug_printf("Failed alloc fifo 3D caps buffer.\n");
      goto out_no_3d;
   }

   vws->ioctl.cap_3d = calloc(vws->ioctl.num_cap_3d, 
			      sizeof(*vws->ioctl.cap_3d));
   if (!vws->ioctl.cap_3d) {
      debug_printf("Failed alloc fifo 3D caps buffer.\n");
      goto out_no_caparray;
   }
      
   memset(&cap_arg, 0, sizeof(cap_arg));
   cap_arg.buffer = (uint64_t) (unsigned long) (cap_buffer);
   cap_arg.max_size = size;

   ret = drmCommandWrite(vws->ioctl.drm_fd, DRM_VMW_GET_3D_CAP,
			 &cap_arg, sizeof(cap_arg));

   if (ret) {
      debug_printf("Failed to get 3D capabilities"
		   " (%i, %s).\n", ret, strerror(-ret));
      goto out_no_caps;
   }

   ret = vmw_ioctl_parse_caps(vws, cap_buffer);
   if (ret) {
      debug_printf("Failed to parse 3D capabilities"
		   " (%i, %s).\n", ret, strerror(-ret));
      goto out_no_caps;
   }
   free(cap_buffer);
   drmFreeVersion(version);
   vmw_printf("%s OK\n", __FUNCTION__);
   return TRUE;
  out_no_caps:
   free(vws->ioctl.cap_3d);
  out_no_caparray:
   free(cap_buffer);
  out_no_3d:
   drmFreeVersion(version);
  out_no_version:
   vws->ioctl.num_cap_3d = 0;
   debug_printf("%s Failed\n", __FUNCTION__);
   return FALSE;
}
Пример #27
0
/* Initialize the screen-specific data structures for the DRI and the
   Rage 128.  This is the main entry point to the device-specific
   initialization code.  It calls device-independent DRI functions to
   create the DRI data structures and initialize the DRI state. */
static GLboolean R128DRIScreenInit(DRIDriverContext *ctx)
{
    R128InfoPtr info = ctx->driverPrivate;
    R128DRIPtr    pR128DRI;
    int           err, major, minor, patch;
    drmVersionPtr version;
    drm_r128_sarea_t *pSAREAPriv;

    switch (ctx->bpp) {
    case 8:
	/* These modes are not supported (yet). */
    case 15:
    case 24:
	fprintf(stderr,
		   "[dri] R128DRIScreenInit failed (depth %d not supported).  "
		   "[dri] Disabling DRI.\n", ctx->bpp);
	return GL_FALSE;

	/* Only 16 and 32 color depths are supports currently. */
    case 16:
    case 32:
	break;
    }
    r128_drm_page_size = getpagesize();
    
    info->registerSize = ctx->MMIOSize;
    ctx->shared.SAREASize = SAREA_MAX;

    /* Note that drmOpen will try to load the kernel module, if needed. */
    ctx->drmFD = drmOpen("r128", NULL );
    if (ctx->drmFD < 0) {
	fprintf(stderr, "[drm] drmOpen failed\n");
	return 0;
    }
    
    /* Check the r128 DRM version */
    version = drmGetVersion(ctx->drmFD);
    if (version) {
	if (version->version_major != 2 ||
	    version->version_minor < 2) {
	    /* incompatible drm version */
	    fprintf(stderr,
		"[dri] R128DRIScreenInit failed because of a version mismatch.\n"
		"[dri] r128.o kernel module version is %d.%d.%d but version 2.2 or greater is needed.\n"
		"[dri] Disabling the DRI.\n",
		version->version_major,
		version->version_minor,
		version->version_patchlevel);
	    drmFreeVersion(version);
	    return GL_FALSE;
	}
	info->drmMinor = version->version_minor;
	drmFreeVersion(version);
    }
    
    if ((err = drmSetBusid(ctx->drmFD, ctx->pciBusID)) < 0) {
	fprintf(stderr, "[drm] drmSetBusid failed (%d, %s), %s\n",
		ctx->drmFD, ctx->pciBusID, strerror(-err));
	return 0;
    }
    
   if (drmAddMap( ctx->drmFD,
		  0,
		  ctx->shared.SAREASize,
		  DRM_SHM,
		  DRM_CONTAINS_LOCK,
		  &ctx->shared.hSAREA) < 0)
   {
      fprintf(stderr, "[drm] drmAddMap failed\n");
      return 0;
   }
   fprintf(stderr, "[drm] added %d byte SAREA at 0x%08lx\n",
	   ctx->shared.SAREASize, ctx->shared.hSAREA);

   if (drmMap( ctx->drmFD,
	       ctx->shared.hSAREA,
	       ctx->shared.SAREASize,
	       (drmAddressPtr)(&ctx->pSAREA)) < 0)
   {
      fprintf(stderr, "[drm] drmMap failed\n");
      return 0;
   }
   memset(ctx->pSAREA, 0, ctx->shared.SAREASize);
   fprintf(stderr, "[drm] mapped SAREA 0x%08lx to %p, size %d\n",
	   ctx->shared.hSAREA, ctx->pSAREA, ctx->shared.SAREASize);
   
   /* Need to AddMap the framebuffer and mmio regions here:
    */
   if (drmAddMap( ctx->drmFD,
		  (drm_handle_t)ctx->FBStart,
		  ctx->FBSize,
		  DRM_FRAME_BUFFER,
		  0,
		  &ctx->shared.hFrameBuffer) < 0)
   {
      fprintf(stderr, "[drm] drmAddMap framebuffer failed\n");
      return 0;
   }

   fprintf(stderr, "[drm] framebuffer handle = 0x%08lx\n",
	   ctx->shared.hFrameBuffer);

   if (!R128MemoryInit(ctx))
	return GL_FALSE;
   
				/* Initialize AGP */
    if (!info->IsPCI && !R128DRIAgpInit(ctx)) {
	info->IsPCI = GL_TRUE;
	fprintf(stderr,
		   "[agp] AGP failed to initialize -- falling back to PCI mode.\n");
	fprintf(stderr,
		   "[agp] Make sure you have the agpgart kernel module loaded.\n");
    }

				/* Initialize PCIGART */
    if (info->IsPCI && !R128DRIPciInit(ctx)) {
	return GL_FALSE;
    }

				/* DRIScreenInit doesn't add all the
				   common mappings.  Add additional
				   mappings here. */
    if (!R128DRIMapInit(ctx)) {
	return GL_FALSE;
    }

   /* Create a 'server' context so we can grab the lock for
    * initialization ioctls.
    */
   if ((err = drmCreateContext(ctx->drmFD, &ctx->serverContext)) != 0) {
      fprintf(stderr, "%s: drmCreateContext failed %d\n", __FUNCTION__, err);
      return 0;
   }

   DRM_LOCK(ctx->drmFD, ctx->pSAREA, ctx->serverContext, 0); 

    /* Initialize the kernel data structures */
    if (!R128DRIKernelInit(ctx)) {
	return GL_FALSE;
    }

    /* Initialize the vertex buffers list */
    if (!R128DRIBufInit(ctx)) {
	return GL_FALSE;
    }

    /* Initialize IRQ */
    R128DRIIrqInit(ctx);

    /* Initialize and start the CCE if required */
    R128DRICCEInit(ctx);

   /* Quick hack to clear the front & back buffers.  Could also use
    * the clear ioctl to do this, but would need to setup hw state
    * first.
    */
   drimemsetio((char *)ctx->FBAddress + info->frontOffset,
	  0,
	  info->frontPitch * ctx->cpp * ctx->shared.virtualHeight );

   drimemsetio((char *)ctx->FBAddress + info->backOffset,
	  0,
	  info->backPitch * ctx->cpp * ctx->shared.virtualHeight );
    
    pSAREAPriv = (drm_r128_sarea_t *)(((char*)ctx->pSAREA) + 
					sizeof(drm_sarea_t));
    memset(pSAREAPriv, 0, sizeof(*pSAREAPriv));

   /* This is the struct passed to radeon_dri.so for its initialization */
   ctx->driverClientMsg = malloc(sizeof(R128DRIRec));
   ctx->driverClientMsgSize = sizeof(R128DRIRec);
   
    pR128DRI                    = (R128DRIPtr)ctx->driverClientMsg;
    pR128DRI->deviceID          = info->Chipset;
    pR128DRI->width             = ctx->shared.virtualWidth;
    pR128DRI->height            = ctx->shared.virtualHeight;
    pR128DRI->depth             = ctx->bpp;
    pR128DRI->bpp               = ctx->bpp;

    pR128DRI->IsPCI             = info->IsPCI;
    pR128DRI->AGPMode           = info->agpMode;

    pR128DRI->frontOffset       = info->frontOffset;
    pR128DRI->frontPitch        = info->frontPitch;
    pR128DRI->backOffset        = info->backOffset;
    pR128DRI->backPitch         = info->backPitch;
    pR128DRI->depthOffset       = info->depthOffset;
    pR128DRI->depthPitch        = info->depthPitch;
    pR128DRI->spanOffset        = info->spanOffset;
    pR128DRI->textureOffset     = info->textureOffset;
    pR128DRI->textureSize       = info->textureSize;
    pR128DRI->log2TexGran       = info->log2TexGran;

    pR128DRI->registerHandle    = info->registerHandle;
    pR128DRI->registerSize      = info->registerSize;

    pR128DRI->agpTexHandle      = info->agpTexHandle;
    pR128DRI->agpTexMapSize     = info->agpTexMapSize;
    pR128DRI->log2AGPTexGran    = info->log2AGPTexGran;
    pR128DRI->agpTexOffset      = info->agpTexStart;
    pR128DRI->sarea_priv_offset = sizeof(drm_sarea_t);

    return GL_TRUE;
}
static EGLBoolean
droid_get_pci_id(int fd, int *vendor_id, int *chip_id)
{
   drmVersionPtr version;

   *chip_id = -1;

   version = drmGetVersion(fd);
   if (!version) {
      _eglLog(_EGL_WARNING, "invalid drm fd");
      return EGL_FALSE;
   }
   if (!version->name) {
      _eglLog(_EGL_WARNING, "unable to determine the driver name");
      drmFreeVersion(version);
      return EGL_FALSE;
   }

   if (strcmp(version->name, "i915") == 0) {
      struct drm_i915_getparam gp;
      int ret;

      *vendor_id = 0x8086;

      memset(&gp, 0, sizeof(gp));
      gp.param = I915_PARAM_CHIPSET_ID;
      gp.value = chip_id;
      ret = drmCommandWriteRead(fd, DRM_I915_GETPARAM, &gp, sizeof(gp));
      if (ret) {
         _eglLog(_EGL_WARNING, "failed to get param for i915");
	 *chip_id = -1;
      }
   }
   else if (strcmp(version->name, "radeon") == 0) {
      struct drm_radeon_info info;
      int ret;

      *vendor_id = 0x1002;

      memset(&info, 0, sizeof(info));
      info.request = RADEON_INFO_DEVICE_ID;
      info.value = (unsigned long) chip_id;
      ret = drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info));
      if (ret) {
         _eglLog(_EGL_WARNING, "failed to get info for radeon");
	 *chip_id = -1;
      }
   }
   else if (strcmp(version->name, "nouveau") == 0) {
      *vendor_id = 0x10de;
      /* not used */
      *chip_id = 0;
   }
   else if (strcmp(version->name, "vmwgfx") == 0) {
      *vendor_id = 0x15ad;
      /* assume SVGA II */
      *chip_id = 0x0405;
   }

   drmFreeVersion(version);

   return (*chip_id >= 0);
}
/* Helper function to do the ioctls needed for setup and init. */
static boolean do_winsys_init(struct radeon_drm_winsys *ws)
{
    struct drm_radeon_gem_info gem_info;
    int retval;
    drmVersionPtr version;

    memset(&gem_info, 0, sizeof(gem_info));

    /* We do things in a specific order here.
     *
     * DRM version first. We need to be sure we're running on a KMS chipset.
     * This is also for some features.
     *
     * Then, the PCI ID. This is essential and should return usable numbers
     * for all Radeons. If this fails, we probably got handed an FD for some
     * non-Radeon card.
     *
     * The GEM info is actually bogus on the kernel side, as well as our side
     * (see radeon_gem_info_ioctl in radeon_gem.c) but that's alright because
     * we don't actually use the info for anything yet.
     *
     * The GB and Z pipe requests should always succeed, but they might not
     * return sensical values for all chipsets, but that's alright because
     * the pipe drivers already know that.
     */

    /* Get DRM version. */
    version = drmGetVersion(ws->fd);
    if (version->version_major != 2 ||
        version->version_minor < 3) {
        fprintf(stderr, "%s: DRM version is %d.%d.%d but this driver is "
                "only compatible with 2.3.x (kernel 2.6.34) or later.\n",
                __FUNCTION__,
                version->version_major,
                version->version_minor,
                version->version_patchlevel);
        drmFreeVersion(version);
        return FALSE;
    }

    ws->info.drm_major = version->version_major;
    ws->info.drm_minor = version->version_minor;
    ws->info.drm_patchlevel = version->version_patchlevel;
    drmFreeVersion(version);

    /* Get PCI ID. */
    if (!radeon_get_drm_value(ws->fd, RADEON_INFO_DEVICE_ID, "PCI ID",
                              &ws->info.pci_id))
        return FALSE;

    /* Check PCI ID. */
    switch (ws->info.pci_id) {
#define CHIPSET(pci_id, name, cfamily) case pci_id: ws->info.family = CHIP_##cfamily; ws->gen = DRV_R300; break;
#include "pci_ids/r300_pci_ids.h"
#undef CHIPSET

#define CHIPSET(pci_id, name, cfamily) case pci_id: ws->info.family = CHIP_##cfamily; ws->gen = DRV_R600; break;
#include "pci_ids/r600_pci_ids.h"
#undef CHIPSET

#define CHIPSET(pci_id, name, cfamily) case pci_id: ws->info.family = CHIP_##cfamily; ws->gen = DRV_SI; break;
#include "pci_ids/radeonsi_pci_ids.h"
#undef CHIPSET

    default:
        fprintf(stderr, "radeon: Invalid PCI ID.\n");
        return FALSE;
    }

    switch (ws->info.family) {
    default:
    case CHIP_UNKNOWN:
        fprintf(stderr, "radeon: Unknown family.\n");
        return FALSE;
    case CHIP_R300:
    case CHIP_R350:
    case CHIP_RV350:
    case CHIP_RV370:
    case CHIP_RV380:
    case CHIP_RS400:
    case CHIP_RC410:
    case CHIP_RS480:
        ws->info.chip_class = R300;
        break;
    case CHIP_R420:     /* R4xx-based cores. */
    case CHIP_R423:
    case CHIP_R430:
    case CHIP_R480:
    case CHIP_R481:
    case CHIP_RV410:
    case CHIP_RS600:
    case CHIP_RS690:
    case CHIP_RS740:
        ws->info.chip_class = R400;
        break;
    case CHIP_RV515:    /* R5xx-based cores. */
    case CHIP_R520:
    case CHIP_RV530:
    case CHIP_R580:
    case CHIP_RV560:
    case CHIP_RV570:
        ws->info.chip_class = R500;
        break;
    case CHIP_R600:
    case CHIP_RV610:
    case CHIP_RV630:
    case CHIP_RV670:
    case CHIP_RV620:
    case CHIP_RV635:
    case CHIP_RS780:
    case CHIP_RS880:
        ws->info.chip_class = R600;
        break;
    case CHIP_RV770:
    case CHIP_RV730:
    case CHIP_RV710:
    case CHIP_RV740:
        ws->info.chip_class = R700;
        break;
    case CHIP_CEDAR:
    case CHIP_REDWOOD:
    case CHIP_JUNIPER:
    case CHIP_CYPRESS:
    case CHIP_HEMLOCK:
    case CHIP_PALM:
    case CHIP_SUMO:
    case CHIP_SUMO2:
    case CHIP_BARTS:
    case CHIP_TURKS:
    case CHIP_CAICOS:
        ws->info.chip_class = EVERGREEN;
        break;
    case CHIP_CAYMAN:
    case CHIP_ARUBA:
        ws->info.chip_class = CAYMAN;
        break;
    case CHIP_TAHITI:
    case CHIP_PITCAIRN:
    case CHIP_VERDE:
    case CHIP_OLAND:
    case CHIP_HAINAN:
        ws->info.chip_class = SI;
        break;
    case CHIP_BONAIRE:
    case CHIP_KAVERI:
    case CHIP_KABINI:
    case CHIP_HAWAII:
    case CHIP_MULLINS:
        ws->info.chip_class = CIK;
        break;
    }

    /* Check for dma */
    ws->info.r600_has_dma = FALSE;
    /* DMA is disabled on R700. There is IB corruption and hangs. */
    if (ws->info.chip_class >= EVERGREEN && ws->info.drm_minor >= 27) {
        ws->info.r600_has_dma = TRUE;
    }

    /* Check for UVD and VCE */
    ws->info.has_uvd = FALSE;
    ws->info.vce_fw_version = 0x00000000;
    if (ws->info.drm_minor >= 32) {
	uint32_t value = RADEON_CS_RING_UVD;
        if (radeon_get_drm_value(ws->fd, RADEON_INFO_RING_WORKING,
                                 "UVD Ring working", &value))
            ws->info.has_uvd = value;

        value = RADEON_CS_RING_VCE;
        if (radeon_get_drm_value(ws->fd, RADEON_INFO_RING_WORKING,
                                 NULL, &value) && value) {

            if (radeon_get_drm_value(ws->fd, RADEON_INFO_VCE_FW_VERSION,
                                     "VCE FW version", &value))
                ws->info.vce_fw_version = value;
	}
    }

    /* Check for userptr support. */
    {
        struct drm_radeon_gem_userptr args = {0};

        /* If the ioctl doesn't exist, -EINVAL is returned.
         *
         * If the ioctl exists, it should return -EACCES
         * if RADEON_GEM_USERPTR_READONLY or RADEON_GEM_USERPTR_REGISTER
         * aren't set.
         */
        ws->info.has_userptr =
            drmCommandWriteRead(ws->fd, DRM_RADEON_GEM_USERPTR,
                                &args, sizeof(args)) == -EACCES;
    }

    /* Get GEM info. */
    retval = drmCommandWriteRead(ws->fd, DRM_RADEON_GEM_INFO,
            &gem_info, sizeof(gem_info));
    if (retval) {
        fprintf(stderr, "radeon: Failed to get MM info, error number %d\n",
                retval);
        return FALSE;
    }
    ws->info.gart_size = gem_info.gart_size;
    ws->info.vram_size = gem_info.vram_size;

    /* Get max clock frequency info and convert it to MHz */
    radeon_get_drm_value(ws->fd, RADEON_INFO_MAX_SCLK, NULL,
                         &ws->info.max_sclk);
    ws->info.max_sclk /= 1000;

    radeon_get_drm_value(ws->fd, RADEON_INFO_SI_BACKEND_ENABLED_MASK, NULL,
                         &ws->info.si_backend_enabled_mask);

    ws->num_cpus = sysconf(_SC_NPROCESSORS_ONLN);

    /* Generation-specific queries. */
    if (ws->gen == DRV_R300) {
        if (!radeon_get_drm_value(ws->fd, RADEON_INFO_NUM_GB_PIPES,
                                  "GB pipe count",
                                  &ws->info.r300_num_gb_pipes))
            return FALSE;

        if (!radeon_get_drm_value(ws->fd, RADEON_INFO_NUM_Z_PIPES,
                                  "Z pipe count",
                                  &ws->info.r300_num_z_pipes))
            return FALSE;
    }
    else if (ws->gen >= DRV_R600) {
        if (ws->info.drm_minor >= 9 &&
            !radeon_get_drm_value(ws->fd, RADEON_INFO_NUM_BACKENDS,
                                  "num backends",
                                  &ws->info.r600_num_backends))
            return FALSE;

        /* get the GPU counter frequency, failure is not fatal */
        radeon_get_drm_value(ws->fd, RADEON_INFO_CLOCK_CRYSTAL_FREQ, NULL,
                             &ws->info.r600_clock_crystal_freq);

        radeon_get_drm_value(ws->fd, RADEON_INFO_TILING_CONFIG, NULL,
                             &ws->info.r600_tiling_config);

        if (ws->info.drm_minor >= 11) {
            radeon_get_drm_value(ws->fd, RADEON_INFO_NUM_TILE_PIPES, NULL,
                                 &ws->info.r600_num_tile_pipes);

            if (radeon_get_drm_value(ws->fd, RADEON_INFO_BACKEND_MAP, NULL,
                                      &ws->info.r600_backend_map))
                ws->info.r600_backend_map_valid = TRUE;
        }

        ws->info.r600_virtual_address = FALSE;
        if (ws->info.drm_minor >= 13) {
            uint32_t ib_vm_max_size;

            ws->info.r600_virtual_address = TRUE;
            if (!radeon_get_drm_value(ws->fd, RADEON_INFO_VA_START, NULL,
                                      &ws->va_start))
                ws->info.r600_virtual_address = FALSE;
            if (!radeon_get_drm_value(ws->fd, RADEON_INFO_IB_VM_MAX_SIZE, NULL,
                                      &ib_vm_max_size))
                ws->info.r600_virtual_address = FALSE;
            radeon_get_drm_value(ws->fd, RADEON_INFO_VA_UNMAP_WORKING, NULL,
                                 &ws->va_unmap_working);
        }
	if (ws->gen == DRV_R600 && !debug_get_bool_option("RADEON_VA", FALSE))
		ws->info.r600_virtual_address = FALSE;
    }

    /* Get max pipes, this is only needed for compute shaders.  All evergreen+
     * chips have at least 2 pipes, so we use 2 as a default. */
    ws->info.r600_max_pipes = 2;
    radeon_get_drm_value(ws->fd, RADEON_INFO_MAX_PIPES, NULL,
                         &ws->info.r600_max_pipes);

    /* All GPUs have at least one compute unit */
    ws->info.max_compute_units = 1;
    radeon_get_drm_value(ws->fd, RADEON_INFO_ACTIVE_CU_COUNT, NULL,
                         &ws->info.max_compute_units);

    radeon_get_drm_value(ws->fd, RADEON_INFO_MAX_SE, NULL,
                         &ws->info.max_se);

    if (!ws->info.max_se) {
        switch (ws->info.family) {
        default:
            ws->info.max_se = 1;
            break;
        case CHIP_CYPRESS:
        case CHIP_HEMLOCK:
        case CHIP_BARTS:
        case CHIP_CAYMAN:
        case CHIP_TAHITI:
        case CHIP_PITCAIRN:
        case CHIP_BONAIRE:
            ws->info.max_se = 2;
            break;
        case CHIP_HAWAII:
            ws->info.max_se = 4;
            break;
        }
    }

    radeon_get_drm_value(ws->fd, RADEON_INFO_MAX_SH_PER_SE, NULL,
                         &ws->info.max_sh_per_se);

    radeon_get_drm_value(ws->fd, RADEON_INFO_ACCEL_WORKING2, NULL,
                         &ws->accel_working2);
    if (ws->info.family == CHIP_HAWAII && ws->accel_working2 < 2) {
        fprintf(stderr, "radeon: GPU acceleration for Hawaii disabled, "
                "returned accel_working2 value %u is smaller than 2. "
                "Please install a newer kernel.\n",
                ws->accel_working2);
        return FALSE;
    }

    if (radeon_get_drm_value(ws->fd, RADEON_INFO_SI_TILE_MODE_ARRAY, NULL,
                             ws->info.si_tile_mode_array)) {
        ws->info.si_tile_mode_array_valid = TRUE;
    }

    if (radeon_get_drm_value(ws->fd, RADEON_INFO_CIK_MACROTILE_MODE_ARRAY, NULL,
                             ws->info.cik_macrotile_mode_array)) {
        ws->info.cik_macrotile_mode_array_valid = TRUE;
    }

    return TRUE;
}
Пример #30
0
Файл: main.c Проект: yuq/gfx
int main(int argc, char **argv)
{
  int fd, newlyopened;
  drmVersionPtr retval;
  char *busid;
  //drmDevicePtr dev;
  //*
  fd = drmOpen(NULL, "pci:0000:01:00.0");
  assert(fd >= 0);
  
  retval = drmGetVersion(fd);
  printf("name=%s\n", retval->name);
  drmFreeVersion(retval);

  busid = drmGetBusid(fd);
  printf("busid=%s\n", busid);
  drmFreeBusid(busid);  
/*
  assert(!drmGetDevice(fd, &dev));
  printf("pci:%04x:%02x:%02x.%d\n",
	   dev->businfo.pci->domain,
	   dev->businfo.pci->bus,
	   dev->businfo.pci->dev,
	   dev->businfo.pci->func);
*/
  drmClose(fd);
  //*/

  fd = drmOpenOnceWithType("pci:0000:01:00.0", &newlyopened, DRM_NODE_PRIMARY);
  //fd = open("/dev/dri/card0", O_RDWR);
  assert(fd >= 0);
  
  retval = drmGetVersion(fd);
  printf("name=%s\n", retval->name);
  drmFreeVersion(retval);

  busid = drmGetBusid(fd);
  printf("busid=%s\n", busid);
  drmFreeBusid(busid);
/*
  assert(!drmGetDevice(fd, &dev));
  printf("pci:%04x:%02x:%02x.%d\n",
	   dev->businfo.pci->domain,
	   dev->businfo.pci->bus,
	   dev->businfo.pci->dev,
	   dev->businfo.pci->func);
*/
  drmClose(fd);
/*
  drmDevicePtr devs[16];
  int num = drmGetDevices(devs, 16);
  assert(num >= 0);
  int i;
  for (i = 0; i < num; i++) {
      printf("pci:%04x:%02x:%02x.%d\n",
	   devs[i]->businfo.pci->domain,
	   devs[i]->businfo.pci->bus,
	   devs[i]->businfo.pci->dev,
	   devs[i]->businfo.pci->func);
  }
*/
  /*
  struct dirent *dent;
  struct stat sbuf;
  DIR *sysdir;
  
  sysdir = opendir("/dev/dri");
  assert(sysdir);
  while ((dent = readdir(sysdir))) {
    char node[1024];
    snprintf(node, 1024, "/dev/dri/%s", dent->d_name);
    if (stat(node, &sbuf))
      continue;
    printf("path=%s, dev=%x rdev=%x maj=%d min=%d\n", node, sbuf.st_dev, sbuf.st_rdev, major(sbuf.st_rdev), minor(sbuf.st_rdev));
  }
  */

  fd = open("/dev/dri/card0", O_RDWR);
  assert(fd >= 0);
  char *path = drmGetDeviceNameFromFd(fd);
  assert(path != NULL);
  printf("get path = %s\n", path);
  return 0;
}