/* helpers to create nice-looking framebuffers */ static int create_bo_for_fb(int fd, int width, int height, int bpp, uint64_t tiling, unsigned bo_size, uint32_t *gem_handle_ret, unsigned *size_ret, unsigned *stride_ret) { uint32_t gem_handle; int size, ret = 0; unsigned stride; if (tiling != LOCAL_DRM_FORMAT_MOD_NONE) { int v; /* Round the tiling up to the next power-of-two and the * region up to the next pot fence size so that this works * on all generations. * * This can still fail if the framebuffer is too large to * be tiled. But then that failure is expected. */ v = width * bpp / 8; for (stride = 512; stride < v; stride *= 2) ; v = stride * height; for (size = 1024*1024; size < v; size *= 2) ; } else { /* Scan-out has a 64 byte alignment restriction */ stride = (width * (bpp / 8) + 63) & ~63; size = stride * height; } if (bo_size == 0) bo_size = size; gem_handle = gem_create(fd, bo_size); if (tiling == LOCAL_I915_FORMAT_MOD_X_TILED) ret = __gem_set_tiling(fd, gem_handle, I915_TILING_X, stride); *stride_ret = stride; *size_ret = size; *gem_handle_ret = gem_handle; return ret; }
static void do_test_invalid_tiling(int fd, uint32_t handle, int tiling, int stride) { igt_assert(__gem_set_tiling(fd, handle, tiling, tiling ? stride : 0) == -EINVAL); }
static void test_huge_copy(int fd, int huge, int tiling_a, int tiling_b) { uint64_t huge_object_size, i; uint32_t bo, *pattern_a, *pattern_b; char *a, *b; switch (huge) { case -2: huge_object_size = gem_mappable_aperture_size() / 4; break; case -1: huge_object_size = gem_mappable_aperture_size() / 2; break; case 0: huge_object_size = gem_mappable_aperture_size() + PAGE_SIZE; break; default: huge_object_size = gem_aperture_size(fd) + PAGE_SIZE; break; } intel_require_memory(2, huge_object_size, CHECK_RAM); pattern_a = malloc(PAGE_SIZE); for (i = 0; i < PAGE_SIZE/4; i++) pattern_a[i] = i; pattern_b = malloc(PAGE_SIZE); for (i = 0; i < PAGE_SIZE/4; i++) pattern_b[i] = ~i; bo = gem_create(fd, huge_object_size); if (tiling_a) igt_require(__gem_set_tiling(fd, bo, tiling_a, tiling_a == I915_TILING_Y ? 128 : 512) == 0); a = __gem_mmap__gtt(fd, bo, huge_object_size, PROT_READ | PROT_WRITE); igt_require(a); gem_close(fd, bo); for (i = 0; i < huge_object_size / PAGE_SIZE; i++) memcpy(a + PAGE_SIZE*i, pattern_a, PAGE_SIZE); bo = gem_create(fd, huge_object_size); if (tiling_b) igt_require(__gem_set_tiling(fd, bo, tiling_b, tiling_b == I915_TILING_Y ? 128 : 512) == 0); b = __gem_mmap__gtt(fd, bo, huge_object_size, PROT_READ | PROT_WRITE); igt_require(b); gem_close(fd, bo); for (i = 0; i < huge_object_size / PAGE_SIZE; i++) memcpy(b + PAGE_SIZE*i, pattern_b, PAGE_SIZE); for (i = 0; i < huge_object_size / PAGE_SIZE; i++) { if (i & 1) memcpy(a + i *PAGE_SIZE, b + i*PAGE_SIZE, PAGE_SIZE); else memcpy(b + i *PAGE_SIZE, a + i*PAGE_SIZE, PAGE_SIZE); } for (i = 0; i < huge_object_size / PAGE_SIZE; i++) { if (i & 1) igt_assert(memcmp(pattern_b, a + PAGE_SIZE*i, PAGE_SIZE) == 0); else igt_assert(memcmp(pattern_a, a + PAGE_SIZE*i, PAGE_SIZE) == 0); } munmap(a, huge_object_size); for (i = 0; i < huge_object_size / PAGE_SIZE; i++) { if (i & 1) igt_assert(memcmp(pattern_b, b + PAGE_SIZE*i, PAGE_SIZE) == 0); else igt_assert(memcmp(pattern_a, b + PAGE_SIZE*i, PAGE_SIZE) == 0); } munmap(b, huge_object_size); free(pattern_a); free(pattern_b); }
static void test_huge_bo(int fd, int huge, int tiling) { uint32_t bo; char *ptr; char *tiled_pattern; char *linear_pattern; uint64_t size, last_offset; int pitch = tiling == I915_TILING_Y ? 128 : 512; int i; switch (huge) { case -1: size = gem_mappable_aperture_size() / 2; break; case 0: size = gem_mappable_aperture_size() + PAGE_SIZE; break; default: size = gem_aperture_size(fd) + PAGE_SIZE; break; } intel_require_memory(1, size, CHECK_RAM); last_offset = size - PAGE_SIZE; /* Create pattern */ bo = gem_create(fd, PAGE_SIZE); if (tiling) igt_require(__gem_set_tiling(fd, bo, tiling, pitch) == 0); linear_pattern = gem_mmap__gtt(fd, bo, PAGE_SIZE, PROT_READ | PROT_WRITE); for (i = 0; i < PAGE_SIZE; i++) linear_pattern[i] = i; tiled_pattern = gem_mmap__cpu(fd, bo, 0, PAGE_SIZE, PROT_READ); gem_set_domain(fd, bo, I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT, 0); gem_close(fd, bo); bo = gem_create(fd, size); if (tiling) igt_require(__gem_set_tiling(fd, bo, tiling, pitch) == 0); /* Initialise first/last page through CPU mmap */ ptr = gem_mmap__cpu(fd, bo, 0, size, PROT_READ | PROT_WRITE); memcpy(ptr, tiled_pattern, PAGE_SIZE); memcpy(ptr + last_offset, tiled_pattern, PAGE_SIZE); munmap(ptr, size); /* Obtain mapping for the object through GTT. */ ptr = __gem_mmap__gtt(fd, bo, size, PROT_READ | PROT_WRITE); igt_require_f(ptr, "Huge BO GTT mapping not supported.\n"); set_domain_gtt(fd, bo); /* Access through GTT should still provide the CPU written values. */ igt_assert(memcmp(ptr , linear_pattern, PAGE_SIZE) == 0); igt_assert(memcmp(ptr + last_offset, linear_pattern, PAGE_SIZE) == 0); gem_set_tiling(fd, bo, I915_TILING_NONE, 0); igt_assert(memcmp(ptr , tiled_pattern, PAGE_SIZE) == 0); igt_assert(memcmp(ptr + last_offset, tiled_pattern, PAGE_SIZE) == 0); munmap(ptr, size); gem_close(fd, bo); munmap(tiled_pattern, PAGE_SIZE); munmap(linear_pattern, PAGE_SIZE); }