From patchwork Thu Dec 13 14:01:08 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arto Merilainen X-Patchwork-Id: 1874181 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by patchwork2.kernel.org (Postfix) with ESMTP id A5DCBDF2EF for ; Thu, 13 Dec 2012 14:33:01 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 6A91FE67E8 for ; Thu, 13 Dec 2012 06:14:58 -0800 (PST) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from hqemgate04.nvidia.com (hqemgate04.nvidia.com [216.228.121.35]) by gabe.freedesktop.org (Postfix) with ESMTP id E33374C8CC for ; Thu, 13 Dec 2012 06:02:11 -0800 (PST) Received: from hqnvupgp05.nvidia.com (Not Verified[216.228.121.13]) by hqemgate04.nvidia.com id ; Thu, 13 Dec 2012 06:01:47 -0800 Received: from hqemhub02.nvidia.com ([172.17.108.22]) by hqnvupgp05.nvidia.com (PGP Universal service); Thu, 13 Dec 2012 06:02:08 -0800 X-PGP-Universal: processed; by hqnvupgp05.nvidia.com on Thu, 13 Dec 2012 06:02:08 -0800 Received: from deemhub01.nvidia.com (10.21.69.137) by hqemhub02.nvidia.com (172.20.150.31) with Microsoft SMTP Server (TLS) id 8.3.279.1; Thu, 13 Dec 2012 06:02:07 -0800 Received: from amerilainen-lnx.Nvidia.com (10.21.65.27) by deemhub01.nvidia.com (10.21.69.137) with Microsoft SMTP Server (TLS) id 8.3.279.1; Thu, 13 Dec 2012 15:02:04 +0100 From: =?UTF-8?q?Arto=20Meril=C3=A4inen?= To: , , Subject: [RFC,libdrm 3/3] tests: tegra: Add 2d tests Date: Thu, 13 Dec 2012 16:01:08 +0200 Message-ID: <1355407268-32381-4-git-send-email-amerilainen@nvidia.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1355407268-32381-1-git-send-email-amerilainen@nvidia.com> References: <1355407268-32381-1-git-send-email-amerilainen@nvidia.com> X-NVConfidentiality: public MIME-Version: 1.0 Cc: fhart@nvidia.com, tbergstrom@nvidia.com X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: dri-devel-bounces+patchwork-dri-devel=patchwork.kernel.org@lists.freedesktop.org Errors-To: dri-devel-bounces+patchwork-dri-devel=patchwork.kernel.org@lists.freedesktop.org From: Francis Hart This patch adds a test application for 2d library. The application performs 2d operations using the hardware and outputs the results into files. Signed-off-by: Francis Hart --- configure.ac | 1 + tests/tegra/2d/Makefile.am | 13 ++ tests/tegra/2d/tegra_2d_test.c | 413 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 427 insertions(+) create mode 100644 tests/tegra/2d/Makefile.am create mode 100644 tests/tegra/2d/tegra_2d_test.c diff --git a/configure.ac b/configure.ac index 36c55c7..b1170d3 100644 --- a/configure.ac +++ b/configure.ac @@ -376,6 +376,7 @@ AC_CONFIG_FILES([ tests/kmstest/Makefile tests/radeon/Makefile tests/vbltest/Makefile + tests/tegra/2d/Makefile include/Makefile include/drm/Makefile man/Makefile diff --git a/tests/tegra/2d/Makefile.am b/tests/tegra/2d/Makefile.am new file mode 100644 index 0000000..6967fbf --- /dev/null +++ b/tests/tegra/2d/Makefile.am @@ -0,0 +1,13 @@ +AM_CFLAGS = \ + -I $(top_srcdir)/include/drm \ + -I $(top_srcdir) + +LDADD = \ + $(top_builddir)/libdrm.la \ + $(top_builddir)/tegra/libdrm_tegra.la + +noinst_PROGRAMS = \ + tegra_2d_test + +tegra_2d_test_SOURCES = \ + tegra_2d_test.c diff --git a/tests/tegra/2d/tegra_2d_test.c b/tests/tegra/2d/tegra_2d_test.c new file mode 100644 index 0000000..11cc089 --- /dev/null +++ b/tests/tegra/2d/tegra_2d_test.c @@ -0,0 +1,413 @@ +/* + * Copyright (C) 2012 NVIDIA 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: + * Francis Hart + */ + +#include +#include +#include +#include "tegra/tegra_drmif.h" +#include "tegra/tegra_2d.h" +#include "xf86drm.h" +#include "xf86drmMode.h" +#include "include/drm/drm_fourcc.h" + +static void +set_pixel_color(struct tegra_2d_surface *surface, + int x, + int y, + struct tegra_2d_surface_color *color) +{ + int i; + + for (i=0; inum_planes; ++i) + { + int px; + int py; + int offset; + uint32_t bytes_per_pixel; + const uint8_t *src; + uint8_t *dst; + void *ptr; + struct tegra_2d_plane *plane = &surface->planes[i]; + + bytes_per_pixel = TEGRA_2D_FORMAT_BYTES(plane->format); + + ptr = tegra_bo_map(plane->mem_handle); + if (ptr == NULL) + continue; + + px = (x * plane->width) / surface->planes[0].width; + py = (y * plane->height) / surface->planes[0].height; + + offset = (py * plane->pitch) + (px * bytes_per_pixel); + + src = (const uint8_t *) &color->planes[i].value; + dst = ((uint8_t *) ptr) + plane->mem_offset + offset; + + switch (bytes_per_pixel) + { + case 4: dst[3] = src[3]; + case 3: dst[2] = src[2]; + case 2: dst[1] = src[1]; + case 1: dst[0] = src[0]; + default: + break; + } + + tegra_bo_unmap(plane->mem_handle); + } +} + +static void +set_pixel_rgba(struct tegra_2d_surface *surface, + int x, + int y, + uint32_t r, + uint32_t g, + uint32_t b, + uint32_t a) +{ + struct tegra_2d_surface_color color; + + color.num_planes = surface->num_planes; + color.planes[0].format = surface->planes[0].format; + color.planes[1].format = surface->planes[1].format; + color.planes[2].format = surface->planes[2].format; + + tegra_2d_color_from_rgba(&color, r, g, b, a); + + set_pixel_color(surface, x, y, &color); +} + +static void +clear_surface(struct tegra_2d_surface *surface, + uint32_t r, + uint32_t g, + uint32_t b, + uint32_t a) +{ + int x; + int y; + struct tegra_2d_surface_color color; + + color.num_planes = surface->num_planes; + color.planes[0].format = surface->planes[0].format; + color.planes[1].format = surface->planes[1].format; + color.planes[2].format = surface->planes[2].format; + + tegra_2d_color_from_rgba(&color, r, g, b, a); + + for (y=0; yplanes[0].height; ++y) + for (x=0; xplanes[0].width; ++x) + set_pixel_color(surface, x, y, &color); +} + +static int +test_fill(struct tegra_2d_context *ctx) +{ + int result; + struct tegra_2d_surface dst; + struct tegra_2d_surface_color color; + + memset(&dst, 0, sizeof(struct tegra_2d_surface)); + + dst.num_planes = 1; + dst.planes[0].width = 16; + dst.planes[0].height = 16; + dst.planes[0].format = TEGRA_2D_FORMAT_A8R8G8B8; + dst.planes[0].layout = TEGRA_2D_LAYOUT_LINEAR; + + color.num_planes = 1; + color.planes[0].format = TEGRA_2D_FORMAT_A8R8G8B8; + color.planes[0].value = 0xFF00FFFF; + + result = tegra_2d_allocate_surface(ctx, &dst); + if (result != TEGRA_2D_OK) + goto exit; + + clear_surface(&dst, 255, 255, 0, 255); + + result = tegra_2d_begin(ctx, NULL); + if (result != TEGRA_2D_OK) + goto exit; + + result = tegra_2d_fill(ctx, &dst, &color, NULL); + if (result != TEGRA_2D_OK) + goto exit; + + result = tegra_2d_end(ctx, NULL); + if (result != TEGRA_2D_OK) + goto exit; + +exit: + tegra_2d_free_surface(ctx, &dst); + + return result == TEGRA_2D_OK ? 1 : 0; +} + +static int +test_copy(struct tegra_2d_context *ctx) +{ + int result; + struct tegra_2d_surface src; + struct tegra_2d_surface dst; + + memset(&dst, 0, sizeof(struct tegra_2d_surface)); + + src.num_planes = 3; + src.planes[0].width = 16; + src.planes[0].height = 16; + src.planes[0].format = TEGRA_2D_FORMAT_Y8; + src.planes[0].layout = TEGRA_2D_LAYOUT_LINEAR; + src.planes[1].width = 8; + src.planes[1].height = 8; + src.planes[1].format = TEGRA_2D_FORMAT_U8; + src.planes[1].layout = TEGRA_2D_LAYOUT_LINEAR; + src.planes[2].width = 8; + src.planes[2].height = 8; + src.planes[2].format = TEGRA_2D_FORMAT_V8; + src.planes[2].layout = TEGRA_2D_LAYOUT_LINEAR; + + dst.num_planes = 3; + dst.planes[0].width = 16; + dst.planes[0].height = 16; + dst.planes[0].format = TEGRA_2D_FORMAT_Y8; + dst.planes[0].layout = TEGRA_2D_LAYOUT_LINEAR; + dst.planes[1].width = 8; + dst.planes[1].height = 8; + dst.planes[1].format = TEGRA_2D_FORMAT_U8; + dst.planes[1].layout = TEGRA_2D_LAYOUT_LINEAR; + dst.planes[2].width = 8; + dst.planes[2].height = 8; + dst.planes[2].format = TEGRA_2D_FORMAT_V8; + dst.planes[2].layout = TEGRA_2D_LAYOUT_LINEAR; + + result = tegra_2d_allocate_surface(ctx, &src); + if (result != TEGRA_2D_OK) + goto exit; + + result = tegra_2d_allocate_surface(ctx, &dst); + if (result != TEGRA_2D_OK) + goto exit; + + clear_surface(&dst, 255, 255, 0, 255); + clear_surface(&src, 255, 0, 255, 255); + + set_pixel_rgba(&src, 1, 1, 255, 0, 0, 255); + set_pixel_rgba(&src, 2, 1, 0, 255, 0, 255); + set_pixel_rgba(&src, 1, 2, 0, 0, 255, 255); + + result = tegra_2d_begin(ctx, NULL); + if (result != TEGRA_2D_OK) + goto exit; + + result = tegra_2d_copy(ctx, + &dst, + &src, + NULL, + NULL, + TEGRA_2D_TRANSFORM_IDENTITY); + if (result != TEGRA_2D_OK) + goto exit; + + result = tegra_2d_end(ctx, NULL); + if (result != TEGRA_2D_OK) + goto exit; + +exit: + tegra_2d_free_surface(ctx, &src); + tegra_2d_free_surface(ctx, &dst); + + return result == TEGRA_2D_OK ? 1 : 0; +} + +static int +test_transform(struct tegra_2d_context *ctx) +{ + int result; + struct tegra_2d_surface src; + struct tegra_2d_surface dst; + + memset(&dst, 0, sizeof(struct tegra_2d_surface)); + + src.num_planes = 1; + src.planes[0].width = 10; + src.planes[0].height = 10; + src.planes[0].format = TEGRA_2D_FORMAT_A8R8G8B8; + src.planes[0].layout = TEGRA_2D_LAYOUT_LINEAR; + + dst.num_planes = 1; + dst.planes[0].width = 10; + dst.planes[0].height = 10; + dst.planes[0].format = TEGRA_2D_FORMAT_A8R8G8B8; + dst.planes[0].layout = TEGRA_2D_LAYOUT_LINEAR; + + result = tegra_2d_allocate_surface(ctx, &src); + if (result != TEGRA_2D_OK) + goto exit; + + result = tegra_2d_allocate_surface(ctx, &dst); + if (result != TEGRA_2D_OK) + goto exit; + + clear_surface(&dst, 255, 255, 0, 255); + clear_surface(&src, 255, 0, 255, 255); + + set_pixel_rgba(&src, 1, 1, 255, 0, 0, 255); + set_pixel_rgba(&src, 2, 1, 0, 255, 0, 255); + set_pixel_rgba(&src, 1, 2, 0, 0, 255, 255); + + result = tegra_2d_begin(ctx, NULL); + if (result != TEGRA_2D_OK) + goto exit; + + result = tegra_2d_copy(ctx, + &dst, + &src, + NULL, + NULL, + TEGRA_2D_TRANSFORM_ROT_90); + if (result != TEGRA_2D_OK) + goto exit; + + result = tegra_2d_end(ctx, NULL); + if (result != TEGRA_2D_OK) + goto exit; + +exit: + tegra_2d_free_surface(ctx, &src); + tegra_2d_free_surface(ctx, &dst); + + return result == TEGRA_2D_OK ? 1 : 0; +} + +static int +test_scale(struct tegra_2d_context *ctx) +{ + int result; + struct tegra_2d_surface src; + struct tegra_2d_surface dst; + + memset(&dst, 0, sizeof(struct tegra_2d_surface)); + + src.num_planes = 1; + src.planes[0].width = 10; + src.planes[0].height = 10; + src.planes[0].format = TEGRA_2D_FORMAT_A8R8G8B8; + src.planes[0].layout = TEGRA_2D_LAYOUT_LINEAR; + + dst.num_planes = 1; + dst.planes[0].width = 20; + dst.planes[0].height = 20; + dst.planes[0].format = TEGRA_2D_FORMAT_A8R8G8B8; + dst.planes[0].layout = TEGRA_2D_LAYOUT_LINEAR; + + result = tegra_2d_allocate_surface(ctx, &src); + if (result != TEGRA_2D_OK) + goto exit; + + result = tegra_2d_allocate_surface(ctx, &dst); + if (result != TEGRA_2D_OK) + goto exit; + + clear_surface(&dst, 255, 255, 0, 255); + clear_surface(&src, 255, 255, 255, 255); + + set_pixel_rgba(&src, 1, 1, 255, 0, 0, 255); + set_pixel_rgba(&src, 2, 1, 0, 255, 0, 255); + set_pixel_rgba(&src, 1, 2, 0, 0, 255, 255); + + result = tegra_2d_begin(ctx, NULL); + if (result != TEGRA_2D_OK) + goto exit; + + result = tegra_2d_copy(ctx, + &dst, + &src, + NULL, + NULL, + TEGRA_2D_TRANSFORM_IDENTITY); + if (result != TEGRA_2D_OK) + goto exit; + + result = tegra_2d_end(ctx, NULL); + if (result != TEGRA_2D_OK) + goto exit; + +exit: + tegra_2d_free_surface(ctx, &src); + tegra_2d_free_surface(ctx, &dst); + + return result == TEGRA_2D_OK ? 1 : 0; +} + +int +main(int argc, + char *argv[]) +{ + int num_failures = 0; + struct tegra_2d_context *ctx; + int fd; + + fd = drmOpen("tegra", NULL); + if (fd < 0) { + ++num_failures; + goto exit; + } + + ctx = tegra_2d_open(fd); + if (ctx == NULL) + { + ++num_failures; + goto exit; + } + + ctx->log_enable = 1; + ctx->dump_enable = 1; + + if (test_fill(ctx) == 0) + ++num_failures; + + if (test_copy(ctx) == 0) + ++num_failures; + + if (test_transform(ctx) == 0) + ++num_failures; + + if (test_scale(ctx) == 0) + ++num_failures; + +exit: + tegra_2d_close(ctx); + + if (num_failures > 0) + printf("FAILED\n"); + else + printf("PASSED\n"); + + if (fd > 0) + drmClose(fd); + return EXIT_SUCCESS; +}