diff options
Diffstat (limited to 'tests/gem_wo_map.c')
-rw-r--r-- | tests/gem_wo_map.c | 235 |
1 files changed, 235 insertions, 0 deletions
diff --git a/tests/gem_wo_map.c b/tests/gem_wo_map.c new file mode 100644 index 00000000..54165728 --- /dev/null +++ b/tests/gem_wo_map.c @@ -0,0 +1,235 @@ +/* + * Copyright © 2011 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 <ben@bwidawsk.net> + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <stdbool.h> +#include <stdint.h> +#include <string.h> +#include <assert.h> +#include <fcntl.h> +#include <inttypes.h> +#include <errno.h> +#include <sys/ioctl.h> +#include <sys/stat.h> +#include <sys/time.h> +#include <pthread.h> +#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; +drm_intel_bo *src, *dst; +int fd; +pthread_cond_t cond = PTHREAD_COND_INITIALIZER; +int num_writes = 1; + +#define NUM_MAPS 128 * 1024 +#define NUM_BLITS 128 * 1024 +#define SURFACE_SIZE (1<<20) +#define SURFACE_PAGEES (SURFACE_SIZE >> 12) +#define SURFACE_PAGES (SURFACE_SIZE >> 12) + +bool thread_ret; + +/* acts like a gpu memcpy */ +static void +blit(void) +{ + uint32_t pitch = 4096; + uint32_t lines = SURFACE_SIZE / pitch; + uint32_t line_width = pitch; + + BEGIN_BATCH(8); + OUT_BATCH((2<<29) | (0x43<<22) | (0x3<<20) | 4); + OUT_BATCH((0x3<<24) | (0xcc<<16) | pitch); + OUT_BATCH((lines<<16) | line_width); + OUT_RELOC(dst, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); + OUT_BATCH(pitch); + OUT_RELOC(src, I915_GEM_DOMAIN_RENDER, 0, 0); + ADVANCE_BATCH(); + + intel_batchbuffer_flush(batch); +} + +static inline int +get_offset(void) +{ + return (rand() % SURFACE_PAGES) * 4096; +} + +static void +touch_page(char * const base) +{ + int i = 0; + for(i = 0; i < num_writes; i++) { + base[get_offset()] = 1; + } +} + +static void * +blits(void *arg) +{ + int i = 0; + for (i = 0; i < NUM_BLITS; i++) { + blit(); + usleep(100); + } + pthread_exit(NULL); +} + +static void * +maps(void *arg) +{ + int i = 0; + for (i = 0; i < NUM_MAPS; i++) { + drm_intel_bo_map(src, 1); + touch_page(src->virtual); + drm_intel_bo_unmap(src); + } + pthread_exit(NULL); +} + +static void * +maps_nb(void *arg) +{ + int i = 0; + for (i = 0; i < NUM_MAPS; i++) { + drm_intel_gem_bo_map_nonblocking(src); + touch_page(src->virtual); + drm_intel_gem_bo_unmap_nonblocking(src); + } + pthread_exit(NULL); +} + +static void * +functional_test_nb(void *arg) +{ + drm_intel_gem_bo_map_nonblocking(src); + ((char *)src->virtual)[1000] = 1; + drm_intel_gem_bo_unmap_nonblocking(src); + blit(); + drm_intel_bo_wait_rendering(batch->bo); + + drm_intel_bo_map(dst, 0); + thread_ret = (((char *)dst->virtual)[1000] == 1); + drm_intel_bo_unmap(dst); + pthread_exit(&thread_ret); +} + +static void * +functional_test(void *arg) +{ + drm_intel_bo_map(src, 1); + ((char *)src->virtual)[1000] = 1; + drm_intel_bo_unmap(src); + blit(); + drm_intel_bo_wait_rendering(batch->bo); + + drm_intel_bo_map(dst, 0); + thread_ret = (((char *)dst->virtual)[1000] == 1); + drm_intel_bo_unmap(dst); + pthread_exit(&thread_ret); +} + +typedef void * (*thread_function)(void *); +thread_function ffuncs[2] = {functional_test, functional_test_nb}; +thread_function sfuncs[2] = {maps, maps_nb}; + +static void usage(const char *name) +{ + fprintf(stderr, "Usage: %s [-n non blocking] " + "[-f function test] " + "[-c count]\n", name); +} + +int main(int argc, char **argv) +{ + pthread_t blit_thread; + pthread_t map_thread; + int test = 0; + int non_block = 0; + char opt; + bool ret[1]; + + while ((opt = getopt(argc, argv, "nfc:")) != -1) { + switch(opt) { + case 'c': + num_writes = atoi(optarg); + break; + case 'f': + test = 1; + break; + case 'n': + non_block = 1; + break; + case 'h': + case '?': + default: + usage(argv[0]); + exit(EXIT_FAILURE); + } + } + + srandom(0xdeadbeef); + 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)); + + src = drm_intel_bo_alloc(bufmgr, "src", SURFACE_SIZE, 4096); + dst = drm_intel_bo_alloc(bufmgr, "dst", SURFACE_SIZE, 4096); + + switch (test) { + case 2: + pthread_create(&map_thread, NULL, ffuncs[non_block], NULL); + pthread_join(map_thread, (void **)&ret); + assert(*ret == true); + break; + default: + pthread_create(&blit_thread, NULL, blits, NULL); + pthread_create(&map_thread, NULL, sfuncs[non_block], NULL); + pthread_join(map_thread, NULL); + /* We don't want to time blit performance for this benchmark, + * though it is relevant. + */ + pthread_join(blit_thread, NULL); + break; + } + + intel_batchbuffer_free(batch); + drm_intel_bufmgr_destroy(bufmgr); + + close(fd); + + return 0; +} |