Пример #1
0
int util_open(const char *device, const char *module)
{
	int fd;

	if (module) {
		fd = drmOpen(module, device);
		if (fd < 0) {
			fprintf(stderr, "failed to open device '%s': %s\n",
				module, strerror(errno));
			return -errno;
		}
	} else {
		unsigned int i;

		for (i = 0; i < ARRAY_SIZE(modules); i++) {
			printf("trying to open device '%s'...", modules[i]);

			fd = drmOpen(modules[i], device);
			if (fd < 0) {
				printf("failed\n");
			} else {
				printf("done\n");
				break;
			}
		}

		if (fd < 0) {
			fprintf(stderr, "no device found\n");
			return -ENODEV;
		}
	}

	return fd;
}
Пример #2
0
bool CDRMUtils::OpenDrm()
{
  std::vector<const char*>modules =
  {
    "i915",
    "amdgpu",
    "radeon",
    "nouveau",
    "vmwgfx",
    "msm",
    "imx-drm",
    "rockchip",
    "vc4",
    "virtio_gpu",
    "sun4i-drm",
  };

  for(int i = 0; i < 10; ++i)
  {
    std::string device = "/dev/dri/card";
    device.append(std::to_string(i));

    for (auto module : modules)
    {
      m_fd = drmOpen(module, device.c_str());
      if (m_fd >= 0)
      {
        if(!GetResources())
        {
          continue;
        }

        if(!GetConnector())
        {
          continue;
        }

        drmModeFreeResources(m_drm_resources);
        m_drm_resources = nullptr;

        drmModeFreeConnector(m_connector->connector);
        m_connector->connector = nullptr;

        drmModeFreeObjectProperties(m_connector->props);
        m_connector->props = nullptr;

        drmModeFreeProperty(*m_connector->props_info);
        *m_connector->props_info = nullptr;

        CLog::Log(LOGDEBUG, "CDRMUtils::%s - opened device: %s using module: %s", __FUNCTION__, device.c_str(), module);
        return true;
      }

      drmClose(m_fd);
      m_fd = -1;
    }
  }

  return false;
}
Пример #3
0
int main(int argc, char** argv)
{
	struct kms_driver *kms;
	int ret, fd, i;

	for (i = 0, fd = -1; fd < 0 && drivers[i]; i++)
		fd = drmOpen(drivers[i], NULL);
	CHECK_RET_RETURN(fd, "Could not open device");

	ret = kms_create(fd, &kms);
	CHECK_RET_RETURN(ret, "Failed to create kms driver");

	ret = test_bo(kms);
	if (ret)
		goto err;

	printf("%s: All ok!\n", __func__);

	kms_destroy(&kms);
	return 0;

err:
	kms_destroy(&kms);
	return ret;
}
Пример #4
0
static void init(void)
{
	int fd = drmOpen("kgsl", NULL);

	drmSetMaster(fd);

	dev = fd_device_new(fd);
	pipe = fd_pipe_new(dev, FD_PIPE_2D);

	context_bos[0] = fd_bo_new(dev, 0x1000, DRM_FREEDRENO_GEM_TYPE_KMEM);
	context_bos[1] = fd_bo_new(dev, 0x9000, DRM_FREEDRENO_GEM_TYPE_KMEM);
	context_bos[2] = fd_bo_new(dev, 0x81000, DRM_FREEDRENO_GEM_TYPE_KMEM);

	next_ring();

	ring_pre(ring);

	BEGIN_RING(8);
	OUT_RING  (ring, REGM(VGV1_DIRTYBASE, 3));
	OUT_RELOC (ring, context_bos[0]); /* VGV1_DIRTYBASE */
	OUT_RELOC (ring, context_bos[1]); /* VGV1_CBASE1 */
	OUT_RELOC (ring, context_bos[2]); /* VGV1_UBASE2 */
	OUT_RING  (ring, 0x11000000);
	OUT_RING  (ring, 0x10fff000);
	OUT_RING  (ring, 0x10ffffff);
	OUT_RING  (ring, 0x0d000404);
	END_RING  ();
}
Пример #5
0
bool QEglFSKmsEglDevice::open()
{
    Q_ASSERT(fd() == -1);

    int fd = drmOpen(devicePath().toLocal8Bit().constData(), Q_NULLPTR);
    if (Q_UNLIKELY(fd < 0))
        qFatal("Could not open DRM (NV) device");

    setFd(fd);

    return true;
}
Пример #6
0
static bool
load_driver (ply_renderer_backend_t *backend)
{
  char *driver_name;
  int device_fd;

  driver_name = find_driver_for_device (backend->device_name);
  ply_trace ("Attempting to load driver '%s'", driver_name);
  device_fd = drmOpen (driver_name, NULL);

  if (device_fd < 0)
    {
      ply_trace ("drmOpen failed");
      free (driver_name);
      return false;
    }

  if (strcmp (driver_name, "i915") == 0)
    {
      backend->driver_interface = ply_renderer_i915_driver_get_interface ();
      backend->driver_supports_mapping_console = true;
    }
  else if (strcmp (driver_name, "radeon") == 0)
    {
      backend->driver_interface = ply_renderer_radeon_driver_get_interface ();
      backend->driver_supports_mapping_console = false;
    }
  else if (strcmp (driver_name, "nouveau") == 0)
    {
      backend->driver_interface = ply_renderer_nouveau_driver_get_interface ();
      backend->driver_supports_mapping_console = false;
    }
  free (driver_name);

  if (backend->driver_interface == NULL)
    {
      close (device_fd);
      return false;
    }

  backend->driver = backend->driver_interface->create_driver (device_fd);

  if (backend->driver == NULL)
    {
      close (device_fd);
      return false;
    }

  backend->device_fd = device_fd;

  return true;
}
Пример #7
0
// main function
int main(void)
{
	struct csc_bo* input_bo;
	struct csc_bo* output_bo;
	int ret, fd;

	// open DRM device
	if ((fd = drmOpen("imx-drm", "platform:imx-drm:00")) < 0) {
		printf("drmOpen failed.\n");
		return -1;
	}

	// create buffer for csc input
	input_bo = csc_bo_create(fd, WIDTH, HEIGHT, 32);
	if (!input_bo) {
		printf("Couldn't create input gem bo\n");
		return -1;
	}

	// map the input buffer
	if (csc_bo_map(fd, input_bo)) {
		printf("Couldn't map input bo\n");
		return -1;
	}

	// create buffer for csc output
	output_bo = csc_bo_create(fd, WIDTH, HEIGHT, 32);
	if (!output_bo) {
		printf("Couldn't create output gem bo\n");
		return -1;
	}

	// create ipu csc request
	struct drm_imx_ipu_queue req = {
		.task = IPU_TASK_CSC,
		.input = {
			.phys = input_bo->phys,
			.pix = {
				.pixelformat = V4L2_PIX_FMT_UYVY,
				.bytesperline = 2 * WIDTH,
				.width = WIDTH,
				.height = HEIGHT,
			},
			.rect = {
				.width = WIDTH,
				.height = HEIGHT,
			},
		},
		.output = {
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;
}
Пример #9
0
static int
kms_open (gchar ** driver)
{
  static const char *drivers[] = { "i915", "radeon", "nouveau", "vmwgfx",
    "exynos", "amdgpu", "imx-drm", "rockchip", "atmel-hlcdc"
  };
  int i, fd = -1;

  for (i = 0; i < G_N_ELEMENTS (drivers); i++) {
    fd = drmOpen (drivers[i], NULL);
    if (fd >= 0) {
      if (driver)
        *driver = g_strdup (drivers[i]);
      break;
    }
  }

  return fd;
}
Пример #10
0
int main(int argc, char *argv[])
{
	const char *modules[] = { "i915", "radeon", "nouveau", "vmwgfx", "omapdrm", "msm", "rockchip" };
	unsigned int i, ret = 0;

	for (i = 0; i < ARRAY_SIZE(modules); i++){
		fd = drmOpen(modules[i], NULL);
		if (fd >= 0) {
			printf("Module %s loaded.\n", modules[i]);
			break;
		}
	}

	if (i == ARRAY_SIZE(modules)) {
		fprintf(stderr, "Failed to load drm modules.\n");
		return 1;
	}

	res = drmModeGetResources(fd);
	if (!res) {
		fprintf(stderr, "Failed to get resources: %s\n",
			strerror(errno));
		ret = 1;
		goto done;
	}

	if (argc < 2) {
		listAllProperties();
	} else if (argc == 5) {
		ret = setProperty(argv);
	} else {
		printUsage();
		ret = 1;
	}

	drmModeFreeResources(res);
done:
	drmClose(fd);
	return ret;
}
Пример #11
0
Rk30MaliDRI2 *Rk30MaliDRI2_Init(ScreenPtr pScreen)
{
    int drm_fd;
    DRI2InfoRec info;

    if (!xf86LoadSubModule(xf86Screens[pScreen->myNum], "dri2"))
        return FALSE;

    if ((drm_fd = drmOpen("mali_drm", NULL)) < 0) {
        ErrorF("Rk30MaliDRI2_Init: drmOpen failed!\n");
        return FALSE;
    }

    if (ump_open() != UMP_OK) {
        drmClose(drm_fd);
        ErrorF("Rk30MaliDRI2_Init: ump_open() != UMP_OK\n");
        return FALSE;
    }

    info.version = 3;

    info.driverName = "rk30-mali";
    info.deviceName = "/dev/dri/card0";
    info.fd = drm_fd;

    info.CreateBuffer = MaliDRI2CreateBuffer;
    info.DestroyBuffer = MaliDRI2DestroyBuffer;
    info.CopyRegion = MaliDRI2CopyRegion;

    if (!DRI2ScreenInit(pScreen, &info)) {
        drmClose(drm_fd);
        return NULL;
    }
    else {
        Rk30MaliDRI2 *private = calloc(1, sizeof(Rk30MaliDRI2));
        private->drm_fd = drm_fd;
        return private;
    }
Пример #12
0
int mggh::DRMHelper::open_drm_device()
{
    static const char *drivers[] = {
        "i915", "radeon", "nouveau", 0
    };
    int tmp_fd = -1;

    const char** driver{drivers};

    while (tmp_fd < 0 && *driver)
    {
        tmp_fd = drmOpen(*driver, NULL);
        ++driver;
    }

    if (tmp_fd < 0)
    {
        BOOST_THROW_EXCEPTION(
            boost::enable_error_info(
                std::runtime_error("Problem opening DRM device")) << boost::errinfo_errno(-tmp_fd));
    }

    return tmp_fd;
}
Пример #13
0
int init_drm(void)
{
	static const char *modules[] = {
			"i915", "radeon", "nouveau", "vmwgfx", "omapdrm", "exynos", "msm"
	};
	drmModeRes *resources;
	drmModeConnector *connector = NULL;
	drmModeEncoder *encoder = NULL;
	int i, area;

	for (i = 0; i < ARRAY_SIZE(modules); i++) {
		printf("trying to load module %s...", modules[i]);
		drm.fd = drmOpen(modules[i], NULL);
		if (drm.fd < 0) {
			printf("failed.\n");
		} else {
			printf("success.\n");
			break;
		}
	}

	if (drm.fd < 0) {
		printf("could not open drm device\n");
		return -1;
	}

	resources = drmModeGetResources(drm.fd);
	if (!resources) {
		printf("drmModeGetResources failed: %s\n", strerror(errno));
		return -1;
	}

	/* find a connected connector: */
	for (i = 0; i < resources->count_connectors; i++) {
		connector = drmModeGetConnector(drm.fd, resources->connectors[i]);
		if (connector->connection == DRM_MODE_CONNECTED) {
			/* it's connected, let's use this! */
			break;
		}
		drmModeFreeConnector(connector);
		connector = NULL;
	}

	if (!connector) {
		/* we could be fancy and listen for hotplug events and wait for
		 * a connector..
		 */
		printf("no connected connector!\n");
		return -1;
	}

	/* find highest resolution mode: */
	for (i = 0, area = 0; i < connector->count_modes; i++) {
		drmModeModeInfo *current_mode = &connector->modes[i];
		int current_area = current_mode->hdisplay * current_mode->vdisplay;
		if (current_area > area) {
			drm.mode = current_mode;
			area = current_area;
		}
	}

	if (!drm.mode) {
		printf("could not find mode!\n");
		return -1;
	}

	/* find encoder: */
	for (i = 0; i < resources->count_encoders; i++) {
		encoder = drmModeGetEncoder(drm.fd, resources->encoders[i]);
		if (encoder->encoder_id == connector->encoder_id)
			break;
		drmModeFreeEncoder(encoder);
		encoder = NULL;
	}

	if (!encoder) {
		printf("no encoder!\n");
		return -1;
	}

	drm.crtc_id = encoder->crtc_id;
	drm.connector_id = connector->connector_id;

	return 0;
}
Пример #14
0
static bool gfx_ctx_init(void)
{
   if (g_inited)
      return false;

   static const char *modules[] = {
      "i915", "radeon", "nouveau", "vmwgfx", "omapdrm", "exynos", NULL
   };

   for (int i = 0; modules[i]; i++)
   {
      RARCH_LOG("[KMS/EGL]: Trying to load module %s ...\n", modules[i]);
      g_drm_fd = drmOpen(modules[i], NULL);
      if (g_drm_fd >= 0)
      {
         RARCH_LOG("[KMS/EGL]: Found module %s.\n", modules[i]);
         break;
      }
   }

   if (g_drm_fd < 0)
   {
      RARCH_ERR("[KMS/EGL]: Couldn't open DRM device.\n");
      goto error;
   }

   g_resources = drmModeGetResources(g_drm_fd);
   if (!g_resources)
   {
      RARCH_ERR("[KMS/EGL]: Couldn't get device resources.\n");
      goto error;
   }

   for (int i = 0; i < g_resources->count_connectors; i++)
   {
      g_connector = drmModeGetConnector(g_drm_fd, g_resources->connectors[i]);
      if (g_connector->connection == DRM_MODE_CONNECTED)
         break;

      drmModeFreeConnector(g_connector);
      g_connector = NULL;
   }

   // TODO: Figure out what index for crtcs to use ...
   g_orig_crtc = drmModeGetCrtc(g_drm_fd, g_resources->crtcs[0]);
   if (!g_orig_crtc)
      RARCH_WARN("[KMS/EGL]: Cannot find original CRTC.\n");

   if (!g_connector)
   {
      RARCH_ERR("[KMS/EGL]: Couldn't get device connector.\n");
      goto error;
   }

   for (int i = 0, area = 0; i < g_connector->count_modes; i++)
   {
      drmModeModeInfo *current_mode = &g_connector->modes[i];
      int current_area = current_mode->hdisplay * current_mode->vdisplay;
      if (current_area > area)
      {
         g_drm_mode = current_mode;
         area       = current_area;
      }
   }

   if (!g_drm_mode)
   {
      RARCH_ERR("[KMS/EGL]: Couldn't find DRM mode.\n");
      goto error;
   }

	for (int i = 0; i < g_resources->count_encoders; i++)
   {
		g_encoder = drmModeGetEncoder(g_drm_fd, g_resources->encoders[i]);
		if (g_encoder->encoder_id == g_connector->encoder_id)
			break;

		drmModeFreeEncoder(g_encoder);
		g_encoder = NULL;
	}

	if (!g_encoder)
   {
      RARCH_ERR("[KMS/EGL]: Couldn't find DRM encoder.\n");
      goto error;
   }

   g_crtc_id      = g_encoder->crtc_id;
   g_connector_id = g_connector->connector_id;

   g_fb_width  = g_drm_mode->hdisplay;
   g_fb_height = g_drm_mode->vdisplay;

   g_gbm_dev     = gbm_create_device(g_drm_fd);
   g_gbm_surface = gbm_surface_create(g_gbm_dev,
         g_fb_width, g_fb_height,
         GBM_FORMAT_XRGB8888,
         GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);

   if (!g_gbm_surface)
   {
      RARCH_ERR("[KMS/EGL]: Couldn't create GBM surface.\n");
      goto error;
   }

   return true;

error:
   gfx_ctx_destroy();
   return false;
}
Пример #15
0
int main(int argc, char **argv)
{
	struct exynos_device *dev;
	struct exynos_bo *bo, *src;
	struct connector con;
	unsigned int fb_id;
	uint32_t handles[4] = {0}, pitches[4] = {0}, offsets[4] = {0};
	drmModeRes *resources;
	int ret, fd, c;

	memset(&con, 0, sizeof(struct connector));

	if (argc != 3) {
		usage(argv[0]);
		return -EINVAL;
	}

	while ((c = getopt(argc, argv, optstr)) != -1) {
		switch (c) {
		case 's':
			con.crtc = -1;
			if (sscanf(optarg, "%d:0x%64s",
						&con.id,
						con.mode_str) != 2 &&
					sscanf(optarg, "%d@%d:%64s",
						&con.id,
						&con.crtc,
						con.mode_str) != 3)
				usage(argv[0]);
			break;
		default:
			usage(argv[0]);
			return -EINVAL;
		}
	}

	fd = drmOpen(DRM_MODULE_NAME, NULL);
	if (fd < 0) {
		fprintf(stderr, "failed to open.\n");
		return fd;
	}

	dev = exynos_device_create(fd);
	if (!dev) {
		drmClose(dev->fd);
		return -EFAULT;
	}

	resources = drmModeGetResources(dev->fd);
	if (!resources) {
		fprintf(stderr, "drmModeGetResources failed: %s\n",
				strerror(errno));
		ret = -EFAULT;
		goto err_drm_close;
	}

	connector_find_mode(dev->fd, &con, resources);
	drmModeFreeResources(resources);

	if (!con.mode) {
		fprintf(stderr, "failed to find usable connector\n");
		ret = -EFAULT;
		goto err_drm_close;
	}

	screen_width = con.mode->hdisplay;
	screen_height = con.mode->vdisplay;

	if (screen_width == 0 || screen_height == 0) {
		fprintf(stderr, "failed to find sane resolution on connector\n");
		ret = -EFAULT;
		goto err_drm_close;
	}

	printf("screen width = %d, screen height = %d\n", screen_width,
			screen_height);

	bo = exynos_create_buffer(dev, screen_width * screen_height * 4, 0);
	if (!bo) {
		ret = -EFAULT;
		goto err_drm_close;
	}

	handles[0] = bo->handle;
	pitches[0] = screen_width * 4;
	offsets[0] = 0;

	ret = drmModeAddFB2(dev->fd, screen_width, screen_height,
				DRM_FORMAT_RGBA8888, handles,
				pitches, offsets, &fb_id, 0);
	if (ret < 0)
		goto err_destroy_buffer;

	con.plane_zpos = -1;

	memset(bo->vaddr, 0xff, screen_width * screen_height * 4);

	ret = drm_set_crtc(dev, &con, fb_id);
	if (ret < 0)
		goto err_rm_fb;

	ret = test_case.solid_fill(dev, bo);
	if (ret < 0) {
		fprintf(stderr, "failed to solid fill operation.\n");
		goto err_rm_fb;
	}

	wait_for_user_input(0);

	src = exynos_create_buffer(dev, screen_width * screen_height * 4, 0);
	if (!src) {
		ret = -EFAULT;
		goto err_rm_fb;
	}

	ret = test_case.copy(dev, src, bo, G2D_IMGBUF_GEM);
	if (ret < 0) {
		fprintf(stderr, "failed to test copy operation.\n");
		goto err_free_src;
	}

	wait_for_user_input(0);

	ret = test_case.copy_with_scale(dev, src, bo, G2D_IMGBUF_GEM);
	if (ret < 0) {
		fprintf(stderr, "failed to test copy and scale operation.\n");
		goto err_free_src;
	}

	wait_for_user_input(0);

	ret = test_case.checkerboard(dev, src, bo, G2D_IMGBUF_GEM);
	if (ret < 0) {
		fprintf(stderr, "failed to issue checkerboard test.\n");
		goto err_free_src;
	}

	wait_for_user_input(1);

	/*
	 * The blend test uses the userptr functionality of exynos-drm, which
	 * is currently not safe to use. If the kernel hasn't been build with
	 * exynos-iommu support, then the blend test is going to produce (kernel)
	 * memory corruption, eventually leading to a system crash.
	 *
	 * Disable the test for now, until the kernel code has been sanitized.
	 */
#if 0
	ret  = test_case.blend(dev, src, bo, G2D_IMGBUF_USERPTR);
	if (ret < 0)
		fprintf(stderr, "failed to test blend operation.\n");

	getchar();
#endif

err_free_src:
	if (src)
		exynos_destroy_buffer(src);

err_rm_fb:
	drmModeRmFB(dev->fd, fb_id);

err_destroy_buffer:
	exynos_destroy_buffer(bo);

err_drm_close:
	drmClose(dev->fd);
	exynos_device_destroy(dev);

	return 0;
}
Пример #16
0
/*
 * checks if a modesetting capable driver has attached to the pci id
 * returns 0 if modesetting supported.
 *  -EINVAL or invalid bus id
 *  -ENOSYS if no modesetting support
*/
int drmCheckModesettingSupported(const char *busid)
{
#if defined (__linux__)
	char pci_dev_dir[1024];
	int domain, bus, dev, func;
	DIR *sysdir;
	struct dirent *dent;
	int found = 0, ret;

	ret = sscanf(busid, "pci:%04x:%02x:%02x.%d", &domain, &bus, &dev, &func);
	if (ret != 4)
		return -EINVAL;

	sprintf(pci_dev_dir, "/sys/bus/pci/devices/%04x:%02x:%02x.%d/drm",
		domain, bus, dev, func);

	sysdir = opendir(pci_dev_dir);
	if (sysdir) {
		dent = readdir(sysdir);
		while (dent) {
			if (!strncmp(dent->d_name, "controlD", 8)) {
				found = 1;
				break;
			}

			dent = readdir(sysdir);
		}
		closedir(sysdir);
		if (found)
			return 0;
	}

	sprintf(pci_dev_dir, "/sys/bus/pci/devices/%04x:%02x:%02x.%d/",
		domain, bus, dev, func);

	sysdir = opendir(pci_dev_dir);
	if (!sysdir)
		return -EINVAL;

	dent = readdir(sysdir);
	while (dent) {
		if (!strncmp(dent->d_name, "drm:controlD", 12)) {
			found = 1;
			break;
		}

		dent = readdir(sysdir);
	}

	closedir(sysdir);
	if (found)
		return 0;
#elif defined (__FreeBSD__) || defined (__FreeBSD_kernel__)
	char kbusid[1024], sbusid[1024];
	char oid[128];
	int domain, bus, dev, func;
	int i, modesetting, ret;
	size_t len;

	ret = sscanf(busid, "pci:%04x:%02x:%02x.%d", &domain, &bus, &dev,
	    &func);
	if (ret != 4)
		return -EINVAL;
	snprintf(kbusid, sizeof(kbusid), "pci:%04x:%02x:%02x.%d", domain, bus,
	    dev, func);

	/* How many GPUs do we expect in the machine ? */
	for (i = 0; i < 16; i++) {
		snprintf(oid, sizeof(oid), "hw.dri.%d.busid", i);
		len = sizeof(sbusid);
		ret = sysctlbyname(oid, sbusid, &len, NULL, 0);
		if (ret == -1) {
			if (errno == ENOENT)
				continue;
			return -EINVAL;
		}
		if (strcmp(sbusid, kbusid) != 0)
			continue;
		snprintf(oid, sizeof(oid), "hw.dri.%d.modesetting", i);
		len = sizeof(modesetting);
		ret = sysctlbyname(oid, &modesetting, &len, NULL, 0);
		if (ret == -1 || len != sizeof(modesetting))
			return -EINVAL;
		return (modesetting ? 0 : -ENOSYS);
	}
#elif defined(__DragonFly__)
	return 0;
#else
	int fd;
	static const struct drm_mode_card_res zero_res;
	struct drm_mode_card_res res = zero_res;
	int ret;
 
	fd = drmOpen(NULL, busid);
	if (fd == -1)
		return -EINVAL;
	ret = drmIoctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &res);
	drmClose(fd);
	if (ret == 0)
		return 0;
#endif
#ifdef __OpenBSD__
	int	fd;
	struct drm_mode_card_res res;
	drmModeResPtr r = 0;

	if ((fd = drmOpen(NULL, busid)) < 0)
		return -EINVAL;

	memset(&res, 0, sizeof(struct drm_mode_card_res));

	if (drmIoctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &res)) {
		drmClose(fd);
		return -errno;
	}

	drmClose(fd);
	return 0;
#endif
	return -ENOSYS;
}
Пример #17
0
int main(int argc, char **argv)
{
    int            c;
    int            r  = 0;
    int            fd = -1;
    drm_handle_t      handle;
    void           *address;
    char           *pt;
    unsigned long  count;
    unsigned long  offset;
    unsigned long  size;
    drm_context_t  context;
    int            loops;
    char           buf[1024];
    int            i;
    drmBufInfoPtr  info;
    drmBufMapPtr   bufs;
    drmLockPtr     lock;
    int            secs;

    while ((c = getopt(argc, argv,
		       "lc:vo:O:f:s:w:W:b:r:R:P:L:C:XS:B:F:")) != EOF)
	switch (c) {
	case 'F':
	    count  = strtoul(optarg, NULL, 0);
	    if (!fork()) {
		dup(fd);
		sleep(count);
	    }
	    close(fd);
	    break;
	case 'v': getversion(fd);                                        break;
	case 'X':
	    if ((r = drmCreateContext(fd, &context))) {
		drmError(r, argv[0]);
		return 1;
	    }
	    printf( "Got %d\n", context);
	    break;
	case 'S':
	    process_sigio(optarg);
	    break;
	case 'C':
	    if ((r = drmSwitchToContext(fd, strtoul(optarg, NULL, 0)))) {
		drmError(r, argv[0]);
		return 1;
	    }
	    break;
	case 'c':
	    if ((r = drmSetBusid(fd,optarg))) {
		drmError(r, argv[0]);
		return 1;
	    }
	    break;
	case 'o':
	    if ((fd = drmOpen(optarg, NULL)) < 0) {
		drmError(fd, argv[0]);
		return 1;
	    }
	    break;
	case 'O':
	    if ((fd = drmOpen(NULL, optarg)) < 0) {
		drmError(fd, argv[0]);
		return 1;
	    }
	    break;
	case 'B':		/* Test buffer allocation */
	    count  = strtoul(optarg, &pt, 0);
	    size   = strtoul(pt+1, &pt, 0);
	    secs   = strtoul(pt+1, NULL, 0);
	    {
		drmDMAReq      dma;
		int            *indices, *sizes;

		indices = alloca(sizeof(*indices) * count);
		sizes   = alloca(sizeof(*sizes)   * count);
		dma.context         = context;
		dma.send_count      = 0;
		dma.request_count   = count;
		dma.request_size    = size;
		dma.request_list    = indices;
		dma.request_sizes   = sizes;
		dma.flags           = DRM_DMA_WAIT;
		if ((r = drmDMA(fd, &dma))) {
		    drmError(r, argv[0]);
		    return 1;
		}
		for (i = 0; i < dma.granted_count; i++) {
		    printf("%5d: index = %d, size = %d\n",
			   i, dma.request_list[i], dma.request_sizes[i]);
		}
		sleep(secs);
		drmFreeBufs(fd, dma.granted_count, indices);
	    }
	    break;
	case 'b':
	    count   = strtoul(optarg, &pt, 0);
	    size    = strtoul(pt+1, NULL, 0);
	    if ((r = drmAddBufs(fd, count, size, 0, 65536)) < 0) {
		drmError(r, argv[0]);
		return 1;
	    }
	    if (!(info = drmGetBufInfo(fd))) {
		drmError(0, argv[0]);
		return 1;
	    }
	    for (i = 0; i < info->count; i++) {
		printf("%5d buffers of size %6d (low = %d, high = %d)\n",
		       info->list[i].count,
		       info->list[i].size,
		       info->list[i].low_mark,
		       info->list[i].high_mark);
	    }
	    if ((r = drmMarkBufs(fd, 0.50, 0.80))) {
		drmError(r, argv[0]);
		return 1;
	    }
	    if (!(info = drmGetBufInfo(fd))) {
		drmError(0, argv[0]);
		return 1;
	    }
	    for (i = 0; i < info->count; i++) {
		printf("%5d buffers of size %6d (low = %d, high = %d)\n",
		       info->list[i].count,
		       info->list[i].size,
		       info->list[i].low_mark,
		       info->list[i].high_mark);
	    }
	    printf("===== /proc/dri/0/mem =====\n");
	    snprintf(buf, sizeof(buf), "cat /proc/dri/0/mem");
	    system(buf);
#if 1
	    if (!(bufs = drmMapBufs(fd))) {
		drmError(0, argv[0]);
		return 1;
	    }
	    printf("===============================\n");
	    printf( "%d bufs\n", bufs->count);
	    for (i = 0; i < bufs->count; i++) {
		printf( "  %4d: %8d bytes at %p\n",
			i,
			bufs->list[i].total,
			bufs->list[i].address);
	    }
	    printf("===== /proc/dri/0/vma =====\n");
	    snprintf(buf, sizeof(buf), "cat /proc/dri/0/vma");
	    system(buf);
#endif
	    break;
	case 'f':
	    offset  = strtoul(optarg, &pt, 0);
	    size    = strtoul(pt+1, NULL, 0);
	    handle  = 0;
	    if ((r = drmAddMap(fd, offset, size,
			       DRM_FRAME_BUFFER, 0, &handle))) {
		drmError(r, argv[0]);
		return 1;
	    }
	    printf("0x%08lx:0x%04lx added\n", offset, size);
	    printf("===== /proc/dri/0/mem =====\n");
	    snprintf(buf, sizeof(buf), "cat /proc/dri/0/mem");
	    system(buf);
	    break;
	case 'r':
	case 'R':
	    offset  = strtoul(optarg, &pt, 0);
	    size    = strtoul(pt+1, NULL, 0);
	    handle  = 0;
	    if ((r = drmAddMap(fd, offset, size,
			       DRM_REGISTERS,
			       c == 'R' ? DRM_READ_ONLY : 0,
			       &handle))) {
		drmError(r, argv[0]);
		return 1;
	    }
	    printf("0x%08lx:0x%04lx added\n", offset, size);
	    printf("===== /proc/dri/0/mem =====\n");
	    snprintf(buf, sizeof(buf), "cat /proc/dri/0/mem");
	    system(buf);
	    break;
	case 's':
	    size = strtoul(optarg, &pt, 0);
	    handle = 0;
	    if ((r = drmAddMap(fd, 0, size,
			       DRM_SHM, DRM_CONTAINS_LOCK,
			       &handle))) {
		drmError(r, argv[0]);
		return 1;
	    }
	    printf("0x%04lx byte shm added at 0x%08lx\n", size, handle);
	    snprintf(buf, sizeof(buf), "cat /proc/dri/0/vm");
	    system(buf);
	    break;
	case 'P':
	    offset  = strtoul(optarg, &pt, 0);
	    size    = strtoul(pt+1, NULL, 0);
	    address = NULL;
	    if ((r = drmMap(fd, offset, size, &address))) {
		drmError(r, argv[0]);
		return 1;
	    }
	    printf("0x%08lx:0x%04lx mapped at %p for pid %d\n",
		   offset, size, address, getpid());
	    printf("===== /proc/dri/0/vma =====\n");
	    snprintf(buf, sizeof(buf), "cat /proc/dri/0/vma");
	    system(buf);
	    mprotect((void *)offset, size, PROT_READ);
	    printf("===== /proc/dri/0/vma =====\n");
	    snprintf(buf, sizeof(buf), "cat /proc/dri/0/vma");
	    system(buf);
	    break;
	case 'w':
	case 'W':
	    offset  = strtoul(optarg, &pt, 0);
	    size    = strtoul(pt+1, NULL, 0);
	    address = NULL;
	    if ((r = drmMap(fd, offset, size, &address))) {
		drmError(r, argv[0]);
		return 1;
	    }
	    printf("0x%08lx:0x%04lx mapped at %p for pid %d\n",
		   offset, size, address, getpid());
	    printf("===== /proc/%d/maps =====\n", getpid());
	    snprintf(buf, sizeof(buf), "cat /proc/%d/maps", getpid());
	    system(buf);
	    printf("===== /proc/dri/0/mem =====\n");
	    snprintf(buf, sizeof(buf), "cat /proc/dri/0/mem");
	    system(buf);
	    printf("===== /proc/dri/0/vma =====\n");
	    snprintf(buf, sizeof(buf), "cat /proc/dri/0/vma");
	    system(buf);
	    printf("===== READING =====\n");
	    for (i = 0; i < 0x10; i++)
		printf("%02x ", (unsigned int)((unsigned char *)address)[i]);
	    printf("\n");
	    if (c == 'w') {
		printf("===== WRITING =====\n");
		for (i = 0; i < size; i+=2) {
		    ((char *)address)[i]   = i & 0xff;
		    ((char *)address)[i+1] = i & 0xff;
		}
	    }
	    printf("===== READING =====\n");
	    for (i = 0; i < 0x10; i++)
		printf("%02x ", (unsigned int)((unsigned char *)address)[i]);
	    printf("\n");
	    printf("===== /proc/dri/0/vma =====\n");
	    snprintf(buf, sizeof(buf), "cat /proc/dri/0/vma");
	    system(buf);
	    break;
	case 'L':
	    context = strtoul(optarg, &pt, 0);
	    offset  = strtoul(pt+1, &pt, 0);
	    size    = strtoul(pt+1, &pt, 0);
	    loops   = strtoul(pt+1, NULL, 0);
	    address = NULL;
	    if ((r = drmMap(fd, offset, size, &address))) {
		drmError(r, argv[0]);
		return 1;
	    }
	    lock       = address;
#if 1
	    {
		int            counter = 0;
		struct timeval loop_start, loop_end;
		struct timeval lock_start, lock_end;
		double         wt;
#define HISTOSIZE 9
		int            histo[HISTOSIZE];
		int            output = 0;
		int            fast   = 0;

		if (loops < 0) {
		    loops = -loops;
		    ++output;
		}

		for (i = 0; i < HISTOSIZE; i++) histo[i] = 0;

		gettimeofday(&loop_start, NULL);
		for (i = 0; i < loops; i++) {
		    gettimeofday(&lock_start, NULL);
		    DRM_LIGHT_LOCK_COUNT(fd,lock,context,fast);
		    gettimeofday(&lock_end, NULL);
		    DRM_UNLOCK(fd,lock,context);
		    ++counter;
		    wt = usec(&lock_end, &lock_start);
		    if      (wt <=      2.5) ++histo[8];
		    if      (wt <       5.0) ++histo[0];
		    else if (wt <      50.0) ++histo[1];
		    else if (wt <     500.0) ++histo[2];
		    else if (wt <    5000.0) ++histo[3];
		    else if (wt <   50000.0) ++histo[4];
		    else if (wt <  500000.0) ++histo[5];
		    else if (wt < 5000000.0) ++histo[6];
		    else                     ++histo[7];
		    if (output) printf( "%.2f uSec, %d fast\n", wt, fast);
		}
		gettimeofday(&loop_end, NULL);
		printf( "Average wait time = %.2f usec, %d fast\n",
			usec(&loop_end, &loop_start) /  counter, fast);
		printf( "%9d <=     2.5 uS\n", histo[8]);
		printf( "%9d <        5 uS\n", histo[0]);
		printf( "%9d <       50 uS\n", histo[1]);
		printf( "%9d <      500 uS\n", histo[2]);
		printf( "%9d <     5000 uS\n", histo[3]);
		printf( "%9d <    50000 uS\n", histo[4]);
		printf( "%9d <   500000 uS\n", histo[5]);
		printf( "%9d <  5000000 uS\n", histo[6]);
		printf( "%9d >= 5000000 uS\n", histo[7]);
	    }
#else
	    printf( "before lock: 0x%08x\n", lock->lock);
	    printf( "lock: 0x%08x\n", lock->lock);
	    sleep(5);
	    printf( "unlock: 0x%08x\n", lock->lock);
#endif
	    break;
	default:
	    fprintf( stderr, "Usage: drmstat [options]\n" );
	    return 1;
	}

    return r; 
}
Пример #18
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;
}
Пример #19
0
static void ricochet(int tiled, int sprite_w, int sprite_h,
		     int out_w, int out_h, int dump_info)
{
	int                                 ret;
	int                                 gfx_fd;
	int                                 keep_moving;
	const int                           num_surfaces = 3;
	uint32_t                            sprite_handles[num_surfaces];
	uint32_t                            sprite_fb_id[num_surfaces];
	int                                 *sprite_x = NULL;
	int                                 *sprite_y = NULL;
	uint32_t                            sprite_stride;
	uint32_t                            sprite_size;
	uint32_t                            handles[4],
					    pitches[4],
					    offsets[4]; /* we only use [0] */
	uint32_t                            prim_width,
					    prim_height,
					    prim_handle,
					    prim_stride,
					    prim_size,
					    prim_fb_id;
	struct drm_intel_sprite_colorkey    set;
	struct connector                    curr_connector;
	drmModeRes                          *gfx_resources;
	struct termios                      orig_term,
					    curr_term;
	int                                 c_index;
	int                                 sprite_index;
	unsigned int                        *sprite_plane_id = NULL;
	uint32_t                            plane_flags = 0;
	int                                 *delta_x = NULL,
					    *delta_y = NULL;
	struct timeval                      stTimeVal;
	long long                           currTime,
	     prevFlipTime,
	     prevMoveTime,
	     deltaFlipTime,
	     deltaMoveTime,
	     SleepTime;
	char                                key;
	int				    sprite_plane_count = 0;
	int 				    i;
	// Open up I915 graphics device
	gfx_fd = drmOpen("i915", NULL);
	if (gfx_fd < 0) {
		printf("Failed to load i915 driver: %s\n", strerror(errno));
		return;
	}

	// Obtain pointer to struct containing graphics resources
	gfx_resources = drmModeGetResources(gfx_fd);
	if (!gfx_resources) {
		printf("drmModeGetResources failed: %s\n", strerror(errno));
		return;
	}

	if (dump_info != 0) {
		dump_connectors(gfx_fd, gfx_resources);
		dump_crtcs(gfx_fd, gfx_resources);
		dump_planes(gfx_fd, gfx_resources);
	}

	// Save previous terminal settings
	if (tcgetattr( 0, &orig_term) != 0) {
		printf("tcgetattr failure: %s\n",
				strerror(errno));
		return;
	}

	// Set up input to return characters immediately
	curr_term = orig_term;
	curr_term.c_lflag &= ~(ICANON | ECHO | ECHONL);
	curr_term.c_cc[VMIN] = 0;       // No minimum number of characters
	curr_term.c_cc[VTIME] = 0 ;     // Return immediately, even if
	// nothing has been entered.
	if (tcsetattr( 0, TCSANOW, &curr_term) != 0) {
		printf("tcgetattr failure: %s\n", strerror(errno));
		return;
	}

	// Cycle through all connectors and display the flying sprite
	// where there are displays attached and the hardware will support it.
	for (c_index = 0; c_index < gfx_resources->count_connectors; c_index++)  {
		curr_connector.id = gfx_resources->connectors[c_index];

		// Find the native (preferred) display mode
		connector_find_preferred_mode(gfx_fd, gfx_resources, &curr_connector);
		if (curr_connector.mode_valid == 0) {
			printf("No valid preferred mode detected\n");
			goto out;
		}

		// Determine if sprite hardware is available on pipe
		// associated with this connector.
		sprite_plane_count = connector_find_plane(gfx_fd, &curr_connector,
							  &sprite_plane_id);
		if (!sprite_plane_count) {
			printf("Failed to find sprite plane on crtc\n");
			goto out;
		}

		// Width and height of preferred mode
		prim_width = curr_connector.mode.hdisplay;
		prim_height = curr_connector.mode.vdisplay;

		// Allocate and fill memory for primary surface
		ret = prepare_primary_surface(
				gfx_fd,
				prim_width,
				prim_height,
				&prim_handle,
				&prim_stride,
				&prim_size,
				tiled);
		if (ret != 0) {
			printf("Failed to add primary fb (%dx%d): %s\n",
				prim_width, prim_height, strerror(errno));
			goto out;
		}

		// Add the primary surface framebuffer
		ret = drmModeAddFB(gfx_fd, prim_width, prim_height, 24, 32,
				   prim_stride, prim_handle, &prim_fb_id);
		gem_close(gfx_fd, prim_handle);

		if (ret != 0) {
			printf("Failed to add primary fb (%dx%d): %s\n",
					prim_width, prim_height, strerror(errno));
			goto out;
		}

		// Allocate and fill sprite surfaces
		ret = prepare_sprite_surfaces(gfx_fd, sprite_w, sprite_h, num_surfaces,
					      &sprite_handles[0],
					      &sprite_stride, &sprite_size,
					      tiled);
		if (ret != 0) {
			printf("Preparation of sprite surfaces failed %dx%d\n",
				sprite_w, sprite_h);
			goto out;
		}

		// Add the sprite framebuffers
		for (sprite_index = 0; sprite_index < num_surfaces; sprite_index++) {
			handles[0] = sprite_handles[sprite_index];
			handles[1] = handles[0];
			handles[2] = handles[0];
			handles[3] = handles[0];
			pitches[0] = sprite_stride;
			pitches[1] = sprite_stride;
			pitches[2] = sprite_stride;
			pitches[3] = sprite_stride;
			memset(offsets, 0, sizeof(offsets));

			ret = drmModeAddFB2(gfx_fd, sprite_w, sprite_h,
					    DRM_FORMAT_XRGB8888,
					    handles, pitches, offsets,
					    &sprite_fb_id[sprite_index], plane_flags);
			gem_close(gfx_fd, sprite_handles[sprite_index]);

			if (ret) {
				printf("Failed to add sprite fb (%dx%d): %s\n",
				       sprite_w, sprite_h, strerror(errno));

				sprite_index--;
				while (sprite_index >= 0) {
					drmModeRmFB(gfx_fd, sprite_fb_id[sprite_index]);
					sprite_index--;
				}
				goto out;
			}
		}

		if (dump_info != 0) {
			printf("Displayed Mode Connector struct:\n"
				"    .id = %d\n"
				"    .mode_valid = %d\n"
				"    .crtc = %d\n"
				"    .pipe = %d\n"
				"    drmModeModeInfo ...\n"
				"        .name = %s\n"
				"        .type = %d\n"
				"        .flags = %08x\n"
				"    drmModeEncoder ...\n"
				"        .encoder_id = %d\n"
				"        .encoder_type = %d (%s)\n"
				"        .crtc_id = %d\n"
				"        .possible_crtcs = %d\n"
				"        .possible_clones = %d\n"
				"    drmModeConnector ...\n"
				"        .connector_id = %d\n"
				"        .encoder_id = %d\n"
				"        .connector_type = %d (%s)\n"
				"        .connector_type_id = %d\n\n",
				curr_connector.id,
				curr_connector.mode_valid,
				curr_connector.crtc,
				curr_connector.pipe,
				curr_connector.mode.name,
				curr_connector.mode.type,
				curr_connector.mode.flags,
				curr_connector.encoder->encoder_id,
				curr_connector.encoder->encoder_type,
				kmstest_encoder_type_str(curr_connector.encoder->encoder_type),
				curr_connector.encoder->crtc_id,
				curr_connector.encoder->possible_crtcs,
				curr_connector.encoder->possible_clones,
				curr_connector.connector->connector_id,
				curr_connector.connector->encoder_id,
				curr_connector.connector->connector_type,
				kmstest_connector_type_str(curr_connector.connector->connector_type),
				curr_connector.connector->connector_type_id);

			printf("Sprite surface dimensions = %dx%d\n"
				"Sprite output dimensions = %dx%d\n"
				"Press any key to continue >\n",
				sprite_w, sprite_h, out_w, out_h);

			// Wait for a key-press
			while( read(0, &key, 1) == 0);
			// Purge unread characters
			tcflush(0, TCIFLUSH);
		}

		// Set up the primary display mode
		ret = drmModeSetCrtc(gfx_fd, curr_connector.crtc, prim_fb_id,
				     0, 0, &curr_connector.id, 1, &curr_connector.mode);
		if (ret != 0) {
			printf("Failed to set mode (%dx%d@%dHz): %s\n",
				prim_width, prim_height, curr_connector.mode.vrefresh,
				strerror(errno));
			continue;
		}

		// Set the sprite colorkey state
		for(i = 0; i < sprite_plane_count; i++) {
			set.plane_id = sprite_plane_id[i];
			set.min_value = 0;
			set.max_value = 0;
			set.flags = I915_SET_COLORKEY_NONE;
			ret = drmCommandWrite(gfx_fd, DRM_I915_SET_SPRITE_COLORKEY, &set,
					      sizeof(set));
			assert(ret == 0);
		}

		// Set up sprite output dimensions, initial position, etc.
		if (out_w > prim_width / 2)
			out_w = prim_width / 2;
		if (out_h > prim_height / 2)
			out_h = prim_height / 2;

		delta_x = (int *) malloc(sprite_plane_count * sizeof(int));
		delta_y = (int *) malloc(sprite_plane_count * sizeof(int));
		sprite_x = (int *) malloc(sprite_plane_count * sizeof(int));
		sprite_y = (int *) malloc(sprite_plane_count * sizeof(int));

		/* Initializing the coordinates (x,y) of the available sprites on the
		 * connector, equally spaced along the diagonal of the rectangle
		 * {(0,0),(prim_width/2, prim_height/2)}.
		 */
		for(i = 0; i < sprite_plane_count; i++) {
			delta_x[i] = 3;
			delta_y[i] = 4;
			sprite_x[i] = i * (prim_width / (2 * sprite_plane_count));
			sprite_y[i] = i * (prim_height / (2 * sprite_plane_count));
		}

		currTime = 0;
		prevFlipTime = 0;       // Will force immediate sprite flip
		prevMoveTime = 0;       // Will force immediate sprite move
		deltaFlipTime = 500000; // Flip sprite surface every 1/2 second
		deltaMoveTime = 100000; // Move sprite every 100 ms
		sprite_index = num_surfaces - 1;
		keep_moving = 1;

		// Bounce sprite off the walls
		while (keep_moving) {
			// Obtain system time in usec.
			if (gettimeofday( &stTimeVal, NULL ) != 0)
				printf("gettimeofday error: %s\n", strerror(errno));
			else
				currTime = ((long long)stTimeVal.tv_sec * 1000000) + stTimeVal.tv_usec;

			// Check if it's time to flip the sprite surface
			if (currTime - prevFlipTime > deltaFlipTime) {
				sprite_index = (sprite_index + 1) % num_surfaces;

				prevFlipTime = currTime;
			}

			// Move the sprite on the screen and flip
			// the surface if the index has changed
			// NB: sprite_w and sprite_h must be 16.16 fixed point, herego << 16
			for(i = 0; i < sprite_plane_count; i++) {
				if (drmModeSetPlane(gfx_fd, sprite_plane_id[i],
						    curr_connector.crtc,
						    sprite_fb_id[sprite_index],
						    plane_flags,
						    sprite_x[i], sprite_y[i],
						    out_w, out_h,
						    0, 0,
						    sprite_w << 16, sprite_h << 16))
					printf("Failed to enable sprite plane: %s\n",
						strerror(errno));
			}

			// Check if it's time to move the sprite surface
			if (currTime - prevMoveTime > deltaMoveTime)  {

				// Compute the next position for sprite
				for(i = 0; i < sprite_plane_count; i++) {
					sprite_x[i] += delta_x[i];
					sprite_y[i] += delta_y[i];
					if (sprite_x[i] < 0) {
						sprite_x[i] = 0;
						delta_x[i] = -delta_x[i];
					}
					else if (sprite_x[i] > prim_width - out_w) {
						sprite_x[i] = prim_width - out_w;
						delta_x[i] = -delta_x[i];
					}

					if (sprite_y[i] < 0) {
						sprite_y[i] = 0;
						delta_y[i] = -delta_y[i];
					}
					else if (sprite_y[i] > prim_height - out_h) {
						sprite_y[i] = prim_height - out_h;
						delta_y[i] = -delta_y[i];
					}
				}
				prevMoveTime = currTime;
			}

			// Fetch a key from input (non-blocking)
			if (read(0, &key, 1) == 1) {
				switch (key) {
				case 'q':       // Kill the program
				case 'Q':
					goto out;
					break;
				case 's':       // Slow down sprite movement;
					deltaMoveTime = (deltaMoveTime * 100) / 90;
					if (deltaMoveTime > 800000) {
						deltaMoveTime = 800000;
					}
					break;
				case 'S':       // Speed up sprite movement;
					deltaMoveTime = (deltaMoveTime * 100) / 110;
					if (deltaMoveTime < 2000) {
						deltaMoveTime = 2000;
					}
					break;
				case 'f':       // Slow down sprite flipping;
					deltaFlipTime = (deltaFlipTime * 100) / 90;
					if (deltaFlipTime > 1000000)
						deltaFlipTime = 1000000;
					break;
				case 'F':       // Speed up sprite flipping;
					deltaFlipTime = (deltaFlipTime * 100) / 110;
					if (deltaFlipTime < 20000)
						deltaFlipTime = 20000;
					break;
				case 'n':       // Next connector
				case 'N':
					keep_moving = 0;
					break;
				default:
					break;
				}

				// Purge unread characters
				tcflush(0, TCIFLUSH);
			}

			// Wait for min of flip or move deltas
			SleepTime = (deltaFlipTime < deltaMoveTime) ?
				deltaFlipTime : deltaMoveTime;
			usleep(SleepTime);
		}

		free(sprite_plane_id);
		free(sprite_x);
		free(sprite_y);
		free(delta_x);
		free(delta_y);
		sprite_plane_id = NULL;
		sprite_plane_count = 0;
		sprite_x = sprite_y = delta_x = delta_y = NULL;
	}

out:
	// Purge unread characters
	tcflush(0, TCIFLUSH);
	// Restore previous terminal settings
	if (tcsetattr( 0, TCSANOW, &orig_term) != 0) {
		printf("tcgetattr failure: %s\n", strerror(errno));
		return;
	}

	drmModeFreeResources(gfx_resources);
}
Пример #20
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;
}
Пример #21
0
static struct pipe_screen *
radeon_hardpipe_screen_create(void)
{
   Display *dpy;
   Window rootWin;
   XWindowAttributes winAttr;
   int isCapable;
   int screen;
   char *driverName;
   char *curBusID;
   unsigned magic;
   int ddxDriverMajor;
   int ddxDriverMinor;
   int ddxDriverPatch;
   drm_handle_t sAreaOffset;
   int ret;
   int drmFD;
   drm_context_t hHWContext;
   XID id;

   dpy = XOpenDisplay(":0");
   if (!dpy) {
      fprintf(stderr, "Open Display Failed\n");
      return NULL;
   }

   screen = DefaultScreen(dpy);
   rootWin = RootWindow(dpy, screen);
   XGetWindowAttributes(dpy, rootWin, &winAttr);

   ret = uniDRIQueryDirectRenderingCapable(dpy, screen, &isCapable);
   if (!ret || !isCapable) {
      fprintf(stderr, "No DRI on this display:sceen\n");
      goto error;
   }

   if (!uniDRIOpenConnection(dpy, screen, &sAreaOffset,
                             &curBusID)) {
      fprintf(stderr, "Could not open DRI connection.\n");
      goto error;
   }

   if (!uniDRIGetClientDriverName(dpy, screen, &ddxDriverMajor,
                                  &ddxDriverMinor, &ddxDriverPatch,
                                  &driverName)) {
      fprintf(stderr, "Could not get DRI driver name.\n");
      goto error;
   }

   if ((drmFD = drmOpen(NULL, curBusID)) < 0) {
      perror("DRM Device could not be opened");
      goto error;
   }

   drmGetMagic(drmFD, &magic);
   if (!uniDRIAuthConnection(dpy, screen, magic)) {
      fprintf(stderr, "Could not get X server to authenticate us.\n");
      goto error;
   }

   if (!uniDRICreateContext(dpy, screen, winAttr.visual,
                            &id, &hHWContext)) {
      fprintf(stderr, "Could not create DRI context.\n");
      goto error;
   }

   /* FIXME: create a radeon pipe_screen from drmFD and hHWContext */

   return NULL;
   
error:
   return NULL;
}
Пример #22
0
int
main()
{
	int fd, fd2;
	int result;
	int ret;
	int i;
	
        fd = drmOpen("pscnv", 0);
        fd2 = drmOpen("pscnv", 0);

	if (fd == -1 || fd2 == -1)
		return 1;

	uint32_t size = 0x2000;
	uint32_t handle;
	uint64_t map_handle;
	ret = pscnv_gem_new(fd, 0xf1f0c0de, PSCNV_GEM_VRAM_SMALL, 0, size, 0, &handle, &map_handle);
	if (ret) {
		printf("new: failed ret = %d\n", ret);
		return 1;
	}
	printf("new: handle %d map %llx\n", handle, map_handle);

	uint32_t *pb_map = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, map_handle);
	printf ("Mapped at %p\n", pb_map);

	uint32_t vid;
	ret = pscnv_vspace_new(fd, &vid);
	if (ret) {
		printf("vnew: failed ret = %d\n", ret);
		return 1;
	}
	printf ("VID %d\n", vid);

	uint32_t cid;
	uint64_t ch_map_handle;
	ret = pscnv_chan_new(fd, vid, &cid, &ch_map_handle);
	if (ret) {
		printf("cnew: failed ret = %d\n", ret);
		return 1;
	}
	printf ("CID %d %llx\n", cid, ch_map_handle);

	uint64_t offset;
	ret = pscnv_vspace_map(fd, vid, handle, 0x4001000, 1ull << 32, 0, 0, &offset);
	if (ret) {
		printf("vmap: failed ret = %d\n", ret);
		return 1;
	}
	printf ("vmap at %llx\n", offset);

	ret = pscnv_fifo_init_ib(fd, cid, 0xbeef, 0, 1, offset, 3);
	if (ret) {
		printf("fifo_init: failed ret = %d\n", ret);
		return 1;
	}

	volatile uint32_t *chmap = mmap(0, 0x1000, PROT_READ | PROT_WRITE, MAP_SHARED, fd, ch_map_handle);
	if ((void *)chmap == MAP_FAILED) {
		perror("mmap");
		return 1;
	}
	printf ("Mapped at %p\n", chmap);

	pb_map[0] = offset+0x100;
	pb_map[1] = 0x0800;
	
	pb_map[0x40] = 0x20010014;
	pb_map[0x41] = 0xdeadbeef;

	chmap[0x8c/4] = 1;

	while (chmap[0x48/4] != 0xdeadbeef);

	for (i = 0x40; i < 0x90; i+= 4) {
		printf ("%03x: %08x\n", i, chmap[i/4]);
	}

        close (fd);
        close (fd2);
        
        return 0;
}
Пример #23
0
static Bool
PreInit(ScrnInfoPtr pScrn, int flags)
{
    modesettingPtr ms;
    rgb defaultWeight = { 0, 0, 0 };
    EntityInfoPtr pEnt;
    EntPtr msEnt = NULL;
    char *BusID = NULL;
    const char *devicename;
    Bool prefer_shadow = TRUE;
    uint64_t value = 0;
    int ret;
    int bppflags;
    int defaultdepth, defaultbpp;

    if (pScrn->numEntities != 1)
	return FALSE;

    pEnt = xf86GetEntityInfo(pScrn->entityList[0]);

    if (flags & PROBE_DETECT) {
	return FALSE;
    }

    /* Allocate driverPrivate */
    if (!GetRec(pScrn))
	return FALSE;

    ms = modesettingPTR(pScrn);
    ms->SaveGeneration = -1;
    ms->pEnt = pEnt;

    pScrn->displayWidth = 640;	       /* default it */

    /* Allocate an entity private if necessary */
    if (xf86IsEntityShared(pScrn->entityList[0])) {
	msEnt = xf86GetEntityPrivate(pScrn->entityList[0],
				     modesettingEntityIndex)->ptr;
	ms->entityPrivate = msEnt;
    } else
	ms->entityPrivate = NULL;

    if (xf86IsEntityShared(pScrn->entityList[0])) {
	if (xf86IsPrimInitDone(pScrn->entityList[0])) {
	    /* do something */
	} else {
	    xf86SetPrimInitDone(pScrn->entityList[0]);
	}
    }

    pScrn->monitor = pScrn->confScreen->monitor;
    pScrn->progClock = TRUE;
    pScrn->rgbBits = 8;

#if XSERVER_PLATFORM_BUS
    if (pEnt->location.type == BUS_PLATFORM) {
#ifdef XF86_PDEV_SERVER_FD
        if (pEnt->location.id.plat->flags & XF86_PDEV_SERVER_FD)
            ms->fd = xf86_get_platform_device_int_attrib(pEnt->location.id.plat, ODEV_ATTRIB_FD, -1);
        else
#endif
        {
            char *path = xf86_get_platform_device_attrib(pEnt->location.id.plat, ODEV_ATTRIB_PATH);
            ms->fd = open_hw(path);
        }
    }
    else 
#endif
    if (pEnt->location.type == BUS_PCI) {
        ms->PciInfo = xf86GetPciInfoForEntity(ms->pEnt->index);
        if (ms->PciInfo) {
            BusID = malloc(64);
            sprintf(BusID, "PCI:%d:%d:%d",
#if XSERVER_LIBPCIACCESS
                    ((ms->PciInfo->domain << 8) | ms->PciInfo->bus),
                    ms->PciInfo->dev, ms->PciInfo->func
#else
                    ((pciConfigPtr) ms->PciInfo->thisCard)->busnum,
                    ((pciConfigPtr) ms->PciInfo->thisCard)->devnum,
                    ((pciConfigPtr) ms->PciInfo->thisCard)->funcnum
#endif
                );
        }
        ms->fd = drmOpen(NULL, BusID);
    } else {
        devicename = xf86FindOptionValue(ms->pEnt->device->options, "kmsdev");
        ms->fd = open_hw(devicename);
    }
    if (ms->fd < 0)
	return FALSE;

    ms->drmmode.fd = ms->fd;

#ifdef MODESETTING_OUTPUT_SLAVE_SUPPORT
    pScrn->capabilities = 0;
#ifdef DRM_CAP_PRIME
    ret = drmGetCap(ms->fd, DRM_CAP_PRIME, &value);
    if (ret == 0) {
        if (value & DRM_PRIME_CAP_IMPORT)
            pScrn->capabilities |= RR_Capability_SinkOutput;
    }
#endif
#endif
    drmmode_get_default_bpp(pScrn, &ms->drmmode, &defaultdepth, &defaultbpp);
    if (defaultdepth == 24 && defaultbpp == 24)
	    bppflags = SupportConvert32to24 | Support24bppFb;
    else
	    bppflags = PreferConvert24to32 | SupportConvert24to32 | Support32bppFb;
    
    if (!xf86SetDepthBpp
	(pScrn, defaultdepth, defaultdepth, defaultbpp, bppflags))
	return FALSE;

    switch (pScrn->depth) {
    case 15:
    case 16:
    case 24:
	break;
    default:
	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
		   "Given depth (%d) is not supported by the driver\n",
		   pScrn->depth);
	return FALSE;
    }
    xf86PrintDepthBpp(pScrn);

    /* Process the options */
    xf86CollectOptions(pScrn, NULL);
    if (!(ms->Options = malloc(sizeof(Options))))
	return FALSE;
    memcpy(ms->Options, Options, sizeof(Options));
    xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, ms->Options);

    if (!xf86SetWeight(pScrn, defaultWeight, defaultWeight))
	return FALSE;
    if (!xf86SetDefaultVisual(pScrn, -1))
	return FALSE;

    if (xf86ReturnOptValBool(ms->Options, OPTION_SW_CURSOR, FALSE)) {
	ms->drmmode.sw_cursor = TRUE;
    }

    ret = drmGetCap(ms->fd, DRM_CAP_DUMB_PREFER_SHADOW, &value);
    if (!ret) {
	prefer_shadow = !!value;
    }

    ms->cursor_width = 64;
    ms->cursor_height = 64;
    ret = drmGetCap(ms->fd, DRM_CAP_CURSOR_WIDTH, &value);
    if (!ret) {
	ms->cursor_width = value;
    }
    ret = drmGetCap(ms->fd, DRM_CAP_CURSOR_HEIGHT, &value);
    if (!ret) {
	ms->cursor_height = value;
    }

    ms->drmmode.shadow_enable = xf86ReturnOptValBool(ms->Options, OPTION_SHADOW_FB, prefer_shadow);

    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ShadowFB: preferred %s, enabled %s\n", prefer_shadow ? "YES" : "NO", ms->drmmode.shadow_enable ? "YES" : "NO");
    if (drmmode_pre_init(pScrn, &ms->drmmode, pScrn->bitsPerPixel / 8) == FALSE) {
	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "KMS setup failed\n");
	goto fail;
    }

    /*
     * If the driver can do gamma correction, it should call xf86SetGamma() here.
     */
    {
	Gamma zeros = { 0.0, 0.0, 0.0 };

	if (!xf86SetGamma(pScrn, zeros)) {
	    return FALSE;
	}
    }

    if (pScrn->modes == NULL) {
	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No modes.\n");
	return FALSE;
    }

    pScrn->currentMode = pScrn->modes;

    /* Set display resolution */
    xf86SetDpi(pScrn, 0, 0);

    /* Load the required sub modules */
    if (!xf86LoadSubModule(pScrn, "fb")) {
	return FALSE;
    }

    if (ms->drmmode.shadow_enable) {
	if (!xf86LoadSubModule(pScrn, "shadow")) {
	    return FALSE;
	}
    }

    return TRUE;
    fail:
    return FALSE;
}
Пример #24
0
static int init_drm(void)
{
        static const char *modules[] = {
                        "omapdrm", "i915", "radeon", "nouveau", "vmwgfx", "exynos"
        };
        drmModeRes *resources;
        drmModeConnector *connector = NULL;
        drmModeEncoder *encoder = NULL;
        int i, j;
        uint32_t maxRes, curRes;

        for (i = 0; i < ARRAY_SIZE(modules); i++) {
                printf("trying to load module %s...", modules[i]);
                drm.fd = drmOpen(modules[i], NULL);
                if (drm.fd < 0) {
                        printf("failed.\n");
                } else {
                        printf("success.\n");
                        break;
                }
        }

        if (drm.fd < 0) {
                printf("could not open drm device\n");
                return -1;
        }

        resources = drmModeGetResources(drm.fd);
        if (!resources) {
                printf("drmModeGetResources failed: %s\n", strerror(errno));
                return -1;
        }
        drm.resource_id = (uint32_t) resources;

        /* find a connected connector: */
        for (i = 0; i < resources->count_connectors; i++) {
                connector = drmModeGetConnector(drm.fd, resources->connectors[i]);
                if (connector->connection == DRM_MODE_CONNECTED) {
                        /* choose the first supported mode */
                        drm.mode[drm.ndisp] = &connector->modes[0];
                        drm.connector_id[drm.ndisp] = connector->connector_id;

                        for (j=0; j<resources->count_encoders; j++) {
                                encoder = drmModeGetEncoder(drm.fd, resources->encoders[j]);
                                if (encoder->encoder_id == connector->encoder_id)
                                        break;

                                drmModeFreeEncoder(encoder);
                                encoder = NULL;
                        }

                        if (!encoder) {
                                printf("no encoder!\n");
                                return -1;
                        }

                        drm.encoder[drm.ndisp]  = (uint32_t) encoder;
                        drm.crtc_id[drm.ndisp] = encoder->crtc_id;
                        drm.connectors[drm.ndisp] = connector;

                        printf("### Display [%d]: CRTC = %d, Connector = %d\n", drm.ndisp, drm.crtc_id[drm.ndisp], drm.connector_id[drm.ndisp]);
                        printf("\tMode chosen [%s] : Clock => %d, Vertical refresh => %d, Type => %d\n", drm.mode[drm.ndisp]->name, drm.mode[drm.ndisp]->clock, drm.mode[drm.ndisp]->vrefresh, drm.mode[drm.ndisp]->type);
                        printf("\tHorizontal => %d, %d, %d, %d, %d\n", drm.mode[drm.ndisp]->hdisplay, drm.mode[drm.ndisp]->hsync_start, drm.mode[drm.ndisp]->hsync_end, drm.mode[drm.ndisp]->htotal, drm.mode[drm.ndisp]->hskew);
                        printf("\tVertical => %d, %d, %d, %d, %d\n", drm.mode[drm.ndisp]->vdisplay, drm.mode[drm.ndisp]->vsync_start, drm.mode[drm.ndisp]->vsync_end, drm.mode[drm.ndisp]->vtotal, drm.mode[drm.ndisp]->vscan);

                        /* If a connector_id is specified, use the corresponding display */
                        if ((connector_id != -1) && (connector_id == (int)drm.connector_id[drm.ndisp]))
                                DISP_ID = drm.ndisp;

                        /* If all displays are enabled, choose the connector with maximum
                        * resolution as the primary display */
                        if (all_display) {
                                maxRes = drm.mode[DISP_ID]->vdisplay * drm.mode[DISP_ID]->hdisplay;
                                curRes = drm.mode[drm.ndisp]->vdisplay * drm.mode[drm.ndisp]->hdisplay;

                                if (curRes > maxRes)
                                        DISP_ID = drm.ndisp;
                        }

                        drm.ndisp++;
                } else {
                        drmModeFreeConnector(connector);
                }
        }

        if (drm.ndisp == 0) {
                /* we could be fancy and listen for hotplug events and wait for
                 * a connector..
                 */
                printf("no connected connector!\n");
                return -1;
        }

        return 0;
}
Пример #25
0
static gboolean
gst_kms_sink_start (GstBaseSink * bsink)
{
  GstKMSSink *self;
  drmModeRes *res;
  drmModeConnector *conn;
  drmModeCrtc *crtc;
  drmModePlaneRes *pres;
  drmModePlane *plane;
  gboolean universal_planes;
  gboolean ret;

  self = GST_KMS_SINK (bsink);
  universal_planes = FALSE;
  ret = FALSE;
  res = NULL;
  conn = NULL;
  crtc = NULL;
  pres = NULL;
  plane = NULL;

  if (self->devname)
    self->fd = drmOpen (self->devname, NULL);
  else
    self->fd = kms_open (&self->devname);
  if (self->fd < 0)
    goto open_failed;

  log_drm_version (self);
  if (!get_drm_caps (self))
    goto bail;

  res = drmModeGetResources (self->fd);
  if (!res)
    goto resources_failed;

  if (self->conn_id == -1)
    conn = find_main_monitor (self->fd, res);
  else
    conn = drmModeGetConnector (self->fd, self->conn_id);
  if (!conn)
    goto connector_failed;

  crtc = find_crtc_for_connector (self->fd, res, conn, &self->pipe);
  if (!crtc)
    goto crtc_failed;

retry_find_plane:
  if (universal_planes &&
      drmSetClientCap (self->fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1))
    goto set_cap_failed;

  pres = drmModeGetPlaneResources (self->fd);
  if (!pres)
    goto plane_resources_failed;

  if (self->plane_id == -1)
    plane = find_plane_for_crtc (self->fd, res, pres, crtc->crtc_id);
  else
    plane = drmModeGetPlane (self->fd, self->plane_id);
  if (!plane)
    goto plane_failed;

  /* let's get the available color formats in plane */
  if (!ensure_allowed_caps (self, plane, res))
    goto bail;

  self->conn_id = conn->connector_id;
  self->crtc_id = crtc->crtc_id;
  self->plane_id = plane->plane_id;

  GST_INFO_OBJECT (self, "connector id = %d / crtc id = %d / plane id = %d",
      self->conn_id, self->crtc_id, self->plane_id);

  self->hdisplay = crtc->mode.hdisplay;
  self->vdisplay = crtc->mode.vdisplay;
  self->buffer_id = crtc->buffer_id;

  self->mm_width = conn->mmWidth;
  self->mm_height = conn->mmHeight;

  GST_INFO_OBJECT (self, "display size: pixels = %dx%d / millimeters = %dx%d",
      self->hdisplay, self->vdisplay, self->mm_width, self->mm_height);

  self->pollfd.fd = self->fd;
  gst_poll_add_fd (self->poll, &self->pollfd);
  gst_poll_fd_ctl_read (self->poll, &self->pollfd, TRUE);

  ret = TRUE;

bail:
  if (plane)
    drmModeFreePlane (plane);
  if (pres)
    drmModeFreePlaneResources (pres);
  if (crtc)
    drmModeFreeCrtc (crtc);
  if (conn)
    drmModeFreeConnector (conn);
  if (res)
    drmModeFreeResources (res);

  if (!ret && self->fd >= 0) {
    drmClose (self->fd);
    self->fd = -1;
  }

  return ret;

  /* ERRORS */
open_failed:
  {
    GST_ERROR_OBJECT (self, "Could not open DRM module %s: %s",
        GST_STR_NULL (self->devname), strerror (errno));
    return FALSE;
  }

resources_failed:
  {
    GST_ERROR_OBJECT (self, "drmModeGetResources failed: %s (%d)",
        strerror (errno), errno);
    goto bail;
  }

connector_failed:
  {
    GST_ERROR_OBJECT (self, "Could not find a valid monitor connector");
    goto bail;
  }

crtc_failed:
  {
    GST_ERROR_OBJECT (self, "Could not find a crtc for connector");
    goto bail;
  }

set_cap_failed:
  {
    GST_ERROR_OBJECT (self, "Could not set universal planes capability bit");
    goto bail;
  }

plane_resources_failed:
  {
    GST_ERROR_OBJECT (self, "drmModeGetPlaneResources failed: %s (%d)",
        strerror (errno), errno);
    goto bail;
  }

plane_failed:
  {
    if (universal_planes) {
      GST_ERROR_OBJECT (self, "Could not find a plane for crtc");
      goto bail;
    } else {
      universal_planes = TRUE;
      goto retry_find_plane;
    }
  }
}
Пример #26
0
int main(int argc, char **argv)
{
	unsigned i;
	int c, fd, ret;
	const char *modules[] = { "i915", "radeon", "nouveau", "vmwgfx", "exynos", "omapdrm", "tilcdc", "msm", "tegra", "imx-drm", "rockchip", "mediatek" };
	drmVBlank vbl;
	drmEventContext evctx;
	struct vbl_info handler_info;

	opterr = 0;
	while ((c = getopt(argc, argv, optstr)) != -1) {
		switch (c) {
		case 's':
			secondary = 1;
			break;
		default:
			usage(argv[0]);
			break;
		}
	}

	for (i = 0; i < ARRAY_SIZE(modules); i++) {
		printf("trying to load module %s...", modules[i]);
		fd = drmOpen(modules[i], NULL);
		if (fd < 0) {
			printf("failed.\n");
		} else {
			printf("success.\n");
			break;
		}
	}

	if (i == ARRAY_SIZE(modules)) {
		fprintf(stderr, "failed to load any modules, aborting.\n");
		return -1;
	}

	/* Get current count first */
	vbl.request.type = DRM_VBLANK_RELATIVE;
	if (secondary)
		vbl.request.type |= DRM_VBLANK_SECONDARY;
	vbl.request.sequence = 0;
	ret = drmWaitVBlank(fd, &vbl);
	if (ret != 0) {
		printf("drmWaitVBlank (relative) failed ret: %i\n", ret);
		return -1;
	}

	printf("starting count: %d\n", vbl.request.sequence);

	handler_info.vbl_count = 0;
	gettimeofday(&handler_info.start, NULL);

	/* Queue an event for frame + 1 */
	vbl.request.type = DRM_VBLANK_RELATIVE | DRM_VBLANK_EVENT;
	if (secondary)
		vbl.request.type |= DRM_VBLANK_SECONDARY;
	vbl.request.sequence = 1;
	vbl.request.signal = (unsigned long)&handler_info;
	ret = drmWaitVBlank(fd, &vbl);
	if (ret != 0) {
		printf("drmWaitVBlank (relative, event) failed ret: %i\n", ret);
		return -1;
	}

	/* Set up our event handler */
	memset(&evctx, 0, sizeof evctx);
	evctx.version = DRM_EVENT_CONTEXT_VERSION;
	evctx.vblank_handler = vblank_handler;
	evctx.page_flip_handler = NULL;

	/* Poll for events */
	while (1) {
		struct timeval timeout = { .tv_sec = 3, .tv_usec = 0 };
		fd_set fds;
		int ret;

		FD_ZERO(&fds);
		FD_SET(0, &fds);
		FD_SET(fd, &fds);
		ret = select(fd + 1, &fds, NULL, NULL, &timeout);

		if (ret <= 0) {
			fprintf(stderr, "select timed out or error (ret %d)\n",
				ret);
			continue;
		} else if (FD_ISSET(0, &fds)) {
			break;
		}

		ret = drmHandleEvent(fd, &evctx);
		if (ret != 0) {
			printf("drmHandleEvent failed: %i\n", ret);
			return -1;
		}
	}

	return 0;
}
Пример #27
0
static int callCompute_Linux()
{
    Mx_Compute *compute = NULL;
    int drmFd = 0;
    struct omap_device *dev = NULL;
    struct omap_bo *compute_bo = NULL;
    struct omap_bo *inBuf_bo = NULL;
    struct omap_bo *outBuf_bo = NULL;
    uint32_t * inBufPtr = NULL;
    uint32_t * outBufPtr = NULL;
    int status = 0;
    int size;
    uint32_t val;
    int i;
    int32_t ret;

    /* On Linux, use omapdrm driver to get a Tiler buffer for shared memory */
    drmFd = drmOpen("omapdrm", NULL);

    if (drmFd < 0) {
        fprintf(stderr, "could not open omapdrm device: %d: %s\n",
                         errno, strerror(errno));
        return 1;
    }

    dev = omap_device_new(drmFd);
    if (!dev) {
        fprintf(stderr, "could not get device from fd\n");
        goto leave;
    }

    /* allocate a compute structure in shared memory and get a pointer */
    compute_bo = omap_bo_new(dev, sizeof(Mx_Compute), OMAP_BO_CACHED);
    if (compute_bo) {
        compute = (Mx_Compute *)omap_bo_map(compute_bo);
    }
    else {
        fprintf(stderr, "failed to allocate omap_bo\n");
    }

    if (compute == NULL) {
        fprintf(stderr, "failed to map omap_bo to user space\n");
        goto leave;
    }

    /* initialize compute structure */
    compute->coef = 0x80400000;
    compute->key = 0xABA0;
    compute->size = 0x1000;
    compute->inBuf = NULL;
    compute->outBuf = NULL;

    /* allocate an input buffer in shared memory */
    size = compute->size * sizeof(uint32_t);
    inBuf_bo = omap_bo_new(dev, size, OMAP_BO_CACHED);
    if (inBuf_bo) {
        inBufPtr = (uint32_t *)omap_bo_map(inBuf_bo);
    }
    else {
        fprintf(stderr, "failed to allocate inBuf_bo\n");
    }

    if (inBufPtr == NULL) {
        printf("mmrpc_test: Error: inBufPtr == NULL\n");
        status = -1;
        goto leave;
    }

    /* fill input buffer with seed value */
    for (i = 0; i < compute->size; i++) {
        inBufPtr[i] = 0x2010;
    }

    /* allocate an output buffer in shared memory */
    outBuf_bo = omap_bo_new(dev, size, OMAP_BO_CACHED);
    if (outBuf_bo) {
        outBufPtr = (uint32_t *)omap_bo_map(outBuf_bo);
    }
    else {
        fprintf(stderr, "failed to allocate outBuf_bo handle\n");
    }

    if (outBufPtr == NULL) {
        printf("mmrpc_test: Error: outBufPtr == NULL\n");
        status = -1;
        goto leave;
    }

    /* clear output buffer */
    for (i = 0; i < compute->size; i++) {
        outBufPtr[i] = 0;
    }

    compute->inBuf = (uint32_t *)inBufPtr;
    compute->outBuf = (uint32_t *)outBufPtr;

    /* print some debug info */
    printf("mmrpc_test: calling Mx_compute(0x%x)\n", (unsigned int)compute);
    printf("mmrpc_test: compute->coef=0x%x\n", compute->coef);
    printf("mmrpc_test: compute->key=0x%x\n", compute->key);
    printf("mmrpc_test: compute->size=0x%x\n", compute->size);
    printf("mmrpc_test: compute->inBuf=0x%x\n", (unsigned int)compute->inBuf);
    printf("mmrpc_test: compute->outBuf=0x%x\n", (unsigned int)compute->outBuf);

    /* process the buffer */
    ret = Mx_compute_Linux(compute, omap_bo_dmabuf(compute_bo),
                                    omap_bo_dmabuf(inBuf_bo),
                                    omap_bo_dmabuf(outBuf_bo));

    if (ret < 0) {
        status = -1;
        printf("mmrpc_test: Error: Mx_Compute() failed\n");
        goto leave;
    }

    printf("mmrpc_test: after Mx_compute(0x%x)\n", (unsigned int)compute);
    printf("mmrpc_test: compute->coef=0x%x\n", compute->coef);
    printf("mmrpc_test: compute->key=0x%x\n", compute->key);
    printf("mmrpc_test: compute->size=0x%x\n", compute->size);
    printf("mmrpc_test: compute->inBuf=0x%x\n", (unsigned int)compute->inBuf);
    printf("mmrpc_test: compute->outBuf=0x%x\n", (unsigned int)compute->outBuf);
    printf("mmrpc_test: compute->inBuf[0]=0x%x\n",
            (unsigned int)compute->inBuf[0]);
    printf("mmrpc_test: compute->outBuf[0]=0x%x\n",
            (unsigned int)compute->outBuf[0]);

    /* check the output buffer */
    for (i = 0; i < compute->size; i++) {
        val = outBufPtr[i] | compute->coef;
        if (outBufPtr[i] != val) {
            status = -1;
            printf("mmrpc_test: Error: incorrect outBuf\n");
            break;
        }
    }

leave:
    if (outBuf_bo) {
        omap_bo_del(outBuf_bo);
    }
    if (inBuf_bo) {
        omap_bo_del(inBuf_bo);
    }
    if (compute_bo) {
        omap_bo_del(compute_bo);
    }
    if (dev) {
        omap_device_del(dev);
    }
    if (drmFd) {
        close(drmFd);
    }

    return (status);
}
int main(int argc, char *argv[])
{
	int ret;
	struct setup s;

	ret = parse_args(argc, argv, &s);
	BYE_ON(ret, "failed to parse arguments\n");
	BYE_ON(s.module[0] == 0, "DRM module is missing\n");
	BYE_ON(s.video[0] == 0, "video node is missing\n");

	int drmfd = drmOpen(s.module, NULL);
	BYE_ON(drmfd < 0, "drmOpen(%s) failed: %s\n", s.module, ERRSTR);

	int v4lfd = open(s.video, O_RDWR);
	BYE_ON(v4lfd < 0, "failed to open %s: %s\n", s.video, ERRSTR);

	struct v4l2_capability caps;
	memset(&caps, 0, sizeof caps);

	ret = ioctl(v4lfd, VIDIOC_QUERYCAP, &caps);
	BYE_ON(ret, "VIDIOC_QUERYCAP failed: %s\n", ERRSTR);

	/* TODO: add single plane support */
	BYE_ON(~caps.capabilities & V4L2_CAP_VIDEO_CAPTURE,
		"video: singleplanar capture is not supported\n");

	struct v4l2_format fmt;
	memset(&fmt, 0, sizeof fmt);
	fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

	ret = ioctl(v4lfd, VIDIOC_G_FMT, &fmt);
	BYE_ON(ret < 0, "VIDIOC_G_FMT failed: %s\n", ERRSTR);
	printf("G_FMT(start): width = %u, height = %u, 4cc = %.4s\n",
		fmt.fmt.pix.width, fmt.fmt.pix.height,
		(char*)&fmt.fmt.pix.pixelformat);

	if (s.use_wh) {
		fmt.fmt.pix.width = s.w;
		fmt.fmt.pix.height = s.h;
	}
	if (s.in_fourcc)
		fmt.fmt.pix.pixelformat = s.in_fourcc;

	ret = ioctl(v4lfd, VIDIOC_S_FMT, &fmt);
	BYE_ON(ret < 0, "VIDIOC_S_FMT failed: %s\n", ERRSTR);

	ret = ioctl(v4lfd, VIDIOC_G_FMT, &fmt);
	BYE_ON(ret < 0, "VIDIOC_G_FMT failed: %s\n", ERRSTR);
	printf("G_FMT(final): width = %u, height = %u, 4cc = %.4s\n",
		fmt.fmt.pix.width, fmt.fmt.pix.height,
		(char*)&fmt.fmt.pix.pixelformat);

	struct v4l2_requestbuffers rqbufs;
	memset(&rqbufs, 0, sizeof(rqbufs));
	rqbufs.count = s.buffer_count;
	rqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
	rqbufs.memory = V4L2_MEMORY_DMABUF;

	ret = ioctl(v4lfd, VIDIOC_REQBUFS, &rqbufs);
	BYE_ON(ret < 0, "VIDIOC_REQBUFS failed: %s\n", ERRSTR);
	BYE_ON(rqbufs.count < s.buffer_count, "video node allocated only "
		"%u of %u buffers\n", rqbufs.count, s.buffer_count);

	s.in_fourcc = fmt.fmt.pix.pixelformat;
	s.w = fmt.fmt.pix.width;
	s.h = fmt.fmt.pix.height;

	/* TODO: add support for multiplanar formats */
	struct buffer buffer[s.buffer_count];
	uint32_t size = fmt.fmt.pix.sizeimage;
	uint32_t pitch = fmt.fmt.pix.bytesperline;
	printf("size = %u pitch = %u\n", size, pitch);
	for (unsigned int i = 0; i < s.buffer_count; ++i) {
		ret = buffer_create(&buffer[i], drmfd, &s, size, pitch);
		BYE_ON(ret, "failed to create buffer%d\n", i);
	}
	printf("buffers ready\n");

	/*drmModeModeInfo drmmode;
	uint32_t con;
	ret = find_mode(&drmmode, drmfd, &s, &con);
	BYE_ON(ret, "failed to find valid mode\n");

	ret = find_plane(drmfd, &s);
	BYE_ON(ret, "failed to find compatible plane\n");*/

	for (unsigned int i = 0; i < s.buffer_count; ++i) {
		struct v4l2_buffer buf;
		memset(&buf, 0, sizeof buf);

		buf.index = i;
		buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
		buf.memory = V4L2_MEMORY_DMABUF;
		buf.m.fd = buffer[i].dbuf_fd;
		ret = ioctl(v4lfd, VIDIOC_QBUF, &buf);
		BYE_ON(ret < 0, "VIDIOC_QBUF for buffer %d failed: %s (fd %u)\n",
			buf.index, ERRSTR, buffer[i].dbuf_fd);
	}

	int type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
	ret = ioctl(v4lfd, VIDIOC_STREAMON, &type);
	BYE_ON(ret < 0, "STREAMON failed: %s\n", ERRSTR);

	struct pollfd fds[] = {
		{ .fd = v4lfd, .events = POLLIN },
		{ .fd = drmfd, .events = POLLIN },
Пример #29
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;
}
Пример #30
0
static bool
load_driver (ply_renderer_backend_t *backend)
{
  char *driver_name;
  int device_fd;

  driver_name = find_driver_for_device (backend->device_name);
  ply_trace ("Attempting to load driver '%s'", driver_name);
  device_fd = drmOpen (driver_name, NULL);

  if (device_fd < 0)
    {
      ply_trace ("drmOpen failed");
      free (driver_name);
      return false;
    }
  backend->driver_interface = NULL;

/* Try intel driver first if we're supporting the legacy GDM transition
 * since it can map the kernel console, which gives us the ability to do
 * a more seamless transition when plymouth quits before X starts
 */
#if defined(PLY_ENABLE_DEPRECATED_GDM_TRANSITION) && defined(PLY_ENABLE_LIBDRM_INTEL)
  if (backend->driver_interface == NULL && strcmp (driver_name, "i915") == 0)
    {
      backend->driver_interface = ply_renderer_i915_driver_get_interface ();
      backend->driver_supports_mapping_console = true;
    }
#endif

  if (backend->driver_interface == NULL)
    {
      backend->driver_interface = ply_renderer_generic_driver_get_interface (device_fd);
      backend->driver_supports_mapping_console = false;
    }

#ifdef PLY_ENABLE_LIBDRM_INTEL
  if (backend->driver_interface == NULL && strcmp (driver_name, "i915") == 0)
    {
      backend->driver_interface = ply_renderer_i915_driver_get_interface ();
      backend->driver_supports_mapping_console = true;
    }
#endif
#ifdef PLY_ENABLE_LIBDRM_RADEON
  if (backend->driver_interface == NULL && strcmp (driver_name, "radeon") == 0)
    {
      backend->driver_interface = ply_renderer_radeon_driver_get_interface ();
      backend->driver_supports_mapping_console = false;
    }
#endif
#ifdef PLY_ENABLE_LIBDRM_NOUVEAU
  if (backend->driver_interface == NULL && strcmp (driver_name, "nouveau") == 0)
    {
      backend->driver_interface = ply_renderer_nouveau_driver_get_interface ();
      backend->driver_supports_mapping_console = false;
    }
#endif

  free (driver_name);

  if (backend->driver_interface == NULL)
    {
#ifdef PLY_ENABLE_LIBKMS
      backend->driver_interface = ply_renderer_libkms_driver_get_interface ();
      backend->driver_supports_mapping_console = false;
#else
      close (device_fd);
      return false;
#endif
    }

  backend->driver = backend->driver_interface->create_driver (device_fd);

  if (backend->driver == NULL)
    {
      close (device_fd);
      return false;
    }

  backend->device_fd = device_fd;

  return true;
}