Skip to contentSkip to conversation

V4L2 dma-buf support test with UVC + i915 test application

DISCUSSION Laurent Pinchart 2 participants 6 messages Nov 8, 2012 – Nov 12, 2012 Media (V4L/DVB)

lore
Share & tools
lore
#0 lore raw

Hi Mauro,

Here's the application I've used to test V4L2 dma-buf support with a UVC webcam and an Intel GPU supported by the i915 driver.

The kernel code is available in my git tree at

git://linuxtv.org/pinchartl/media.git devel/dma-buf-v10

(http://git.linuxtv.org/pinchartl/media.git/shortlog/refs/heads/devel/v4l2-
clock)

Don't forget to enable dma-buf and UVC support when compiling the kernel.

The userspace code is based on the v4l2-drm-example application written by Tomasz (the original code is available at
git://git.infradead.org/users/kmpark/public-apps). I need to clean up my modifications to push them back to the repository, in the meantime the code is attached to this e-mail.

To compile the application, just run make with the KDIR variable set to the path to your Linux kernel tree with the dma-buf patches applied. Don't forget to make headers_install in the kernel tree as the Makefile will look for headers in $KDIR/usr.

You will need a recent version of libdrm with plane support available. 2.4.39 should do.

The following command line will capture VGA YUYV data from the webcam and display it on the screen. You need to run it in a console as root without the X server running.

./dmabuf-sharing -M i915 -o 7:3:1600x900 -i /dev/video0 -S 640,480 -f YUYV -F YUYV -s 640,480@0,0 -t 640,480@0,0 -b 2

Signature · 3 lines
Regards,

Laurent Pinchart

/*
* Demo application for DMA buffer sharing between V4L2 and DRM
* Tomasz Stanislawski <[email protected]>
*
* Copyright 2012 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

#include <errno.h>
#include <fcntl.h>
#include <math.h>
#include <poll.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include <drm/drm.h>
#include <drm/drm_mode.h>

#include <linux/videodev2.h>

#include <xf86drm.h>
#include <xf86drmMode.h>

#define ERRSTR strerror(errno)

#define BYE_ON(cond, ...) \

do { \
	if (cond) { \
		int errsv = errno; \
		fprintf(stderr, "ERROR(%s:%d) : ", \
			__FILE__, __LINE__); \
		errno = errsv; \
		fprintf(stderr,  __VA_ARGS__); \
		abort(); \
	} \
} while(0)

static inline int warn(const char *file, int line, const char *fmt, ...)

{
	int errsv = errno;
	va_list va;
	va_start(va, fmt);
	fprintf(stderr, "WARN(%s:%d): ", file, line);
	vfprintf(stderr, fmt, va);
	va_end(va);
	errno = errsv;
	return 1;
}
#define WARN_ON(cond, ...) \
	((cond) ? warn(__FILE__, __LINE__, __VA_ARGS__) : 0)
struct setup {
	char module[32];
	int conId;
	uint32_t crtId;
	int crtIdx;
	uint32_t planeId;
	char modestr[32];
	char video[32];
	unsigned int w, h;
	unsigned int use_wh : 1;
	unsigned int in_fourcc;
	unsigned int out_fourcc;
	unsigned int buffer_count;
	unsigned int use_crop : 1;
	unsigned int use_compose : 1;
	struct v4l2_rect crop;
	struct v4l2_rect compose;
};
struct buffer {
	unsigned int bo_handle;
	unsigned int fb_handle;
	int dbuf_fd;
};
struct stream {
	int v4lfd;
	int current_buffer;
	int buffer_count;
	struct buffer *buffer;
} stream;

static void usage(char *name)

{
	fprintf(stderr, "usage: %s [-Moisth]\n", name);
	fprintf(stderr, "\t-M <drm-module>\tset DRM module\n");
	fprintf(stderr, "\t-o <connector_id>:<crtc_id>:<mode>\tset a mode\n");
	fprintf(stderr, "\t-i <video-node>\tset video node like /dev/video*\n");
	fprintf(stderr, "\t-S <width,height>\tset input resolution\n");
	fprintf(stderr, "\t-f <fourcc>\tset input format using 4cc\n");
	fprintf(stderr, "\t-F <fourcc>\tset output format using 4cc\n");
	fprintf(stderr, "\t-s <width,height>@<left,top>\tset crop area\n");
	fprintf(stderr, "\t-t <width,height>@<left,top>\tset compose area\n");
	fprintf(stderr, "\t-b buffer_count\tset number of buffers\n");
	fprintf(stderr, "\t-h\tshow this help\n");
	fprintf(stderr, "\n\tDefault is to dump all info.\n");
}

static inline int parse_rect(char *s, struct v4l2_rect *r)

{
	return sscanf(s, "%d,%d@%d,%d", &r->width, &r->height,
		&r->top, &r->left) != 4;
}

static int parse_args(int argc, char *argv[], struct setup *s)

{
	if (argc <= 1)
		usage(argv[0]);

	int c, ret;
	memset(s, 0, sizeof(*s));

	while ((c = getopt(argc, argv, "M:o:i:S:f:F:s:t:b:h")) != -1) {
		switch (c) {
		case 'M':
			strncpy(s->module, optarg, 31);
			break;
		case 'o':
			ret = sscanf(optarg, "%u:%u:%31s", &s->conId, &s->crtId,
				s->modestr);
			if (WARN_ON(ret != 3, "incorrect mode description\n"))
				return -1;
			break;
		case 'i':
			strncpy(s->video, optarg, 31);
			break;
		case 'S':
			ret = sscanf(optarg, "%u,%u", &s->w, &s->h);
			if (WARN_ON(ret != 2, "incorrect input size\n"))
				return -1;
			s->use_wh = 1;
			break;
		case 'f':
			if (WARN_ON(strlen(optarg) != 4, "invalid fourcc\n"))
				return -1;
			s->in_fourcc = ((unsigned)optarg[0] << 0) |
				((unsigned)optarg[1] << 8) |
				((unsigned)optarg[2] << 16) |
				((unsigned)optarg[3] << 24);
			break;
		case 'F':
			if (WARN_ON(strlen(optarg) != 4, "invalid fourcc\n"))
				return -1;
			s->out_fourcc = ((unsigned)optarg[0] << 0) |
				((unsigned)optarg[1] << 8) |
				((unsigned)optarg[2] << 16) |
				((unsigned)optarg[3] << 24);
			break;
		case 's':
			ret = parse_rect(optarg, &s->crop);
			if (WARN_ON(ret, "incorrect crop area\n"))
				return -1;
			s->use_crop = 1;
			break;
		case 't':
			ret = parse_rect(optarg, &s->compose);
			if (WARN_ON(ret, "incorrect compose area\n"))
				return -1;
			s->use_compose = 1;
			break;
		case 'b':
			ret = sscanf(optarg, "%u", &s->buffer_count);
			if (WARN_ON(ret != 1, "incorrect buffer count\n"))
				return -1;
			break;
		case '?':
		case 'h':
			usage(argv[0]);
			return -1;
		}
	}

	return 0;
}

static int buffer_create(struct buffer *b, int drmfd, struct setup *s,

	uint64_t size, uint32_t pitch)
{
	struct drm_mode_create_dumb gem;
	struct drm_mode_destroy_dumb gem_destroy;
	int ret;

	memset(&gem, 0, sizeof gem);
	gem.width = s->w;
	gem.height = s->h;
	gem.bpp = 16;
	gem.size = size;
	ret = ioctl(drmfd, DRM_IOCTL_MODE_CREATE_DUMB, &gem);
	if (WARN_ON(ret, "CREATE_DUMB failed: %s\n", ERRSTR))
		return -1;
	printf("bo %u %ux%u bpp %u size %lu (%lu)\n", gem.handle, gem.width, gem.height, gem.bpp, gem.size, size);
	b->bo_handle = gem.handle;

	struct drm_prime_handle prime;
	memset(&prime, 0, sizeof prime);
	prime.handle = b->bo_handle;

	ret = ioctl(drmfd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &prime);
	if (WARN_ON(ret, "PRIME_HANDLE_TO_FD failed: %s\n", ERRSTR))
		goto fail_gem;
	printf("dbuf_fd = %d\n", prime.fd);
	b->dbuf_fd = prime.fd;

	uint32_t offsets[4] = { 0 };
	uint32_t pitches[4] = { pitch };
	uint32_t bo_handles[4] = { b->bo_handle };
	unsigned int fourcc = s->out_fourcc;
	if (!fourcc)
		fourcc = s->in_fourcc;
	ret = drmModeAddFB2(drmfd, s->w, s->h, fourcc, bo_handles,
		pitches, offsets, &b->fb_handle, 0);
	if (WARN_ON(ret, "drmModeAddFB2 failed: %s\n", ERRSTR))
		goto fail_prime;

	return 0;

fail_prime:

	close(b->dbuf_fd);

fail_gem:

	memset(&gem_destroy, 0, sizeof gem_destroy);
	gem_destroy.handle = b->bo_handle,
	ret = ioctl(drmfd, DRM_IOCTL_MODE_DESTROY_DUMB, &gem_destroy);
	WARN_ON(ret, "DESTROY_DUMB failed: %s\n", ERRSTR);

	return -1;
}

static int find_mode(drmModeModeInfo *m, int drmfd, struct setup *s,

	uint32_t *con)
{
	int ret = -1;
	int i;
	drmModeRes *res = drmModeGetResources(drmfd);
	if (WARN_ON(!res, "drmModeGetResources failed: %s\n", ERRSTR))
		return -1;

	if (WARN_ON(res->count_crtcs <= 0, "drm: no crts\n"))
		goto fail_res;

	s->crtIdx = -1;

	for (i = 0; i < res->count_crtcs; ++i) {
		if (s->crtId == res->crtcs[i]) {
			s->crtIdx = i;
			break;
		}
	}

	if (WARN_ON(s->crtIdx == -1, "drm: CRTC %u not found\n", s->crtId))
		goto fail_res;

	if (WARN_ON(res->count_connectors <= 0, "drm: no connectors\n"))
		goto fail_res;

	if (WARN_ON(s->conId >= res->count_connectors, "connector %d "
		"is not supported\n", s->conId))
		goto fail_res;

	drmModeConnector *c;
	c = drmModeGetConnector(drmfd, s->conId);
	if (WARN_ON(!c, "drmModeGetConnector failed: %s\n", ERRSTR))
		goto fail_res;

	if (WARN_ON(!c->count_modes, "connector supports no mode\n"))
		goto fail_conn;

	drmModeModeInfo *found = NULL;
	for (int i = 0; i < c->count_modes; ++i)
		if (strcmp(c->modes[i].name, s->modestr) == 0)
			found = &c->modes[i];

	if (WARN_ON(!found, "mode %s not supported\n", s->modestr)) {
		fprintf(stderr, "Valid modes:");
		for (int i = 0; i < c->count_modes; ++i)
			fprintf(stderr, " %s", c->modes[i].name);
		fprintf(stderr, "\n");
		goto fail_conn;
	}

	memcpy(m, found, sizeof *found);
	if (con)
		*con = c->connector_id;
	ret = 0;

fail_conn:

	drmModeFreeConnector(c);

fail_res:

	drmModeFreeResources(res);

	return ret;
}

static int find_plane(int drmfd, struct setup *s)

{
	drmModePlaneResPtr planes;
	drmModePlanePtr plane;
	unsigned int i;
	unsigned int j;
	int ret = 0;

	planes = drmModeGetPlaneResources(drmfd);
	if (WARN_ON(!planes, "drmModeGetPlaneResources failed: %s\n", ERRSTR))
		return -1;

	for (i = 0; i < planes->count_planes; ++i) {
		plane = drmModeGetPlane(drmfd, planes->planes[i]);
		if (WARN_ON(!planes, "drmModeGetPlane failed: %s\n", ERRSTR))
			break;

		if (!(plane->possible_crtcs & (1 << s->crtIdx))) {
			drmModeFreePlane(plane);
			continue;
		}

		for (j = 0; j < plane->count_formats; ++j) {
			if (plane->formats[j] == s->out_fourcc)
				break;
		}

		if (j == plane->count_formats) {
			drmModeFreePlane(plane);
			continue;
		}

		s->planeId = plane->plane_id;
		drmModeFreePlane(plane);
		break;
	}

	if (i == planes->count_planes)
		ret = -1;

	drmModeFreePlaneResources(planes);
	return ret;
}

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 },
	};

	/* buffer currently used by drm */
	stream.v4lfd = v4lfd;
	stream.current_buffer = -1;
	stream.buffer = buffer;

	if (!s.use_compose) {
		s.compose.left = 0;
		s.compose.top = 0;
		s.compose.width = fmt.fmt.pix.width;
		s.compose.height = fmt.fmt.pix.height;
	}

	while ((ret = poll(fds, 2, 5000)) > 0) {
		struct v4l2_buffer buf;

		/* dequeue buffer */
		memset(&buf, 0, sizeof buf);
		buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
		buf.memory = V4L2_MEMORY_DMABUF;
		ret = ioctl(v4lfd, VIDIOC_DQBUF, &buf);
		BYE_ON(ret, "VIDIOC_DQBUF failed: %s\n", ERRSTR);

		ret = drmModeSetPlane(drmfd, s.planeId, s.crtId,
				      buffer[buf.index].fb_handle, 0,
				      s.compose.left, s.compose.top,
				      s.compose.width,
				      s.compose.height,
				      0, 0, s.w << 16, s.h << 16);
		BYE_ON(ret, "drmModeSetPlane failed: %s\n", ERRSTR);

		if (stream.current_buffer != -1) {
			memset(&buf, 0, sizeof buf);
			buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
			buf.memory = V4L2_MEMORY_DMABUF;
			buf.index = stream.current_buffer;
			buf.m.fd = stream.buffer[stream.current_buffer].dbuf_fd;

			ret = ioctl(stream.v4lfd, VIDIOC_QBUF, &buf);
			BYE_ON(ret, "VIDIOC_QBUF(index = %d) failed: %s\n",
			       stream.current_buffer, ERRSTR);
		}

		stream.current_buffer = buf.index;
	}

	return 0;
}

CROSS_COMPILE ?=
KDIR ?=

CC := $(CROSS_COMPILE)gcc
CFLAGS ?= -O2 -W -Wall -std=gnu99 -I$(KDIR)/usr/include -I/usr/include/libdrm
LDFLAGS ?=
LIBS := -lrt -ldrm

%.o : %.c

	$(CC) $(CFLAGS) -c -o $@ $<

all: dmabuf-sharing

dmabuf-sharing: dmabuf-sharing.o

	$(CC) $(LDFLAGS) -o $@ $^ $(LIBS)

clean:

	-rm -f *.o
	-rm -f dmabuf-sharing
#1 lore raw
Quoted 28 lines · On Thursday 08 November 2012 19:14:18 Laurent Pinchart wrote:

Hi Mauro,

Here's the application I've used to test V4L2 dma-buf support with a UVC webcam and an Intel GPU supported by the i915 driver.

The kernel code is available in my git tree at

git://linuxtv.org/pinchartl/media.git devel/dma-buf-v10

(http://git.linuxtv.org/pinchartl/media.git/shortlog/refs/heads/devel/v4l2-
clock)

Don't forget to enable dma-buf and UVC support when compiling the kernel.

The userspace code is based on the v4l2-drm-example application written by Tomasz (the original code is available at
git://git.infradead.org/users/kmpark/public-apps). I need to clean up my modifications to push them back to the repository, in the meantime the code is attached to this e-mail.

To compile the application, just run make with the KDIR variable set to the path to your Linux kernel tree with the dma-buf patches applied. Don't forget to make headers_install in the kernel tree as the Makefile will look for headers in $KDIR/usr.

You will need a recent version of libdrm with plane support available. 2.4.39 should do.

Quoted 6 lines

The following command line will capture VGA YUYV data from the webcam and display it on the screen. You need to run it in a console as root without the X server running.

./dmabuf-sharing -M i915 -o 7:3:1600x900 -i /dev/video0 -S 640,480 -f YUYV -F YUYV -s 640,480@0,0 -t 640,480@0,0 -b 2

I forgot to mention that the -o parameter takes the connector ID, CRTC ID and mode as parameters. The mode is easy to find, but the connector and CRTC IDs are a bit more tricky. You can run the modetest application (part of libdrm but not installed by most distributions, so a manual compilation is needed) to dump all CRTC, encoder and connector information to the console. Pick the connector associated with your display, and the CRTC associated with the encoder associated with that connector.

Signature · 3 lines
Regards,

Laurent Pinchart
#2 lore raw

Em Thu, 08 Nov 2012 19:34:14 +0100
Laurent Pinchart <[email protected]> escreveu:

Quoted 36 lines · On Thursday 08 November 2012 19:14:18 Laurent Pinchart wrote:
Quoted 28 lines

Hi Mauro,

Here's the application I've used to test V4L2 dma-buf support with a UVC webcam and an Intel GPU supported by the i915 driver.

The kernel code is available in my git tree at

git://linuxtv.org/pinchartl/media.git devel/dma-buf-v10

(http://git.linuxtv.org/pinchartl/media.git/shortlog/refs/heads/devel/v4l2-
clock)

Don't forget to enable dma-buf and UVC support when compiling the kernel.

The userspace code is based on the v4l2-drm-example application written by Tomasz (the original code is available at
git://git.infradead.org/users/kmpark/public-apps). I need to clean up my modifications to push them back to the repository, in the meantime the code is attached to this e-mail.

To compile the application, just run make with the KDIR variable set to the path to your Linux kernel tree with the dma-buf patches applied. Don't forget to make headers_install in the kernel tree as the Makefile will look for headers in $KDIR/usr.

You will need a recent version of libdrm with plane support available. 2.4.39 should do.

Quoted 6 lines

The following command line will capture VGA YUYV data from the webcam and display it on the screen. You need to run it in a console as root without the X server running.

./dmabuf-sharing -M i915 -o 7:3:1600x900 -i /dev/video0 -S 640,480 -f YUYV -F YUYV -s 640,480@0,0 -t 640,480@0,0 -b 2

Quoted 7 lines

I forgot to mention that the -o parameter takes the connector ID, CRTC ID and mode as parameters. The mode is easy to find, but the connector and CRTC IDs are a bit more tricky. You can run the modetest application (part of libdrm but not installed by most distributions, so a manual compilation is needed) to dump all CRTC, encoder and connector information to the console. Pick the connector associated with your display, and the CRTC associated with the encoder associated with that connector.

Didn't work:

$ sudo ./modetest 
trying to load module i915...failed.
trying to load module radeon...failed.
trying to load module nouveau...failed.
trying to load module vmwgfx...failed.
trying to load module omapdrm...failed.
failed to load any modules, aborting.

Even so,

$ sudo /usr/bin/dristat
/dev/dri/card0

and:

$ lsmod|grep i915
i915                  530346  2 
video                  18936  1 i915
i2c_algo_bit           13257  1 i915
drm_kms_helper         44701  1 i915
drm                   255010  3 i915,drm_kms_helper
i2c_core               38314  5 drm,i915,i2c_i801,drm_kms_helper,i2c_algo_bit

The GPU on this notebook is this one:

00:02.0 VGA compatible controller: Intel Corporation Mobile GM965/GL960 Integrated Graphics Controller (primary) (rev 0c) (prog-if 00 [VGA controller])
Subsystem: Dell Device 026f
Flags: bus master, fast devsel, latency 0, IRQ 45
Memory at f8000000 (64-bit, non-prefetchable) [size=1M]
Memory at d0000000 (64-bit, prefetchable) [size=256M]
I/O ports at 1800 [size=8]
Expansion ROM at <unassigned> [disabled]
Capabilities: [90] MSI: Enable+ Count=1/1 Maskable- 64bit-
Capabilities: [d0] Power Management version 3
Kernel driver in use: i915

Regards,
Mauro

#3 lore raw

Hi Mauro,

Quoted 73 lines · On Friday 09 November 2012 09:51:11 Mauro Carvalho Chehab wrote:

Laurent Pinchart <[email protected]> escreveu:

Quoted 37 lines · On Thursday 08 November 2012 19:14:18 Laurent Pinchart wrote:
Quoted 29 lines

Hi Mauro,

Here's the application I've used to test V4L2 dma-buf support with a UVC webcam and an Intel GPU supported by the i915 driver.

The kernel code is available in my git tree at

git://linuxtv.org/pinchartl/media.git devel/dma-buf-v10

(http://git.linuxtv.org/pinchartl/media.git/shortlog/refs/heads/devel/
v4l2-clock)

Don't forget to enable dma-buf and UVC support when compiling the kernel.

The userspace code is based on the v4l2-drm-example application written by Tomasz (the original code is available at
git://git.infradead.org/users/kmpark/public-apps). I need to clean up my modifications to push them back to the repository, in the meantime the code is attached to this e-mail.

To compile the application, just run make with the KDIR variable set to the path to your Linux kernel tree with the dma-buf patches applied. Don't forget to make headers_install in the kernel tree as the Makefile will look for headers in $KDIR/usr.

You will need a recent version of libdrm with plane support available. 2.4.39 should do.

Quoted 6 lines

The following command line will capture VGA YUYV data from the webcam and display it on the screen. You need to run it in a console as root without the X server running.

./dmabuf-sharing -M i915 -o 7:3:1600x900 -i /dev/video0 -S 640,480 -f YUYV -F YUYV -s 640,480@0,0 -t 640,480@0,0 -b 2

Quoted 8 lines

I forgot to mention that the -o parameter takes the connector ID, CRTC ID and mode as parameters. The mode is easy to find, but the connector and CRTC IDs are a bit more tricky. You can run the modetest application (part of libdrm but not installed by most distributions, so a manual compilation is needed) to dump all CRTC, encoder and connector information to the console. Pick the connector associated with your display, and the CRTC associated with the encoder associated with that connector.

Didn't work:

$ sudo ./modetest
trying to load module i915...failed.
trying to load module radeon...failed.
trying to load module nouveau...failed.
trying to load module vmwgfx...failed.
trying to load module omapdrm...failed.
failed to load any modules, aborting.

Even so,

$ sudo /usr/bin/dristat
/dev/dri/card0

and:

$ lsmod|grep i915
i915                  530346  2
video                  18936  1 i915
i2c_algo_bit           13257  1 i915
drm_kms_helper         44701  1 i915
drm                   255010  3 i915,drm_kms_helper
i2c_core               38314  5
drm,i915,i2c_i801,drm_kms_helper,i2c_algo_bit
Quoted 5 lines

The GPU on this notebook is this one:

00:02.0 VGA compatible controller: Intel Corporation Mobile GM965/GL960 Integrated Graphics Controller (primary) (rev 0c) (prog-if 00 [VGA controller])

There's the explanation. Your graphics controller doesn't support planes :-( Any chance to have access to a computer based on an Ironlake, Sandy Bridge, Ivy Bridge or Haswell ?

Quoted 9 lines

Subsystem: Dell Device 026f
Flags: bus master, fast devsel, latency 0, IRQ 45 Memory at f8000000 (64-bit, non-prefetchable) [size=1M] Memory at d0000000 (64-bit, prefetchable) [size=256M] I/O ports at 1800 [size=8]
Expansion ROM at <unassigned> [disabled]
Capabilities: [90] MSI: Enable+ Count=1/1 Maskable- 64bit-
Capabilities: [d0] Power Management version 3 Kernel driver in use: i915

Signature · 3 lines
Regards,

Laurent Pinchart
#4 lore raw
In reply to Laurent Pinchart

Em Thu, 08 Nov 2012 19:34:14 +0100
Laurent Pinchart <[email protected]> escreveu:

Quoted 36 lines · On Thursday 08 November 2012 19:14:18 Laurent Pinchart wrote:
Quoted 28 lines

Hi Mauro,

Here's the application I've used to test V4L2 dma-buf support with a UVC webcam and an Intel GPU supported by the i915 driver.

The kernel code is available in my git tree at

git://linuxtv.org/pinchartl/media.git devel/dma-buf-v10

(http://git.linuxtv.org/pinchartl/media.git/shortlog/refs/heads/devel/v4l2-
clock)

Don't forget to enable dma-buf and UVC support when compiling the kernel.

The userspace code is based on the v4l2-drm-example application written by Tomasz (the original code is available at
git://git.infradead.org/users/kmpark/public-apps). I need to clean up my modifications to push them back to the repository, in the meantime the code is attached to this e-mail.

To compile the application, just run make with the KDIR variable set to the path to your Linux kernel tree with the dma-buf patches applied. Don't forget to make headers_install in the kernel tree as the Makefile will look for headers in $KDIR/usr.

You will need a recent version of libdrm with plane support available. 2.4.39 should do.

Quoted 6 lines

The following command line will capture VGA YUYV data from the webcam and display it on the screen. You need to run it in a console as root without the X server running.

./dmabuf-sharing -M i915 -o 7:3:1600x900 -i /dev/video0 -S 640,480 -f YUYV -F YUYV -s 640,480@0,0 -t 640,480@0,0 -b 2

Quoted 7 lines

I forgot to mention that the -o parameter takes the connector ID, CRTC ID and mode as parameters. The mode is easy to find, but the connector and CRTC IDs are a bit more tricky. You can run the modetest application (part of libdrm but not installed by most distributions, so a manual compilation is needed) to dump all CRTC, encoder and connector information to the console. Pick the connector associated with your display, and the CRTC associated with the encoder associated with that connector.

Got modetest running, but I didn't figure out what of the values below should be used for the -o parameter:

trying to load module i915...success.
Encoders:
id crtc type possible crtcs possible clones
6 3 LVDS 0x00000003 0x00000001
13 0 DAC 0x00000003 0x00000002
15 0 TVDAC 0x00000003 0x00000004

Connectors:
id encoder status type size (mm) modes encoders
5 6 connected LVDS 290x180 1 6
modes:
name refresh (Hz) hdisp hss hse htot vdisp vss vse vtot)
1280x800 60 1280 1328 1360 1448 800 803 809 823 flags: nhsync, nvsync; type: preferred, driver props:

	1 EDID:
		flags: immutable blob
		blobs:

		value:
			00ffffffffffff0006af241400000000
			01110103801d12780a87f594574f8c27
			27505400000001010101010101010101
			010101010101ee1b00a8502017303020
			360022b410000019ee1b00a850201730
			3020360022b410000000000000fe0044
			573930398042313333455731000000fe
			00000000000000000001010a20200022
	2 DPMS:
		flags: enum
		enums: On=0 Standby=1 Suspend=2 Off=3
		value: 0
	7 scaling mode:
		flags: enum
		enums: None=0 Full=1 Center=2 Full aspect=3
		value: 3

12 0 disconnected VGA 0x0 0 13
14 0 disconnected s-video 0x0 0 15

CRTCs:
id fb pos size
3 9 (0,0) (0x0)
1280x800 60 1280 1328 1360 1448 800 803 809 823 flags: nhsync, nvsync; type: preferred, driver props:
4 0 (0,0) (0x0)
0 0 0 0 0 0 0 0 0 flags: ; type:
props:

Planes:
id crtc fb CRTC x,y x,y gamma size

Frame buffers:
id size pitch

Quoted 1 line

Cheers,
Mauro

#5 lore raw

Em Fri, 9 Nov 2012 17:37:42 +0100
Mauro Carvalho Chehab <[email protected]> escreveu:

Quoted 97 lines

Em Thu, 08 Nov 2012 19:34:14 +0100
Laurent Pinchart <[email protected]> escreveu:

Quoted 36 lines · On Thursday 08 November 2012 19:14:18 Laurent Pinchart wrote:
Quoted 28 lines

Hi Mauro,

Here's the application I've used to test V4L2 dma-buf support with a UVC webcam and an Intel GPU supported by the i915 driver.

The kernel code is available in my git tree at

git://linuxtv.org/pinchartl/media.git devel/dma-buf-v10

(http://git.linuxtv.org/pinchartl/media.git/shortlog/refs/heads/devel/v4l2-
clock)

Don't forget to enable dma-buf and UVC support when compiling the kernel.

The userspace code is based on the v4l2-drm-example application written by Tomasz (the original code is available at
git://git.infradead.org/users/kmpark/public-apps). I need to clean up my modifications to push them back to the repository, in the meantime the code is attached to this e-mail.

To compile the application, just run make with the KDIR variable set to the path to your Linux kernel tree with the dma-buf patches applied. Don't forget to make headers_install in the kernel tree as the Makefile will look for headers in $KDIR/usr.

You will need a recent version of libdrm with plane support available. 2.4.39 should do.

Quoted 6 lines

The following command line will capture VGA YUYV data from the webcam and display it on the screen. You need to run it in a console as root without the X server running.

./dmabuf-sharing -M i915 -o 7:3:1600x900 -i /dev/video0 -S 640,480 -f YUYV -F YUYV -s 640,480@0,0 -t 640,480@0,0 -b 2

Quoted 7 lines

I forgot to mention that the -o parameter takes the connector ID, CRTC ID and mode as parameters. The mode is easy to find, but the connector and CRTC IDs are a bit more tricky. You can run the modetest application (part of libdrm but not installed by most distributions, so a manual compilation is needed) to dump all CRTC, encoder and connector information to the console. Pick the connector associated with your display, and the CRTC associated with the encoder associated with that connector.

Got modetest running, but I didn't figure out what of the values below should be used for the -o parameter:

trying to load module i915...success.
Encoders:
id crtc type possible crtcs possible clones
6 3 LVDS 0x00000003 0x00000001
13 0 DAC 0x00000003 0x00000002
15 0 TVDAC 0x00000003 0x00000004

Connectors:
id encoder status type size (mm) modes encoders
5 6 connected LVDS 290x180 1 6
modes:
name refresh (Hz) hdisp hss hse htot vdisp vss vse vtot)
1280x800 60 1280 1328 1360 1448 800 803 809 823 flags: nhsync, nvsync; type: preferred, driver props:

	1 EDID:
		flags: immutable blob
		blobs:

		value:
			00ffffffffffff0006af241400000000
			01110103801d12780a87f594574f8c27
			27505400000001010101010101010101
			010101010101ee1b00a8502017303020
			360022b410000019ee1b00a850201730
			3020360022b410000000000000fe0044
			573930398042313333455731000000fe
			00000000000000000001010a20200022
	2 DPMS:
		flags: enum
		enums: On=0 Standby=1 Suspend=2 Off=3
		value: 0
	7 scaling mode:
		flags: enum
		enums: None=0 Full=1 Center=2 Full aspect=3
		value: 3

12 0 disconnected VGA 0x0 0 13
14 0 disconnected s-video 0x0 0 15

CRTCs:
id fb pos size
3 9 (0,0) (0x0)
1280x800 60 1280 1328 1360 1448 800 803 809 823 flags: nhsync, nvsync; type: preferred, driver props:
4 0 (0,0) (0x0)
0 0 0 0 0 0 0 0 0 flags: ; type:
props:

Quoted 5 lines

Planes:
id crtc fb CRTC x,y x,y gamma size

Frame buffers:
id size pitch

FYI, this is that I'm getting there:

# ./dmabuf-sharing -M i915 -o 5:3:1280x800 -i /dev/video0 -S 640,480 -f YUYV -F YUYV -s 640,480@0,0 -t 640,480@0,0 -b 2

G_FMT(start): width = 640, height = 480, 4cc = YUYV G_FMT(final): width = 640, height = 480, 4cc = YUYV size = 614400 pitch = 1280
bo 1 640x480 bpp 16 size 614400 (614400) dbuf_fd = 5
bo 2 640x480 bpp 16 size 614400 (614400) dbuf_fd = 6
buffers ready
WARN(dmabuf-sharing.c:278): connector 5 is not supported ERROR(dmabuf-sharing.c:441) : failed to find valid mode

Cheers,
Mauro