Example #1
0
static void draw_rect_render(int fd, struct cmd_data *cmd_data,
			     struct buf_data *buf, struct rect *rect,
			     uint32_t color)
{
	drm_intel_bo *src, *dst;
	uint32_t devid = intel_get_drm_devid(fd);
	igt_render_copyfunc_t rendercopy = igt_get_render_copyfunc(devid);
	struct igt_buf src_buf, dst_buf;
	struct intel_batchbuffer *batch;
	uint32_t tiling, swizzle;
	struct buf_data tmp;
	int pixel_size = buf->bpp / 8;
	unsigned adjusted_w, adjusted_dst_x;

	igt_skip_on(!rendercopy);

	/* Rendercopy works at 32bpp, so if you try to do copies on buffers with
	 * smaller bpps you won't succeeed if you need to copy "half" of a 32bpp
	 * pixel or something similar. */
	igt_skip_on(rect->x % (32 / buf->bpp) != 0 ||
		    rect->y % (32 / buf->bpp) != 0 ||
		    rect->w % (32 / buf->bpp) != 0 ||
		    rect->h % (32 / buf->bpp) != 0);

	gem_get_tiling(fd, buf->handle, &tiling, &swizzle);

	/* We create a temporary buffer and copy from it using rendercopy. */
	tmp.size = rect->w * rect->h * pixel_size;
	tmp.handle = gem_create(fd, tmp.size);
	tmp.stride = rect->w * pixel_size;
	tmp.bpp = buf->bpp;
	draw_rect_mmap_cpu(fd, &tmp, &(struct rect){0, 0, rect->w, rect->h},
Example #2
0
static void draw_rect_mmap_wc(int fd, struct buf_data *buf, struct rect *rect,
			      uint32_t color)
{
	uint32_t *ptr;
	uint32_t tiling, swizzle;

	gem_set_domain(fd, buf->handle, I915_GEM_DOMAIN_GTT,
		       I915_GEM_DOMAIN_GTT);
	gem_get_tiling(fd, buf->handle, &tiling, &swizzle);

	/* We didn't implement suport for the older tiling methods yet. */
	if (tiling != I915_TILING_NONE)
		igt_require(intel_gen(intel_get_drm_devid(fd)) >= 5);

	ptr = gem_mmap__wc(fd, buf->handle, 0, buf->size,
			   PROT_READ | PROT_WRITE);

	switch (tiling) {
	case I915_TILING_NONE:
		draw_rect_ptr_linear(ptr, buf->stride, rect, color, buf->bpp);
		break;
	case I915_TILING_X:
		draw_rect_ptr_tiled(ptr, buf->stride, swizzle, rect, color,
				    buf->bpp);
		break;
	default:
		igt_assert(false);
		break;
	}

	igt_assert(munmap(ptr, buf->size) == 0);
}
Example #3
0
static void draw_rect_blt(int fd, struct cmd_data *cmd_data,
			  struct buf_data *buf, struct rect *rect,
			  uint32_t color)
{
	drm_intel_bo *dst;
	struct intel_batchbuffer *batch;
	int blt_cmd_len, blt_cmd_tiling, blt_cmd_depth;
	uint32_t devid = intel_get_drm_devid(fd);
	int gen = intel_gen(devid);
	uint32_t tiling, swizzle;
	int pitch;

	gem_get_tiling(fd, buf->handle, &tiling, &swizzle);

	dst = gem_handle_to_libdrm_bo(cmd_data->bufmgr, fd, "", buf->handle);
	igt_assert(dst);

	batch = intel_batchbuffer_alloc(cmd_data->bufmgr, devid);
	igt_assert(batch);

	switch (buf->bpp) {
	case 8:
		blt_cmd_depth = 0;
		break;
	case 16: /* we're assuming 565 */
		blt_cmd_depth = 1 << 24;
		break;
	case 32:
		blt_cmd_depth = 3 << 24;
		break;
	default:
		igt_assert(false);
	}

	blt_cmd_len = (gen >= 8) ?  0x5 : 0x4;
	blt_cmd_tiling = (tiling) ? XY_COLOR_BLT_TILED : 0;
	pitch = (tiling) ? buf->stride / 4 : buf->stride;

	BEGIN_BATCH(6, 1);
	OUT_BATCH(XY_COLOR_BLT_CMD_NOLEN | XY_COLOR_BLT_WRITE_ALPHA |
		  XY_COLOR_BLT_WRITE_RGB | blt_cmd_tiling | blt_cmd_len);
	OUT_BATCH(blt_cmd_depth | (0xF0 << 16) | pitch);
	OUT_BATCH((rect->y << 16) | rect->x);
	OUT_BATCH(((rect->y + rect->h) << 16) | (rect->x + rect->w));
	OUT_RELOC_FENCED(dst, 0, I915_GEM_DOMAIN_RENDER, 0);
	OUT_BATCH(color);
	ADVANCE_BATCH();

	intel_batchbuffer_flush(batch);
	intel_batchbuffer_free(batch);
}
Example #4
0
static void draw_rect_pwrite(int fd, struct buf_data *buf,
			     struct rect *rect, uint32_t color)
{
	uint32_t tiling, swizzle;

	gem_get_tiling(fd, buf->handle, &tiling, &swizzle);

	switch (tiling) {
	case I915_TILING_NONE:
		draw_rect_pwrite_untiled(fd, buf, rect, color);
		break;
	case I915_TILING_X:
		draw_rect_pwrite_tiled(fd, buf, rect, color, swizzle);
		break;
	default:
		igt_assert(false);
		break;
	}
}
int
main(int argc, char **argv)
{
	int fd;
	int i, iter = 100;
	uint32_t tiling, swizzle;
	uint32_t handle;
	uint32_t devid;

	fd = drm_open_any();

	handle = create_bo(fd);
	gem_get_tiling(fd, handle, &tiling, &swizzle);

	devid = intel_get_drm_devid(fd);

	if (IS_GEN2(devid)) {
		tile_height = 16;
		tile_width = 128;
		tile_size = 2048;
	} else {
		tile_height = 8;
		tile_width = 512;
		tile_size = PAGE_SIZE;
	}

	/* Read a bunch of random subsets of the data and check that they come
	 * out right.
	 */
	for (i = 0; i < iter; i++) {
		int size = WIDTH * HEIGHT * 4;
		int offset = (random() % size) & ~3;
		int len = (random() % size) & ~3;
		int j;

		if (len == 0)
			len = 4;

		if (offset + len > size)
			len = size - offset;

		if (i == 0) {
			offset = 0;
			len = size;
		}

		gem_read(fd, handle, offset, linear, len);

		/* Translate from offsets in the read buffer to the swizzled
		 * address that it corresponds to.  This is the opposite of
		 * what Mesa does (calculate offset to be read given the linear
		 * offset it's looking for).
		 */
		for (j = offset; j < offset + len; j += 4) {
			uint32_t expected_val, found_val;
			int swizzled_offset;
			const char *swizzle_str;

			switch (swizzle) {
			case I915_BIT_6_SWIZZLE_NONE:
				swizzled_offset = j;
				swizzle_str = "none";
				break;
			case I915_BIT_6_SWIZZLE_9:
				swizzled_offset = j ^
					swizzle_bit(9, j);
				swizzle_str = "bit9";
				break;
			case I915_BIT_6_SWIZZLE_9_10:
				swizzled_offset = j ^
					swizzle_bit(9, j) ^
					swizzle_bit(10, j);
				swizzle_str = "bit9^10";
				break;
			case I915_BIT_6_SWIZZLE_9_11:
				swizzled_offset = j ^
					swizzle_bit(9, j) ^
					swizzle_bit(11, j);
				swizzle_str = "bit9^11";
				break;
			case I915_BIT_6_SWIZZLE_9_10_11:
				swizzled_offset = j ^
					swizzle_bit(9, j) ^
					swizzle_bit(10, j) ^
					swizzle_bit(11, j);
				swizzle_str = "bit9^10^11";
				break;
			default:
				fprintf(stderr, "Bad swizzle bits; %d\n",
					swizzle);
				abort();
			}
			expected_val = calculate_expected(swizzled_offset);
			found_val = linear[(j - offset) / 4];
			if (expected_val != found_val) {
				fprintf(stderr,
					"Bad read [%d]: %d instead of %d at 0x%08x "
					"for read from 0x%08x to 0x%08x, swizzle=%s\n",
					i, found_val, expected_val, j,
					offset, offset + len,
					swizzle_str);
				abort();
			}
		}
	}

	close(fd);

	return 0;
}