Ejemplo n.º 1
0
static void gpu_blit(struct igt_fb *dst_fb, struct igt_fb *src_fb)
{
	drm_intel_bo *dst_bo;
	drm_intel_bo *src_bo;
	int bpp;

	igt_assert(dst_fb->drm_format == src_fb->drm_format);
	igt_assert(src_fb->drm_format == DRM_FORMAT_RGB565 ||
	       igt_drm_format_to_bpp(src_fb->drm_format) != 16);
	bpp = igt_drm_format_to_bpp(src_fb->drm_format);
	dst_bo = gem_handle_to_libdrm_bo(bufmgr, drm_fd, "destination",
					 dst_fb->gem_handle);
	igt_assert(dst_bo);
	src_bo = gem_handle_to_libdrm_bo(bufmgr, drm_fd, "source",
					 src_fb->gem_handle);
	igt_assert(src_bo);

	intel_blt_copy(batch,
		       src_bo, 0, 0, src_fb->width * bpp / 8,
		       dst_bo, 0, 0, dst_fb->width * bpp / 8,
		       src_fb->width, src_fb->height, bpp);
	intel_batchbuffer_flush(batch);
	gem_quiescent_gpu(drm_fd);

	drm_intel_bo_unreference(src_bo);
	drm_intel_bo_unreference(dst_bo);
}
Ejemplo n.º 2
0
/**
 * igt_create_fb_with_bo_size:
 * @fd: open i915 drm file descriptor
 * @width: width of the framebuffer in pixel
 * @height: height of the framebuffer in pixel
 * @format: drm fourcc pixel format code
 * @tiling: tiling layout of the framebuffer (as framebuffer modifier)
 * @fb: pointer to an #igt_fb structure
 * @bo_size: size of the backing bo (0 for minimum needed size)
 *
 * This function allocates a gem buffer object suitable to back a framebuffer
 * with the requested properties and then wraps it up in a drm framebuffer
 * object of the requested size. All metadata is stored in @fb.
 *
 * The backing storage of the framebuffer is filled with all zeros, i.e. black
 * for rgb pixel formats.
 *
 * Returns:
 * The kms id of the created framebuffer.
 */
unsigned int
igt_create_fb_with_bo_size(int fd, int width, int height,
			   uint32_t format, uint64_t tiling,
			   struct igt_fb *fb, unsigned bo_size)
{
	uint32_t fb_id;
	int bpp;

	memset(fb, 0, sizeof(*fb));

	bpp = igt_drm_format_to_bpp(format);

	igt_debug("%s(width=%d, height=%d, format=0x%x [bpp=%d], tiling=0x%"PRIx64", size=%d)\n",
		  __func__, width, height, format, bpp, tiling, bo_size);
	do_or_die(create_bo_for_fb(fd, width, height, bpp, tiling, bo_size,
				   &fb->gem_handle, &fb->size, &fb->stride));

	igt_debug("%s(handle=%d, pitch=%d)\n",
		  __func__, fb->gem_handle, fb->stride);

	if (tiling != LOCAL_DRM_FORMAT_MOD_NONE &&
	    tiling != LOCAL_I915_FORMAT_MOD_X_TILED) {
		do_or_die(__kms_addfb(fd, fb->gem_handle, width, height,
				      fb->stride, format, tiling,
				      LOCAL_DRM_MODE_FB_MODIFIERS, &fb_id));
	} else {
		uint32_t handles[4];
		uint32_t pitches[4];
		uint32_t offsets[4];

		memset(handles, 0, sizeof(handles));
		memset(pitches, 0, sizeof(pitches));
		memset(offsets, 0, sizeof(offsets));

		handles[0] = fb->gem_handle;
		pitches[0] = fb->stride;

		do_or_die(drmModeAddFB2(fd, width, height, format,
					handles, pitches, offsets,
					&fb_id, 0));
	}

	fb->width = width;
	fb->height = height;
	fb->tiling = tiling;
	fb->drm_format = format;
	fb->fb_id = fb_id;

	return fb_id;
}
Ejemplo n.º 3
0
static void create_cairo_surface__blit(int fd, struct igt_fb *fb)
{
	struct fb_blit_upload *blit;
	cairo_format_t cairo_format;
	unsigned int obj_tiling = fb_mod_to_obj_tiling(fb->tiling);
	int bpp, ret;

	blit = malloc(sizeof(*blit));
	igt_assert(blit);

	/*
	 * We create a linear BO that we'll map for the CPU to write to (using
	 * cairo). This linear bo will be then blitted to its final
	 * destination, tiling it at the same time.
	 */
	bpp = igt_drm_format_to_bpp(fb->drm_format);
	ret = create_bo_for_fb(fd, fb->width, fb->height, bpp,
				LOCAL_DRM_FORMAT_MOD_NONE, 0,
				&blit->linear.handle,
				&blit->linear.size,
				&blit->linear.stride);

	igt_assert(ret == 0);

	blit->fd = fd;
	blit->fb = fb;

	/* Copy fb content to linear BO */
	gem_set_domain(fd, blit->linear.handle,
			I915_GEM_DOMAIN_GTT, 0);

	igt_blitter_fast_copy__raw(fd,
				   fb->gem_handle,
				   fb->stride,
				   obj_tiling,
				   0, 0, /* src_x, src_y */
				   fb->width, fb->height,
				   blit->linear.handle,
				   blit->linear.stride,
				   I915_TILING_NONE,
				   0, 0 /* dst_x, dst_y */);

	gem_sync(fd, blit->linear.handle);

	gem_set_domain(fd, blit->linear.handle,
		       I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);

	/* Setup cairo context */
	blit->linear.map = gem_mmap__cpu(fd,
					 blit->linear.handle,
					 0,
					 blit->linear.size,
					 PROT_READ | PROT_WRITE);

	cairo_format = drm_format_to_cairo(fb->drm_format);
	fb->cairo_surface =
		cairo_image_surface_create_for_data(blit->linear.map,
						    cairo_format,
						    fb->width, fb->height,
						    blit->linear.stride);

	cairo_surface_set_user_data(fb->cairo_surface,
				    (cairo_user_data_key_t *)create_cairo_surface__blit,
				    blit, destroy_cairo_surface__blit);
}