From 9fd7e35c39a2fd82b95376c8a8a8424bc79f2d23 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 1 Feb 2011 19:22:32 +0000 Subject: Simple test to ensure that working sets larger than memory, just work. Based on gem_tiled_blit, but without the complication of the tiling. Signed-off-by: Chris Wilson --- .gitignore | 1 + tests/Makefile.am | 1 + tests/gem_linear_blits.c | 167 +++++++++++++++++++++++++++++++++++++++++++++++ tests/gem_tiled_pread.c | 165 ++++++++++++++++++++++++++++++---------------- 4 files changed, 277 insertions(+), 57 deletions(-) create mode 100644 tests/gem_linear_blits.c diff --git a/.gitignore b/.gitignore index 73e32eba..63750139 100644 --- a/.gitignore +++ b/.gitignore @@ -45,6 +45,7 @@ tests/gem_pread_after_blit tests/gem_pwrite tests/gem_readwrite tests/gem_ringfill +tests/gem_linear_blits tests/gem_tiled_blits tests/gem_tiled_fence_blits tests/gem_tiled_pread diff --git a/tests/Makefile.am b/tests/Makefile.am index b5ca62b2..56f7ec47 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -11,6 +11,7 @@ TESTS = getversion \ gem_pwrite \ gem_pread_after_blit \ gem_tiled_pread \ + gem_linear_blits \ gem_tiled_blits \ gem_tiled_fence_blits \ gem_largeobject \ diff --git a/tests/gem_linear_blits.c b/tests/gem_linear_blits.c new file mode 100644 index 00000000..375a5fc3 --- /dev/null +++ b/tests/gem_linear_blits.c @@ -0,0 +1,167 @@ +/* + * Copyright © 2009 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Authors: + * Eric Anholt + * + */ + +/** @file gem_linear_blits.c + * + * This is a test of doing many blits, with a working set + * larger than the aperture size. + * + * The goal is to simply ensure the basics work. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "drm.h" +#include "i915_drm.h" +#include "drmtest.h" +#include "intel_bufmgr.h" +#include "intel_batchbuffer.h" +#include "intel_gpu_tools.h" + +static drm_intel_bufmgr *bufmgr; +struct intel_batchbuffer *batch; +static int width = 512, height = 512; + +static uint64_t +gem_aperture_size(int fd) +{ + struct drm_i915_gem_get_aperture aperture; + + aperture.aper_size = 512*1024*1024; + (void)drmIoctl(fd, DRM_IOCTL_I915_GEM_GET_APERTURE, &aperture); + return aperture.aper_size; +} + +static drm_intel_bo * +create_bo(uint32_t start_val) +{ + drm_intel_bo *bo; + uint32_t *linear; + int i; + + bo = drm_intel_bo_alloc(bufmgr, "linear bo", 1024 * 1024, 4096); + + /* Fill the BO with dwords starting at start_val */ + drm_intel_bo_map(bo, 1); + linear = bo->virtual; + for (i = 0; i < 1024 * 1024 / 4; i++) + linear[i] = start_val++; + drm_intel_bo_unmap(bo); + + return bo; +} + +static void +check_bo(drm_intel_bo *bo, uint32_t start_val) +{ + uint32_t *linear; + int i; + + drm_intel_bo_map(bo, 0); + linear = bo->virtual; + + for (i = 0; i < 1024 * 1024 / 4; i++) { + if (linear[i] != start_val) { + fprintf(stderr, "Expected 0x%08x, found 0x%08x " + "at offset 0x%08x\n", + start_val, linear[i], i * 4); + abort(); + } + start_val++; + } + drm_intel_bo_unmap(bo); +} + +int main(int argc, char **argv) +{ + drm_intel_bo *bo[4096]; + uint32_t bo_start_val[4096]; + uint32_t start = 0; + int i, fd, count; + + fd = drm_open_any(); + + count = 3 * gem_aperture_size(fd) / (1024*1024) / 2; + printf("Using %d 1MiB buffers\n", count); + assert(count <= 4096); + + bufmgr = drm_intel_bufmgr_gem_init(fd, 4096); + drm_intel_bufmgr_gem_enable_reuse(bufmgr); + batch = intel_batchbuffer_alloc(bufmgr, intel_get_drm_devid(fd)); + + for (i = 0; i < count; i++) { + bo[i] = create_bo(start); + bo_start_val[i] = start; + + /* + printf("Creating bo %d\n", i); + check_bo(bo[i], bo_start_val[i]); + */ + + start += 1024 * 1024 / 4; + } + + for (i = 0; i < count * 4; i++) { + int src = random() % count; + int dst = random() % count; + + if (src == dst) + continue; + + intel_copy_bo(batch, bo[dst], bo[src], width, height); + bo_start_val[dst] = bo_start_val[src]; + + /* + check_bo(bo[dst], bo_start_val[dst]); + printf("%d: copy bo %d to %d\n", i, src, dst); + */ + } + + for (i = 0; i < count; i++) { + /* + printf("check %d\n", i); + */ + check_bo(bo[i], bo_start_val[i]); + + drm_intel_bo_unreference(bo[i]); + bo[i] = NULL; + } + + intel_batchbuffer_free(batch); + drm_intel_bufmgr_destroy(bufmgr); + + close(fd); + + return 0; +} diff --git a/tests/gem_tiled_pread.c b/tests/gem_tiled_pread.c index ed7d8582..c3c6ed74 100644 --- a/tests/gem_tiled_pread.c +++ b/tests/gem_tiled_pread.c @@ -44,48 +44,108 @@ #include #include #include +#include +#include #include "drm.h" #include "i915_drm.h" #include "drmtest.h" -#include "intel_bufmgr.h" -#include "intel_batchbuffer.h" -#include "intel_gpu_tools.h" -static drm_intel_bufmgr *bufmgr; -struct intel_batchbuffer *batch; -static const int width = 512, height = 512; -static const int size = 1024 * 1024; +#define WIDTH 512 +#define HEIGHT 512 +static uint32_t linear[WIDTH * HEIGHT]; #define PAGE_SIZE 4096 -static drm_intel_bo * -create_bo(uint32_t devid) +static uint32_t +gem_create(int fd, int size) { - drm_intel_bo *bo, *linear_bo; - uint32_t *linear; - uint32_t tiling = I915_TILING_X; - int ret, i; - int val = 0; - - bo = drm_intel_bo_alloc(bufmgr, "tiled bo", size, 4096); - ret = drm_intel_bo_set_tiling(bo, &tiling, width * 4); + struct drm_i915_gem_create create; + + create.handle = 0; + create.size = size; + (void)drmIoctl(fd, DRM_IOCTL_I915_GEM_CREATE, &create); + + return create.handle; +} + +static void *gem_mmap(int fd, uint32_t handle, int size, int prot) +{ + struct drm_i915_gem_mmap_gtt mmap_arg; + void *ptr; + + mmap_arg.handle = handle; + if (drmIoctl(fd, DRM_IOCTL_I915_GEM_MMAP_GTT, &mmap_arg)) + return NULL; + + ptr = mmap(0, size, prot, MAP_SHARED, fd, mmap_arg.offset); + if (ptr == MAP_FAILED) + ptr = NULL; + + return ptr; +} + +static void +gem_read(int fd, uint32_t handle, int offset, int length, void *buf) +{ + struct drm_i915_gem_pread pread; + int ret; + + pread.handle = handle; + pread.offset = offset; + pread.size = length; + pread.data_ptr = (uintptr_t)buf; + ret = drmIoctl(fd, DRM_IOCTL_I915_GEM_PREAD, &pread); assert(ret == 0); - assert(tiling == I915_TILING_X); - linear_bo = drm_intel_bo_alloc(bufmgr, "linear src", size, 4096); +} - /* Fill the BO with dwords starting at start_val */ - drm_intel_bo_map(linear_bo, 1); - linear = linear_bo->virtual; +static void +gem_set_tiling(int fd, uint32_t handle, int tiling) +{ + struct drm_i915_gem_set_tiling set_tiling; + int ret; - for (i = 0; i < 1024 * 1024 / 4; i++) - linear[i] = val++; - drm_intel_bo_unmap(linear_bo); + do { + set_tiling.handle = handle; + set_tiling.tiling_mode = tiling; + set_tiling.stride = WIDTH * sizeof(uint32_t); - intel_copy_bo(batch, bo, linear_bo, width, height); + ret = ioctl(fd, DRM_IOCTL_I915_GEM_SET_TILING, &set_tiling); + } while (ret == -1 && (errno == EINTR || errno == EAGAIN)); +} - drm_intel_bo_unreference(linear_bo); +static void +gem_get_tiling(int fd, uint32_t handle, uint32_t *tiling, uint32_t *swizzle) +{ + struct drm_i915_gem_get_tiling get_tiling; + int ret; - return bo; + memset(&get_tiling, 0, sizeof(get_tiling)); + get_tiling.handle = handle; + + ret = drmIoctl(fd, DRM_IOCTL_I915_GEM_GET_TILING, &get_tiling); + assert(ret == 0); + + *tiling = get_tiling.tiling_mode; + *swizzle = get_tiling.swizzle_mode; +} + +static uint32_t +create_bo(int fd) +{ + uint32_t handle; + uint32_t *data; + int i; + + handle = gem_create(fd, sizeof(linear)); + gem_set_tiling(fd, handle, I915_TILING_X); + + /* Fill the BO with dwords starting at start_val */ + data = gem_mmap(fd, handle, sizeof(linear), PROT_READ | PROT_WRITE); + for (i = 0; i < WIDTH*HEIGHT; i++) + data[i] = i; + munmap(data, sizeof(linear)); + + return handle; } static int @@ -101,48 +161,40 @@ static uint32_t calculate_expected(int offset) { int tile_off = offset & (PAGE_SIZE - 1); - int tile_base = offset - tile_off; + int tile_base = offset & -PAGE_SIZE; int tile_index = tile_base / PAGE_SIZE; - int tiles_per_row = width / (512 / 4); /* X tiled = 512b rows */ + int tiles_per_row = 4*WIDTH / 512; /* X tiled = 512b rows */ /* base x,y values from the tile (page) index. */ int base_y = tile_index / tiles_per_row * 8; int base_x = tile_index % tiles_per_row * 128; - assert((offset % 4) == 0); /* x, y offsets within the tile */ int tile_y = tile_off / 512; int tile_x = (tile_off % 512) / 4; /* printf("%3d, %3d, %3d,%3d\n", base_x, base_y, tile_x, tile_y); */ - return (base_y + tile_y) * width + base_x + tile_x; + return (base_y + tile_y) * WIDTH + base_x + tile_x; } int main(int argc, char **argv) { int fd; - uint32_t devid; - drm_intel_bo *bo; int i, iter = 100; - uint32_t buf[width * height]; uint32_t tiling, swizzle; + uint32_t handle; fd = drm_open_any(); - devid = intel_get_drm_devid(fd); - - bufmgr = drm_intel_bufmgr_gem_init(fd, 4096); - drm_intel_bufmgr_gem_enable_reuse(bufmgr); - batch = intel_batchbuffer_alloc(bufmgr, intel_get_drm_devid(fd)); - bo = create_bo(devid); - - drm_intel_bo_get_tiling(bo, &tiling, &swizzle); + handle = create_bo(fd); + gem_get_tiling(fd, handle, &tiling, &swizzle); /* 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; @@ -153,15 +205,12 @@ main(int argc, char **argv) if (offset + len > size) len = size - offset; - /* For sanity of reporting, make the first iteration be the - * whole buffer. - */ if (i == 0) { offset = 0; len = size; } - drm_intel_bo_get_subdata(bo, offset, len, buf); + gem_read(fd, handle, offset, len, linear); /* Translate from offsets in the read buffer to the swizzled * address that it corresponds to. This is the opposite of @@ -171,30 +220,36 @@ main(int argc, char **argv) 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", @@ -202,23 +257,19 @@ main(int argc, char **argv) abort(); } expected_val = calculate_expected(swizzled_offset); - found_val = buf[(j - offset) / 4]; + found_val = linear[(j - offset) / 4]; if (expected_val != found_val) { fprintf(stderr, - "Bad read: %d instead of %d at 0x%08x " - "for read from 0x%08x to 0x%08x\n", - found_val, expected_val, j, - offset, offset + len); + "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(); } } } - drm_intel_bo_unreference(bo); - - intel_batchbuffer_free(batch); - drm_intel_bufmgr_destroy(bufmgr); - close(fd); return 0; -- cgit v1.2.3