summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarek Szyprowski <m.szyprowski@samsung.com>2018-08-09 14:41:43 +0200
committerSeung-Woo Kim <sw0312.kim@samsung.com>2019-04-25 17:59:27 +0900
commita3c749e12b4596b5165f74d0ac6b20e69e9081af (patch)
tree4af6b77b322b4abaaa6e3bd097f8caee1be0ff44
parentb8a1aeee6b582531b263ebaa6dc0268e1c31e83d (diff)
downloadlibdrm-a3c749e12b4596b5165f74d0ac6b20e69e9081af.tar.gz
libdrm-a3c749e12b4596b5165f74d0ac6b20e69e9081af.tar.bz2
libdrm-a3c749e12b4596b5165f74d0ac6b20e69e9081af.zip
ipptest: add support for newly merged Exynos DRM IPPv2 kernel interface
This patch allows to run ipptool on latest kernels. Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com> Change-Id: I0a1a1a74b199d62b880012d14217d420e08b5e8a
-rw-r--r--tests/ipptest/Makefile.am3
-rw-r--r--tests/ipptest/fimc-ipp_v2.c274
-rw-r--r--tests/ipptest/fimc.c2
-rw-r--r--tests/ipptest/fimc.h12
-rw-r--r--tests/ipptest/fimctest.c31
5 files changed, 316 insertions, 6 deletions
diff --git a/tests/ipptest/Makefile.am b/tests/ipptest/Makefile.am
index 7b10df95..59dcae86 100644
--- a/tests/ipptest/Makefile.am
+++ b/tests/ipptest/Makefile.am
@@ -16,7 +16,8 @@ ipptest_SOURCES = \
fimctest.c \
gem.c \
util.c \
- fimc.c
+ fimc.c \
+ fimc-ipp_v2.c
ipptest_LDADD = \
$(top_builddir)/libdrm.la \
diff --git a/tests/ipptest/fimc-ipp_v2.c b/tests/ipptest/fimc-ipp_v2.c
new file mode 100644
index 00000000..84c8cea4
--- /dev/null
+++ b/tests/ipptest/fimc-ipp_v2.c
@@ -0,0 +1,274 @@
+/*
+ * DRM based IPPv2 test program
+ * Copyright 2018 Samsung Electronics
+ * Marek Szyprowski <m.szyprowski@sasmsung.com>
+ *
+ * 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 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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <sys/mman.h>
+
+#include "exynos_drm.h"
+#include "fimctest.h"
+#include "gem.h"
+#include "util.h"
+#include "fimc.h"
+
+
+#include "drm_fourcc.h"
+#include "drm_mode.h"
+#include "libkms.h"
+#include "internal.h"
+
+struct exynos_drm_ipp_std_task {
+ struct drm_exynos_ipp_task_buffer buf[2];
+ struct drm_exynos_ipp_task_rect rect[2];
+ struct drm_exynos_ipp_task_transform transform;
+} __packed;
+
+void fimc_v2_m2m_set_mode(struct device *dev, struct connector *c, int count,
+ enum drm_exynos_degree degree, enum drm_exynos_ipp_cmd_m2m display,
+ long int *usec)
+{
+ struct drm_exynos_sz def_sz;
+ struct drm_exynos_sz src_sz;
+ void *usr_addr1[MAX_BUF], *usr_addr2[MAX_BUF];
+ uint32_t handles[4], pitches[4], offsets[4] = {0};
+ struct kms_bo *bo_src[MAX_BUF] = { NULL, }, *bo_dst = NULL;
+ struct pipe_arg pipe;
+ unsigned int fb_id_dst;
+ int ret, i, j;
+
+ struct timeval begin, end;
+ char filename[80];
+
+ struct exynos_drm_ipp_std_task task = { 0 };
+ struct drm_exynos_ioctl_ipp_commit arg = { 0 };
+
+ src_sz = c[0].src_sz;
+ printf("source image resolution [%ux%u]\n", src_sz.hsize, src_sz.vsize);
+
+ dev->mode.width = 0;
+ dev->mode.height = 0;
+
+ /* For crtc and mode */
+ for (i = 0; i < count; i++) {
+ ret = pipe_find_crtc_and_mode(dev, &pipe, &c[i]);
+ if (ret < 0)
+ continue;
+
+ dev->mode.width += pipe.mode->hdisplay;
+ if (dev->mode.height < pipe.mode->vdisplay)
+ dev->mode.height = pipe.mode->vdisplay;
+ }
+
+ for (i = 0; i < MAX_BUF; i++) {
+ /* For source buffer */
+ bo_src[i] = util_kms_gem_create_mmap(dev->kms, DRM_FORMAT_XRGB8888,
+ src_sz.hsize, src_sz.vsize,
+ handles, pitches, offsets);
+ if (!bo_src[i])
+ goto err_ipp_src_buff_close;
+
+ usr_addr1[i] = bo_src[i]->ptr;
+ }
+
+ /* Create test Image
+ * Display is YUV422 format, file is RGB888 format
+ */
+ if (display == IPP_CMD_M2M_DISPLAY)
+ util_draw_buffer_yuv(usr_addr1, src_sz.hsize, src_sz.vsize);
+ else
+ fill_smpte_rgb32(usr_addr1[0], src_sz.hsize, src_sz.vsize,
+ src_sz.hsize * 4);
+
+ /* For destination buffer */
+ bo_dst = util_kms_gem_create_mmap(dev->kms, DRM_FORMAT_XRGB8888,
+ dev->mode.width, dev->mode.height,
+ handles, pitches, offsets);
+ if (!bo_dst)
+ goto err_ipp_src_buff_close;
+
+ usr_addr2[0] = bo_dst->ptr;
+
+ def_sz.hsize = dev->mode.width;
+ def_sz.vsize = dev->mode.height;
+
+ /* src buf */
+ task.buf[0].id = DRM_EXYNOS_IPP_TASK_BUFFER | DRM_EXYNOS_IPP_TASK_TYPE_SOURCE;
+ task.buf[0].width = src_sz.hsize;
+ task.buf[0].height = src_sz.vsize;
+ task.buf[0].fourcc = (display == IPP_CMD_M2M_FILE) ? DRM_FORMAT_XRGB8888 : DRM_FORMAT_YUV422;
+ for (i = 0; i < MAX_BUF; i++)
+ task.buf[0].gem_id[i] = bo_src[i]->handle;
+
+ /* dst buf */
+ task.buf[1].id = DRM_EXYNOS_IPP_TASK_BUFFER | DRM_EXYNOS_IPP_TASK_TYPE_DESTINATION;
+ task.buf[1].fourcc = DRM_FORMAT_XRGB8888;
+ task.buf[1].width = def_sz.hsize;
+ task.buf[1].height = def_sz.vsize;
+ task.buf[1].gem_id[0] = bo_dst->handle;
+ task.buf[1].pitch[0] = bo_dst->pitch;
+ task.buf[1].offset[0] = bo_dst->offset;
+
+ task.rect[0].id = DRM_EXYNOS_IPP_TASK_RECTANGLE | DRM_EXYNOS_IPP_TASK_TYPE_SOURCE;
+ task.rect[0].x = 0;
+ task.rect[0].y = 0;
+ task.rect[0].w = src_sz.hsize;
+ task.rect[0].h = src_sz.vsize;
+
+ task.rect[1].id = DRM_EXYNOS_IPP_TASK_RECTANGLE | DRM_EXYNOS_IPP_TASK_TYPE_DESTINATION;
+ task.rect[1].x = 0;
+ task.rect[1].y = 0;
+ task.rect[1].w = def_sz.hsize;
+ task.rect[1].h = def_sz.vsize;
+
+ task.transform.id = DRM_EXYNOS_IPP_TASK_TRANSFORM;
+ if (degree == EXYNOS_DRM_DEGREE_0)
+ task.transform.rotation = DRM_MODE_ROTATE_0;
+ else if (degree == EXYNOS_DRM_DEGREE_90)
+ task.transform.rotation = DRM_MODE_ROTATE_90;
+ else if (degree == EXYNOS_DRM_DEGREE_180)
+ task.transform.rotation = DRM_MODE_ROTATE_180;
+ else if (degree == EXYNOS_DRM_DEGREE_270)
+ task.transform.rotation = DRM_MODE_ROTATE_270;
+ else {
+ fprintf(stderr, "invalid rotation value\n");
+ goto err_ipp_close;
+ }
+
+ /* prepare ioctl data */
+ arg.flags = 0; /* BLOCKING call, no event */
+ arg.ipp_id = 0; /* use first IPP module available */
+ arg.params_size = sizeof(task);
+ arg.params_ptr = (unsigned long)(&task);
+ arg.user_data = 0; /* unused */
+
+ /* Display OR File */
+ switch (display) {
+ case IPP_CMD_M2M_FILE:
+
+ /* For src image write file */
+ sprintf(filename, RESULT_PATH "fimc_m2m_org_src.bmp");
+ util_write_bmp(filename, usr_addr1[0],
+ src_sz.hsize, src_sz.vsize);
+
+ for (j = 0; j < MAX_LOOP; j++) {
+
+ gettimeofday(&begin, NULL);
+ ret = ioctl(dev->fd, DRM_IOCTL_EXYNOS_IPP_COMMIT, &arg);
+ if (ret) {
+ fprintf(stderr, "failed to process image\n");
+ goto err_ipp_close;
+ }
+
+ gettimeofday(&end, NULL);
+
+ usec[j] = (end.tv_sec - begin.tv_sec) * 1000000 +
+ (end.tv_usec - begin.tv_usec);
+
+ sprintf(filename, RESULT_PATH "fimc_m2m_dst%d.bmp", j);
+ util_write_bmp(filename, usr_addr2[0], def_sz.hsize, def_sz.vsize);
+ }
+ break;
+
+ case IPP_CMD_M2M_DISPLAY:
+ /* Add fb2 dst */
+ ret = drmModeAddFB2(dev->fd, dev->mode.width, dev->mode.height,
+ pipe.fourcc, handles, pitches,
+ offsets, &fb_id_dst, 0);
+ if (ret) {
+ fprintf(stderr, "failed to add fb (%ux%u):%d\n",
+ dev->mode.width, dev->mode.height,
+ errno);
+ goto err_ipp_close;
+ }
+
+ for (j = 0; j < 2; j++) {
+
+ gettimeofday(&begin, NULL);
+ ret = ioctl(dev->fd, DRM_IOCTL_EXYNOS_IPP_COMMIT, &arg);
+ if (ret) {
+ fprintf(stderr, "failed to process image\n");
+ goto err_ipp_close;
+ }
+ gettimeofday(&end, NULL);
+ usec[j] = (end.tv_sec - begin.tv_sec) * 1000000 +
+ (end.tv_usec - begin.tv_usec);
+
+ if (j == 0) {
+ /* Set crtc */
+ ret = drmModeSetCrtc(dev->fd, pipe.crtc->crtc->crtc_id,
+ fb_id_dst, 0, 0, pipe.con_ids,
+ pipe.num_cons, pipe.mode);
+ if (ret) {
+ fprintf(stderr, "failed to set crtc: %d\n", errno);
+ goto err_ipp_close;
+ }
+ /* reset rotation for the next frame */
+ task.transform.rotation = DRM_MODE_ROTATE_0;
+ } else {
+ /* Set Flip */
+ ret = drmModePageFlip(dev->fd, pipe.crtc->crtc->crtc_id,
+ fb_id_dst, 0, &pipe);
+ if (ret) {
+ fprintf(stderr, "failed to page flip: %d\n",
+ errno);
+ goto err_ipp_close;
+ }
+ }
+
+ getchar();
+ }
+ break;
+ case IPP_CMD_M2M_NONE:
+ break;
+ }
+
+err_ipp_close:
+err_ipp_dst_buff_close:
+ util_kms_gem_destroy_mmap(&bo_dst);
+err_ipp_src_buff_close:
+ /* Close source buffer */
+ for (i = 0; i < MAX_BUF; i++) {
+ ret = util_kms_gem_destroy_mmap(&bo_src[i]);
+ if (ret < 0)
+ break;
+ }
+}
+
+void fimc_v2_wb_set_mode(struct connector *c, int count, int page_flip,
+ long int *usec)
+{
+ fprintf(stderr, "not supported.\n");
+}
+
+void fimc_v2_output_set_mode(struct connector *c, int count, int page_flip,
+ long int *usec)
+{
+ fprintf(stderr, "not supported.\n");
+}
diff --git a/tests/ipptest/fimc.c b/tests/ipptest/fimc.c
index 16b1d7a8..7bd315e0 100644
--- a/tests/ipptest/fimc.c
+++ b/tests/ipptest/fimc.c
@@ -332,7 +332,7 @@ struct crtc *pipe_find_crtc(struct device *dev, struct pipe_arg *pipe)
return &dev->resources->crtcs[crtc_idx - 1];
}
-static int pipe_find_crtc_and_mode(struct device *dev, struct pipe_arg *pipe,
+int pipe_find_crtc_and_mode(struct device *dev, struct pipe_arg *pipe,
struct connector *c)
{
drmModeModeInfo *mode = NULL;
diff --git a/tests/ipptest/fimc.h b/tests/ipptest/fimc.h
index 85261958..b758d941 100644
--- a/tests/ipptest/fimc.h
+++ b/tests/ipptest/fimc.h
@@ -8,7 +8,19 @@ void fimc_wb_set_mode(struct connector *c, int count, int page_flip,
long int *usec);
void fimc_output_set_mode(struct connector *c, int count, int page_flip,
long int *usec);
+
+void fimc_v2_m2m_set_mode(struct device *dev, struct connector *c, int count,
+ enum drm_exynos_degree degree, enum drm_exynos_ipp_cmd_m2m display,
+ long int *usec);
+void fimc_v2_wb_set_mode(struct connector *c, int count, int page_flip,
+ long int *usec);
+void fimc_v2_output_set_mode(struct connector *c, int count, int page_flip,
+ long int *usec);
+
struct resources *get_resources(struct device *dev);
void free_resources(struct resources *res);
+int pipe_find_crtc_and_mode(struct device *dev, struct pipe_arg *pipe,
+ struct connector *c);
+
#endif
diff --git a/tests/ipptest/fimctest.c b/tests/ipptest/fimctest.c
index f044bb54..f6981de1 100644
--- a/tests/ipptest/fimctest.c
+++ b/tests/ipptest/fimctest.c
@@ -383,6 +383,7 @@ static void usage(char *name)
int main(int argc, char **argv)
{
+ drmVersionPtr drm_version;
struct device dev;
int c;
int operations = 0, encoders = 0, connectors = 0, crtcs = 0, framebuffers = 0;
@@ -391,6 +392,7 @@ int main(int argc, char **argv)
int test_vsync = 0;
const char *module = "exynos";
int i, count = 0;
+ int use_ippv2 = 0;
struct connector con_args[2];
memset(&dev, 0, sizeof(dev));
@@ -470,6 +472,17 @@ int main(int argc, char **argv)
dev.fd = fd;
+ drm_version = drmGetVersion(fd);
+ if (!drm_version) {
+ fprintf(stderr, "no drm version: %m");
+ return -1;
+ } else {
+ if (drm_version->version_major > 1 ||
+ (drm_version->version_major == 1 && drm_version->version_minor >= 1))
+ use_ippv2 = 1;
+ drmFreeVersion(drm_version);
+ }
+
dev.resources = get_resources(&dev);
if (!dev.resources) {
fprintf(stderr, "get_resources failed: %d\n", errno);
@@ -503,15 +516,25 @@ int main(int argc, char **argv)
break;
}
- fimc_m2m_set_mode(&dev, con_args, count,
- degree, display, usec);
+ if (use_ippv2)
+ fimc_v2_m2m_set_mode(&dev, con_args, count,
+ degree, display, usec);
+ else
+ fimc_m2m_set_mode(&dev, con_args, count,
+ degree, display, usec);
kms_destroy(&dev.kms);
break;
case 1:
- fimc_wb_set_mode(con_args, count, test_vsync, usec);
+ if (use_ippv2)
+ fimc_v2_wb_set_mode(con_args, count, test_vsync, usec);
+ else
+ fimc_wb_set_mode(con_args, count, test_vsync, usec);
break;
case 2:
- fimc_output_set_mode(con_args, count, test_vsync, usec);
+ if (use_ippv2)
+ fimc_v2_output_set_mode(con_args, count, test_vsync, usec);
+ else
+ fimc_output_set_mode(con_args, count, test_vsync, usec);
break;
default:
break;