@@ -26,6 +26,7 @@
*/
#include "igt.h"
+#include "igt_vgem.h"
#include <unistd.h>
#include <stdlib.h>
#include <stdint.h>
@@ -79,6 +80,93 @@ static const char *bytes_per_sec(char *buf, double v)
return buf;
}
+static void do_write_loop(int fd, const char *name, uint32_t handle,
+ uint32_t *src, int size, int count)
+{
+ double usecs;
+ char buf[100];
+ const char* bps;
+ struct timeval start, end;
+
+ gettimeofday(&start, NULL);
+ do_gem_write(fd, handle, src, size, count);
+ gettimeofday(&end, NULL);
+ usecs = elapsed(&start, &end, count);
+ bps = bytes_per_sec(buf, size/usecs*1e6);
+ igt_info("Time to %s pwrite %d bytes x %6d:\t%7.3fµs, %s\n",
+ name, size, count, usecs, bps);
+ fflush(stdout);
+}
+
+static void test_i915_bo(int fd, const char *name, uint32_t handle,
+ uint32_t *src, int size)
+{
+ unsigned i, count;
+
+ for (count = 1; count <= 1<<17; count <<= 1) {
+ uint32_t *ptr = gem_mmap__cpu(fd, handle, 0, size, PROT_WRITE);
+ gem_set_domain(fd, handle, I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);
+ memset(ptr, 0, size);
+ munmap(ptr, size);
+
+ do_write_loop(fd, name, handle, src, size, count);
+
+ ptr = gem_mmap__cpu(fd, handle, 0, size, PROT_READ);
+ gem_set_domain(fd, handle, I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);
+
+ for (i = 0; i < size / 4096; i++)
+ igt_assert_eq(ptr[i * 1024], i);
+ }
+}
+
+struct foreign_bo {
+ int vgem_fd;
+ struct vgem_bo bo;
+ uint32_t handle;
+};
+
+static struct foreign_bo create_foreign_bo(int fd, uint32_t size)
+{
+ struct foreign_bo f_bo;
+
+ f_bo.vgem_fd = drm_open_driver(DRIVER_VGEM);
+
+ f_bo.bo.width = 1024;
+ f_bo.bo.height = size / 4096;
+ f_bo.bo.bpp = 32;
+ f_bo.handle = vgem_create_and_import(f_bo.vgem_fd, &f_bo.bo, fd, NULL);
+ igt_assert_eq(size, f_bo.bo.size);
+
+ return f_bo;
+}
+
+static void destroy_foreign_bo(int fd, struct foreign_bo *f_bo)
+{
+ gem_close(fd, f_bo->handle);
+ gem_close(f_bo->vgem_fd, f_bo->bo.handle);
+ close(f_bo->vgem_fd);
+}
+
+static void test_foreign_bo(int fd, const char *name, struct foreign_bo *f_bo,
+ uint32_t *src, int size)
+{
+ unsigned i, count;
+
+ for (count = 1; count <= 1<<17; count <<= 1) {
+ uint32_t *ptr = vgem_mmap(f_bo->vgem_fd, &f_bo->bo, PROT_WRITE);
+ memset(ptr, 0, size);
+ munmap(ptr, size);
+
+ do_write_loop(fd, name, f_bo->handle, src, size, count);
+
+ ptr = vgem_mmap(f_bo->vgem_fd, &f_bo->bo, PROT_READ);
+ gem_set_domain(fd, f_bo->handle, I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);
+
+ for (i = 0; i < size / 4096; i++)
+ igt_assert_eq(ptr[i * 1024], i);
+ }
+}
+
#define FORWARD 0x1
#define BACKWARD 0x2
#define RANDOM 0x4
@@ -205,16 +293,11 @@ static void test_big_gtt(int fd, int scale, unsigned flags)
gem_close(fd, handle);
}
-uint32_t *src, dst;
-int fd;
-
int main(int argc, char **argv)
{
+ int fd;
+ uint32_t *src;
int object_size = 0;
- double usecs;
- const char* bps;
- char buf[100];
- int count;
const struct {
int level;
const char *name;
@@ -236,50 +319,56 @@ int main(int argc, char **argv)
object_size = (object_size + 3) & -4;
igt_fixture {
+ unsigned i = 0;
fd = drm_open_driver(DRIVER_INTEL);
-
- dst = gem_create(fd, object_size);
src = malloc(object_size);
+ igt_assert(src);
+
+ for (i = 0; i < object_size / 4096; i++)
+ ((uint32_t *)src)[i * 1024] = i;
}
- igt_subtest("basic") {
- for (count = 1; count <= 1<<17; count <<= 1) {
- struct timeval start, end;
-
- gettimeofday(&start, NULL);
- do_gem_write(fd, dst, src, object_size, count);
- gettimeofday(&end, NULL);
- usecs = elapsed(&start, &end, count);
- bps = bytes_per_sec(buf, object_size/usecs*1e6);
- igt_info("Time to pwrite %d bytes x %6d: %7.3fµs, %s\n",
- object_size, count, usecs, bps);
- fflush(stdout);
+ igt_subtest_group {
+ uint32_t handle;
+ igt_fixture
+ handle = gem_create(fd, object_size);
+
+ igt_subtest("basic")
+ test_i915_bo(fd, "basic", handle, src, object_size);
+
+ for (c = cache; c->level != -1; c++) {
+ igt_subtest(c->name) {
+ gem_set_caching(fd, handle, c->level);
+ test_i915_bo(fd, c->name, handle, src, object_size);
+ }
}
+
+ igt_fixture
+ gem_close(fd, handle);
}
- for (c = cache; c->level != -1; c++) {
- igt_subtest(c->name) {
- gem_set_caching(fd, dst, c->level);
-
- for (count = 1; count <= 1<<17; count <<= 1) {
- struct timeval start, end;
-
- gettimeofday(&start, NULL);
- do_gem_write(fd, dst, src, object_size, count);
- gettimeofday(&end, NULL);
- usecs = elapsed(&start, &end, count);
- bps = bytes_per_sec(buf, object_size/usecs*1e6);
- igt_info("Time to %s pwrite %d bytes x %6d: %7.3fµs, %s\n",
- c->name, object_size, count, usecs, bps);
- fflush(stdout);
+ igt_subtest_group {
+ struct foreign_bo f_bo;
+
+ igt_fixture
+ f_bo = create_foreign_bo(fd, object_size);
+
+ igt_subtest("foreign-bo-basic")
+ test_foreign_bo(fd, "basic", &f_bo, src, object_size);
+
+ for (c = cache; c->level != -1; c++) {
+ igt_subtest_f("foreign-bo-%s", c->name) {
+ gem_set_caching(fd, f_bo.handle, c->level);
+ test_foreign_bo(fd, c->name, &f_bo, src, object_size);
}
}
+
+ igt_fixture
+ destroy_foreign_bo(fd, &f_bo);
}
- igt_fixture {
+ igt_fixture
free(src);
- gem_close(fd, dst);
- }
{
const struct mode {
Using an imported vgem bo we can test writes to an object not backed by struct page. These reads use different paths in the kernel. Suggested-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> --- tests/gem_pwrite.c | 167 ++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 128 insertions(+), 39 deletions(-)