diff options
author | Thierry Reding <treding@nvidia.com> | 2014-02-24 11:54:49 +0100 |
---|---|---|
committer | Thierry Reding <treding@nvidia.com> | 2018-05-02 17:29:40 +0200 |
commit | 1761999b7710e13e1a18c0ae1d2fb6ee5ef00825 (patch) | |
tree | 259fce9bdd514cdef80f84a19bd90786cfcc99bc | |
parent | 3797649a814c670562d8871db21133899bf1045d (diff) |
tests: tegra: Add VIC support
Implement a small abstraction interface to allow different versions of
VIC to be used transparently. An operations structure is selected based
on the VIC version number reported by the DRM_TEGRA_IOCTL_OPEN_CHANNEL
IOCTL.
Signed-off-by: Thierry Reding <treding@nvidia.com>
-rw-r--r-- | tegra/channel.c | 4 | ||||
-rw-r--r-- | tegra/private.h | 1 | ||||
-rw-r--r-- | tegra/tegra.h | 1 | ||||
-rw-r--r-- | tests/tegra/Makefile.am | 4 | ||||
-rw-r--r-- | tests/tegra/meson.build | 7 | ||||
-rw-r--r-- | tests/tegra/vic.c | 150 | ||||
-rw-r--r-- | tests/tegra/vic.h | 169 |
7 files changed, 334 insertions, 2 deletions
diff --git a/tegra/channel.c b/tegra/channel.c index 9c7d8016..804f2d63 100644 --- a/tegra/channel.c +++ b/tegra/channel.c @@ -55,6 +55,10 @@ int drm_tegra_channel_open(struct drm_tegra_channel **channelp, class = HOST1X_CLASS_GR3D; break; + case DRM_TEGRA_VIC: + class = HOST1X_CLASS_VIC; + break; + default: return -EINVAL; } diff --git a/tegra/private.h b/tegra/private.h index c30fd68f..644899f5 100644 --- a/tegra/private.h +++ b/tegra/private.h @@ -48,6 +48,7 @@ enum host1x_class { HOST1X_CLASS_HOST1X = 0x01, HOST1X_CLASS_GR2D = 0x51, HOST1X_CLASS_GR2D_SB = 0x52, + HOST1X_CLASS_VIC = 0x5d, HOST1X_CLASS_GR3D = 0x60, }; diff --git a/tegra/tegra.h b/tegra/tegra.h index 694eb2c0..6448f9c6 100644 --- a/tegra/tegra.h +++ b/tegra/tegra.h @@ -34,6 +34,7 @@ enum drm_tegra_class { DRM_TEGRA_HOST1X, DRM_TEGRA_GR2D, DRM_TEGRA_GR3D, + DRM_TEGRA_VIC, }; enum drm_fence_type { diff --git a/tests/tegra/Makefile.am b/tests/tegra/Makefile.am index 434aed22..adf87805 100644 --- a/tests/tegra/Makefile.am +++ b/tests/tegra/Makefile.am @@ -10,7 +10,9 @@ libdrm_test_la_SOURCES = \ drm-test.c \ drm-test.h \ drm-test-tegra.c \ - drm-test-tegra.h + drm-test-tegra.h \ + vic.c \ + vic.h libdrm_test_la_LIBADD = \ ../../libdrm.la diff --git a/tests/tegra/meson.build b/tests/tegra/meson.build index 784a6c89..a815a284 100644 --- a/tests/tegra/meson.build +++ b/tests/tegra/meson.build @@ -29,7 +29,12 @@ libdrm_test = static_library( libdrm_test_tegra = static_library( 'drm-test-tegra', - [files('drm-test-tegra.c', 'drm-test-tegra.h'), config_file ], + [files( + 'drm-test-tegra.c', + 'drm-test-tegra.h', + 'vic.c', + 'vic.h', + ), config_file ], include_directories : [inc_root, inc_drm, inc_tegra], link_with : libdrm, ) diff --git a/tests/tegra/vic.c b/tests/tegra/vic.c new file mode 100644 index 00000000..062e215d --- /dev/null +++ b/tests/tegra/vic.c @@ -0,0 +1,150 @@ +/* + * Copyright © 2018 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 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 <errno.h> +#include <stdio.h> /* XXX remove */ +#include <stdlib.h> + +#include "util_math.h" + +#include "tegra.h" +#include "host1x.h" +#include "vic.h" + +#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) + +const struct vic_format_info *vic_format_get_info(unsigned int format) +{ + static const struct vic_format_info formats[] = { + { .format = VIC_PIXEL_FORMAT_A8R8G8B8, .cpp = 4 }, + }; + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(formats); i++) { + if (formats[i].format == format) + return &formats[i]; + } + + return 0; +} + +int vic_image_new(struct vic_image **imagep, struct drm_tegra *drm, + unsigned int width, unsigned int height, + unsigned int format, unsigned int kind) +{ + const struct vic_format_info *info = vic_format_get_info(format); + struct vic_image *image; + int err; + + if (!info) + return -EINVAL; + + image = calloc(1, sizeof(*image)); + if (!image) + return -ENOMEM; + + if (kind == VIC_BLK_KIND_PITCH) + image->align = 256; + else + image->align = 256; /* XXX */ + + image->width = width; + image->stride = ALIGN(width, image->align); + image->pitch = image->stride * info->cpp; + image->height = height; + image->format = format; + image->kind = kind; + + image->size = image->pitch * image->height; + + printf("image: %ux%u align: %zu stride: %u pitch: %u size: %zu\n", + image->width, image->height, image->align, image->stride, + image->pitch, image->size); + + err = drm_tegra_bo_new(&image->bo, drm, 0, image->size); + if (err < 0) { + free(image); + return err; + } + + *imagep = image; + return 0; +} + +void vic_image_free(struct vic_image *image) +{ + if (image) { + drm_tegra_bo_unref(image->bo); + free(image); + } +} + +void vic_image_dump(struct vic_image *image, FILE *fp) +{ + unsigned int i, j; + void *ptr; + int err; + + err = drm_tegra_bo_map(image->bo, &ptr); + if (err < 0) + return; + + for (j = 0; j < image->height; j++) { + uint32_t *pixels = (uint32_t *)((unsigned long)ptr + j * image->pitch); + + printf(" "); + + for (i = 0; i < image->width; i++) + printf(" %08x", pixels[i]); + + printf("\n"); + } + + drm_tegra_bo_unmap(image->bo); +} + +int vic_new(struct vic **vicp, unsigned int version) +{ + const struct vic_ops *ops; + struct vic *vic; + + switch (version) { + default: + return -ENOTSUP; + } + + vic = calloc(1, sizeof(*vic)); + if (!vic) + return -ENOMEM; + + vic->version = version; + vic->ops = ops; + + *vicp = vic; + + return 0; +} + +void vic_free(struct vic *vic) +{ + free(vic); +} diff --git a/tests/tegra/vic.h b/tests/tegra/vic.h new file mode 100644 index 00000000..d623da3a --- /dev/null +++ b/tests/tegra/vic.h @@ -0,0 +1,169 @@ +/* + * Copyright © 2018 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 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. + */ + +#ifndef VIC_H +#define VIC_H + +#include <stdio.h> + +#include "host1x.h" + +#define DXVAHD_FRAME_FORMAT_PROGRESSIVE 0 +#define DXVAHD_FRAME_FORMAT_INTERLACED_TOP_FIELD_FIRST 1 +#define DXVAHD_FRAME_FORMAT_INTERLACED_BOTTOM_FIELD_FIRST 2 +#define DXVAHD_FRAME_FORMAT_TOP_FIELD 3 +#define DXVAHD_FRAME_FORMAT_BOTTOM_FIELD 4 +#define DXVAHD_FRAME_FORMAT_SUBPIC_PROGRESSIVE 5 +#define DXVAHD_FRAME_FORMAT_SUBPIC_INTERLACED_TOP_FIELD_FIRST 6 +#define DXVAHD_FRAME_FORMAT_SUBPIC_INTERLACED_BOTTOM_FIELD_FIRST 7 +#define DXVAHD_FRAME_FORMAT_SUBPIC_TOP_FIELD 8 +#define DXVAHD_FRAME_FORMAT_SUBPIC_BOTTOM_FIELD 9 +#define DXVAHD_FRAME_FORMAT_TOP_FIELD_CHROMA_BOTTOM 10 +#define DXVAHD_FRAME_FORMAT_BOTTOM_FIELD_CHROMA_TOP 11 +#define DXVAHD_FRAME_FORMAT_SUBPIC_TOP_FIELD_CHROMA_BOTTOM 12 +#define DXVAHD_FRAME_FORMAT_SUBPIC_BOTTOM_FIELD_CHROMA_TOP 13 + +#define DXVAHD_ALPHA_FILL_MODE_OPAQUE 0 +#define DXVAHD_ALPHA_FILL_MODE_BACKGROUND 1 +#define DXVAHD_ALPHA_FILL_MODE_DESTINATION 2 +#define DXVAHD_ALPHA_FILL_MODE_SOURCE_STREAM 3 +#define DXVAHD_ALPHA_FILL_MODE_COMPOSITED 4 +#define DXVAHD_ALPHA_FILL_MODE_SOURCE_ALPHA 5 + +#define VIC_BLEND_SRCFACTC_K1 0 +#define VIC_BLEND_SRCFACTC_K1_TIMES_DST 1 +#define VIC_BLEND_SRCFACTC_NEG_K1_TIMES_DST 2 +#define VIC_BLEND_SRCFACTC_K1_TIMES_SRC 3 +#define VIC_BLEND_SRCFACTC_ZERO 4 + +#define VIC_BLEND_DSTFACTC_K1 0 +#define VIC_BLEND_DSTFACTC_K2 1 +#define VIC_BLEND_DSTFACTC_K1_TIMES_DST 2 +#define VIC_BLEND_DSTFACTC_NEG_K1_TIMES_DST 3 +#define VIC_BLEND_DSTFACTC_NEG_K1_TIMES_SRC 4 +#define VIC_BLEND_DSTFACTC_ZERO 5 +#define VIC_BLEND_DSTFACTC_ONE 6 + +#define VIC_BLEND_SRCFACTA_K1 0 +#define VIC_BLEND_SRCFACTA_K2 1 +#define VIC_BLEND_SRCFACTA_NEG_K1_TIMES_DST 2 +#define VIC_BLEND_SRCFACTA_ZERO 3 + +#define VIC_BLEND_DSTFACTA_K2 0 +#define VIC_BLEND_DSTFACTA_NEG_K1_TIMES_SRC 1 +#define VIC_BLEND_DSTFACTA_ZERO 2 +#define VIC_BLEND_DSTFACTA_ONE 3 + +#define VIC_BLK_KIND_PITCH 0 +#define VIC_BLK_KIND_GENERIC_16Bx2 1 + +#define VIC_PIXEL_FORMAT_L8 1 +#define VIC_PIXEL_FORMAT_R8 4 +#define VIC_PIXEL_FORMAT_A8R8G8B8 32 +#define VIC_PIXEL_FORMAT_R8G8B8A8 34 +#define VIC_PIXEL_FORMAT_Y8_U8V8_N420 67 +#define VIC_PIXEL_FORMAT_Y8_V8U8_N420 68 + +#define VIC_CACHE_WIDTH_16Bx16 0 /* BL16Bx2 */ +#define VIC_CACHE_WIDTH_32Bx8 1 /* BL16Bx2 */ +#define VIC_CACHE_WIDTH_64Bx4 2 /* BL16Bx2, PL */ +#define VIC_CACHE_WIDTH_128Bx2 3 /* BL16Bx2, PL */ +#define VIC_CACHE_WIDTH_256Bx1 4 /* PL */ + +struct vic_format_info { + unsigned int format; + unsigned int cpp; +}; + +struct vic_image { + struct drm_tegra_bo *bo; + unsigned int width; + unsigned int stride; + unsigned int pitch; + unsigned int height; + unsigned int format; + unsigned int kind; + + size_t align; + size_t size; +}; + +const struct vic_format_info *vic_format_get_info(unsigned int format); + +int vic_image_new(struct vic_image **imagep, struct drm_tegra *drm, + unsigned int width, unsigned int height, + unsigned int format, unsigned int kind); +void vic_image_free(struct vic_image *image); +void vic_image_dump(struct vic_image *image, FILE *fp); + +#define VIC_UCLASS_INCR_SYNCPT 0x00 +#define VIC_UCLASS_METHOD_OFFSET 0x10 +#define VIC_UCLASS_METHOD_DATA 0x11 + +static inline void VIC_PUSH_METHOD(struct drm_tegra_pushbuf *pushbuf, + uint32_t method, uint32_t value) +{ + *pushbuf->ptr++ = HOST1X_OPCODE_INCR(VIC_UCLASS_METHOD_OFFSET, 2); + *pushbuf->ptr++ = method >> 2; + *pushbuf->ptr++ = value; +} + +static inline void VIC_PUSH_BUFFER(struct drm_tegra_pushbuf *pushbuf, + uint32_t method, struct drm_tegra_bo *bo, + unsigned long offset) +{ + *pushbuf->ptr++ = HOST1X_OPCODE_INCR(VIC_UCLASS_METHOD_OFFSET, 2); + *pushbuf->ptr++ = method >> 2; + + drm_tegra_pushbuf_relocate(pushbuf, bo, offset, 8); +} + +struct vic_ops { + void (*clear)(void *ptr, struct vic_image *output, + unsigned int alpha, unsigned int red, + unsigned int green, unsigned int blue); + void (*fill)(void *ptr, struct vic_image *output, + unsigned int left, unsigned int top, + unsigned int right, unsigned int bottom, + unsigned int alpha, unsigned red, + unsigned int green, unsigned int blue); + void (*blit)(void *ptr, struct vic_image *output, + struct vic_image *input); + void (*flip)(void *ptr, struct vic_image *output, + struct vic_image *input); + int (*execute)(struct drm_tegra_pushbuf *pushbuf, + struct drm_tegra_bo *config, + struct drm_tegra_bo *hist, + struct vic_image *output, + struct vic_image **inputs, + unsigned int num_inputs); +}; + +struct vic { + const struct vic_ops *ops; + unsigned int version; +}; + +int vic_new(struct vic **vicp, unsigned int version); +void vic_free(struct vic *vic); + +#endif |