From 9cfcb75b79829230dc9dde1247a82ffe8b0b9702 Mon Sep 17 00:00:00 2001 From: Ben Widawsky Date: Fri, 11 May 2012 13:54:12 -0700 Subject: tests/wait render timeout test Assures that signals interrupting the wait works properly. Because of the scheduling around signals, interrupted waits will *seem* faster as the GPU continues to work while all the CPU scheduling stuff happens. Signed-off-by: Ben Widawsky --- tests/Makefile.am | 3 + tests/gem_wait_render_timeout.c | 155 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 158 insertions(+) create mode 100644 tests/gem_wait_render_timeout.c diff --git a/tests/Makefile.am b/tests/Makefile.am index c7f4f736..1b49c295 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -63,6 +63,7 @@ TESTS_progs = \ drm_vma_limiter_cached \ sysfs_rc6_residency \ flip_test \ + gem_wait_render_timeout \ $(NULL) # IMPORTANT: The ZZ_ tests need to be run last! @@ -117,3 +118,5 @@ AM_CFLAGS += $(CAIRO_CFLAGS) $(LIBUDEV_CFLAGS) $(GLIB_CFLAGS) gem_fence_thrash_CFLAGS = $(AM_CFLAGS) $(THREAD_CFLAGS) gem_fence_thrash_LDADD = $(LDADD) -lpthread + +gem_wait_render_timeout_LDADD = $(LDADD) -lrt diff --git a/tests/gem_wait_render_timeout.c b/tests/gem_wait_render_timeout.c new file mode 100644 index 00000000..8edfc43e --- /dev/null +++ b/tests/gem_wait_render_timeout.c @@ -0,0 +1,155 @@ +/* + * Copyright © 2012 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: + * Ben Widawsky + * + */ + +#include +#include +#include "drm.h" +#include "rendercopy.h" + +#define MSEC_PER_SEC 1000L +#define USEC_PER_MSEC 1000L +#define NSEC_PER_USEC 1000L +#define NSEC_PER_MSEC 1000000L +#define USEC_PER_SEC 1000000L +#define NSEC_PER_SEC 1000000000L + +#define ENOUGH_WORK_IN_SECONDS 2 +#define BUF_SIZE (8<<20) +#define BUF_PAGES ((8<<20)>>12) +drm_intel_bo *dst, *dst2; + +/* returns time diff in milliseconds */ +static int64_t +do_time_diff(struct timespec *end, struct timespec *start) +{ + int64_t ret; + ret = (NSEC_PER_MSEC * difftime(end->tv_sec, start->tv_sec)) + + ((end->tv_nsec/NSEC_PER_MSEC) - (start->tv_nsec/NSEC_PER_MSEC)); + return ret; +} + + +static void blt_color_fill(struct intel_batchbuffer *batch, + drm_intel_bo *buf, + const unsigned int pages) +{ + const unsigned short height = pages; + const unsigned short width = 4096; + BEGIN_BATCH(5); + OUT_BATCH(COLOR_BLT_CMD | + COLOR_BLT_WRITE_ALPHA | + COLOR_BLT_WRITE_RGB); + OUT_BATCH((3 << 24) | /* 32 Bit Color */ + 0xF0 | /* Raster OP copy background register */ + 0); /* Dest pitch is 0 */ + OUT_BATCH(width << 16 | + height); + OUT_RELOC(buf, I915_GEM_DOMAIN_RENDER, 0, 0); + OUT_BATCH(rand()); /* random pattern */ + ADVANCE_BATCH(); +} + +int main(int argc, char **argv) +{ + drm_intel_bufmgr *bufmgr; + struct intel_batchbuffer *batch; + uint64_t timeout = ENOUGH_WORK_IN_SECONDS * NSEC_PER_SEC; + int fd, ret; + const bool do_signals = true; /* signals will seem to make the operation + * use less process CPU time */ + bool done = false; + int i, iter = 0x100; + + fd = drm_open_any(); + + 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)); + + dst = drm_intel_bo_alloc(bufmgr, "dst", BUF_SIZE, 4096); + dst2 = drm_intel_bo_alloc(bufmgr, "dst2", BUF_SIZE, 4096); + + /* Figure out a rough number of fills required to consume 1 second of + * GPU work. + */ + do { + struct timespec start, end; + long diff; + + assert(clock_gettime(CLOCK_MONOTONIC_RAW, &start) == 0); + for (i = 0; i < iter; i++) + blt_color_fill(batch, dst, BUF_PAGES); + intel_batchbuffer_flush(batch); + drm_intel_bo_wait_rendering(dst); + assert(clock_gettime(CLOCK_MONOTONIC_RAW, &end) == 0); + + diff = do_time_diff(&end, &start); + assert(diff >= 0); + + if ((diff / MSEC_PER_SEC) > ENOUGH_WORK_IN_SECONDS) + done = true; + else + iter <<= 1; + } while (!done && iter < 1000000); + + assert(iter < 1000000); + + printf("%d iters is enough work\n", iter); + gem_quiescent_gpu(fd); + if (do_signals) + drmtest_fork_signal_helper(); + /* We should be able to do half as much work in the same amount of time */ + for (i = 0; i < iter; i++) + blt_color_fill(batch, dst2, BUF_PAGES); + + intel_batchbuffer_flush(batch); + + ret = drm_intel_gem_bo_wait(dst2, &timeout); + if (do_signals) + drmtest_stop_signal_helper(); + if (ret) { + fprintf(stderr, "Timed wait failed %s\n", strerror(errno)); + exit(EXIT_FAILURE); + } + + assert(timeout != 0); + + if (timeout == (ENOUGH_WORK_IN_SECONDS * NSEC_PER_SEC)) + printf("Buffer was already done!\n"); + else { + printf("Finished with %lu time remaining\n", timeout); + } + + drm_intel_bo_unreference(dst2); + drm_intel_bo_unreference(dst); + intel_batchbuffer_free(batch); + drm_intel_bufmgr_destroy(bufmgr); + + close(fd); + + return 0; +} -- cgit v1.2.3