From 2a849a1af3d5525068274d0daa80ef09eb3d6f80 Mon Sep 17 00:00:00 2001 From: Tiago Vignatti Date: Mon, 18 May 2015 22:38:12 -0300 Subject: [PATCH] tests/vgem_fb_test: Use GEM for creating objects and mapping Important to note that GEM performs one order of magnitude better than VGEM or DRM. This commit also sets by default the printing of profiling numbers. Signed-off-by: Tiago Vignatti --- tests/vgem_fb_test.c | 108 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 91 insertions(+), 17 deletions(-) diff --git a/tests/vgem_fb_test.c b/tests/vgem_fb_test.c index 079cc970..f43d13f6 100644 --- a/tests/vgem_fb_test.c +++ b/tests/vgem_fb_test.c @@ -2,6 +2,16 @@ * Copyright 2014 The Chromium OS Authors. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. + * + * This is a test meant to benchmark VGEM performance. There are three running + * paths (VGEM, GEM and DRM) that one should set via the define macros below. + * At the moment we are only measuring memory mapping performance of a PRIME + * imported buffer object - this is pretty much useful for graphics systems + * like the Chrome's where one process creates the buffer to render and another + * maps to display it on the screen. + * + * vgem_fb_test is originally inspired from: + * https://chromium.googlesource.com/chromiumos/platform/drm-tests/+/master/vgem_fb_test.c */ #define _GNU_SOURCE @@ -18,15 +28,23 @@ #include #include -#include #include #include #include #include "drmtest.h" +// to use DRM, one has to comment both USE_GEM and USE_VGEM defines. +#define USE_GEM +//#define USE_VGEM + +#ifdef USE_GEM +#include "ioctl_wrappers.h" +#else +#include +#endif + #define BUFFERS 2 -#define USE_VGEM struct context { int drm_card_fd; @@ -34,20 +52,30 @@ struct context { int vgem_card_fd; #endif int card_fd; - struct gbm_device *drm_gbm; drmModeRes *resources; drmModeConnector *connector; drmModeEncoder *encoder; drmModeModeInfo *mode; - struct gbm_bo *gbm_buffer[BUFFERS]; - uint32_t bo_handle[BUFFERS]; uint32_t drm_fb_id[BUFFERS]; +#ifdef USE_GEM + drm_intel_bufmgr *bufmgr; + drm_intel_bo *intel_bo_handle[BUFFERS]; + unsigned long bo_stride; +#else + struct gbm_device *drm_gbm; + struct gbm_bo *gbm_buffer[BUFFERS]; +#endif + uint32_t bo_handle[BUFFERS]; }; -static int enable_profiling = false; +#ifdef USE_GEM +#define BO_SIZE (16*4096) +#endif + +static int disable_profiling = false; void disable_psr() { const char psr_path[] = "/sys/module/i915/parameters/enable_psr"; @@ -112,6 +140,17 @@ static double elapsed(const struct timeval *start, const struct timeval *end) return 1e6*(end->tv_sec - start->tv_sec) + (end->tv_usec - start->tv_usec); } +#ifdef USE_GEM +void * mmap_intel_bo(drm_intel_bo *buffer) +{ + if (drm_intel_bo_map(buffer, 1)) { + fprintf(stderr, "fail to map a drm buffer\n"); + return NULL; + } + assert(buffer->virtual); + return buffer->virtual; +} +#else void * mmap_dumb_bo(int fd, int handle, size_t size) { struct drm_mode_map_dumb mmap_arg; @@ -133,6 +172,7 @@ void * mmap_dumb_bo(int fd, int handle, size_t size) return ptr; } +#endif bool setup_drm(struct context *ctx) { @@ -271,8 +311,13 @@ void draw(struct context *ctx) for (sequence_index = 0; sequence_index < 4; sequence_index++) { show_sequence(sequences[sequence_index]); for (i = 0; i < 0x100; i++) { +#ifdef USE_GEM + size_t bo_stride = ctx->bo_stride; + size_t bo_size = ctx->bo_stride * ctx->mode->vdisplay; +#else size_t bo_stride = gbm_bo_get_stride(ctx->gbm_buffer[fb_idx]); size_t bo_size = gbm_bo_get_stride(ctx->gbm_buffer[fb_idx]) * gbm_bo_get_height(ctx->gbm_buffer[fb_idx]); +#endif uint32_t *bo_ptr; volatile uint32_t *ptr; struct timeval start, end; @@ -280,10 +325,14 @@ void draw(struct context *ctx) for (sequence_subindex = 0; sequence_subindex < 4; sequence_subindex++) { switch (sequences[sequence_index][sequence_subindex]) { case STEP_MMAP: - if (enable_profiling) + if (!disable_profiling) gettimeofday(&start, NULL); +#ifdef USE_GEM + bo_ptr = (uint32_t*)mmap_intel_bo(ctx->intel_bo_handle[fb_idx]); +#else bo_ptr = mmap_dumb_bo(ctx->drm_card_fd, ctx->bo_handle[fb_idx], bo_size); - if (enable_profiling) { +#endif + if (!disable_profiling) { gettimeofday(&end, NULL); fprintf(stderr, "time to execute mmap: %7.3fms\n", elapsed(&start, &end) / 1000); @@ -321,9 +370,11 @@ void draw(struct context *ctx) break; } } - +#ifdef USE_GEM + drm_intel_bo_unmap(ctx->intel_bo_handle[fb_idx]); +#else munmap(bo_ptr, bo_size); - +#endif usleep(1e6 / 120); /* 120 Hz */ fb_idx = fb_idx ^ 1; @@ -338,7 +389,7 @@ static int opt_handler(int opt, int opt_index) drm_card_path = optarg; break; case 'p': - enable_profiling = true; + disable_profiling = true; break; } @@ -354,7 +405,7 @@ int main(int argc, char **argv) int drm_prime_fd; size_t i; - igt_simple_init_parse_opts(&argc, argv, "d:p", NULL, NULL, opt_handler); + igt_simple_init_parse_opts(&argc, argv, "d:p", NULL, NULL, opt_handler, NULL); igt_skip_on_simulation(); do_fixes(); @@ -365,6 +416,11 @@ int main(int argc, char **argv) ret = 1; goto fail; } +#ifdef USE_GEM + ctx.bufmgr = drm_intel_bufmgr_gem_init(ctx.drm_card_fd, BO_SIZE); + ctx.card_fd = ctx.drm_card_fd; + fprintf(stderr, "Method to open video card: GEM\n"); +#else #ifdef USE_VGEM ctx.vgem_card_fd = drm_open_vgem(); if (ctx.vgem_card_fd < 0) { @@ -385,6 +441,7 @@ int main(int argc, char **argv) ret = 1; goto close_card; } +#endif // USE_GEM if (!setup_drm(&ctx)) { fprintf(stderr, "failed to setup drm resources\n"); @@ -395,8 +452,18 @@ int main(int argc, char **argv) fprintf(stderr, "display size: %dx%d\n", ctx.mode->hdisplay, ctx.mode->vdisplay); - for (i = 0; i < BUFFERS; ++i) { +#ifdef USE_GEM + uint32_t tiling_mode = I915_TILING_NONE; + drm_intel_bo *intel_bo = NULL; + intel_bo = drm_intel_bo_alloc_tiled( + ctx.bufmgr, + "chromium-gpu-memory-buffer", + ctx.mode->hdisplay, ctx.mode->vdisplay, + 4, &tiling_mode, &bo_stride, 0); + ctx.bo_stride = bo_stride; + drm_intel_bo_gem_export_to_prime(intel_bo, &drm_prime_fd); +#else ctx.gbm_buffer[i] = gbm_bo_create(ctx.drm_gbm, ctx.mode->hdisplay, ctx.mode->vdisplay, GBM_BO_FORMAT_XRGB8888, GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING); @@ -411,7 +478,7 @@ int main(int argc, char **argv) bo_stride = gbm_bo_get_stride(ctx.gbm_buffer[i]); drm_prime_fd = gbm_bo_get_fd(ctx.gbm_buffer[i]); - +#endif // USE_GEM if (drm_prime_fd < 0) { fprintf(stderr, "failed to turn handle into fd\n"); ret = 1; @@ -419,16 +486,19 @@ int main(int argc, char **argv) } ret = drmPrimeFDToHandle(ctx.drm_card_fd, drm_prime_fd, - &ctx.bo_handle[i]); + &ctx.bo_handle[i]); if (ret) { fprintf(stderr, "failed to import handle\n"); ret = 1; goto free_buffers; } +#ifdef USE_GEM + ctx.intel_bo_handle[i] = drm_intel_bo_gem_create_from_prime( + ctx.bufmgr, drm_prime_fd, BO_SIZE); +#endif ret = drmModeAddFB(ctx.drm_card_fd, ctx.mode->hdisplay, ctx.mode->vdisplay, - 24, 32, bo_stride, bo_handle, &ctx.drm_fb_id[i]); - + 24, 32, bo_stride, ctx.bo_handle[i], &ctx.drm_fb_id[i]); if (ret) { fprintf(stderr, "failed to add fb\n"); ret = 1; @@ -449,15 +519,19 @@ free_buffers: for (i = 0; i < BUFFERS; ++i) { if (ctx.drm_fb_id[i]) drmModeRmFB(ctx.drm_card_fd, ctx.drm_fb_id[i]); +#ifndef USE_GEM if (ctx.gbm_buffer[i]) gbm_bo_destroy(ctx.gbm_buffer[i]); +#endif } drmModeFreeConnector(ctx.connector); drmModeFreeEncoder(ctx.encoder); drmModeFreeResources(ctx.resources); destroy_drm_gbm: +#ifndef USE_GEM gbm_device_destroy(ctx.drm_gbm); +#endif close_card: #ifdef USE_VGEM close(ctx.vgem_card_fd);