diff -Nru libdrm-2.4.110/core-symbols.txt libdrm-2.4.113/core-symbols.txt --- libdrm-2.4.110/core-symbols.txt 2022-02-16 10:00:13.000000000 +0000 +++ libdrm-2.4.113/core-symbols.txt 2022-08-31 14:38:38.000000000 +0000 @@ -103,6 +103,7 @@ drmModeAtomicMerge drmModeAtomicSetCursor drmModeAttachMode +drmModeConnectorGetPossibleCrtcs drmModeConnectorSetProperty drmModeCreateLease drmModeCreatePropertyBlob @@ -126,6 +127,7 @@ drmModeFreeResources drmModeGetConnector drmModeGetConnectorCurrent +drmModeGetConnectorTypeName drmModeGetCrtc drmModeGetEncoder drmModeGetFB @@ -201,3 +203,4 @@ drmWaitVBlank drmGetFormatModifierName drmGetFormatModifierVendor +drmGetFormatName diff -Nru libdrm-2.4.110/data/amdgpu.ids libdrm-2.4.113/data/amdgpu.ids --- libdrm-2.4.110/data/amdgpu.ids 2022-02-16 10:00:13.000000000 +0000 +++ libdrm-2.4.113/data/amdgpu.ids 2022-08-31 14:38:38.000000000 +0000 @@ -275,18 +275,37 @@ 7341, 00, AMD Radeon Pro W5500 7347, 00, AMD Radeon Pro W5500M 73A3, 00, AMD Radeon Pro W6800 +73A5, C0, AMD Radeon RX 6950 XT 73AF, C0, AMD Radeon RX 6900 XT 73BF, C0, AMD Radeon RX 6900 XT 73BF, C1, AMD Radeon RX 6800 XT 73BF, C3, AMD Radeon RX 6800 +73DF, C0, AMD Radeon RX 6750 XT 73DF, C1, AMD Radeon RX 6700 XT 73DF, C3, AMD Radeon RX 6800M 73DF, C5, AMD Radeon RX 6700 XT 73DF, CF, AMD Radeon RX 6700M +73DF, D7, AMD TDC-235 73E1, 00, AMD Radeon Pro W6600M 73E3, 00, AMD Radeon Pro W6600 +73EF, C0, AMD Radeon RX 6800S +73EF, C1, AMD Radeon RX 6650 XT +73EF, C2, AMD Radeon RX 6700S +73EF, C3, AMD Radeon RX 6650M +73EF, C4, AMD Radeon RX 6650M XT 73FF, C1, AMD Radeon RX 6600 XT 73FF, C3, AMD Radeon RX 6600M +73FF, C7, AMD Radeon RX 6600 +73FF, CB, AMD Radeon RX 6600S +7421, 00, AMD Radeon Pro W6500M +7422, 00, AMD Radeon PRO W6400 +7423, 00, AMD Radeon Pro W6300M +7423, 01, AMD Radeon PRO W6300 +7424, 00, AMD Radeon RX 6300 +743F, C1, AMD Radeon RX 6500 XT +743F, C3, AMD Radeon RX 6500 +743F, C7, AMD Radeon RX 6400 +743F, CF, AMD Radeon RX 6300M 9874, C4, AMD Radeon R7 Graphics 9874, C5, AMD Radeon R6 Graphics 9874, C6, AMD Radeon R6 Graphics diff -Nru libdrm-2.4.110/debian/changelog libdrm-2.4.113/debian/changelog --- libdrm-2.4.110/debian/changelog 2022-03-16 09:12:41.000000000 +0000 +++ libdrm-2.4.113/debian/changelog 2022-12-06 07:19:45.000000000 +0000 @@ -1,9 +1,51 @@ -libdrm (2.4.110-1ubuntu1) jammy; urgency=medium +libdrm (2.4.113-2~ubuntu0.22.04.1) jammy; urgency=medium - * Merge from Debian. - * Refresh revert patch. + * Backport to jammy. (LP: #1991761) + * patches, symbols: Revert dropping unused tegra IOCTL. - -- Timo Aaltonen Wed, 16 Mar 2022 11:12:41 +0200 + -- Timo Aaltonen Tue, 06 Dec 2022 09:19:45 +0200 + +libdrm (2.4.113-2) unstable; urgency=medium + + * rules: Fix arm FTBFS. + + -- Timo Aaltonen Mon, 19 Sep 2022 18:52:34 +0300 + +libdrm (2.4.113-1) unstable; urgency=medium + + * New upstream release. + * rules: Rework confflags to match current upstream. + * symbols: Updated. + + -- Timo Aaltonen Mon, 19 Sep 2022 10:53:18 +0300 + +libdrm (2.4.112-3) unstable; urgency=medium + + * libdrm-tegra0.symbols: Updated. + + -- Timo Aaltonen Fri, 29 Jul 2022 15:25:31 +0300 + +libdrm (2.4.112-2) unstable; urgency=medium + + * rules: Fix arm build. + + -- Timo Aaltonen Fri, 29 Jul 2022 14:39:16 +0300 + +libdrm (2.4.112-1) unstable; urgency=medium + + * New upstream release. + * symbols: Updated. + * rules: Add more test binaries for arm. (Closes: #1016096) + + -- Timo Aaltonen Fri, 29 Jul 2022 11:24:00 +0300 + +libdrm (2.4.111-1) unstable; urgency=medium + + * New upstream release. + * install, rules: libkms got removed. + * symbols: Updated. + + -- Timo Aaltonen Wed, 06 Jul 2022 08:26:24 +0300 libdrm (2.4.110-1) unstable; urgency=medium @@ -14,12 +56,6 @@ -- Timo Aaltonen Fri, 18 Feb 2022 15:22:07 +0200 -libdrm (2.4.109-2ubuntu1) jammy; urgency=medium - - * Merge from debian. - - -- Timo Aaltonen Thu, 27 Jan 2022 20:58:06 +0200 - libdrm (2.4.109-2) unstable; urgency=medium * amdgpu1.symbols: Updated. (Closes: #1001965) @@ -41,12 +77,6 @@ -- Timo Aaltonen Wed, 17 Nov 2021 11:33:25 +0200 -libdrm (2.4.107-8ubuntu1) impish; urgency=medium - - * Revert adding static libs, fix flutter. - - -- Timo Aaltonen Tue, 05 Oct 2021 09:12:31 +0300 - libdrm (2.4.107-8) unstable; urgency=medium * rules: Forcibly disable valgrind. diff -Nru libdrm-2.4.110/debian/libdrm2.symbols libdrm-2.4.113/debian/libdrm2.symbols --- libdrm-2.4.110/debian/libdrm2.symbols 2022-02-18 12:54:32.000000000 +0000 +++ libdrm-2.4.113/debian/libdrm2.symbols 2022-12-06 07:17:31.000000000 +0000 @@ -67,6 +67,7 @@ drmGetEntry@Base 2.3.1 drmGetFormatModifierName@Base 2.4.107 drmGetFormatModifierVendor@Base 2.4.107 + drmGetFormatName@Base 2.4.113 drmGetHashTable@Base 2.3.1 drmGetInterruptFromBusID@Base 2.3.1 drmGetLibVersion@Base 2.3.1 @@ -106,6 +107,7 @@ drmModeAtomicMerge@Base 2.4.62 drmModeAtomicSetCursor@Base 2.4.62 drmModeAttachMode@Base 2.4.3 + drmModeConnectorGetPossibleCrtcs@Base 2.4.112 drmModeConnectorSetProperty@Base 2.4.3 drmModeCreateLease@Base 2.4.89 drmModeCreatePropertyBlob@Base 2.4.62 @@ -129,6 +131,7 @@ drmModeFreeResources@Base 2.4.3 drmModeGetConnector@Base 2.4.3 drmModeGetConnectorCurrent@Base 2.4.61 + drmModeGetConnectorTypeName@Base 2.4.112 drmModeGetCrtc@Base 2.4.3 drmModeGetEncoder@Base 2.4.3 drmModeGetFB2@Base 2.4.101 diff -Nru libdrm-2.4.110/debian/libdrm-dev.install libdrm-2.4.113/debian/libdrm-dev.install --- libdrm-2.4.110/debian/libdrm-dev.install 2022-03-16 09:08:43.000000000 +0000 +++ libdrm-2.4.113/debian/libdrm-dev.install 2022-11-21 15:49:21.000000000 +0000 @@ -1,4 +1,5 @@ usr/include/* +usr/lib/*/lib*.a usr/lib/*/lib*.so usr/lib/*/pkgconfig/* usr/share/man/man3/* diff -Nru libdrm-2.4.110/debian/libdrm-nouveau2.symbols libdrm-2.4.113/debian/libdrm-nouveau2.symbols --- libdrm-2.4.110/debian/libdrm-nouveau2.symbols 2022-02-18 12:54:32.000000000 +0000 +++ libdrm-2.4.113/debian/libdrm-nouveau2.symbols 2022-11-21 15:49:21.000000000 +0000 @@ -14,6 +14,7 @@ nouveau_bufctx_new@Base 2.4.34 nouveau_bufctx_refn@Base 2.4.34 nouveau_bufctx_reset@Base 2.4.34 + nouveau_check_dead_channel@Base 2.4.111 nouveau_client_del@Base 2.4.34 nouveau_client_new@Base 2.4.34 nouveau_device_del@Base 2.4.34 diff -Nru libdrm-2.4.110/debian/libdrm-tegra0.symbols libdrm-2.4.113/debian/libdrm-tegra0.symbols --- libdrm-2.4.110/debian/libdrm-tegra0.symbols 2022-02-18 12:54:32.000000000 +0000 +++ libdrm-2.4.113/debian/libdrm-tegra0.symbols 2022-12-06 07:19:45.000000000 +0000 @@ -1,15 +1,37 @@ libdrm_tegra.so.0 libdrm-tegra0 #MINVER# + drm_tegra_bo_export@Base 2.4.112 drm_tegra_bo_get_flags@Base 0 drm_tegra_bo_get_handle@Base 0 + drm_tegra_bo_get_name@Base 2.4.112 drm_tegra_bo_get_tiling@Base 0 + drm_tegra_bo_import@Base 2.4.112 drm_tegra_bo_map@Base 0 drm_tegra_bo_new@Base 0 + drm_tegra_bo_open@Base 2.4.112 drm_tegra_bo_ref@Base 0 drm_tegra_bo_set_flags@Base 0 drm_tegra_bo_set_tiling@Base 0 drm_tegra_bo_unmap@Base 0 drm_tegra_bo_unref@Base 0 drm_tegra_bo_wrap@Base 0 + drm_tegra_channel_close@Base 2.4.112 + drm_tegra_channel_get_version@Base 2.4.112 + drm_tegra_channel_map@Base 2.4.112 + drm_tegra_channel_open@Base 2.4.112 + drm_tegra_channel_unmap@Base 2.4.112 drm_tegra_close@Base 0 + drm_tegra_fence_wait@Base 2.4.112 + drm_tegra_job_free@Base 2.4.112 + drm_tegra_job_get_pushbuf@Base 2.4.112 + drm_tegra_job_new@Base 2.4.112 + drm_tegra_job_submit@Base 2.4.112 + drm_tegra_job_wait@Base 2.4.112 drm_tegra_new@Base 0 - + drm_tegra_pushbuf_begin@Base 2.4.112 + drm_tegra_pushbuf_end@Base 2.4.112 + drm_tegra_pushbuf_relocate@Base 2.4.112 + drm_tegra_pushbuf_sync@Base 2.4.112 + drm_tegra_pushbuf_sync_cond@Base 2.4.112 + drm_tegra_pushbuf_wait@Base 2.4.112 + drm_tegra_syncpoint_free@Base 2.4.112 + drm_tegra_syncpoint_new@Base 2.4.112 diff -Nru libdrm-2.4.110/debian/libdrm-tests.install libdrm-2.4.113/debian/libdrm-tests.install --- libdrm-2.4.110/debian/libdrm-tests.install 2022-02-18 12:54:32.000000000 +0000 +++ libdrm-2.4.113/debian/libdrm-tests.install 2022-11-21 15:49:21.000000000 +0000 @@ -2,7 +2,5 @@ usr/bin/drmdevice usr/bin/modetest usr/bin/vbltest -usr/bin/kms-steal-crtc usr/bin/modeprint -usr/bin/kms-universal-planes usr/bin/proptest diff -Nru libdrm-2.4.110/debian/patches/0001-Revert-tegra-Remove-unused-IOCTL-implementations.patch libdrm-2.4.113/debian/patches/0001-Revert-tegra-Remove-unused-IOCTL-implementations.patch --- libdrm-2.4.110/debian/patches/0001-Revert-tegra-Remove-unused-IOCTL-implementations.patch 1970-01-01 00:00:00.000000000 +0000 +++ libdrm-2.4.113/debian/patches/0001-Revert-tegra-Remove-unused-IOCTL-implementations.patch 2022-12-06 07:19:45.000000000 +0000 @@ -0,0 +1,160 @@ +From f50a1aaf40153e8f457d23047330886a74899715 Mon Sep 17 00:00:00 2001 +From: Timo Aaltonen +Date: Thu, 15 Dec 2022 15:17:19 +0200 +Subject: [PATCH] Revert "tegra: Remove unused IOCTL implementations" + +This reverts commit bec2a28e98f430f4a82b085b4d1c69a98988359f. +--- + tegra/tegra-symbols.txt | 4 ++ + tegra/tegra.c | 95 +++++++++++++++++++++++++++++++++++++++++ + tegra/tegra.h | 13 ++++++ + 3 files changed, 112 insertions(+) + +diff --git a/tegra/tegra-symbols.txt b/tegra/tegra-symbols.txt +index 1a75c3d2..ddac5ffe 100644 +--- a/tegra/tegra-symbols.txt ++++ b/tegra/tegra-symbols.txt +@@ -1,11 +1,15 @@ + drm_tegra_bo_export ++drm_tegra_bo_get_flags + drm_tegra_bo_get_handle ++drm_tegra_bo_get_tiling + drm_tegra_bo_get_name + drm_tegra_bo_import + drm_tegra_bo_map + drm_tegra_bo_new + drm_tegra_bo_open + drm_tegra_bo_ref ++drm_tegra_bo_set_flags ++drm_tegra_bo_set_tiling + drm_tegra_bo_unmap + drm_tegra_bo_unref + drm_tegra_bo_wrap +diff --git a/tegra/tegra.c b/tegra/tegra.c +index 6a51c431..5b97cd66 100644 +--- a/tegra/tegra.c ++++ b/tegra/tegra.c +@@ -352,3 +352,98 @@ free: + free(bo); + return err; + } ++ ++drm_public int drm_tegra_bo_get_flags(struct drm_tegra_bo *bo, uint32_t *flags) ++{ ++ struct drm_tegra_gem_get_flags args; ++ struct drm_tegra *drm = bo->drm; ++ int err; ++ ++ if (!bo) ++ return -EINVAL; ++ ++ memset(&args, 0, sizeof(args)); ++ args.handle = bo->handle; ++ ++ err = drmCommandWriteRead(drm->fd, DRM_TEGRA_GEM_GET_FLAGS, &args, ++ sizeof(args)); ++ if (err < 0) ++ return -errno; ++ ++ if (flags) ++ *flags = args.flags; ++ ++ return 0; ++} ++ ++drm_public int drm_tegra_bo_set_flags(struct drm_tegra_bo *bo, uint32_t flags) ++{ ++ struct drm_tegra_gem_get_flags args; ++ struct drm_tegra *drm = bo->drm; ++ int err; ++ ++ if (!bo) ++ return -EINVAL; ++ ++ memset(&args, 0, sizeof(args)); ++ args.handle = bo->handle; ++ args.flags = flags; ++ ++ err = drmCommandWriteRead(drm->fd, DRM_TEGRA_GEM_SET_FLAGS, &args, ++ sizeof(args)); ++ if (err < 0) ++ return -errno; ++ ++ return 0; ++} ++ ++drm_public int ++drm_tegra_bo_get_tiling(struct drm_tegra_bo *bo, ++ struct drm_tegra_bo_tiling *tiling) ++{ ++ struct drm_tegra_gem_get_tiling args; ++ struct drm_tegra *drm = bo->drm; ++ int err; ++ ++ if (!bo) ++ return -EINVAL; ++ ++ memset(&args, 0, sizeof(args)); ++ args.handle = bo->handle; ++ ++ err = drmCommandWriteRead(drm->fd, DRM_TEGRA_GEM_GET_TILING, &args, ++ sizeof(args)); ++ if (err < 0) ++ return -errno; ++ ++ if (tiling) { ++ tiling->mode = args.mode; ++ tiling->value = args.value; ++ } ++ ++ return 0; ++} ++ ++drm_public int ++drm_tegra_bo_set_tiling(struct drm_tegra_bo *bo, ++ const struct drm_tegra_bo_tiling *tiling) ++{ ++ struct drm_tegra_gem_set_tiling args; ++ struct drm_tegra *drm = bo->drm; ++ int err; ++ ++ if (!bo) ++ return -EINVAL; ++ ++ memset(&args, 0, sizeof(args)); ++ args.handle = bo->handle; ++ args.mode = tiling->mode; ++ args.value = tiling->value; ++ ++ err = drmCommandWriteRead(drm->fd, DRM_TEGRA_GEM_SET_TILING, &args, ++ sizeof(args)); ++ if (err < 0) ++ return -errno; ++ ++ return 0; ++} +diff --git a/tegra/tegra.h b/tegra/tegra.h +index 8f3c0554..192ea031 100644 +--- a/tegra/tegra.h ++++ b/tegra/tegra.h +@@ -124,4 +124,17 @@ int drm_tegra_syncpoint_new(struct drm_tegra *drm, + int drm_tegra_syncpoint_free(struct drm_tegra_syncpoint *syncpt); + int drm_tegra_fence_wait(struct drm_tegra_fence *fence, unsigned long timeout); + ++int drm_tegra_bo_get_flags(struct drm_tegra_bo *bo, uint32_t *flags); ++int drm_tegra_bo_set_flags(struct drm_tegra_bo *bo, uint32_t flags); ++ ++struct drm_tegra_bo_tiling { ++ uint32_t mode; ++ uint32_t value; ++}; ++ ++int drm_tegra_bo_get_tiling(struct drm_tegra_bo *bo, ++ struct drm_tegra_bo_tiling *tiling); ++int drm_tegra_bo_set_tiling(struct drm_tegra_bo *bo, ++ const struct drm_tegra_bo_tiling *tiling); ++ + #endif /* __DRM_TEGRA_H__ */ +-- +2.37.2 + diff -Nru libdrm-2.4.110/debian/patches/Revert-meson-use-library-instead-of-shared_library.patch libdrm-2.4.113/debian/patches/Revert-meson-use-library-instead-of-shared_library.patch --- libdrm-2.4.110/debian/patches/Revert-meson-use-library-instead-of-shared_library.patch 2022-03-16 09:11:58.000000000 +0000 +++ libdrm-2.4.113/debian/patches/Revert-meson-use-library-instead-of-shared_library.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,141 +0,0 @@ -From f91aa47da756f020f02ce8db7dfc08aa52039d2b Mon Sep 17 00:00:00 2001 -From: Timo Aaltonen -Date: Sat, 8 May 2021 22:42:51 +0300 -Subject: [PATCH] Revert "meson: use library() instead of shared_library()." - -This reverts commit 52f05d3d896480ee5431dcd444f53bb2a8e41cce. ---- - amdgpu/meson.build | 2 +- - etnaviv/meson.build | 2 +- - exynos/meson.build | 2 +- - freedreno/meson.build | 2 +- - intel/meson.build | 2 +- - libkms/meson.build | 2 +- - meson.build | 2 +- - nouveau/meson.build | 2 +- - omap/meson.build | 2 +- - radeon/meson.build | 2 +- - tegra/meson.build | 2 +- - 11 files changed, 11 insertions(+), 11 deletions(-) - ---- a/amdgpu/meson.build -+++ b/amdgpu/meson.build -@@ -21,7 +21,7 @@ - - datadir_amdgpu = join_paths(get_option('prefix'), get_option('datadir'), 'libdrm') - --libdrm_amdgpu = library( -+libdrm_amdgpu = shared_library( - 'drm_amdgpu', - [ - files( ---- a/etnaviv/meson.build -+++ b/etnaviv/meson.build -@@ -19,7 +19,7 @@ - # SOFTWARE. - - --libdrm_etnaviv = library( -+libdrm_etnaviv = shared_library( - 'drm_etnaviv', - [ - files( ---- a/exynos/meson.build -+++ b/exynos/meson.build -@@ -18,7 +18,7 @@ - # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - # SOFTWARE. - --libdrm_exynos = library( -+libdrm_exynos = shared_library( - 'drm_exynos', - [files('exynos_drm.c', 'exynos_fimg2d.c'), config_file], - c_args : libdrm_c_args, ---- a/freedreno/meson.build -+++ b/freedreno/meson.build -@@ -39,7 +39,7 @@ if with_freedreno_kgsl - ) - endif - --libdrm_freedreno = library( -+libdrm_freedreno = shared_library( - 'drm_freedreno', - [files_freedreno, config_file], - c_args : libdrm_c_args, ---- a/intel/meson.build -+++ b/intel/meson.build -@@ -18,7 +18,7 @@ - # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - # SOFTWARE. - --libdrm_intel = library( -+libdrm_intel = shared_library( - 'drm_intel', - [ - files( ---- a/libkms/meson.build -+++ b/libkms/meson.build -@@ -41,7 +41,7 @@ if with_exynos - libkms_include += include_directories('../exynos') - endif - --libkms = library( -+libkms = shared_library( - 'kms', - [files_libkms, config_file], - c_args : libdrm_c_args, ---- a/meson.build -+++ b/meson.build -@@ -312,7 +312,7 @@ else - libdrm_kw = {'version' : '2.4.0'} - endif - --libdrm = library( -+libdrm = shared_library( - 'drm', - libdrm_files, - c_args : libdrm_c_args, ---- a/nouveau/meson.build -+++ b/nouveau/meson.build -@@ -19,7 +19,7 @@ - # SOFTWARE. - - --libdrm_nouveau = library( -+libdrm_nouveau = shared_library( - 'drm_nouveau', - [files( 'nouveau.c', 'pushbuf.c', 'bufctx.c', 'abi16.c'), config_file], - c_args : libdrm_c_args, ---- a/omap/meson.build -+++ b/omap/meson.build -@@ -18,7 +18,7 @@ - # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - # SOFTWARE. - --libdrm_omap = library( -+libdrm_omap = shared_library( - 'drm_omap', - [files('omap_drm.c'), config_file], - include_directories : [inc_root, inc_drm], ---- a/radeon/meson.build -+++ b/radeon/meson.build -@@ -19,7 +19,7 @@ - # SOFTWARE. - - --libdrm_radeon = library( -+libdrm_radeon = shared_library( - 'drm_radeon', - [ - files( ---- a/tegra/meson.build -+++ b/tegra/meson.build -@@ -18,7 +18,7 @@ - # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - # SOFTWARE. - --libdrm_tegra = library( -+libdrm_tegra = shared_library( - 'drm_tegra', - [files('tegra.c'), config_file], - include_directories : [inc_root, inc_drm], diff -Nru libdrm-2.4.110/debian/patches/series libdrm-2.4.113/debian/patches/series --- libdrm-2.4.110/debian/patches/series 2022-03-16 09:08:43.000000000 +0000 +++ libdrm-2.4.113/debian/patches/series 2022-12-06 07:19:45.000000000 +0000 @@ -1,2 +1,2 @@ 01_default_perms.diff -Revert-meson-use-library-instead-of-shared_library.patch +0001-Revert-tegra-Remove-unused-IOCTL-implementations.patch diff -Nru libdrm-2.4.110/debian/rules libdrm-2.4.113/debian/rules --- libdrm-2.4.110/debian/rules 2022-03-16 09:08:53.000000000 +0000 +++ libdrm-2.4.113/debian/rules 2022-11-21 15:49:21.000000000 +0000 @@ -10,23 +10,25 @@ DEB_HOST_ARCH_CPU ?= $(shell dpkg-architecture -qDEB_HOST_ARCH_CPU) confflags = \ - -Dradeon=true \ - -Damdgpu=true \ - -Dlibkms=false \ + --auto-features=disabled \ + -Ddefault_library=both \ + -Dman-pages=enabled \ + -Dradeon=enabled \ + -Damdgpu=enabled \ -Dinstall-test-programs=true \ - -Dvalgrind=false \ + -Dvalgrind=disabled \ $() # Linux vs. the rest: ifeq (linux, $(DEB_HOST_ARCH_OS)) confflags += -Dudev=true - confflags += -Dvmwgfx=true - confflags += -Dnouveau=true + confflags += -Dvmwgfx=enabled + confflags += -Dnouveau=enabled NOUVEAU = yes else confflags += -Dudev=false - confflags += -Dvmwgfx=false - confflags += -Dnouveau=false + confflags += -Dvmwgfx=disabled + confflags += -Dnouveau=disabled NOUVEAU = no endif @@ -37,9 +39,9 @@ endif endif ifeq ($(INTEL), yes) - confflags += -Dintel=true + confflags += -Dintel=enabled else - confflags += -Dintel=false + confflags += -Dintel=disabled endif # Exynos/Omap/Tegra are only on arm @@ -47,11 +49,11 @@ ARM = yes endif ifeq ($(ARM), yes) - confflags += -Dexynos=true - confflags += -Domap=true + confflags += -Dexynos=enabled + confflags += -Domap=enabled else - confflags += -Dexynos=false - confflags += -Domap=false + confflags += -Dexynos=disabled + confflags += -Domap=disabled endif # Etnaviv is on armhf and arm64 @@ -59,9 +61,9 @@ ETNAVIV = yes endif ifeq ($(ETNAVIV), yes) - confflags += -Detnaviv=true + confflags += -Detnaviv=enabled else - confflags += -Detnaviv=false + confflags += -Detnaviv=disabled endif # Tegra is on arm and arm64 @@ -69,9 +71,9 @@ TEGRA = yes endif ifeq ($(TEGRA), yes) - confflags += -Dtegra=true + confflags += -Dtegra=enabled else - confflags += -Dtegra=false + confflags += -Dtegra=disabled endif # Freedreno is on arm and arm64 @@ -79,9 +81,9 @@ FREEDRENO = yes endif ifeq ($(FREEDRENO), yes) - confflags += -Dfreedreno=true -Dfreedreno-kgsl=true + confflags += -Dfreedreno=enabled -Dfreedreno-kgsl=true else - confflags += -Dfreedreno=false + confflags += -Dfreedreno=disabled endif ### @@ -103,6 +105,11 @@ mv $$file debian/libdrm-tests/usr/bin; \ done endif + ifneq (,$(filter $(DEB_HOST_ARCH_CPU),arm arm64)) + for file in debian/tmp/usr/bin/tegra-*; do \ + mv $$file debian/libdrm-tests/usr/bin; \ + done + endif ifneq (,$(filter $(DEB_HOST_ARCH),armhf arm64)) for file in debian/tmp/usr/bin/etnaviv*; do \ mv $$file debian/libdrm-tests/usr/bin; \ diff -Nru libdrm-2.4.110/gen_table_fourcc.py libdrm-2.4.113/gen_table_fourcc.py --- libdrm-2.4.110/gen_table_fourcc.py 2022-02-16 10:00:13.000000000 +0000 +++ libdrm-2.4.113/gen_table_fourcc.py 2022-08-31 14:38:38.000000000 +0000 @@ -56,7 +56,7 @@ that script instead of adding here entries manually! */ static const struct drmFormatModifierInfo drm_format_modifier_table[] = { ''') - f.write(' { DRM_MODIFIER_INVALID(NONE, INVALID_MODIFIER) },\n') + f.write(' { DRM_MODIFIER_INVALID(NONE, INVALID) },\n') f.write(' { DRM_MODIFIER_LINEAR(NONE, LINEAR) },\n') for entry in fm_re['intel']: diff -Nru libdrm-2.4.110/.gitlab-ci/debian-install.sh libdrm-2.4.113/.gitlab-ci/debian-install.sh --- libdrm-2.4.110/.gitlab-ci/debian-install.sh 2022-02-16 10:00:13.000000000 +0000 +++ libdrm-2.4.113/.gitlab-ci/debian-install.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,66 +0,0 @@ -#!/usr/bin/env bash -set -o errexit -set -o xtrace - -export DEBIAN_FRONTEND=noninteractive - -CROSS_ARCHITECTURES=(i386 armhf arm64 ppc64el) -for arch in ${CROSS_ARCHITECTURES[@]}; do - dpkg --add-architecture $arch -done - -apt-get install -y \ - ca-certificates - -sed -i -e 's/http:\/\/deb/https:\/\/deb/g' /etc/apt/sources.list -echo 'deb https://deb.debian.org/debian buster-backports main' >/etc/apt/sources.list.d/backports.list - -apt-get update - -# Use newer packages from backports by default -cat >/etc/apt/preferences <refcount) > 0); - if (atomic_add_unless(&bo_gem->refcount, -1, 1)) { - drm_intel_bufmgr_gem *bufmgr_gem = - (drm_intel_bufmgr_gem *) bo->bufmgr; - struct timespec time; + if (atomic_add_unless(&bo_gem->refcount, -1, 1)) + return; - clock_gettime(CLOCK_MONOTONIC, &time); + drm_intel_bufmgr_gem *bufmgr_gem = + (drm_intel_bufmgr_gem *) bo->bufmgr; + struct timespec time; - pthread_mutex_lock(&bufmgr_gem->lock); + clock_gettime(CLOCK_MONOTONIC, &time); - if (atomic_dec_and_test(&bo_gem->refcount)) { - drm_intel_gem_bo_unreference_final(bo, time.tv_sec); - drm_intel_gem_cleanup_bo_cache(bufmgr_gem, time.tv_sec); - } + pthread_mutex_lock(&bufmgr_gem->lock); - pthread_mutex_unlock(&bufmgr_gem->lock); + if (atomic_dec_and_test(&bo_gem->refcount)) { + drm_intel_gem_bo_unreference_final(bo, time.tv_sec); + drm_intel_gem_cleanup_bo_cache(bufmgr_gem, time.tv_sec); } + + pthread_mutex_unlock(&bufmgr_gem->lock); } static int drm_intel_gem_bo_map(drm_intel_bo *bo, int write_enable) @@ -3377,16 +3378,17 @@ { drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *)bufmgr; - if (atomic_add_unless(&bufmgr_gem->refcount, -1, 1)) { - pthread_mutex_lock(&bufmgr_list_mutex); + if (atomic_add_unless(&bufmgr_gem->refcount, -1, 1)) + return; - if (atomic_dec_and_test(&bufmgr_gem->refcount)) { - DRMLISTDEL(&bufmgr_gem->managers); - drm_intel_bufmgr_gem_destroy(bufmgr); - } + pthread_mutex_lock(&bufmgr_list_mutex); - pthread_mutex_unlock(&bufmgr_list_mutex); + if (atomic_dec_and_test(&bufmgr_gem->refcount)) { + DRMLISTDEL(&bufmgr_gem->managers); + drm_intel_bufmgr_gem_destroy(bufmgr); } + + pthread_mutex_unlock(&bufmgr_list_mutex); } drm_public void *drm_intel_gem_bo_map__gtt(drm_intel_bo *bo) diff -Nru libdrm-2.4.110/intel/intel_chipset.c libdrm-2.4.113/intel/intel_chipset.c --- libdrm-2.4.110/intel/intel_chipset.c 2022-02-16 10:00:13.000000000 +0000 +++ libdrm-2.4.113/intel/intel_chipset.c 2022-08-31 14:38:38.000000000 +0000 @@ -35,9 +35,13 @@ uint16_t gen; } pciids[] = { /* Keep ids sorted by gen; latest gen first */ - INTEL_RPLS_IDS(12), + INTEL_MTL_IDS(12), + INTEL_ATS_M_IDS(12), + INTEL_DG2_IDS(12), INTEL_ADLN_IDS(12), + INTEL_RPLP_IDS(12), INTEL_ADLP_IDS(12), + INTEL_RPLS_IDS(12), INTEL_ADLS_IDS(12), INTEL_RKL_IDS(12), INTEL_DG1_IDS(12), diff -Nru libdrm-2.4.110/intel/test_decode.c libdrm-2.4.113/intel/test_decode.c --- libdrm-2.4.110/intel/test_decode.c 2022-02-16 10:00:13.000000000 +0000 +++ libdrm-2.4.113/intel/test_decode.c 2022-08-31 14:38:38.000000000 +0000 @@ -86,7 +86,8 @@ compare_batch(struct drm_intel_decode *ctx, const char *batch_filename) { FILE *out = NULL; - void *ptr, *ref_ptr, *batch_ptr; + char *ptr; + void *ref_ptr, *batch_ptr; #if HAVE_OPEN_MEMSTREAM size_t size; #endif @@ -106,7 +107,7 @@ * inside of an automake project's test infrastructure. */ #if HAVE_OPEN_MEMSTREAM - out = open_memstream((char **)&ptr, &size); + out = open_memstream(&ptr, &size); #else fprintf(stderr, "platform lacks open_memstream, skipping.\n"); exit(77); diff -Nru libdrm-2.4.110/libkms/Android.mk libdrm-2.4.113/libkms/Android.mk --- libdrm-2.4.110/libkms/Android.mk 2022-02-16 10:00:13.000000000 +0000 +++ libdrm-2.4.113/libkms/Android.mk 1970-01-01 00:00:00.000000000 +0000 @@ -1,51 +0,0 @@ -DRM_GPU_DRIVERS := $(strip $(filter-out swrast, $(BOARD_GPU_DRIVERS))) - -intel_drivers := i915 i965 i915g iris -radeon_drivers := r300g r600g radeonsi -nouveau_drivers := nouveau -virgl_drivers := virgl -vmwgfx_drivers := vmwgfx - -valid_drivers := \ - $(intel_drivers) \ - $(radeon_drivers) \ - $(nouveau_drivers) \ - $(virgl_drivers) \ - $(vmwgfx_drivers) - -# warn about invalid drivers -invalid_drivers := $(filter-out $(valid_drivers), $(DRM_GPU_DRIVERS)) -ifneq ($(invalid_drivers),) -$(warning invalid GPU drivers: $(invalid_drivers)) -# tidy up -DRM_GPU_DRIVERS := $(filter-out $(invalid_drivers), $(DRM_GPU_DRIVERS)) -endif - -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) -include $(LOCAL_PATH)/Makefile.sources - -LOCAL_SRC_FILES := $(LIBKMS_FILES) - -ifneq ($(filter $(vmwgfx_drivers), $(DRM_GPU_DRIVERS)),) -LOCAL_SRC_FILES += $(LIBKMS_VMWGFX_FILES) -endif - -ifneq ($(filter $(intel_drivers), $(DRM_GPU_DRIVERS)),) -LOCAL_SRC_FILES += $(LIBKMS_INTEL_FILES) -endif - -ifneq ($(filter $(nouveau_drivers), $(DRM_GPU_DRIVERS)),) -LOCAL_SRC_FILES += $(LIBKMS_NOUVEAU_FILES) -endif - -ifneq ($(filter $(radeon_drivers), $(DRM_GPU_DRIVERS)),) -LOCAL_SRC_FILES += $(LIBKMS_RADEON_FILES) -endif - -LOCAL_MODULE := libkms -LOCAL_SHARED_LIBRARIES := libdrm - -include $(LIBDRM_COMMON_MK) -include $(BUILD_SHARED_LIBRARY) diff -Nru libdrm-2.4.110/libkms/api.c libdrm-2.4.113/libkms/api.c --- libdrm-2.4.110/libkms/api.c 2022-02-16 10:00:13.000000000 +0000 +++ libdrm-2.4.113/libkms/api.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,139 +0,0 @@ -/************************************************************************** - * - * Copyright © 2009 VMware, Inc., Palo Alto, CA., USA - * All Rights Reserved. - * - * 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, sub license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS 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 -#include -#include - -#include "libdrm_macros.h" -#include "internal.h" - -drm_public int kms_create(int fd, struct kms_driver **out) -{ - return linux_create(fd, out); -} - -drm_public int kms_get_prop(struct kms_driver *kms, unsigned key, unsigned *out) -{ - switch (key) { - case KMS_BO_TYPE: - break; - default: - return -EINVAL; - } - return kms->get_prop(kms, key, out); -} - -drm_public int kms_destroy(struct kms_driver **kms) -{ - if (!(*kms)) - return 0; - - free(*kms); - *kms = NULL; - return 0; -} - -drm_public int kms_bo_create(struct kms_driver *kms, const unsigned *attr, struct kms_bo **out) -{ - unsigned width = 0; - unsigned height = 0; - enum kms_bo_type type = KMS_BO_TYPE_SCANOUT_X8R8G8B8; - int i; - - for (i = 0; attr[i];) { - unsigned key = attr[i++]; - unsigned value = attr[i++]; - - switch (key) { - case KMS_WIDTH: - width = value; - break; - case KMS_HEIGHT: - height = value; - break; - case KMS_BO_TYPE: - type = value; - break; - default: - return -EINVAL; - } - } - - if (width == 0 || height == 0) - return -EINVAL; - - /* XXX sanity check type */ - - if (type == KMS_BO_TYPE_CURSOR_64X64_A8R8G8B8 && - (width != 64 || height != 64)) - return -EINVAL; - - return kms->bo_create(kms, width, height, type, attr, out); -} - -drm_public int kms_bo_get_prop(struct kms_bo *bo, unsigned key, unsigned *out) -{ - switch (key) { - case KMS_PITCH: - *out = bo->pitch; - break; - case KMS_HANDLE: - *out = bo->handle; - break; - default: - return -EINVAL; - } - - return 0; -} - -drm_public int kms_bo_map(struct kms_bo *bo, void **out) -{ - return bo->kms->bo_map(bo, out); -} - -drm_public int kms_bo_unmap(struct kms_bo *bo) -{ - return bo->kms->bo_unmap(bo); -} - -drm_public int kms_bo_destroy(struct kms_bo **bo) -{ - int ret; - - if (!(*bo)) - return 0; - - ret = (*bo)->kms->bo_destroy(*bo); - if (ret) - return ret; - - *bo = NULL; - return 0; -} diff -Nru libdrm-2.4.110/libkms/dumb.c libdrm-2.4.113/libkms/dumb.c --- libdrm-2.4.110/libkms/dumb.c 2022-02-16 10:00:13.000000000 +0000 +++ libdrm-2.4.113/libkms/dumb.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,216 +0,0 @@ -/************************************************************************** - * - * Copyright © 2009 VMware, Inc., Palo Alto, CA., USA - * All Rights Reserved. - * - * 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, sub license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS 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 -#include -#include -#include -#include "internal.h" - -#include -#include "xf86drm.h" -#include "libdrm_macros.h" - -struct dumb_bo -{ - struct kms_bo base; - unsigned map_count; -}; - -static int -dumb_get_prop(struct kms_driver *kms, unsigned key, unsigned *out) -{ - switch (key) { - case KMS_BO_TYPE: - *out = KMS_BO_TYPE_SCANOUT_X8R8G8B8 | KMS_BO_TYPE_CURSOR_64X64_A8R8G8B8; - break; - default: - return -EINVAL; - } - return 0; -} - -static int -dumb_destroy(struct kms_driver *kms) -{ - free(kms); - return 0; -} - -static int -dumb_bo_create(struct kms_driver *kms, - const unsigned width, const unsigned height, - const enum kms_bo_type type, const unsigned *attr, - struct kms_bo **out) -{ - struct drm_mode_create_dumb arg; - struct dumb_bo *bo; - int i, ret; - - for (i = 0; attr[i]; i += 2) { - switch (attr[i]) { - case KMS_WIDTH: - case KMS_HEIGHT: - break; - case KMS_BO_TYPE: - break; - default: - return -EINVAL; - } - } - - bo = calloc(1, sizeof(*bo)); - if (!bo) - return -ENOMEM; - - memset(&arg, 0, sizeof(arg)); - - /* All BO_TYPE currently are 32bpp formats */ - arg.bpp = 32; - arg.width = width; - arg.height = height; - - ret = drmIoctl(kms->fd, DRM_IOCTL_MODE_CREATE_DUMB, &arg); - if (ret) - goto err_free; - - bo->base.kms = kms; - bo->base.handle = arg.handle; - bo->base.size = arg.size; - bo->base.pitch = arg.pitch; - - *out = &bo->base; - - return 0; - -err_free: - free(bo); - return ret; -} - -static int -dumb_bo_get_prop(struct kms_bo *bo, unsigned key, unsigned *out) -{ - switch (key) { - default: - return -EINVAL; - } -} - -static int -dumb_bo_map(struct kms_bo *_bo, void **out) -{ - struct dumb_bo *bo = (struct dumb_bo *)_bo; - struct drm_mode_map_dumb arg; - void *map = NULL; - int ret; - - if (bo->base.ptr) { - bo->map_count++; - *out = bo->base.ptr; - return 0; - } - - memset(&arg, 0, sizeof(arg)); - arg.handle = bo->base.handle; - - ret = drmIoctl(bo->base.kms->fd, DRM_IOCTL_MODE_MAP_DUMB, &arg); - if (ret) - return ret; - - map = drm_mmap(0, bo->base.size, PROT_READ | PROT_WRITE, MAP_SHARED, bo->base.kms->fd, arg.offset); - if (map == MAP_FAILED) - return -errno; - - bo->base.ptr = map; - bo->map_count++; - *out = bo->base.ptr; - - return 0; -} - -static int -dumb_bo_unmap(struct kms_bo *_bo) -{ - struct dumb_bo *bo = (struct dumb_bo *)_bo; - bo->map_count--; - return 0; -} - -static int -dumb_bo_destroy(struct kms_bo *_bo) -{ - struct dumb_bo *bo = (struct dumb_bo *)_bo; - struct drm_mode_destroy_dumb arg; - int ret; - - if (bo->base.ptr) { - /* XXX Sanity check map_count */ - drm_munmap(bo->base.ptr, bo->base.size); - bo->base.ptr = NULL; - } - - memset(&arg, 0, sizeof(arg)); - arg.handle = bo->base.handle; - - ret = drmIoctl(bo->base.kms->fd, DRM_IOCTL_MODE_DESTROY_DUMB, &arg); - if (ret) - return -errno; - - free(bo); - return 0; -} - -drm_private int -dumb_create(int fd, struct kms_driver **out) -{ - struct kms_driver *kms; - int ret; - uint64_t cap = 0; - - ret = drmGetCap(fd, DRM_CAP_DUMB_BUFFER, &cap); - if (ret || cap == 0) - return -EINVAL; - - kms = calloc(1, sizeof(*kms)); - if (!kms) - return -ENOMEM; - - kms->fd = fd; - - kms->bo_create = dumb_bo_create; - kms->bo_map = dumb_bo_map; - kms->bo_unmap = dumb_bo_unmap; - kms->bo_get_prop = dumb_bo_get_prop; - kms->bo_destroy = dumb_bo_destroy; - kms->get_prop = dumb_get_prop; - kms->destroy = dumb_destroy; - *out = kms; - - return 0; -} diff -Nru libdrm-2.4.110/libkms/exynos.c libdrm-2.4.113/libkms/exynos.c --- libdrm-2.4.110/libkms/exynos.c 2022-02-16 10:00:13.000000000 +0000 +++ libdrm-2.4.113/libkms/exynos.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,220 +0,0 @@ -/* exynos.c - * - * Copyright 2009 Samsung Electronics Co., Ltd. - * Authors: - * SooChan Lim - * Sangjin LEE - * - * 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. - */ - -#include -#include -#include -#include -#include "internal.h" - -#include -#include -#include "xf86drm.h" - -#include "libdrm_macros.h" -#include "exynos_drm.h" - -struct exynos_bo -{ - struct kms_bo base; - unsigned map_count; -}; - -static int -exynos_get_prop(struct kms_driver *kms, unsigned key, unsigned *out) -{ - switch (key) { - case KMS_BO_TYPE: - *out = KMS_BO_TYPE_SCANOUT_X8R8G8B8 | KMS_BO_TYPE_CURSOR_64X64_A8R8G8B8; - break; - default: - return -EINVAL; - } - return 0; -} - -static int -exynos_destroy(struct kms_driver *kms) -{ - free(kms); - return 0; -} - -static int -exynos_bo_create(struct kms_driver *kms, - const unsigned width, const unsigned height, - const enum kms_bo_type type, const unsigned *attr, - struct kms_bo **out) -{ - struct drm_exynos_gem_create arg; - unsigned size, pitch; - struct exynos_bo *bo; - int i, ret; - - for (i = 0; attr[i]; i += 2) { - switch (attr[i]) { - case KMS_WIDTH: - case KMS_HEIGHT: - case KMS_BO_TYPE: - break; - default: - return -EINVAL; - } - } - - bo = calloc(1, sizeof(*bo)); - if (!bo) - return -ENOMEM; - - if (type == KMS_BO_TYPE_CURSOR_64X64_A8R8G8B8) { - pitch = 64 * 4; - size = 64 * 64 * 4; - } else if (type == KMS_BO_TYPE_SCANOUT_X8R8G8B8) { - pitch = width * 4; - pitch = (pitch + 512 - 1) & ~(512 - 1); - size = pitch * ((height + 4 - 1) & ~(4 - 1)); - } else { - ret = -EINVAL; - goto err_free; - } - - memset(&arg, 0, sizeof(arg)); - arg.size = size; - - ret = drmCommandWriteRead(kms->fd, DRM_EXYNOS_GEM_CREATE, &arg, sizeof(arg)); - if (ret) - goto err_free; - - bo->base.kms = kms; - bo->base.handle = arg.handle; - bo->base.size = size; - bo->base.pitch = pitch; - - *out = &bo->base; - - return 0; - -err_free: - free(bo); - return ret; -} - -static int -exynos_bo_get_prop(struct kms_bo *bo, unsigned key, unsigned *out) -{ - switch (key) { - default: - return -EINVAL; - } -} - -static int -exynos_bo_map(struct kms_bo *_bo, void **out) -{ - struct exynos_bo *bo = (struct exynos_bo *)_bo; - struct drm_mode_map_dumb arg; - void *map = NULL; - int ret; - - if (bo->base.ptr) { - bo->map_count++; - *out = bo->base.ptr; - return 0; - } - - memset(&arg, 0, sizeof(arg)); - arg.handle = bo->base.handle; - - ret = drmIoctl(bo->base.kms->fd, DRM_IOCTL_MODE_MAP_DUMB, &arg); - if (ret) - return ret; - - map = drm_mmap(0, bo->base.size, PROT_READ | PROT_WRITE, MAP_SHARED, bo->base.kms->fd, arg.offset); - if (map == MAP_FAILED) - return -errno; - - bo->base.ptr = map; - bo->map_count++; - *out = bo->base.ptr; - - return 0; -} - -static int -exynos_bo_unmap(struct kms_bo *_bo) -{ - struct exynos_bo *bo = (struct exynos_bo *)_bo; - bo->map_count--; - return 0; -} - -static int -exynos_bo_destroy(struct kms_bo *_bo) -{ - struct exynos_bo *bo = (struct exynos_bo *)_bo; - struct drm_gem_close arg; - int ret; - - if (bo->base.ptr) { - /* XXX Sanity check map_count */ - munmap(bo->base.ptr, bo->base.size); - bo->base.ptr = NULL; - } - - memset(&arg, 0, sizeof(arg)); - arg.handle = bo->base.handle; - - ret = drmIoctl(bo->base.kms->fd, DRM_IOCTL_GEM_CLOSE, &arg); - if (ret) - return -errno; - - free(bo); - return 0; -} - -drm_private int -exynos_create(int fd, struct kms_driver **out) -{ - struct kms_driver *kms; - - kms = calloc(1, sizeof(*kms)); - if (!kms) - return -ENOMEM; - - kms->fd = fd; - - kms->bo_create = exynos_bo_create; - kms->bo_map = exynos_bo_map; - kms->bo_unmap = exynos_bo_unmap; - kms->bo_get_prop = exynos_bo_get_prop; - kms->bo_destroy = exynos_bo_destroy; - kms->get_prop = exynos_get_prop; - kms->destroy = exynos_destroy; - *out = kms; - - return 0; -} diff -Nru libdrm-2.4.110/libkms/intel.c libdrm-2.4.113/libkms/intel.c --- libdrm-2.4.110/libkms/intel.c 2022-02-16 10:00:13.000000000 +0000 +++ libdrm-2.4.113/libkms/intel.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,236 +0,0 @@ -/************************************************************************** - * - * Copyright © 2009 VMware, Inc., Palo Alto, CA., USA - * All Rights Reserved. - * - * 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, sub license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS 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 -#include -#include -#include -#include "internal.h" - -#include -#include "xf86drm.h" -#include "libdrm_macros.h" - -#include "i915_drm.h" - -struct intel_bo -{ - struct kms_bo base; - unsigned map_count; -}; - -static int -intel_get_prop(struct kms_driver *kms, unsigned key, unsigned *out) -{ - switch (key) { - case KMS_BO_TYPE: - *out = KMS_BO_TYPE_SCANOUT_X8R8G8B8 | KMS_BO_TYPE_CURSOR_64X64_A8R8G8B8; - break; - default: - return -EINVAL; - } - return 0; -} - -static int -intel_destroy(struct kms_driver *kms) -{ - free(kms); - return 0; -} - -static int -intel_bo_create(struct kms_driver *kms, - const unsigned width, const unsigned height, - const enum kms_bo_type type, const unsigned *attr, - struct kms_bo **out) -{ - struct drm_i915_gem_create arg; - unsigned size, pitch; - struct intel_bo *bo; - int i, ret; - - for (i = 0; attr[i]; i += 2) { - switch (attr[i]) { - case KMS_WIDTH: - case KMS_HEIGHT: - case KMS_BO_TYPE: - break; - default: - return -EINVAL; - } - } - - bo = calloc(1, sizeof(*bo)); - if (!bo) - return -ENOMEM; - - if (type == KMS_BO_TYPE_CURSOR_64X64_A8R8G8B8) { - pitch = 64 * 4; - size = 64 * 64 * 4; - } else if (type == KMS_BO_TYPE_SCANOUT_X8R8G8B8) { - pitch = width * 4; - pitch = (pitch + 512 - 1) & ~(512 - 1); - size = pitch * ((height + 4 - 1) & ~(4 - 1)); - } else { - free(bo); - return -EINVAL; - } - - memset(&arg, 0, sizeof(arg)); - arg.size = size; - - ret = drmCommandWriteRead(kms->fd, DRM_I915_GEM_CREATE, &arg, sizeof(arg)); - if (ret) - goto err_free; - - bo->base.kms = kms; - bo->base.handle = arg.handle; - bo->base.size = size; - bo->base.pitch = pitch; - - *out = &bo->base; - if (type == KMS_BO_TYPE_SCANOUT_X8R8G8B8 && pitch > 512) { - struct drm_i915_gem_set_tiling tile; - - memset(&tile, 0, sizeof(tile)); - tile.handle = bo->base.handle; - tile.tiling_mode = I915_TILING_X; - tile.stride = bo->base.pitch; - - ret = drmCommandWriteRead(kms->fd, DRM_I915_GEM_SET_TILING, &tile, sizeof(tile)); -#if 0 - if (ret) { - kms_bo_destroy(out); - return ret; - } -#endif - } - - return 0; - -err_free: - free(bo); - return ret; -} - -static int -intel_bo_get_prop(struct kms_bo *bo, unsigned key, unsigned *out) -{ - switch (key) { - default: - return -EINVAL; - } -} - -static int -intel_bo_map(struct kms_bo *_bo, void **out) -{ - struct intel_bo *bo = (struct intel_bo *)_bo; - struct drm_i915_gem_mmap_gtt arg; - void *map = NULL; - int ret; - - if (bo->base.ptr) { - bo->map_count++; - *out = bo->base.ptr; - return 0; - } - - memset(&arg, 0, sizeof(arg)); - arg.handle = bo->base.handle; - - ret = drmCommandWriteRead(bo->base.kms->fd, DRM_I915_GEM_MMAP_GTT, &arg, sizeof(arg)); - if (ret) - return ret; - - map = drm_mmap(0, bo->base.size, PROT_READ | PROT_WRITE, MAP_SHARED, bo->base.kms->fd, arg.offset); - if (map == MAP_FAILED) - return -errno; - - bo->base.ptr = map; - bo->map_count++; - *out = bo->base.ptr; - - return 0; -} - -static int -intel_bo_unmap(struct kms_bo *_bo) -{ - struct intel_bo *bo = (struct intel_bo *)_bo; - bo->map_count--; - return 0; -} - -static int -intel_bo_destroy(struct kms_bo *_bo) -{ - struct intel_bo *bo = (struct intel_bo *)_bo; - struct drm_gem_close arg; - int ret; - - if (bo->base.ptr) { - /* XXX Sanity check map_count */ - drm_munmap(bo->base.ptr, bo->base.size); - bo->base.ptr = NULL; - } - - memset(&arg, 0, sizeof(arg)); - arg.handle = bo->base.handle; - - ret = drmIoctl(bo->base.kms->fd, DRM_IOCTL_GEM_CLOSE, &arg); - if (ret) - return -errno; - - free(bo); - return 0; -} - -drm_private int -intel_create(int fd, struct kms_driver **out) -{ - struct kms_driver *kms; - - kms = calloc(1, sizeof(*kms)); - if (!kms) - return -ENOMEM; - - kms->fd = fd; - - kms->bo_create = intel_bo_create; - kms->bo_map = intel_bo_map; - kms->bo_unmap = intel_bo_unmap; - kms->bo_get_prop = intel_bo_get_prop; - kms->bo_destroy = intel_bo_destroy; - kms->get_prop = intel_get_prop; - kms->destroy = intel_destroy; - *out = kms; - - return 0; -} diff -Nru libdrm-2.4.110/libkms/internal.h libdrm-2.4.113/libkms/internal.h --- libdrm-2.4.110/libkms/internal.h 2022-02-16 10:00:13.000000000 +0000 +++ libdrm-2.4.113/libkms/internal.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,80 +0,0 @@ -/************************************************************************** - * - * Copyright © 2009 VMware, Inc., Palo Alto, CA., USA - * All Rights Reserved. - * - * 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, sub license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS 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 INTERNAL_H_ -#define INTERNAL_H_ - -#include "libdrm_macros.h" -#include "libkms.h" - -struct kms_driver -{ - int (*get_prop)(struct kms_driver *kms, const unsigned key, - unsigned *out); - int (*destroy)(struct kms_driver *kms); - - int (*bo_create)(struct kms_driver *kms, - unsigned width, - unsigned height, - enum kms_bo_type type, - const unsigned *attr, - struct kms_bo **out); - int (*bo_get_prop)(struct kms_bo *bo, const unsigned key, - unsigned *out); - int (*bo_map)(struct kms_bo *bo, void **out); - int (*bo_unmap)(struct kms_bo *bo); - int (*bo_destroy)(struct kms_bo *bo); - - int fd; -}; - -struct kms_bo -{ - struct kms_driver *kms; - void *ptr; - size_t size; - size_t offset; - size_t pitch; - unsigned handle; -}; - -drm_private int linux_create(int fd, struct kms_driver **out); - -drm_private int vmwgfx_create(int fd, struct kms_driver **out); - -drm_private int intel_create(int fd, struct kms_driver **out); - -drm_private int dumb_create(int fd, struct kms_driver **out); - -drm_private int nouveau_create(int fd, struct kms_driver **out); - -drm_private int radeon_create(int fd, struct kms_driver **out); - -drm_private int exynos_create(int fd, struct kms_driver **out); - -#endif diff -Nru libdrm-2.4.110/libkms/kms-symbols.txt libdrm-2.4.113/libkms/kms-symbols.txt --- libdrm-2.4.110/libkms/kms-symbols.txt 2022-02-16 10:00:13.000000000 +0000 +++ libdrm-2.4.113/libkms/kms-symbols.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,8 +0,0 @@ -kms_bo_create -kms_bo_destroy -kms_bo_get_prop -kms_bo_map -kms_bo_unmap -kms_create -kms_destroy -kms_get_prop diff -Nru libdrm-2.4.110/libkms/libkms.h libdrm-2.4.113/libkms/libkms.h --- libdrm-2.4.110/libkms/libkms.h 2022-02-16 10:00:13.000000000 +0000 +++ libdrm-2.4.113/libkms/libkms.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,82 +0,0 @@ -/************************************************************************** - * - * Copyright © 2009 VMware, Inc., Palo Alto, CA., USA - * All Rights Reserved. - * - * 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, sub license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS 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 _LIBKMS_H_ -#define _LIBKMS_H_ - -#if defined(__cplusplus) -extern "C" { -#endif - -/** - * \file - * - */ - -struct kms_driver; -struct kms_bo; - -enum kms_attrib -{ - KMS_TERMINATE_PROP_LIST, -#define KMS_TERMINATE_PROP_LIST KMS_TERMINATE_PROP_LIST - KMS_BO_TYPE, -#define KMS_BO_TYPE KMS_BO_TYPE - KMS_WIDTH, -#define KMS_WIDTH KMS_WIDTH - KMS_HEIGHT, -#define KMS_HEIGHT KMS_HEIGHT - KMS_PITCH, -#define KMS_PITCH KMS_PITCH - KMS_HANDLE, -#define KMS_HANDLE KMS_HANDLE -}; - -enum kms_bo_type -{ - KMS_BO_TYPE_SCANOUT_X8R8G8B8 = (1 << 0), -#define KMS_BO_TYPE_SCANOUT_X8R8G8B8 KMS_BO_TYPE_SCANOUT_X8R8G8B8 - KMS_BO_TYPE_CURSOR_64X64_A8R8G8B8 = (1 << 1), -#define KMS_BO_TYPE_CURSOR_64X64_A8R8G8B8 KMS_BO_TYPE_CURSOR_64X64_A8R8G8B8 -}; - -int kms_create(int fd, struct kms_driver **out); -int kms_get_prop(struct kms_driver *kms, unsigned key, unsigned *out); -int kms_destroy(struct kms_driver **kms); - -int kms_bo_create(struct kms_driver *kms, const unsigned *attr, struct kms_bo **out); -int kms_bo_get_prop(struct kms_bo *bo, unsigned key, unsigned *out); -int kms_bo_map(struct kms_bo *bo, void **out); -int kms_bo_unmap(struct kms_bo *bo); -int kms_bo_destroy(struct kms_bo **bo); - -#if defined(__cplusplus) -}; -#endif - -#endif diff -Nru libdrm-2.4.110/libkms/libkms.pc.in libdrm-2.4.113/libkms/libkms.pc.in --- libdrm-2.4.110/libkms/libkms.pc.in 2022-02-16 10:00:13.000000000 +0000 +++ libdrm-2.4.113/libkms/libkms.pc.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,11 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ - -Name: libkms -Description: Library that abstracts away the different mm interface for kernel drivers -Version: 1.0.0 -Libs: -L${libdir} -lkms -Cflags: -I${includedir}/libkms -Requires.private: libdrm diff -Nru libdrm-2.4.110/libkms/linux.c libdrm-2.4.113/libkms/linux.c --- libdrm-2.4.110/libkms/linux.c 2022-02-16 10:00:13.000000000 +0000 +++ libdrm-2.4.113/libkms/linux.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,147 +0,0 @@ -/************************************************************************** - * - * Copyright © 2009 VMware, Inc., Palo Alto, CA., USA - * All Rights Reserved. - * - * 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, sub license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS 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. - * - **************************************************************************/ -/* - * Thanks to krh and jcristau for the tips on - * going from fd to pci id via fstat and udev. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef MAJOR_IN_MKDEV -#include -#endif -#ifdef MAJOR_IN_SYSMACROS -#include -#endif - -#include "libdrm_macros.h" -#include "internal.h" - -#define PATH_SIZE 512 - -static int -linux_name_from_sysfs(int fd, char **out) -{ - char path[PATH_SIZE+1] = ""; /* initialize to please valgrind */ - char link[PATH_SIZE+1] = ""; - struct stat buffer; - unsigned maj, min; - char* slash_name; - int ret; - - /* - * Inside the sysfs directory for the device there is a symlink - * to the directory representing the driver module, that path - * happens to hold the name of the driver. - * - * So lets get the symlink for the drm device. Then read the link - * and filter out the last directory which happens to be the name - * of the driver, which we can use to load the correct interface. - * - * Thanks to Ray Strode of Plymouth for the code. - */ - - ret = fstat(fd, &buffer); - if (ret) - return -EINVAL; - - if (!S_ISCHR(buffer.st_mode)) - return -EINVAL; - - maj = major(buffer.st_rdev); - min = minor(buffer.st_rdev); - - snprintf(path, PATH_SIZE, "/sys/dev/char/%d:%d/device/driver", maj, min); - - if (readlink(path, link, PATH_SIZE) < 0) - return -EINVAL; - - /* link looks something like this: ../../../bus/pci/drivers/intel */ - slash_name = strrchr(link, '/'); - if (!slash_name) - return -EINVAL; - - /* copy name and at the same time remove the slash */ - *out = strdup(slash_name + 1); - return 0; -} - -static int -linux_from_sysfs(int fd, struct kms_driver **out) -{ - char *name; - int ret; - - ret = linux_name_from_sysfs(fd, &name); - if (ret) - return ret; - -#if HAVE_INTEL - if (!strcmp(name, "intel")) - ret = intel_create(fd, out); - else -#endif -#if HAVE_VMWGFX - if (!strcmp(name, "vmwgfx")) - ret = vmwgfx_create(fd, out); - else -#endif -#if HAVE_NOUVEAU - if (!strcmp(name, "nouveau")) - ret = nouveau_create(fd, out); - else -#endif -#if HAVE_RADEON - if (!strcmp(name, "radeon")) - ret = radeon_create(fd, out); - else -#endif -#if HAVE_EXYNOS - if (!strcmp(name, "exynos")) - ret = exynos_create(fd, out); - else -#endif - ret = -ENOSYS; - - free(name); - return ret; -} - -drm_private int -linux_create(int fd, struct kms_driver **out) -{ - if (!dumb_create(fd, out)) - return 0; - - return linux_from_sysfs(fd, out); -} diff -Nru libdrm-2.4.110/libkms/Makefile.sources libdrm-2.4.113/libkms/Makefile.sources --- libdrm-2.4.110/libkms/Makefile.sources 2022-02-16 10:00:13.000000000 +0000 +++ libdrm-2.4.113/libkms/Makefile.sources 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -LIBKMS_FILES := \ - internal.h \ - linux.c \ - dumb.c \ - api.c - -LIBKMS_VMWGFX_FILES := \ - vmwgfx.c - -LIBKMS_INTEL_FILES := \ - intel.c - -LIBKMS_NOUVEAU_FILES := \ - nouveau.c - -LIBKMS_RADEON_FILES := \ - radeon.c - -LIBKMS_EXYNOS_FILES := \ - exynos.c - -LIBKMS_H_FILES := \ - libkms.h diff -Nru libdrm-2.4.110/libkms/meson.build libdrm-2.4.113/libkms/meson.build --- libdrm-2.4.110/libkms/meson.build 2022-02-16 10:00:13.000000000 +0000 +++ libdrm-2.4.113/libkms/meson.build 1970-01-01 00:00:00.000000000 +0000 @@ -1,81 +0,0 @@ -# Copyright © 2017-2018 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 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. - -libkms_include = [inc_root, inc_drm] -files_libkms = files( - 'linux.c', - 'dumb.c', - 'api.c', -) -if with_vmwgfx - files_libkms += files('vmwgfx.c') -endif -if with_intel - files_libkms += files('intel.c') -endif -if with_nouveau - files_libkms += files('nouveau.c') -endif -if with_radeon - files_libkms += files('radeon.c') -endif -if with_exynos - files_libkms += files('exynos.c') - libkms_include += include_directories('../exynos') -endif - -libkms = library( - 'kms', - [files_libkms, config_file], - c_args : libdrm_c_args, - include_directories : libkms_include, - link_with : libdrm, - version : '1.0.0', - install : true, -) - -ext_libkms = declare_dependency( - link_with : [libdrm, libkms], - include_directories : [libkms_include], -) - -if meson.version().version_compare('>= 0.54.0') - meson.override_dependency('kms', ext_libkms) -endif - -install_headers('libkms.h', subdir : 'libkms') - -pkg.generate( - libkms, - name : 'libkms', - subdirs : ['libkms'], - version : '1.0.0', - description : 'Library that abstracts away the different mm interfaces for kernel drivers', -) - -test( - 'kms-symbols-check', - symbols_check, - args : [ - '--lib', libkms, - '--symbols-file', files('kms-symbols.txt'), - '--nm', prog_nm.path(), - ], -) diff -Nru libdrm-2.4.110/libkms/nouveau.c libdrm-2.4.113/libkms/nouveau.c --- libdrm-2.4.110/libkms/nouveau.c 2022-02-16 10:00:13.000000000 +0000 +++ libdrm-2.4.113/libkms/nouveau.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,218 +0,0 @@ -/************************************************************************** - * - * Copyright © 2009 VMware, Inc., Palo Alto, CA., USA - * All Rights Reserved. - * - * 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, sub license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS 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 -#include -#include -#include -#include "internal.h" - -#include -#include "xf86drm.h" -#include "libdrm_macros.h" - -#include "nouveau_drm.h" - -struct nouveau_bo -{ - struct kms_bo base; - uint64_t map_handle; - unsigned map_count; -}; - -static int -nouveau_get_prop(struct kms_driver *kms, unsigned key, unsigned *out) -{ - switch (key) { - case KMS_BO_TYPE: - *out = KMS_BO_TYPE_SCANOUT_X8R8G8B8 | KMS_BO_TYPE_CURSOR_64X64_A8R8G8B8; - break; - default: - return -EINVAL; - } - return 0; -} - -static int -nouveau_destroy(struct kms_driver *kms) -{ - free(kms); - return 0; -} - -static int -nouveau_bo_create(struct kms_driver *kms, - const unsigned width, const unsigned height, - const enum kms_bo_type type, const unsigned *attr, - struct kms_bo **out) -{ - struct drm_nouveau_gem_new arg; - unsigned size, pitch; - struct nouveau_bo *bo; - int i, ret; - - for (i = 0; attr[i]; i += 2) { - switch (attr[i]) { - case KMS_WIDTH: - case KMS_HEIGHT: - case KMS_BO_TYPE: - break; - default: - return -EINVAL; - } - } - - bo = calloc(1, sizeof(*bo)); - if (!bo) - return -ENOMEM; - - if (type == KMS_BO_TYPE_CURSOR_64X64_A8R8G8B8) { - pitch = 64 * 4; - size = 64 * 64 * 4; - } else if (type == KMS_BO_TYPE_SCANOUT_X8R8G8B8) { - pitch = width * 4; - pitch = (pitch + 512 - 1) & ~(512 - 1); - size = pitch * height; - } else { - free(bo); - return -EINVAL; - } - - memset(&arg, 0, sizeof(arg)); - arg.info.size = size; - arg.info.domain = NOUVEAU_GEM_DOMAIN_MAPPABLE | NOUVEAU_GEM_DOMAIN_VRAM; - arg.info.tile_mode = 0; - arg.info.tile_flags = 0; - arg.align = 512; - arg.channel_hint = 0; - - ret = drmCommandWriteRead(kms->fd, DRM_NOUVEAU_GEM_NEW, &arg, sizeof(arg)); - if (ret) - goto err_free; - - bo->base.kms = kms; - bo->base.handle = arg.info.handle; - bo->base.size = size; - bo->base.pitch = pitch; - bo->map_handle = arg.info.map_handle; - - *out = &bo->base; - - return 0; - -err_free: - free(bo); - return ret; -} - -static int -nouveau_bo_get_prop(struct kms_bo *bo, unsigned key, unsigned *out) -{ - switch (key) { - default: - return -EINVAL; - } -} - -static int -nouveau_bo_map(struct kms_bo *_bo, void **out) -{ - struct nouveau_bo *bo = (struct nouveau_bo *)_bo; - void *map = NULL; - - if (bo->base.ptr) { - bo->map_count++; - *out = bo->base.ptr; - return 0; - } - - map = drm_mmap(0, bo->base.size, PROT_READ | PROT_WRITE, MAP_SHARED, bo->base.kms->fd, bo->map_handle); - if (map == MAP_FAILED) - return -errno; - - bo->base.ptr = map; - bo->map_count++; - *out = bo->base.ptr; - - return 0; -} - -static int -nouveau_bo_unmap(struct kms_bo *_bo) -{ - struct nouveau_bo *bo = (struct nouveau_bo *)_bo; - bo->map_count--; - return 0; -} - -static int -nouveau_bo_destroy(struct kms_bo *_bo) -{ - struct nouveau_bo *bo = (struct nouveau_bo *)_bo; - struct drm_gem_close arg; - int ret; - - if (bo->base.ptr) { - /* XXX Sanity check map_count */ - drm_munmap(bo->base.ptr, bo->base.size); - bo->base.ptr = NULL; - } - - memset(&arg, 0, sizeof(arg)); - arg.handle = bo->base.handle; - - ret = drmIoctl(bo->base.kms->fd, DRM_IOCTL_GEM_CLOSE, &arg); - if (ret) - return -errno; - - free(bo); - return 0; -} - -drm_private int -nouveau_create(int fd, struct kms_driver **out) -{ - struct kms_driver *kms; - - kms = calloc(1, sizeof(*kms)); - if (!kms) - return -ENOMEM; - - kms->fd = fd; - - kms->bo_create = nouveau_bo_create; - kms->bo_map = nouveau_bo_map; - kms->bo_unmap = nouveau_bo_unmap; - kms->bo_get_prop = nouveau_bo_get_prop; - kms->bo_destroy = nouveau_bo_destroy; - kms->get_prop = nouveau_get_prop; - kms->destroy = nouveau_destroy; - *out = kms; - - return 0; -} diff -Nru libdrm-2.4.110/libkms/radeon.c libdrm-2.4.113/libkms/radeon.c --- libdrm-2.4.110/libkms/radeon.c 2022-02-16 10:00:13.000000000 +0000 +++ libdrm-2.4.113/libkms/radeon.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,239 +0,0 @@ -/************************************************************************** - * - * Copyright © 2009 VMware, Inc., Palo Alto, CA., USA - * All Rights Reserved. - * - * 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, sub license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS 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 -#include -#include -#include -#include "internal.h" - -#include -#include "xf86drm.h" -#include "libdrm_macros.h" - -#include "radeon_drm.h" - - -#define ALIGNMENT 512 - -struct radeon_bo -{ - struct kms_bo base; - unsigned map_count; -}; - -static int -radeon_get_prop(struct kms_driver *kms, unsigned key, unsigned *out) -{ - switch (key) { - case KMS_BO_TYPE: - *out = KMS_BO_TYPE_SCANOUT_X8R8G8B8 | KMS_BO_TYPE_CURSOR_64X64_A8R8G8B8; - break; - default: - return -EINVAL; - } - return 0; -} - -static int -radeon_destroy(struct kms_driver *kms) -{ - free(kms); - return 0; -} - -static int -radeon_bo_create(struct kms_driver *kms, - const unsigned width, const unsigned height, - const enum kms_bo_type type, const unsigned *attr, - struct kms_bo **out) -{ - struct drm_radeon_gem_create arg; - unsigned size, pitch; - struct radeon_bo *bo; - int i, ret; - - for (i = 0; attr[i]; i += 2) { - switch (attr[i]) { - case KMS_WIDTH: - case KMS_HEIGHT: - case KMS_BO_TYPE: - break; - default: - return -EINVAL; - } - } - - switch (type) { - case KMS_BO_TYPE_CURSOR_64X64_A8R8G8B8: - pitch = 4 * 64; - size = 4 * 64 * 64; - break; - case KMS_BO_TYPE_SCANOUT_X8R8G8B8: - pitch = width * 4; - pitch = (pitch + ALIGNMENT - 1) & ~(ALIGNMENT - 1); - size = pitch * height; - break; - default: - return -EINVAL; - } - - bo = calloc(1, sizeof(*bo)); - if (!bo) - return -ENOMEM; - - memset(&arg, 0, sizeof(arg)); - arg.size = size; - arg.alignment = ALIGNMENT; - arg.initial_domain = RADEON_GEM_DOMAIN_CPU; - arg.flags = 0; - arg.handle = 0; - - ret = drmCommandWriteRead(kms->fd, DRM_RADEON_GEM_CREATE, - &arg, sizeof(arg)); - if (ret) - goto err_free; - - bo->base.kms = kms; - bo->base.handle = arg.handle; - bo->base.size = size; - bo->base.pitch = pitch; - bo->base.offset = 0; - bo->map_count = 0; - - *out = &bo->base; - - return 0; - -err_free: - free(bo); - return ret; -} - -static int -radeon_bo_get_prop(struct kms_bo *bo, unsigned key, unsigned *out) -{ - switch (key) { - default: - return -EINVAL; - } -} - -static int -radeon_bo_map(struct kms_bo *_bo, void **out) -{ - struct radeon_bo *bo = (struct radeon_bo *)_bo; - struct drm_radeon_gem_mmap arg; - void *map = NULL; - int ret; - - if (bo->base.ptr) { - bo->map_count++; - *out = bo->base.ptr; - return 0; - } - - memset(&arg, 0, sizeof(arg)); - arg.handle = bo->base.handle; - arg.offset = bo->base.offset; - arg.size = (uint64_t)bo->base.size; - - ret = drmCommandWriteRead(bo->base.kms->fd, DRM_RADEON_GEM_MMAP, - &arg, sizeof(arg)); - if (ret) - return -errno; - - map = drm_mmap(0, arg.size, PROT_READ | PROT_WRITE, MAP_SHARED, - bo->base.kms->fd, arg.addr_ptr); - if (map == MAP_FAILED) - return -errno; - - bo->base.ptr = map; - bo->map_count++; - *out = bo->base.ptr; - - return 0; -} - -static int -radeon_bo_unmap(struct kms_bo *_bo) -{ - struct radeon_bo *bo = (struct radeon_bo *)_bo; - if (--bo->map_count == 0) { - drm_munmap(bo->base.ptr, bo->base.size); - bo->base.ptr = NULL; - } - return 0; -} - -static int -radeon_bo_destroy(struct kms_bo *_bo) -{ - struct radeon_bo *bo = (struct radeon_bo *)_bo; - struct drm_gem_close arg; - int ret; - - if (bo->base.ptr) { - /* XXX Sanity check map_count */ - drm_munmap(bo->base.ptr, bo->base.size); - bo->base.ptr = NULL; - } - - memset(&arg, 0, sizeof(arg)); - arg.handle = bo->base.handle; - - ret = drmIoctl(bo->base.kms->fd, DRM_IOCTL_GEM_CLOSE, &arg); - if (ret) - return -errno; - - free(bo); - return 0; -} - -drm_private int -radeon_create(int fd, struct kms_driver **out) -{ - struct kms_driver *kms; - - kms = calloc(1, sizeof(*kms)); - if (!kms) - return -ENOMEM; - - kms->fd = fd; - - kms->bo_create = radeon_bo_create; - kms->bo_map = radeon_bo_map; - kms->bo_unmap = radeon_bo_unmap; - kms->bo_get_prop = radeon_bo_get_prop; - kms->bo_destroy = radeon_bo_destroy; - kms->get_prop = radeon_get_prop; - kms->destroy = radeon_destroy; - *out = kms; - - return 0; -} diff -Nru libdrm-2.4.110/libkms/vmwgfx.c libdrm-2.4.113/libkms/vmwgfx.c --- libdrm-2.4.110/libkms/vmwgfx.c 2022-02-16 10:00:13.000000000 +0000 +++ libdrm-2.4.113/libkms/vmwgfx.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,207 +0,0 @@ -/************************************************************************** - * - * Copyright © 2009 VMware, Inc., Palo Alto, CA., USA - * All Rights Reserved. - * - * 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, sub license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS 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. - * - **************************************************************************/ - -#ifdef __FreeBSD__ -#define _WANT_KERNEL_ERRNO -#endif - -#include -#include -#include -#include "internal.h" - -#include "xf86drm.h" -#include "libdrm_macros.h" -#include "vmwgfx_drm.h" - -struct vmwgfx_bo -{ - struct kms_bo base; - uint64_t map_handle; - unsigned map_count; -}; - -static int -vmwgfx_get_prop(struct kms_driver *kms, unsigned key, unsigned *out) -{ - switch (key) { - case KMS_BO_TYPE: - *out = KMS_BO_TYPE_SCANOUT_X8R8G8B8 | KMS_BO_TYPE_CURSOR_64X64_A8R8G8B8; - break; - default: - return -EINVAL; - } - return 0; -} - -static int -vmwgfx_destroy(struct kms_driver *kms) -{ - free(kms); - return 0; -} - -static int -vmwgfx_bo_create(struct kms_driver *kms, - const unsigned width, const unsigned height, - const enum kms_bo_type type, const unsigned *attr, - struct kms_bo **out) -{ - struct vmwgfx_bo *bo; - int i, ret; - - for (i = 0; attr[i]; i += 2) { - switch (attr[i]) { - case KMS_WIDTH: - case KMS_HEIGHT: - case KMS_BO_TYPE: - break; - default: - return -EINVAL; - } - } - - bo = calloc(1, sizeof(*bo)); - if (!bo) - return -EINVAL; - - { - union drm_vmw_alloc_dmabuf_arg arg; - struct drm_vmw_alloc_dmabuf_req *req = &arg.req; - struct drm_vmw_dmabuf_rep *rep = &arg.rep; - - memset(&arg, 0, sizeof(arg)); - req->size = width * height * 4; - bo->base.size = req->size; - bo->base.pitch = width * 4; - bo->base.kms = kms; - - do { - ret = drmCommandWriteRead(bo->base.kms->fd, - DRM_VMW_ALLOC_DMABUF, - &arg, sizeof(arg)); - } while (ret == -ERESTART); - - if (ret) - goto err_free; - - bo->base.handle = rep->handle; - bo->map_handle = rep->map_handle; - bo->base.handle = rep->cur_gmr_id; - bo->base.offset = rep->cur_gmr_offset; - } - - *out = &bo->base; - - return 0; - -err_free: - free(bo); - return ret; -} - -static int -vmwgfx_bo_get_prop(struct kms_bo *bo, unsigned key, unsigned *out) -{ - switch (key) { - default: - return -EINVAL; - } -} - -static int -vmwgfx_bo_map(struct kms_bo *_bo, void **out) -{ - struct vmwgfx_bo *bo = (struct vmwgfx_bo *)_bo; - void *map; - - if (bo->base.ptr) { - bo->map_count++; - *out = bo->base.ptr; - return 0; - } - - map = drm_mmap(NULL, bo->base.size, PROT_READ | PROT_WRITE, MAP_SHARED, bo->base.kms->fd, bo->map_handle); - if (map == MAP_FAILED) - return -errno; - - bo->base.ptr = map; - bo->map_count++; - *out = bo->base.ptr; - - return 0; -} - -static int -vmwgfx_bo_unmap(struct kms_bo *_bo) -{ - struct vmwgfx_bo *bo = (struct vmwgfx_bo *)_bo; - bo->map_count--; - return 0; -} - -static int -vmwgfx_bo_destroy(struct kms_bo *_bo) -{ - struct vmwgfx_bo *bo = (struct vmwgfx_bo *)_bo; - struct drm_vmw_unref_dmabuf_arg arg; - - if (bo->base.ptr) { - /* XXX Sanity check map_count */ - drm_munmap(bo->base.ptr, bo->base.size); - bo->base.ptr = NULL; - } - - memset(&arg, 0, sizeof(arg)); - arg.handle = bo->base.handle; - drmCommandWrite(bo->base.kms->fd, DRM_VMW_UNREF_DMABUF, &arg, sizeof(arg)); - - free(bo); - return 0; -} - -drm_private int -vmwgfx_create(int fd, struct kms_driver **out) -{ - struct kms_driver *kms; - - kms = calloc(1, sizeof(*kms)); - if (!kms) - return -ENOMEM; - - kms->fd = fd; - - kms->bo_create = vmwgfx_bo_create; - kms->bo_map = vmwgfx_bo_map; - kms->bo_unmap = vmwgfx_bo_unmap; - kms->bo_get_prop = vmwgfx_bo_get_prop; - kms->bo_destroy = vmwgfx_bo_destroy; - kms->get_prop = vmwgfx_get_prop; - kms->destroy = vmwgfx_destroy; - *out = kms; - return 0; -} diff -Nru libdrm-2.4.110/man/drm.7.rst libdrm-2.4.113/man/drm.7.rst --- libdrm-2.4.110/man/drm.7.rst 2022-02-16 10:00:13.000000000 +0000 +++ libdrm-2.4.113/man/drm.7.rst 2022-08-31 14:38:38.000000000 +0000 @@ -73,7 +73,7 @@ used by most DRM drivers. These are the *Translation Table Manager* (TTM) and the *Graphics Execution Manager* (GEM). They provide generic APIs to create, destroy and access buffers from user-space. However, -there are still many differences between the drivers so driver-depedent +there are still many differences between the drivers so driver-dependent code is still needed. Many helpers are provided in *libgbm* (Graphics Buffer Manager) from the *Mesa* project. For more information on DRM memory management, see **drm-memory**\ (7). diff -Nru libdrm-2.4.110/man/drm-kms.7.rst libdrm-2.4.113/man/drm-kms.7.rst --- libdrm-2.4.110/man/drm-kms.7.rst 2022-02-16 10:00:13.000000000 +0000 +++ libdrm-2.4.113/man/drm-kms.7.rst 2022-08-31 14:38:38.000000000 +0000 @@ -102,13 +102,13 @@ information. All valid modes for a connector can be retrieved with a call to -drmModeGetConnector3 You need to select the mode you want to use and save it. +**drmModeGetConnector**\ (3) You need to select the mode you want to use and save it. The first mode in the list is the default mode with the highest resolution possible and often a suitable choice. After you have a working connector+CRTC+mode combination, you need to create a framebuffer that is used for scanout. Memory buffer allocation is -driver-depedent and described in **drm-memory**\ (7). You need to create a +driver-dependent and described in **drm-memory**\ (7). You need to create a buffer big enough for your selected mode. Now you can create a framebuffer object that uses your memory-buffer as scanout buffer. You can do this with **drmModeAddFB**\ (3) and **drmModeAddFB2**\ (3). diff -Nru libdrm-2.4.110/meson.build libdrm-2.4.113/meson.build --- libdrm-2.4.110/meson.build 2022-02-16 10:00:13.000000000 +0000 +++ libdrm-2.4.113/meson.build 2022-08-31 14:38:38.000000000 +0000 @@ -21,10 +21,10 @@ project( 'libdrm', ['c'], - version : '2.4.110', + version : '2.4.113', license : 'MIT', meson_version : '>= 0.53', - default_options : ['buildtype=debugoptimized', 'c_std=c99'], + default_options : ['buildtype=debugoptimized', 'c_std=c11'], ) pkg = import('pkgconfig') @@ -34,6 +34,7 @@ config.set10('UDEV', get_option('udev')) with_freedreno_kgsl = get_option('freedreno-kgsl') with_install_tests = get_option('install-test-programs') +with_tests = get_option('tests') if ['freebsd', 'dragonfly', 'netbsd'].contains(host_machine.system()) dep_pthread_stubs = dependency('pthread-stubs', version : '>= 0.4') @@ -84,55 +85,55 @@ with_intel = false _intel = get_option('intel') -if _intel != 'false' - if _intel == 'true' and not with_atomics +if not _intel.disabled() + if _intel.enabled() and not with_atomics error('libdrm_intel requires atomics.') else - with_intel = _intel == 'true' or host_machine.cpu_family().startswith('x86') + with_intel = (_intel.enabled() or host_machine.cpu_family().startswith('x86')) and with_atomics endif endif summary('Intel', with_intel) with_radeon = false _radeon = get_option('radeon') -if _radeon != 'false' - if _radeon == 'true' and not with_atomics +if not _radeon.disabled() + if _radeon.enabled() and not with_atomics error('libdrm_radeon requires atomics.') endif - with_radeon = true + with_radeon = with_atomics endif summary('Radeon', with_radeon) with_amdgpu = false _amdgpu = get_option('amdgpu') -if _amdgpu != 'false' - if _amdgpu == 'true' and not with_atomics +if not _amdgpu.disabled() + if _amdgpu.enabled() and not with_atomics error('libdrm_amdgpu requires atomics.') endif - with_amdgpu = true + with_amdgpu = with_atomics endif summary('AMDGPU', with_amdgpu) with_nouveau = false _nouveau = get_option('nouveau') -if _nouveau != 'false' - if _nouveau == 'true' and not with_atomics +if not _nouveau.disabled() + if _nouveau.enabled() and not with_atomics error('libdrm_nouveau requires atomics.') endif - with_nouveau = true + with_nouveau = with_atomics endif summary('Nouveau', with_nouveau) with_vmwgfx = false _vmwgfx = get_option('vmwgfx') -if _vmwgfx != 'false' +if not _vmwgfx.disabled() with_vmwgfx = true endif summary('vmwgfx', with_vmwgfx) with_omap = false _omap = get_option('omap') -if _omap == 'true' +if _omap.enabled() if not with_atomics error('libdrm_omap requires atomics.') endif @@ -142,11 +143,11 @@ with_freedreno = false _freedreno = get_option('freedreno') -if _freedreno != 'false' - if _freedreno == 'true' and not with_atomics +if not _freedreno.disabled() + if _freedreno.enabled() and not with_atomics error('libdrm_freedreno requires atomics.') else - with_freedreno = _freedreno == 'true' or ['arm', 'aarch64'].contains(host_machine.cpu_family()) + with_freedreno = (_freedreno.enabled() or ['arm', 'aarch64'].contains(host_machine.cpu_family())) and with_atomics endif endif summary('Freedreno', with_freedreno) @@ -154,7 +155,7 @@ with_tegra = false _tegra = get_option('tegra') -if _tegra == 'true' +if _tegra.enabled() if not with_atomics error('libdrm_tegra requires atomics.') endif @@ -164,33 +165,29 @@ with_etnaviv = false _etnaviv = get_option('etnaviv') -if _etnaviv == 'true' - if not with_atomics +if not _etnaviv.disabled() + if _etnaviv.enabled() and not with_atomics error('libdrm_etnaviv requires atomics.') endif - with_etnaviv = true + with_etnaviv = _etnaviv.enabled() or ( + with_atomics and [ + 'loongarch64', 'mips', 'mips64', + 'arm', 'aarch64', 'arc', + ].contains(host_machine.cpu_family()) + ) endif summary('Etnaviv', with_etnaviv) -with_exynos = get_option('exynos') == 'true' +with_exynos = get_option('exynos').enabled() summary('EXYNOS', with_exynos) with_vc4 = false _vc4 = get_option('vc4') -if _vc4 != 'false' - with_vc4 = _vc4 == 'true' or ['arm', 'aarch64'].contains(host_machine.cpu_family()) +if not _vc4.disabled() + with_vc4 = _vc4.enabled() or ['arm', 'aarch64'].contains(host_machine.cpu_family()) endif summary('VC4', with_vc4) -# XXX: Apparently only freebsd and dragonfly bsd actually need this (and -# gnu/kfreebsd), not openbsd and netbsd -with_libkms = false -_libkms = get_option('libkms') -if _libkms != 'false' - with_libkms = _libkms == 'true' or (['linux', 'freebsd', 'dragonfly'].contains(host_machine.system()) and not android) -endif -summary('libkms', with_libkms) - # Among others FreeBSD does not have a separate dl library. if not cc.has_function('dlsym') dep_dl = cc.find_library('dl', required : with_nouveau) @@ -245,30 +242,18 @@ dep_pciaccess = dependency('pciaccess', version : '>= 0.10', required : with_intel) dep_cunit = dependency('cunit', version : '>= 2.1', required : false) -_cairo_tests = get_option('cairo-tests') -if _cairo_tests != 'false' - dep_cairo = dependency('cairo', required : _cairo_tests == 'true') - with_cairo_tests = dep_cairo.found() -else - dep_cairo = [] - with_cairo_tests = false -endif -_valgrind = get_option('valgrind') -if _valgrind != 'false' - if with_freedreno - dep_valgrind = dependency('valgrind', required : _valgrind == 'true', version : '>=3.10.0') - else - dep_valgrind = dependency('valgrind', required : _valgrind == 'true') - endif - with_valgrind = dep_valgrind.found() -else - dep_valgrind = [] - with_valgrind = false +dep_cairo = dependency('cairo', required : get_option('cairo-tests')) +with_cairo_tests = dep_cairo.found() + +valgrind_version = [] +if with_freedreno + valgrind_version = '>=3.10.0' endif +dep_valgrind = dependency('valgrind', required : get_option('valgrind'), version : valgrind_version) +with_valgrind = dep_valgrind.found() -with_man_pages = get_option('man-pages') -prog_rst2man = find_program('rst2man', 'rst2man.py', required: with_man_pages == 'true') -with_man_pages = with_man_pages != 'false' and prog_rst2man.found() +prog_rst2man = find_program('rst2man', 'rst2man.py', required: get_option('man-pages')) +with_man_pages = prog_rst2man.found() config.set10('HAVE_VISIBILITY', cc.has_function_attribute('visibility:hidden')) @@ -366,9 +351,6 @@ description : 'Userspace interface to kernel DRM services', ) -if with_libkms - subdir('libkms') -endif if with_intel subdir('intel') endif @@ -403,4 +385,6 @@ subdir('man') endif subdir('data') -subdir('tests') +if with_tests + subdir('tests') +endif diff -Nru libdrm-2.4.110/meson_options.txt libdrm-2.4.113/meson_options.txt --- libdrm-2.4.110/meson_options.txt 2022-02-16 10:00:13.000000000 +0000 +++ libdrm-2.4.113/meson_options.txt 2022-08-31 14:38:38.000000000 +0000 @@ -19,108 +19,76 @@ # SOFTWARE. option( - 'libkms', - type : 'combo', - value : 'auto', - choices : ['true', 'false', 'auto'], - description : 'Build libkms mm abstraction library.', -) -option( 'intel', - type : 'combo', - value : 'auto', - choices : ['true', 'false', 'auto'], + type : 'feature', description : '''Enable support for Intel's KMS API.''', ) option( 'radeon', - type : 'combo', - value : 'auto', - choices : ['true', 'false', 'auto'], + type : 'feature', description : '''Enable support for radeons's KMS API.''', ) option( 'amdgpu', - type : 'combo', - value : 'auto', - choices : ['true', 'false', 'auto'], + type : 'feature', description : '''Enable support for amdgpu's KMS API.''', ) option( 'nouveau', - type : 'combo', - value : 'auto', - choices : ['true', 'false', 'auto'], + type : 'feature', description : '''Enable support for nouveau's KMS API.''', ) option( 'vmwgfx', - type : 'combo', - value : 'true', - choices : ['true', 'false', 'auto'], + type : 'feature', description : '''Enable support for vmgfx's KMS API.''', ) option( 'omap', - type : 'combo', - value : 'false', - choices : ['true', 'false', 'auto'], + type : 'feature', + value : 'disabled', description : '''Enable support for OMAP's experimental KMS API.''', ) option( 'exynos', - type : 'combo', - value : 'false', - choices : ['true', 'false', 'auto'], + type : 'feature', + value : 'disabled', description : '''Enable support for EXYNOS's experimental KMS API.''', ) option( 'freedreno', - type : 'combo', - value : 'auto', - choices : ['true', 'false', 'auto'], + type : 'feature', description : '''Enable support for freedreno's KMS API.''', ) option( 'tegra', - type : 'combo', - value : 'false', - choices : ['true', 'false', 'auto'], + type : 'feature', + value : 'disabled', description : '''Enable support for Tegra's experimental KMS API.''', ) option( 'vc4', - type : 'combo', - value : 'auto', - choices : ['true', 'false', 'auto'], + type : 'feature', description : '''Enable support for vc4's KMS API.''', ) option( 'etnaviv', - type : 'combo', - value : 'false', - choices : ['true', 'false', 'auto'], - description : '''Enable support for etnaviv's experimental KMS API.''', + type : 'feature', + description : '''Enable support for etnaviv's KMS API.''', ) option( 'cairo-tests', - type : 'combo', - value : 'auto', - choices : ['true', 'false', 'auto'], + type : 'feature', description : 'Enable support for Cairo rendering in tests.', ) option( 'man-pages', - type : 'combo', - value : 'auto', - choices : ['true', 'false', 'auto'], + type : 'feature', description : 'Enable manpage generation and installation.', ) option( 'valgrind', - type : 'combo', - value : 'auto', - choices : ['true', 'false', 'auto'], + type : 'feature', description : 'Build libdrm with valgrind support.', ) option( @@ -141,3 +109,9 @@ value : false, description : 'Enable support for using udev instead of mknod.', ) +option( + 'tests', + type : 'boolean', + value : true, + description : 'Build test programs.', +) diff -Nru libdrm-2.4.110/nouveau/nouveau.h libdrm-2.4.113/nouveau/nouveau.h --- libdrm-2.4.110/nouveau/nouveau.h 2022-02-16 10:00:13.000000000 +0000 +++ libdrm-2.4.113/nouveau/nouveau.h 2022-08-31 14:38:38.000000000 +0000 @@ -273,4 +273,8 @@ uint32_t offset; uint32_t length; }; + +bool +nouveau_check_dead_channel(struct nouveau_drm *, struct nouveau_object *chan); + #endif diff -Nru libdrm-2.4.110/nouveau/nouveau-symbols.txt libdrm-2.4.113/nouveau/nouveau-symbols.txt --- libdrm-2.4.110/nouveau/nouveau-symbols.txt 2022-02-16 10:00:13.000000000 +0000 +++ libdrm-2.4.113/nouveau/nouveau-symbols.txt 2022-08-31 14:38:38.000000000 +0000 @@ -12,6 +12,7 @@ nouveau_bufctx_new nouveau_bufctx_refn nouveau_bufctx_reset +nouveau_check_dead_channel nouveau_client_del nouveau_client_new nouveau_device_del diff -Nru libdrm-2.4.110/nouveau/pushbuf.c libdrm-2.4.113/nouveau/pushbuf.c --- libdrm-2.4.110/nouveau/pushbuf.c 2022-02-16 10:00:13.000000000 +0000 +++ libdrm-2.4.113/nouveau/pushbuf.c 2022-08-31 14:38:38.000000000 +0000 @@ -782,3 +782,19 @@ pushbuf_flush(push); return pushbuf_validate(push, false); } + +drm_public bool +nouveau_check_dead_channel(struct nouveau_drm *drm, struct nouveau_object *chan) +{ + struct drm_nouveau_gem_pushbuf req = {}; + struct nouveau_fifo *fifo = chan->data; + int ret; + + req.channel = fifo->channel; + req.nr_push = 0; + + ret = drmCommandWriteRead(drm->fd, DRM_NOUVEAU_GEM_PUSHBUF, + &req, sizeof(req)); + /* nouveau returns ENODEV once the channel was killed */ + return ret == -ENODEV; +} diff -Nru libdrm-2.4.110/tegra/channel.c libdrm-2.4.113/tegra/channel.c --- libdrm-2.4.110/tegra/channel.c 1970-01-01 00:00:00.000000000 +0000 +++ libdrm-2.4.113/tegra/channel.c 2022-08-31 14:38:38.000000000 +0000 @@ -0,0 +1,195 @@ +/* + * Copyright © 2012, 2013 Thierry Reding + * Copyright © 2013 Erik Faye-Lund + * Copyright © 2014-2021 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. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#include + +#include "private.h" + +drm_public int +drm_tegra_channel_open(struct drm_tegra *drm, + enum drm_tegra_class client, + struct drm_tegra_channel **channelp) +{ + struct drm_tegra_channel_open args; + struct drm_tegra_channel *channel; + enum host1x_class class; + int err; + + switch (client) { + case DRM_TEGRA_HOST1X: + class = HOST1X_CLASS_HOST1X; + break; + + case DRM_TEGRA_GR2D: + class = HOST1X_CLASS_GR2D; + break; + + case DRM_TEGRA_GR3D: + class = HOST1X_CLASS_GR3D; + break; + + case DRM_TEGRA_VIC: + class = HOST1X_CLASS_VIC; + break; + + default: + return -EINVAL; + } + + channel = calloc(1, sizeof(*channel)); + if (!channel) + return -ENOMEM; + + channel->drm = drm; + + memset(&args, 0, sizeof(args)); + args.host1x_class = class; + + err = ioctl(drm->fd, DRM_IOCTL_TEGRA_CHANNEL_OPEN, &args); + if (err < 0) { + free(channel); + return -errno; + } + + channel->context = args.context; + channel->version = args.version; + channel->capabilities = args.capabilities; + channel->class = class; + + switch (channel->version) { + case 0x20: + case 0x30: + case 0x35: + case 0x40: + case 0x21: + channel->cond_shift = 8; + break; + + case 0x18: + case 0x19: + channel->cond_shift = 10; + break; + + default: + return -ENOTSUP; + } + + *channelp = channel; + + return 0; +} + +drm_public int drm_tegra_channel_close(struct drm_tegra_channel *channel) +{ + struct drm_tegra_channel_close args; + struct drm_tegra *drm; + int err; + + if (!channel) + return -EINVAL; + + drm = channel->drm; + + memset(&args, 0, sizeof(args)); + args.context = channel->context; + + err = ioctl(drm->fd, DRM_IOCTL_TEGRA_CHANNEL_CLOSE, &args); + if (err < 0) + return -errno; + + free(channel); + + return 0; +} + +drm_public unsigned int +drm_tegra_channel_get_version(struct drm_tegra_channel *channel) +{ + return channel->version; +} + +drm_public int +drm_tegra_channel_map(struct drm_tegra_channel *channel, + struct drm_tegra_bo *bo, uint32_t flags, + struct drm_tegra_mapping **mapp) +{ + struct drm_tegra *drm = channel->drm; + struct drm_tegra_channel_map args; + struct drm_tegra_mapping *map; + int err; + + if (!drm || !bo || !mapp) + return -EINVAL; + + map = calloc(1, sizeof(*map)); + if (!map) + return -ENOMEM; + + memset(&args, 0, sizeof(args)); + args.context = channel->context; + args.handle = bo->handle; + args.flags = flags; + + err = ioctl(drm->fd, DRM_IOCTL_TEGRA_CHANNEL_MAP, &args); + if (err < 0) { + free(map); + return -errno; + } + + map->channel = channel; + map->id = args.mapping; + *mapp = map; + + return 0; +} + +drm_public int +drm_tegra_channel_unmap(struct drm_tegra_mapping *map) +{ + struct drm_tegra_channel *channel = map->channel; + struct drm_tegra *drm = channel->drm; + struct drm_tegra_channel_unmap args; + int err; + + if (!channel || !map) + return -EINVAL; + + memset(&args, 0, sizeof(args)); + args.context = channel->context; + args.mapping = map->id; + + err = ioctl(drm->fd, DRM_IOCTL_TEGRA_CHANNEL_UNMAP, &args); + if (err < 0) + return -errno; + + free(map); + return 0; +} diff -Nru libdrm-2.4.110/tegra/job.c libdrm-2.4.113/tegra/job.c --- libdrm-2.4.110/tegra/job.c 1970-01-01 00:00:00.000000000 +0000 +++ libdrm-2.4.113/tegra/job.c 2022-08-31 14:38:38.000000000 +0000 @@ -0,0 +1,187 @@ +/* + * Copyright © 2012, 2013 Thierry Reding + * Copyright © 2013 Erik Faye-Lund + * Copyright © 2014 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. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include +#include +#include + +#include +#include + +#include "private.h" + +struct drm_tegra_submit_cmd * +drm_tegra_job_add_command(struct drm_tegra_job *job, uint32_t type, + uint32_t flags) +{ + struct drm_tegra_submit_cmd *commands, *command; + size_t size; + + size = (job->num_commands + 1) * sizeof(*commands); + + commands = realloc(job->commands, size); + if (!commands) + return NULL; + + command = &commands[job->num_commands]; + memset(command, 0, sizeof(*command)); + command->type = type; + command->flags = flags; + + job->commands = commands; + job->num_commands++; + + return command; +} + +drm_public int +drm_tegra_job_new(struct drm_tegra_channel *channel, + struct drm_tegra_job **jobp) +{ + struct drm_tegra_job *job; + + job = calloc(1, sizeof(*job)); + if (!job) + return -ENOMEM; + + job->page_size = sysconf(_SC_PAGESIZE); + job->channel = channel; + + *jobp = job; + + return 0; +} + +drm_public int drm_tegra_job_free(struct drm_tegra_job *job) +{ + if (!job) + return -EINVAL; + + if (job->pushbuf) + drm_tegra_pushbuf_free(job->pushbuf); + + if (job->commands) + free(job->commands); + + if (job->buffers) + free(job->buffers); + + free(job); + + return 0; +} + +drm_public int +drm_tegra_job_get_pushbuf(struct drm_tegra_job *job, + struct drm_tegra_pushbuf **pushbufp) +{ + struct drm_tegra_pushbuf *pushbuf; + + if (!job->pushbuf) { + pushbuf = calloc(1, sizeof(*pushbuf)); + if (!pushbuf) + return -ENOMEM; + + pushbuf->job = job; + + pushbuf->start = calloc(1, job->page_size); + if (!pushbuf->start) { + free(pushbuf); + return -ENOMEM; + } + + pushbuf->end = pushbuf->start + job->page_size / 4; + pushbuf->ptr = pushbuf->start; + + job->pushbuf = pushbuf; + } + + *pushbufp = job->pushbuf; + + return 0; +} + +drm_public int +drm_tegra_job_submit(struct drm_tegra_job *job, struct drm_tegra_fence *fence) +{ + struct drm_tegra_channel *channel = job->channel; + struct drm_tegra *drm = channel->drm; + struct drm_tegra_channel_submit args; + int err; + + memset(&args, 0, sizeof(args)); + args.context = channel->context; + args.num_bufs = job->num_buffers; + args.num_cmds = job->num_commands; + args.gather_data_words = job->pushbuf->ptr - job->pushbuf->start; + args.syncpt.id = job->syncpt.id; + args.syncpt.increments = job->syncpt.increments; + + args.bufs_ptr = (uintptr_t)job->buffers; + args.cmds_ptr = (uintptr_t)job->commands; + args.gather_data_ptr = (uintptr_t)job->pushbuf->start; + + err = ioctl(drm->fd, DRM_IOCTL_TEGRA_CHANNEL_SUBMIT, &args); + if (err < 0) + return -errno; + + job->syncpt.fence = args.syncpt.value; + + if (fence) { + fence->drm = drm; + fence->syncpt = job->syncpt.id; + fence->value = job->syncpt.fence; + } + + return 0; +} + +drm_public int +drm_tegra_job_wait(struct drm_tegra_job *job, unsigned long timeout) +{ + struct drm_tegra_channel *channel = job->channel; + struct drm_tegra *drm = channel->drm; + struct drm_tegra_syncpoint_wait args; + struct timespec ts; + int err; + + clock_gettime(CLOCK_MONOTONIC, &ts); + + memset(&args, 0, sizeof(args)); + args.timeout_ns = ts.tv_sec * 1000000000 + ts.tv_nsec + timeout; + args.id = job->syncpt.id; + args.threshold = job->syncpt.fence; + + err = ioctl(drm->fd, DRM_IOCTL_TEGRA_SYNCPOINT_WAIT, &args); + if (err < 0) + return -errno; + + return 0; +} diff -Nru libdrm-2.4.110/tegra/meson.build libdrm-2.4.113/tegra/meson.build --- libdrm-2.4.110/tegra/meson.build 2022-02-16 10:00:13.000000000 +0000 +++ libdrm-2.4.113/tegra/meson.build 2022-08-31 14:38:38.000000000 +0000 @@ -20,7 +20,12 @@ libdrm_tegra = library( 'drm_tegra', - [files('tegra.c'), config_file], + [ + files( + 'channel.c', 'job.c', 'private.h', 'pushbuf.c', 'syncpt.c', 'tegra.c' + ), + config_file + ], include_directories : [inc_root, inc_drm], link_with : libdrm, dependencies : [dep_pthread_stubs, dep_atomic_ops], diff -Nru libdrm-2.4.110/tegra/private.h libdrm-2.4.113/tegra/private.h --- libdrm-2.4.110/tegra/private.h 2022-02-16 10:00:13.000000000 +0000 +++ libdrm-2.4.113/tegra/private.h 2022-08-31 14:38:38.000000000 +0000 @@ -26,26 +26,93 @@ #define __DRM_TEGRA_PRIVATE_H__ 1 #include +#include #include #include #include +#include "tegra_drm.h" #include "tegra.h" +#define container_of(ptr, type, member) ({ \ + const __typeof__(((type *)0)->member) *__mptr = (ptr); \ + (type *)((char *)__mptr - offsetof(type, member)); \ + }) + +enum host1x_class { + HOST1X_CLASS_HOST1X = 0x01, + HOST1X_CLASS_GR2D = 0x51, + HOST1X_CLASS_GR2D_SB = 0x52, + HOST1X_CLASS_VIC = 0x5d, + HOST1X_CLASS_GR3D = 0x60, +}; + struct drm_tegra { - bool close; - int fd; + bool close; + int fd; }; struct drm_tegra_bo { - struct drm_tegra *drm; - uint32_t handle; - uint32_t offset; - uint32_t flags; - uint32_t size; - atomic_t ref; - void *map; + struct drm_tegra *drm; + uint32_t handle; + uint64_t offset; + uint32_t flags; + uint32_t size; + atomic_t ref; + void *map; +}; + +struct drm_tegra_channel { + struct drm_tegra *drm; + enum host1x_class class; + uint32_t capabilities; + unsigned int version; + uint64_t context; + + unsigned int cond_shift; +}; + +struct drm_tegra_mapping { + struct drm_tegra_channel *channel; + uint32_t id; +}; + +struct drm_tegra_pushbuf { + struct drm_tegra_job *job; + + uint32_t *start; + uint32_t *end; + uint32_t *ptr; +}; + +void drm_tegra_pushbuf_free(struct drm_tegra_pushbuf *pushbuf); + +struct drm_tegra_job { + struct drm_tegra_channel *channel; + struct drm_tegra_pushbuf *pushbuf; + size_t page_size; + + struct drm_tegra_submit_cmd *commands; + unsigned int num_commands; + + struct drm_tegra_submit_buf *buffers; + unsigned int num_buffers; + + struct { + uint32_t id; + uint32_t increments; + uint32_t fence; + } syncpt; +}; + +struct drm_tegra_submit_cmd * +drm_tegra_job_add_command(struct drm_tegra_job *job, uint32_t type, + uint32_t flags); + +struct drm_tegra_syncpoint { + struct drm_tegra *drm; + uint32_t id; }; #endif /* __DRM_TEGRA_PRIVATE_H__ */ diff -Nru libdrm-2.4.110/tegra/pushbuf.c libdrm-2.4.113/tegra/pushbuf.c --- libdrm-2.4.110/tegra/pushbuf.c 1970-01-01 00:00:00.000000000 +0000 +++ libdrm-2.4.113/tegra/pushbuf.c 2022-08-31 14:38:38.000000000 +0000 @@ -0,0 +1,184 @@ +/* + * Copyright © 2012, 2013 Thierry Reding + * Copyright © 2013 Erik Faye-Lund + * Copyright © 2014 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. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include + +#include "util_math.h" +#include "private.h" + +#define HOST1X_OPCODE_NONINCR(offset, count) \ + ((0x2 << 28) | (((offset) & 0xfff) << 16) | ((count) & 0xffff)) + +static inline unsigned int +drm_tegra_pushbuf_get_offset(struct drm_tegra_pushbuf *pushbuf, uint32_t *ptr) +{ + return ptr - pushbuf->start; +} + +void drm_tegra_pushbuf_free(struct drm_tegra_pushbuf *pushbuf) +{ + if (pushbuf->start) + free(pushbuf->start); + + free(pushbuf); +} + +/** + * drm_tegra_pushbuf_begin() - prepare push buffer for a series of pushes + * @pushbuf: push buffer + * @words: maximum number of words in series of pushes to follow + */ +drm_public int +drm_tegra_pushbuf_begin(struct drm_tegra_pushbuf *pushbuf, + unsigned int words, uint32_t **ptrp) +{ + struct drm_tegra_job *job = pushbuf->job; + unsigned long offset; + size_t size; + void *ptr; + + if (pushbuf->ptr + words >= pushbuf->end) { + words = pushbuf->end - pushbuf->start + words; + size = ALIGN(words * 4, job->page_size); + offset = pushbuf->ptr - pushbuf->start; + + ptr = realloc(pushbuf->start, size); + if (!ptr) + return -ENOMEM; + + pushbuf->start = ptr; + pushbuf->end = pushbuf->start + size / 4; + pushbuf->ptr = pushbuf->start + offset; + } + + if (ptrp) + *ptrp = pushbuf->ptr; + + return 0; +} + +drm_public int +drm_tegra_pushbuf_end(struct drm_tegra_pushbuf *pushbuf, uint32_t *ptr) +{ + struct drm_tegra_submit_cmd *command; + + command = drm_tegra_job_add_command(pushbuf->job, + DRM_TEGRA_SUBMIT_CMD_GATHER_UPTR, + 0); + if (!command) + return -ENOMEM; + + command->gather_uptr.words = ptr - pushbuf->start; + pushbuf->ptr = ptr; + + return 0; +} + +drm_public int +drm_tegra_pushbuf_wait(struct drm_tegra_pushbuf *pushbuf, + struct drm_tegra_syncpoint *syncpt, + uint32_t value) +{ + struct drm_tegra_submit_cmd *command; + + command = drm_tegra_job_add_command(pushbuf->job, + DRM_TEGRA_SUBMIT_CMD_WAIT_SYNCPT, + 0); + if (!command) + return -ENOMEM; + + command->wait_syncpt.id = syncpt->id; + command->wait_syncpt.value = value; + + return 0; +} + +drm_public int +drm_tegra_pushbuf_relocate(struct drm_tegra_pushbuf *pushbuf, uint32_t **ptrp, + struct drm_tegra_mapping *target, + unsigned long offset, unsigned int shift, + uint32_t flags) +{ + struct drm_tegra_submit_buf *buffers, *buffer; + struct drm_tegra_job *job = pushbuf->job; + size_t size; + + size = (job->num_buffers + 1) * sizeof(*buffer); + + buffers = realloc(job->buffers, size); + if (!buffers) + return -ENOMEM; + + buffer = &buffers[job->num_buffers]; + + memset(buffer, 0, sizeof(*buffer)); + buffer->mapping = target->id; + buffer->flags = flags; + buffer->reloc.target_offset = offset; + buffer->reloc.gather_offset_words = drm_tegra_pushbuf_get_offset(pushbuf, + *ptrp); + buffer->reloc.shift = shift; + + *(*ptrp)++ = 0xdeadbeef; + + job->buffers = buffers; + job->num_buffers++; + + return 0; +} + +drm_public int +drm_tegra_pushbuf_sync(struct drm_tegra_pushbuf *pushbuf, + struct drm_tegra_syncpoint *syncpt, + unsigned int count) +{ + struct drm_tegra_job *job = pushbuf->job; + + job->syncpt.increments += count; + job->syncpt.id = syncpt->id; + + return 0; +} + +drm_public int +drm_tegra_pushbuf_sync_cond(struct drm_tegra_pushbuf *pushbuf, uint32_t **ptrp, + struct drm_tegra_syncpoint *syncpt, + enum drm_tegra_sync_cond cond) +{ + struct drm_tegra_channel *channel = pushbuf->job->channel; + + if (cond >= DRM_TEGRA_SYNC_COND_MAX) + return -EINVAL; + + *(*ptrp)++ = HOST1X_OPCODE_NONINCR(0x0, 0x1); + *(*ptrp)++ = cond << channel->cond_shift | syncpt->id; + + return drm_tegra_pushbuf_sync(pushbuf, syncpt, 1); +} diff -Nru libdrm-2.4.110/tegra/syncpt.c libdrm-2.4.113/tegra/syncpt.c --- libdrm-2.4.110/tegra/syncpt.c 1970-01-01 00:00:00.000000000 +0000 +++ libdrm-2.4.113/tegra/syncpt.c 2022-08-31 14:38:38.000000000 +0000 @@ -0,0 +1,101 @@ +/* + * Copyright © 2021 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. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#include + +#include "private.h" + +drm_public int +drm_tegra_syncpoint_new(struct drm_tegra *drm, + struct drm_tegra_syncpoint **syncptp) +{ + struct drm_tegra_syncpoint_allocate args; + struct drm_tegra_syncpoint *syncpt; + int err; + + syncpt = calloc(1, sizeof(*syncpt)); + if (!syncpt) + return -ENOMEM; + + memset(&args, 0, sizeof(args)); + + err = ioctl(drm->fd, DRM_IOCTL_TEGRA_SYNCPOINT_ALLOCATE, &args); + if (err < 0) { + free(syncpt); + return -errno; + } + + syncpt->drm = drm; + syncpt->id = args.id; + + *syncptp = syncpt; + + return 0; +} + +drm_public int +drm_tegra_syncpoint_free(struct drm_tegra_syncpoint *syncpt) +{ + struct drm_tegra_syncpoint_free args; + struct drm_tegra *drm = syncpt->drm; + int err; + + if (!syncpt) + return -EINVAL; + + memset(&args, 0, sizeof(args)); + args.id = syncpt->id; + + err = ioctl(drm->fd, DRM_IOCTL_TEGRA_SYNCPOINT_FREE, &args); + if (err < 0) + return -errno; + + free(syncpt); + + return 0; +} + +drm_public int +drm_tegra_fence_wait(struct drm_tegra_fence *fence, unsigned long timeout) +{ + struct drm_tegra_syncpoint_wait args; + struct drm_tegra *drm = fence->drm; + int err; + + memset(&args, 0, sizeof(args)); + args.timeout_ns = 0; + args.id = fence->syncpt; + args.threshold = fence->value; + + err = ioctl(drm->fd, DRM_IOCTL_TEGRA_SYNCPOINT_WAIT, &args); + if (err < 0) + return -errno; + + return 0; +} diff -Nru libdrm-2.4.110/tegra/tegra.c libdrm-2.4.113/tegra/tegra.c --- libdrm-2.4.110/tegra/tegra.c 2022-02-16 10:00:13.000000000 +0000 +++ libdrm-2.4.113/tegra/tegra.c 2022-08-31 14:38:38.000000000 +0000 @@ -37,288 +37,318 @@ static void drm_tegra_bo_free(struct drm_tegra_bo *bo) { - struct drm_tegra *drm = bo->drm; + struct drm_tegra *drm = bo->drm; - if (bo->map) - munmap(bo->map, bo->size); + if (bo->map) + munmap(bo->map, bo->size); - drmCloseBufferHandle(drm->fd, bo->handle); + drmCloseBufferHandle(drm->fd, bo->handle); - free(bo); + free(bo); } static int drm_tegra_wrap(struct drm_tegra **drmp, int fd, bool close) { - struct drm_tegra *drm; + struct drm_tegra *drm; - if (fd < 0 || !drmp) - return -EINVAL; + if (fd < 0 || !drmp) + return -EINVAL; - drm = calloc(1, sizeof(*drm)); - if (!drm) - return -ENOMEM; + drm = calloc(1, sizeof(*drm)); + if (!drm) + return -ENOMEM; - drm->close = close; - drm->fd = fd; + drm->close = close; + drm->fd = fd; - *drmp = drm; + *drmp = drm; - return 0; + return 0; } -drm_public int drm_tegra_new(struct drm_tegra **drmp, int fd) +drm_public int drm_tegra_new(int fd, struct drm_tegra **drmp) { - bool supported = false; - drmVersionPtr version; + bool supported = false; + drmVersionPtr version; - version = drmGetVersion(fd); - if (!version) - return -ENOMEM; + version = drmGetVersion(fd); + if (!version) + return -ENOMEM; - if (!strncmp(version->name, "tegra", version->name_len)) - supported = true; + if (!strncmp(version->name, "tegra", version->name_len)) + supported = true; - drmFreeVersion(version); + drmFreeVersion(version); - if (!supported) - return -ENOTSUP; + if (!supported) + return -ENOTSUP; - return drm_tegra_wrap(drmp, fd, false); + return drm_tegra_wrap(drmp, fd, false); } drm_public void drm_tegra_close(struct drm_tegra *drm) { - if (!drm) - return; + if (!drm) + return; - if (drm->close) - close(drm->fd); + if (drm->close) + close(drm->fd); - free(drm); + free(drm); } -drm_public int drm_tegra_bo_new(struct drm_tegra_bo **bop, struct drm_tegra *drm, - uint32_t flags, uint32_t size) +static struct drm_tegra_bo *drm_tegra_bo_alloc(struct drm_tegra *drm, + uint32_t handle, + uint32_t flags, + uint32_t size) { - struct drm_tegra_gem_create args; - struct drm_tegra_bo *bo; - int err; + struct drm_tegra_bo *bo; - if (!drm || size == 0 || !bop) - return -EINVAL; + bo = calloc(1, sizeof(*bo)); + if (!bo) + return NULL; - bo = calloc(1, sizeof(*bo)); - if (!bo) - return -ENOMEM; + atomic_set(&bo->ref, 1); + bo->handle = handle; + bo->flags = flags; + bo->size = size; + bo->drm = drm; - atomic_set(&bo->ref, 1); - bo->flags = flags; - bo->size = size; - bo->drm = drm; + return bo; +} + +drm_public int +drm_tegra_bo_new(struct drm_tegra *drm, uint32_t flags, uint32_t size, + struct drm_tegra_bo **bop) +{ + struct drm_tegra_gem_create args; + struct drm_tegra_bo *bo; + int err; + + if (!drm || size == 0 || !bop) + return -EINVAL; + + bo = drm_tegra_bo_alloc(drm, 0, flags, size); + if (!bo) + return -ENOMEM; - memset(&args, 0, sizeof(args)); - args.flags = flags; - args.size = size; + memset(&args, 0, sizeof(args)); + args.flags = flags; + args.size = size; - err = drmCommandWriteRead(drm->fd, DRM_TEGRA_GEM_CREATE, &args, - sizeof(args)); - if (err < 0) { - err = -errno; - free(bo); - return err; - } + err = drmCommandWriteRead(drm->fd, DRM_TEGRA_GEM_CREATE, &args, + sizeof(args)); + if (err < 0) { + err = -errno; + free(bo); + return err; + } - bo->handle = args.handle; + bo->handle = args.handle; - *bop = bo; + *bop = bo; - return 0; + return 0; } -drm_public int drm_tegra_bo_wrap(struct drm_tegra_bo **bop, struct drm_tegra *drm, - uint32_t handle, uint32_t flags, uint32_t size) +drm_public int +drm_tegra_bo_wrap(struct drm_tegra *drm, uint32_t handle, uint32_t flags, + uint32_t size, struct drm_tegra_bo **bop) { - struct drm_tegra_bo *bo; + struct drm_tegra_bo *bo; - if (!drm || !bop) - return -EINVAL; + if (!drm || !bop) + return -EINVAL; - bo = calloc(1, sizeof(*bo)); - if (!bo) - return -ENOMEM; + bo = drm_tegra_bo_alloc(drm, handle, flags, size); + if (!bo) + return -ENOMEM; - atomic_set(&bo->ref, 1); - bo->handle = handle; - bo->flags = flags; - bo->size = size; - bo->drm = drm; + *bop = bo; - *bop = bo; - - return 0; + return 0; } drm_public struct drm_tegra_bo *drm_tegra_bo_ref(struct drm_tegra_bo *bo) { - if (bo) - atomic_inc(&bo->ref); + if (bo) + atomic_inc(&bo->ref); - return bo; + return bo; } drm_public void drm_tegra_bo_unref(struct drm_tegra_bo *bo) { - if (bo && atomic_dec_and_test(&bo->ref)) - drm_tegra_bo_free(bo); + if (bo && atomic_dec_and_test(&bo->ref)) + drm_tegra_bo_free(bo); } -drm_public int drm_tegra_bo_get_handle(struct drm_tegra_bo *bo, uint32_t *handle) +drm_public int +drm_tegra_bo_get_handle(struct drm_tegra_bo *bo, uint32_t *handle) { - if (!bo || !handle) - return -EINVAL; + if (!bo || !handle) + return -EINVAL; - *handle = bo->handle; + *handle = bo->handle; - return 0; + return 0; } drm_public int drm_tegra_bo_map(struct drm_tegra_bo *bo, void **ptr) { - struct drm_tegra *drm = bo->drm; + struct drm_tegra *drm = bo->drm; - if (!bo->map) { - struct drm_tegra_gem_mmap args; - int err; - - memset(&args, 0, sizeof(args)); - args.handle = bo->handle; - - err = drmCommandWriteRead(drm->fd, DRM_TEGRA_GEM_MMAP, &args, - sizeof(args)); - if (err < 0) - return -errno; - - bo->offset = args.offset; - - bo->map = mmap(0, bo->size, PROT_READ | PROT_WRITE, MAP_SHARED, - drm->fd, bo->offset); - if (bo->map == MAP_FAILED) { - bo->map = NULL; - return -errno; - } - } + if (!bo->map) { + struct drm_tegra_gem_mmap args; + int err; + + memset(&args, 0, sizeof(args)); + args.handle = bo->handle; + + err = drmCommandWriteRead(drm->fd, DRM_TEGRA_GEM_MMAP, &args, + sizeof(args)); + if (err < 0) + return -errno; + + bo->offset = args.offset; + + bo->map = drm_mmap(NULL, bo->size, PROT_READ | PROT_WRITE, MAP_SHARED, + drm->fd, bo->offset); + if (bo->map == MAP_FAILED) { + bo->map = NULL; + return -errno; + } + } - if (ptr) - *ptr = bo->map; + if (ptr) + *ptr = bo->map; - return 0; + return 0; } drm_public int drm_tegra_bo_unmap(struct drm_tegra_bo *bo) { - if (!bo) - return -EINVAL; + if (!bo) + return -EINVAL; - if (!bo->map) - return 0; + if (!bo->map) + return 0; - if (munmap(bo->map, bo->size)) - return -errno; + if (munmap(bo->map, bo->size)) + return -errno; - bo->map = NULL; + bo->map = NULL; - return 0; + return 0; } -drm_public int drm_tegra_bo_get_flags(struct drm_tegra_bo *bo, uint32_t *flags) +drm_public int drm_tegra_bo_get_name(struct drm_tegra_bo *bo, uint32_t *name) { - struct drm_tegra_gem_get_flags args; - struct drm_tegra *drm = bo->drm; - int err; - - if (!bo) - return -EINVAL; + struct drm_tegra *drm = bo->drm; + struct drm_gem_flink args; + int err; - memset(&args, 0, sizeof(args)); - args.handle = bo->handle; + memset(&args, 0, sizeof(args)); + args.handle = bo->handle; - err = drmCommandWriteRead(drm->fd, DRM_TEGRA_GEM_GET_FLAGS, &args, - sizeof(args)); - if (err < 0) - return -errno; + err = drmIoctl(drm->fd, DRM_IOCTL_GEM_FLINK, &args); + if (err < 0) + return err; - if (flags) - *flags = args.flags; + if (name) + *name = args.name; - return 0; + return 0; } -drm_public int drm_tegra_bo_set_flags(struct drm_tegra_bo *bo, uint32_t flags) +drm_public int +drm_tegra_bo_open(struct drm_tegra *drm, uint32_t name, uint32_t flags, + struct drm_tegra_bo **bop) { - struct drm_tegra_gem_get_flags args; - struct drm_tegra *drm = bo->drm; - int err; + struct drm_gem_open args; + struct drm_tegra_bo *bo; + int err; + + bo = drm_tegra_bo_alloc(drm, 0, flags, 0); + if (!bo) + return -ENOMEM; + + memset(&args, 0, sizeof(args)); + args.name = name; - if (!bo) - return -EINVAL; + err = drmIoctl(drm->fd, DRM_IOCTL_GEM_OPEN, &args); + if (err < 0) + goto free; - memset(&args, 0, sizeof(args)); - args.handle = bo->handle; - args.flags = flags; + bo->handle = args.handle; + bo->size = args.size; - err = drmCommandWriteRead(drm->fd, DRM_TEGRA_GEM_SET_FLAGS, &args, - sizeof(args)); - if (err < 0) - return -errno; + *bop = bo; - return 0; + return 0; + +free: + free(bo); + return err; } -drm_public int drm_tegra_bo_get_tiling(struct drm_tegra_bo *bo, - struct drm_tegra_bo_tiling *tiling) +drm_public int drm_tegra_bo_export(struct drm_tegra_bo *bo, uint32_t flags) { - struct drm_tegra_gem_get_tiling args; - struct drm_tegra *drm = bo->drm; - int err; + int fd, err; + + flags |= DRM_CLOEXEC; + + err = drmPrimeHandleToFD(bo->drm->fd, bo->handle, flags, &fd); + if (err < 0) + return err; + + return fd; +} - if (!bo) - return -EINVAL; +static ssize_t fd_get_size(int fd) +{ + ssize_t size, offset; + int err; - memset(&args, 0, sizeof(args)); - args.handle = bo->handle; + offset = lseek(fd, 0, SEEK_CUR); + if (offset < 0) + return -errno; - err = drmCommandWriteRead(drm->fd, DRM_TEGRA_GEM_GET_TILING, &args, - sizeof(args)); - if (err < 0) - return -errno; + size = lseek(fd, 0, SEEK_END); + if (size < 0) + return -errno; - if (tiling) { - tiling->mode = args.mode; - tiling->value = args.value; - } + err = lseek(fd, offset, SEEK_SET); + if (err < 0) + return -errno; - return 0; + return size; } -drm_public int drm_tegra_bo_set_tiling(struct drm_tegra_bo *bo, - const struct drm_tegra_bo_tiling *tiling) +drm_public int +drm_tegra_bo_import(struct drm_tegra *drm, int fd, struct drm_tegra_bo **bop) { - struct drm_tegra_gem_set_tiling args; - struct drm_tegra *drm = bo->drm; - int err; + struct drm_tegra_bo *bo; + ssize_t size; + int err; + + size = fd_get_size(fd); + if (size < 0) + return size; + + bo = drm_tegra_bo_alloc(drm, 0, 0, size); + if (!bo) + return -ENOMEM; - if (!bo) - return -EINVAL; + err = drmPrimeFDToHandle(drm->fd, fd, &bo->handle); + if (err < 0) + goto free; - memset(&args, 0, sizeof(args)); - args.handle = bo->handle; - args.mode = tiling->mode; - args.value = tiling->value; + *bop = bo; - err = drmCommandWriteRead(drm->fd, DRM_TEGRA_GEM_SET_TILING, &args, - sizeof(args)); - if (err < 0) - return -errno; + return 0; - return 0; +free: + free(bo); + return err; } diff -Nru libdrm-2.4.110/tegra/tegra.h libdrm-2.4.113/tegra/tegra.h --- libdrm-2.4.110/tegra/tegra.h 2022-02-16 10:00:13.000000000 +0000 +++ libdrm-2.4.113/tegra/tegra.h 2022-08-31 14:38:38.000000000 +0000 @@ -28,33 +28,100 @@ #include #include +#include + +enum drm_tegra_class { + DRM_TEGRA_HOST1X, + DRM_TEGRA_GR2D, + DRM_TEGRA_GR3D, + DRM_TEGRA_VIC, +}; + struct drm_tegra_bo; struct drm_tegra; -int drm_tegra_new(struct drm_tegra **drmp, int fd); +int drm_tegra_new(int fd, struct drm_tegra **drmp); void drm_tegra_close(struct drm_tegra *drm); -int drm_tegra_bo_new(struct drm_tegra_bo **bop, struct drm_tegra *drm, - uint32_t flags, uint32_t size); -int drm_tegra_bo_wrap(struct drm_tegra_bo **bop, struct drm_tegra *drm, - uint32_t handle, uint32_t flags, uint32_t size); +int drm_tegra_bo_new(struct drm_tegra *drm, uint32_t flags, uint32_t size, + struct drm_tegra_bo **bop); +int drm_tegra_bo_wrap(struct drm_tegra *drm, uint32_t handle, uint32_t flags, + uint32_t size, struct drm_tegra_bo **bop); struct drm_tegra_bo *drm_tegra_bo_ref(struct drm_tegra_bo *bo); void drm_tegra_bo_unref(struct drm_tegra_bo *bo); int drm_tegra_bo_get_handle(struct drm_tegra_bo *bo, uint32_t *handle); int drm_tegra_bo_map(struct drm_tegra_bo *bo, void **ptr); int drm_tegra_bo_unmap(struct drm_tegra_bo *bo); -int drm_tegra_bo_get_flags(struct drm_tegra_bo *bo, uint32_t *flags); -int drm_tegra_bo_set_flags(struct drm_tegra_bo *bo, uint32_t flags); - -struct drm_tegra_bo_tiling { - uint32_t mode; - uint32_t value; +int drm_tegra_bo_get_name(struct drm_tegra_bo *bo, uint32_t *name); +int drm_tegra_bo_open(struct drm_tegra *drm, uint32_t name, uint32_t flags, + struct drm_tegra_bo **bop); + +int drm_tegra_bo_export(struct drm_tegra_bo *bo, uint32_t flags); +int drm_tegra_bo_import(struct drm_tegra *drm, int fd, + struct drm_tegra_bo **bop); + +struct drm_tegra_channel; +struct drm_tegra_mapping; +struct drm_tegra_pushbuf; +struct drm_tegra_job; +struct drm_tegra_syncpoint; + +enum drm_tegra_sync_cond { + DRM_TEGRA_SYNC_COND_IMMEDIATE, + DRM_TEGRA_SYNC_COND_OP_DONE, + DRM_TEGRA_SYNC_COND_RD_DONE, + DRM_TEGRA_SYNC_COND_WR_SAFE, + DRM_TEGRA_SYNC_COND_MAX, + }; + +struct drm_tegra_fence { + struct drm_tegra *drm; + uint32_t syncpt; + uint32_t value; }; -int drm_tegra_bo_get_tiling(struct drm_tegra_bo *bo, - struct drm_tegra_bo_tiling *tiling); -int drm_tegra_bo_set_tiling(struct drm_tegra_bo *bo, - const struct drm_tegra_bo_tiling *tiling); +int drm_tegra_channel_open(struct drm_tegra *drm, + enum drm_tegra_class client, + struct drm_tegra_channel **channelp); +int drm_tegra_channel_close(struct drm_tegra_channel *channel); +unsigned int drm_tegra_channel_get_version(struct drm_tegra_channel *channel); +int drm_tegra_channel_map(struct drm_tegra_channel *channel, + struct drm_tegra_bo *bo, uint32_t flags, + struct drm_tegra_mapping **mapp); +int drm_tegra_channel_unmap(struct drm_tegra_mapping *map); + +int drm_tegra_job_new(struct drm_tegra_channel *channel, + struct drm_tegra_job **jobp); +int drm_tegra_job_free(struct drm_tegra_job *job); +int drm_tegra_job_get_pushbuf(struct drm_tegra_job *job, + struct drm_tegra_pushbuf **pushbufp); +int drm_tegra_job_submit(struct drm_tegra_job *job, + struct drm_tegra_fence *fence); +int drm_tegra_job_wait(struct drm_tegra_job *job, unsigned long timeout); + +int drm_tegra_pushbuf_begin(struct drm_tegra_pushbuf *pushbuf, + unsigned int words, uint32_t **ptrp); +int drm_tegra_pushbuf_end(struct drm_tegra_pushbuf *pushbuf, uint32_t *ptr); +int drm_tegra_pushbuf_wait(struct drm_tegra_pushbuf *pushbuf, + struct drm_tegra_syncpoint *syncpt, + uint32_t value); +int drm_tegra_pushbuf_relocate(struct drm_tegra_pushbuf *pushbuf, + uint32_t **ptrp, + struct drm_tegra_mapping *target, + unsigned long offset, unsigned int shift, + uint32_t flags); +int drm_tegra_pushbuf_sync(struct drm_tegra_pushbuf *pushbuf, + struct drm_tegra_syncpoint *syncpt, + unsigned int count); +int drm_tegra_pushbuf_sync_cond(struct drm_tegra_pushbuf *pushbuf, + uint32_t **ptrp, + struct drm_tegra_syncpoint *syncpt, + enum drm_tegra_sync_cond cond); + +int drm_tegra_syncpoint_new(struct drm_tegra *drm, + struct drm_tegra_syncpoint **syncptp); +int drm_tegra_syncpoint_free(struct drm_tegra_syncpoint *syncpt); +int drm_tegra_fence_wait(struct drm_tegra_fence *fence, unsigned long timeout); #endif /* __DRM_TEGRA_H__ */ diff -Nru libdrm-2.4.110/tegra/tegra-symbols.txt libdrm-2.4.113/tegra/tegra-symbols.txt --- libdrm-2.4.110/tegra/tegra-symbols.txt 2022-02-16 10:00:13.000000000 +0000 +++ libdrm-2.4.113/tegra/tegra-symbols.txt 2022-08-31 14:38:38.000000000 +0000 @@ -1,13 +1,32 @@ -drm_tegra_bo_get_flags +drm_tegra_bo_export drm_tegra_bo_get_handle -drm_tegra_bo_get_tiling +drm_tegra_bo_get_name +drm_tegra_bo_import drm_tegra_bo_map drm_tegra_bo_new +drm_tegra_bo_open drm_tegra_bo_ref -drm_tegra_bo_set_flags -drm_tegra_bo_set_tiling drm_tegra_bo_unmap drm_tegra_bo_unref drm_tegra_bo_wrap +drm_tegra_channel_close +drm_tegra_channel_get_version +drm_tegra_channel_map +drm_tegra_channel_open +drm_tegra_channel_unmap drm_tegra_close +drm_tegra_fence_wait +drm_tegra_job_free +drm_tegra_job_get_pushbuf +drm_tegra_job_new +drm_tegra_job_submit +drm_tegra_job_wait drm_tegra_new +drm_tegra_pushbuf_begin +drm_tegra_pushbuf_end +drm_tegra_pushbuf_relocate +drm_tegra_pushbuf_sync +drm_tegra_pushbuf_sync_cond +drm_tegra_pushbuf_wait +drm_tegra_syncpoint_free +drm_tegra_syncpoint_new diff -Nru libdrm-2.4.110/tests/amdgpu/amdgpu_test.c libdrm-2.4.113/tests/amdgpu/amdgpu_test.c --- libdrm-2.4.110/tests/amdgpu/amdgpu_test.c 2022-02-16 10:00:13.000000000 +0000 +++ libdrm-2.4.113/tests/amdgpu/amdgpu_test.c 2022-08-31 14:38:38.000000000 +0000 @@ -73,6 +73,7 @@ #define SYNCOBJ_TIMELINE_TESTS_STR "SYNCOBJ TIMELINE Tests" #define SECURITY_TESTS_STR "Security Tests" #define HOTUNPLUG_TESTS_STR "Hotunplug Tests" +#define CP_DMA_TESTS_STR "CP DMA Tests" /** * Open handles for amdgpu devices @@ -163,6 +164,12 @@ .pCleanupFunc = suite_hotunplug_tests_clean, .pTests = hotunplug_tests, }, + { + .pName = CP_DMA_TESTS_STR, + .pInitFunc = suite_cp_dma_tests_init, + .pCleanupFunc = suite_cp_dma_tests_clean, + .pTests = cp_dma_tests, + }, CU_SUITE_INFO_NULL, }; @@ -232,6 +239,10 @@ .pName = HOTUNPLUG_TESTS_STR, .pActive = suite_hotunplug_tests_enable, }, + { + .pName = CP_DMA_TESTS_STR, + .pActive = suite_cp_dma_tests_enable, + }, }; @@ -311,6 +322,10 @@ int fd; drmVersionPtr version; + for (i = 0; i < MAX_CARDS_SUPPORTED; i++) { + drm_amdgpu[i] = -1; + } + drm_count = drmGetDevices2(0, devices, MAX_CARDS_SUPPORTED); if (drm_count < 0) { @@ -534,6 +549,14 @@ "gfx ring slow bad draw test (set amdgpu.lockup_timeout=50)", CU_FALSE)) fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg()); + if (amdgpu_set_test_active(DEADLOCK_TESTS_STR, + "sdma ring corrupted header test (set amdgpu.lockup_timeout=50)", CU_FALSE)) + fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg()); + + if (amdgpu_set_test_active(DEADLOCK_TESTS_STR, + "sdma ring slow linear copy test (set amdgpu.lockup_timeout=50)", CU_FALSE)) + fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg()); + if (amdgpu_set_test_active(BASIC_TESTS_STR, "bo eviction Test", CU_FALSE)) fprintf(stderr, "test deactivation failed - %s\n", CU_get_error_msg()); diff -Nru libdrm-2.4.110/tests/amdgpu/amdgpu_test.h libdrm-2.4.113/tests/amdgpu/amdgpu_test.h --- libdrm-2.4.110/tests/amdgpu/amdgpu_test.h 2022-02-16 10:00:13.000000000 +0000 +++ libdrm-2.4.113/tests/amdgpu/amdgpu_test.h 2022-08-31 14:38:38.000000000 +0000 @@ -261,11 +261,26 @@ */ extern CU_TestInfo syncobj_timeline_tests[]; -void amdgpu_dispatch_hang_helper(amdgpu_device_handle device_handle, uint32_t ip_type); -void amdgpu_dispatch_hang_slow_helper(amdgpu_device_handle device_handle, uint32_t ip_type); -void amdgpu_memcpy_draw_test(amdgpu_device_handle device_handle, uint32_t ring, - int hang); -void amdgpu_memcpy_draw_hang_slow_test(amdgpu_device_handle device_handle, uint32_t ring); + +/** + * Initialize cp dma test suite + */ +int suite_cp_dma_tests_init(); + +/** + * Deinitialize cp dma test suite + */ +int suite_cp_dma_tests_clean(); + +/** + * Decide if the suite is enabled by default or not. + */ +CU_BOOL suite_cp_dma_tests_enable(void); + +/** + * Tests in cp dma test suite + */ +extern CU_TestInfo cp_dma_tests[]; /** * Initialize security test suite @@ -293,7 +308,12 @@ unsigned ip_type, bool secure); - +extern void amdgpu_test_dispatch_helper(amdgpu_device_handle device_handle, unsigned ip); +extern void amdgpu_test_dispatch_hang_helper(amdgpu_device_handle device_handle, uint32_t ip); +extern void amdgpu_test_dispatch_hang_slow_helper(amdgpu_device_handle device_handle, uint32_t ip); +extern void amdgpu_test_draw_helper(amdgpu_device_handle device_handle); +extern void amdgpu_test_draw_hang_helper(amdgpu_device_handle device_handle); +extern void amdgpu_test_draw_hang_slow_helper(amdgpu_device_handle device_handle); /** * Initialize hotunplug test suite diff -Nru libdrm-2.4.110/tests/amdgpu/basic_tests.c libdrm-2.4.113/tests/amdgpu/basic_tests.c --- libdrm-2.4.110/tests/amdgpu/basic_tests.c 2022-02-16 10:00:13.000000000 +0000 +++ libdrm-2.4.113/tests/amdgpu/basic_tests.c 2022-08-31 14:38:38.000000000 +0000 @@ -292,6 +292,8 @@ #define PKT3_SET_SH_REG 0x76 #define PACKET3_SET_SH_REG_START 0x00002c00 +#define PKT3_SET_SH_REG_INDEX 0x9B + #define PACKET3_DISPATCH_DIRECT 0x15 #define PACKET3_EVENT_WRITE 0x46 #define PACKET3_ACQUIRE_MEM 0x58 @@ -351,6 +353,12 @@ 0xbf810000 }; +static const uint32_t bufferclear_cs_shader_gfx10[] = { + 0xD7460004, 0x04010C08, 0x7E000204, 0x7E020205, + 0x7E040206, 0x7E060207, 0xE01C2000, 0x80000004, + 0xBF810000 +}; + static const uint32_t bufferclear_cs_shader_registers_gfx9[][2] = { {0x2e12, 0x000C0041}, //{ mmCOMPUTE_PGM_RSRC1, 0x000C0041 }, {0x2e13, 0x00000090}, //{ mmCOMPUTE_PGM_RSRC2, 0x00000090 }, @@ -367,6 +375,11 @@ 0xe01c2000, 0x80010200, 0xbf810000 }; +static const uint32_t buffercopy_cs_shader_gfx10[] = { + 0xD7460001, 0x04010C08, 0xE00C2000, 0x80000201, + 0xBF8C3F70, 0xE01C2000, 0x80010201, 0xBF810000 +}; + static const uint32_t preamblecache_gfx9[] = { 0xc0026900, 0x81, 0x80000000, 0x40004000, 0xc0026900, 0x8c, 0xaa99aaaa, 0x0, 0xc0026900, 0x90, 0x80000000, 0x40004000, 0xc0026900, 0x94, 0x80000000, 0x40004000, @@ -390,6 +403,32 @@ 0xc0017900, 0x24b, 0x0 }; +static const uint32_t preamblecache_gfx10[] = { + 0xc0026900, 0x81, 0x80000000, 0x40004000, 0xc0026900, 0x8c, 0xaa99aaaa, 0x0, + 0xc0026900, 0x90, 0x80000000, 0x40004000, 0xc0026900, 0x94, 0x80000000, 0x40004000, + 0xc0026900, 0xb4, 0x0, 0x3f800000, 0xc0016900, 0x103, 0x0, + 0xc0016900, 0x208, 0x0, 0xc0016900, 0x290, 0x0, + 0xc0016900, 0x2a1, 0x0, 0xc0026900, 0x2ad, 0x0, 0x0, + 0xc0016900, 0x2d5, 0x10000, 0xc0016900, 0x2dc, 0x0, + 0xc0066900, 0x2de, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0026900, 0x2e5, 0x0, 0x0, + 0xc0056900, 0x2f9, 0x5, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, + 0xc0046900, 0x310, 0, 0x3, 0, 0x100000, 0xc0026900, 0x316, 0xe, 0x20, + 0xc0016900, 0x349, 0x0, 0xc0016900, 0x358, 0x0, 0xc0016900, 0x367, 0x0, + 0xc0016900, 0x376, 0x0, 0xc0016900, 0x385, 0x0, 0xc0016900, 0x6, 0x0, + 0xc0056900, 0xe8, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc0076900, 0x1e1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc0026900, 0x204, 0x90000, 0x4, 0xc0046900, 0x20c, 0x0, 0x0, 0x0, 0x0, + 0xc0016900, 0x2b2, 0x0, 0xc0026900, 0x30e, 0xffffffff, 0xffffffff, + 0xc0016900, 0x314, 0x0, 0xc0016900, 0x10a, 0, 0xc0016900, 0x2a6, 0, 0xc0016900, 0x210, 0, + 0xc0016900, 0x2db, 0, 0xc0016900, 0x1d4, 0, 0xc0002f00, 0x1, 0xc0016900, 0x1, 0x1, 0xc0016900, 0xe, 0x2, + 0xc0016900, 0x206, 0x300, 0xc0016900, 0x212, 0x200, 0xc0017900, 0x7b, 0x20, 0xc0017a00, 0x20000243, 0x0, + 0xc0017900, 0x249, 0, 0xc0017900, 0x24a, 0, 0xc0017900, 0x24b, 0, 0xc0017900, 0x259, 0xffffffff, + 0xc0017900, 0x25f, 0, 0xc0017900, 0x260, 0, 0xc0017900, 0x262, 0, + 0xc0017600, 0x45, 0x0, 0xc0017600, 0x6, 0x0, + 0xc0067600, 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc0067600, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 +}; + enum ps_type { PS_CONST, PS_TEX, @@ -442,6 +481,39 @@ {0xA1C5, 0x00000004}, //{ mmSPI_SHADER_COL_FORMAT, 0x00000004 } }; +static const uint32_t ps_const_shader_gfx10[] = { + 0x7E000200, 0x7E020201, 0x7E040202, 0x7E060203, + 0x5E000300, 0x5E020702, 0xBF800000, 0xBF800000, + 0xF8001C0F, 0x00000100, 0xBF810000 +}; + +static const uint32_t ps_const_shader_patchinfo_code_size_gfx10 = 6; + +static const uint32_t ps_const_shader_patchinfo_code_gfx10[][10][6] = { + {{ 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xF8001890, 0x00000000 }, + { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xF8001801, 0x00000000 }, + { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xF8001803, 0x00000100 }, + { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xF8001803, 0x00000300 }, + { 0x5E000300, 0x5E020702, 0xBF800000, 0xBF800000, 0xF8001C0F, 0x00000100 }, + { 0xD7690000, 0x00020300, 0xD7690001, 0x00020702, 0xF8001C0F, 0x00000100 }, + { 0xD7680000, 0x00020300, 0xD7680001, 0x00020702, 0xF8001C0F, 0x00000100 }, + { 0xD76A0000, 0x00020300, 0xD76A0001, 0x00020702, 0xF8001C0F, 0x00000100 }, + { 0xD76B0000, 0x00020300, 0xD76B0001, 0x00020702, 0xF8001C0F, 0x00000100 }, + { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xF800180F, 0x03020100 } + } +}; + +static const uint32_t ps_const_shader_patchinfo_offset_gfx10[] = { + 0x00000004 +}; + +static const uint32_t ps_num_sh_registers_gfx10 = 2; + +static const uint32_t ps_const_sh_registers_gfx10[][2] = { + {0x2C0A, 0x000C0000},//{ mmSPI_SHADER_PGM_RSRC1_PS, 0x000C0000 }, + {0x2C0B, 0x00000008}, //{ mmSPI_SHADER_PGM_RSRC2_PS, 0x00000008 } +}; + static const uint32_t ps_tex_shader_gfx9[] = { 0xBEFC000C, 0xBE8E017E, 0xBEFE077E, 0xD4180000, 0xD4190001, 0xD41C0100, 0xD41D0101, 0xF0800F00, @@ -485,6 +557,34 @@ {0xA1C5, 0x00000004}, //{ mmSPI_SHADER_COL_FORMAT, 0x00000004 } }; +static const uint32_t ps_tex_shader_gfx10[] = { + 0xBEFC030C, 0xBE8E047E, 0xBEFE0A7E, 0xC8080000, + 0xC80C0100, 0xC8090001, 0xC80D0101, 0xF0800F0A, + 0x00400402, 0x00000003, 0xBEFE040E, 0xBF8C0F70, + 0x5E000B04, 0x5E020F06, 0xBF800000, 0xBF800000, + 0xF8001C0F, 0x00000100, 0xBF810000 +}; + +static const uint32_t ps_tex_shader_patchinfo_offset_gfx10[] = { + 0x0000000C +}; + +static const uint32_t ps_tex_shader_patchinfo_code_size_gfx10 = 6; + +static const uint32_t ps_tex_shader_patchinfo_code_gfx10[][10][6] = { + {{ 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xF8001890, 0x00000000 }, + { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xF8001801, 0x00000004 }, + { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xF8001803, 0x00000504 }, + { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xF8001803, 0x00000704 }, + { 0x5E000B04, 0x5E020F06, 0xBF800000, 0xBF800000, 0xF8001C0F, 0x00000100 }, + { 0xD7690000, 0x00020B04, 0xD7690001, 0x00020F06, 0xF8001C0F, 0x00000100 }, + { 0xD7680000, 0x00020B04, 0xD7680001, 0x00020F06, 0xF8001C0F, 0x00000100 }, + { 0xD76A0000, 0x00020B04, 0xD76A0001, 0x00020F06, 0xF8001C0F, 0x00000100 }, + { 0xD76B0000, 0x00020B04, 0xD76B0001, 0x00020F06, 0xF8001C0F, 0x00000100 }, + { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xF800180F, 0x07060504 } + } +}; + static const uint32_t vs_RectPosTexFast_shader_gfx9[] = { 0x7E000B00, 0x020000F3, 0xD042000A, 0x00010100, 0x7E020202, 0x7E040200, 0x020000F3, 0x7E060206, @@ -496,6 +596,17 @@ 0xC400020F, 0x05060403, 0xBF810000 }; +static const uint32_t vs_RectPosTexFast_shader_gfx10[] = { + 0x7E000B00, 0x060000F3, 0x7E020202, 0x7E040206, + 0x7C040080, 0x060000F3, 0xD5010001, 0x01AA0200, + 0x7E060203, 0xD5010002, 0x01AA0404, 0x7E080207, + 0x7C040080, 0xD5010000, 0x01A80101, 0xD5010001, + 0x01AA0601, 0x7E060208, 0x7E0A02F2, 0xD5010002, + 0x01A80902, 0xD5010004, 0x01AA0805, 0x7E0C0209, + 0xF80008CF, 0x05030100, 0xF800020F, 0x05060402, + 0xBF810000 +}; + static const uint32_t cached_cmd_gfx9[] = { 0xc0016900, 0x0, 0x0, 0xc0026900, 0x3, 0x2a, 0x0, 0xc0046900, 0xa, 0x0, 0x0, 0x0, 0x200020, @@ -507,6 +618,17 @@ 0xc0026900, 0x2b0, 0x0, 0x0, 0xc0016900, 0x2f8, 0x0 }; +static const uint32_t cached_cmd_gfx10[] = { + 0xc0016900, 0x0, 0x0, 0xc0026900, 0x3, 0x2a, 0x0, + 0xc0046900, 0xa, 0x0, 0x0, 0x0, 0x200020, + 0xc0016900, 0x83, 0xffff, 0xc0026900, 0x8e, 0xf, 0xf, + 0xc0056900, 0x105, 0x0, 0x0, 0x0, 0x0, 0x18, + 0xc0026900, 0x10b, 0x0, 0x0, 0xc0016900, 0x1e0, 0x0, + 0xc0036900, 0x200, 0x0, 0x10000, 0xcc0011, + 0xc0026900, 0x292, 0x20, 0x6020000, + 0xc0026900, 0x2b0, 0x0, 0x0, 0xc0016900, 0x2f8, 0x0 +}; + unsigned int memcpy_ps_hang[] = { 0xFFFFFFFF, 0xBEFE0A7E, 0xBEFC0304, 0xC0C20100, 0xC0800300, 0xC8080000, 0xC80C0100, 0xC8090001, @@ -546,6 +668,18 @@ 1 }; +unsigned int memcpy_cs_hang_slow_nv_codes[] = { + 0xd7460000, 0x04010c08, 0xe00c2000, 0x80000100, + 0xbf8c0f70, 0xe01ca000, 0x80010100, 0xbf810000 +}; + +struct amdgpu_test_shader memcpy_cs_hang_slow_nv = { + memcpy_cs_hang_slow_nv_codes, + 4, + 3, + 1 +}; + unsigned int memcpy_ps_hang_slow_ai_codes[] = { 0xbefc000c, 0xbe8e017e, 0xbefe077e, 0xd4080000, 0xd4090001, 0xd40c0100, 0xd40d0101, 0xf0800f00, @@ -723,6 +857,13 @@ amdgpu_bo_list_handle bo_list; amdgpu_va_handle va_handle, va_handle_ce; int r, i = 0; + struct drm_amdgpu_info_hw_ip info; + + r = amdgpu_query_hw_ip_info(device_handle, AMDGPU_HW_IP_GFX, 0, &info); + CU_ASSERT_EQUAL(r, 0); + + if (info.hw_ip_version_major >= 11) + return; r = amdgpu_cs_ctx_create(device_handle, &context_handle); CU_ASSERT_EQUAL(r, 0); @@ -814,6 +955,13 @@ amdgpu_bo_list_handle bo_list; amdgpu_va_handle va_handle; int r, i = 0; + struct drm_amdgpu_info_hw_ip info; + + r = amdgpu_query_hw_ip_info(device_handle, AMDGPU_HW_IP_GFX, 0, &info); + CU_ASSERT_EQUAL(r, 0); + + if (info.hw_ip_version_major >= 11) + return; r = amdgpu_cs_ctx_create(device_handle, &context_handle); CU_ASSERT_EQUAL(r, 0); @@ -1936,6 +2084,13 @@ amdgpu_va_handle va_handle, va_handle_ce; int r; int i = 0, ib_cs_num = 2; + struct drm_amdgpu_info_hw_ip info; + + r = amdgpu_query_hw_ip_info(device_handle, AMDGPU_HW_IP_GFX, 0, &info); + CU_ASSERT_EQUAL(r, 0); + + if (info.hw_ip_version_major >= 11) + return; r = amdgpu_cs_ctx_create(device_handle, &context_handle); CU_ASSERT_EQUAL(r, 0); @@ -2323,1533 +2478,19 @@ free(ibs_request.dependencies); } -static int amdgpu_dispatch_load_cs_shader_hang_slow(uint32_t *ptr, int family) -{ - struct amdgpu_test_shader *shader; - int i, loop = 0x10000; - - switch (family) { - case AMDGPU_FAMILY_AI: - shader = &memcpy_cs_hang_slow_ai; - break; - case AMDGPU_FAMILY_RV: - shader = &memcpy_cs_hang_slow_rv; - break; - default: - return -1; - break; - } - - memcpy(ptr, shader->shader, shader->header_length * sizeof(uint32_t)); - - for (i = 0; i < loop; i++) - memcpy(ptr + shader->header_length + shader->body_length * i, - shader->shader + shader->header_length, - shader->body_length * sizeof(uint32_t)); - - memcpy(ptr + shader->header_length + shader->body_length * loop, - shader->shader + shader->header_length + shader->body_length, - shader->foot_length * sizeof(uint32_t)); - - return 0; -} - -static int amdgpu_dispatch_load_cs_shader(uint8_t *ptr, - int cs_type) -{ - uint32_t shader_size; - const uint32_t *shader; - - switch (cs_type) { - case CS_BUFFERCLEAR: - shader = bufferclear_cs_shader_gfx9; - shader_size = sizeof(bufferclear_cs_shader_gfx9); - break; - case CS_BUFFERCOPY: - shader = buffercopy_cs_shader_gfx9; - shader_size = sizeof(buffercopy_cs_shader_gfx9); - break; - case CS_HANG: - shader = memcpy_ps_hang; - shader_size = sizeof(memcpy_ps_hang); - break; - default: - return -1; - break; - } - - memcpy(ptr, shader, shader_size); - return 0; -} - -static int amdgpu_dispatch_init(uint32_t *ptr, uint32_t ip_type) -{ - int i = 0; - - /* Write context control and load shadowing register if necessary */ - if (ip_type == AMDGPU_HW_IP_GFX) { - ptr[i++] = PACKET3(PKT3_CONTEXT_CONTROL, 1); - ptr[i++] = 0x80000000; - ptr[i++] = 0x80000000; - } - - /* Issue commands to set default compute state. */ - /* clear mmCOMPUTE_START_Z - mmCOMPUTE_START_X */ - ptr[i++] = PACKET3_COMPUTE(PKT3_SET_SH_REG, 3); - ptr[i++] = 0x204; - i += 3; - - /* clear mmCOMPUTE_TMPRING_SIZE */ - ptr[i++] = PACKET3_COMPUTE(PKT3_SET_SH_REG, 1); - ptr[i++] = 0x218; - ptr[i++] = 0; - - return i; -} - -static int amdgpu_dispatch_write_cumask(uint32_t *ptr) -{ - int i = 0; - - /* Issue commands to set cu mask used in current dispatch */ - /* set mmCOMPUTE_STATIC_THREAD_MGMT_SE1 - mmCOMPUTE_STATIC_THREAD_MGMT_SE0 */ - ptr[i++] = PACKET3_COMPUTE(PKT3_SET_SH_REG, 2); - ptr[i++] = 0x216; - ptr[i++] = 0xffffffff; - ptr[i++] = 0xffffffff; - /* set mmCOMPUTE_STATIC_THREAD_MGMT_SE3 - mmCOMPUTE_STATIC_THREAD_MGMT_SE2 */ - ptr[i++] = PACKET3_COMPUTE(PKT3_SET_SH_REG, 2); - ptr[i++] = 0x219; - ptr[i++] = 0xffffffff; - ptr[i++] = 0xffffffff; - - return i; -} - -static int amdgpu_dispatch_write2hw(uint32_t *ptr, uint64_t shader_addr) -{ - int i, j; - - i = 0; - - /* Writes shader state to HW */ - /* set mmCOMPUTE_PGM_HI - mmCOMPUTE_PGM_LO */ - ptr[i++] = PACKET3_COMPUTE(PKT3_SET_SH_REG, 2); - ptr[i++] = 0x20c; - ptr[i++] = (shader_addr >> 8); - ptr[i++] = (shader_addr >> 40); - /* write sh regs*/ - for (j = 0; j < bufferclear_cs_shader_registers_num_gfx9; j++) { - ptr[i++] = PACKET3_COMPUTE(PKT3_SET_SH_REG, 1); - /* - Gfx9ShRegBase */ - ptr[i++] = bufferclear_cs_shader_registers_gfx9[j][0] - 0x2c00; - ptr[i++] = bufferclear_cs_shader_registers_gfx9[j][1]; - } - - return i; -} - -static void amdgpu_memset_dispatch_test(amdgpu_device_handle device_handle, - uint32_t ip_type, - uint32_t ring) -{ - amdgpu_context_handle context_handle; - amdgpu_bo_handle bo_dst, bo_shader, bo_cmd, resources[3]; - volatile unsigned char *ptr_dst; - void *ptr_shader; - uint32_t *ptr_cmd; - uint64_t mc_address_dst, mc_address_shader, mc_address_cmd; - amdgpu_va_handle va_dst, va_shader, va_cmd; - int i, r; - int bo_dst_size = 16384; - int bo_shader_size = 4096; - int bo_cmd_size = 4096; - struct amdgpu_cs_request ibs_request = {0}; - struct amdgpu_cs_ib_info ib_info= {0}; - amdgpu_bo_list_handle bo_list; - struct amdgpu_cs_fence fence_status = {0}; - uint32_t expired; - - r = amdgpu_cs_ctx_create(device_handle, &context_handle); - CU_ASSERT_EQUAL(r, 0); - - r = amdgpu_bo_alloc_and_map(device_handle, bo_cmd_size, 4096, - AMDGPU_GEM_DOMAIN_GTT, 0, - &bo_cmd, (void **)&ptr_cmd, - &mc_address_cmd, &va_cmd); - CU_ASSERT_EQUAL(r, 0); - memset(ptr_cmd, 0, bo_cmd_size); - - r = amdgpu_bo_alloc_and_map(device_handle, bo_shader_size, 4096, - AMDGPU_GEM_DOMAIN_VRAM, 0, - &bo_shader, &ptr_shader, - &mc_address_shader, &va_shader); - CU_ASSERT_EQUAL(r, 0); - memset(ptr_shader, 0, bo_shader_size); - - r = amdgpu_dispatch_load_cs_shader(ptr_shader, CS_BUFFERCLEAR); - CU_ASSERT_EQUAL(r, 0); - - r = amdgpu_bo_alloc_and_map(device_handle, bo_dst_size, 4096, - AMDGPU_GEM_DOMAIN_VRAM, 0, - &bo_dst, (void **)&ptr_dst, - &mc_address_dst, &va_dst); - CU_ASSERT_EQUAL(r, 0); - - i = 0; - i += amdgpu_dispatch_init(ptr_cmd + i, ip_type); - - /* Issue commands to set cu mask used in current dispatch */ - i += amdgpu_dispatch_write_cumask(ptr_cmd + i); - - /* Writes shader state to HW */ - i += amdgpu_dispatch_write2hw(ptr_cmd + i, mc_address_shader); - - /* Write constant data */ - /* Writes the UAV constant data to the SGPRs. */ - ptr_cmd[i++] = PACKET3_COMPUTE(PKT3_SET_SH_REG, 4); - ptr_cmd[i++] = 0x240; - ptr_cmd[i++] = mc_address_dst; - ptr_cmd[i++] = (mc_address_dst >> 32) | 0x100000; - ptr_cmd[i++] = 0x400; - ptr_cmd[i++] = 0x74fac; - - /* Sets a range of pixel shader constants */ - ptr_cmd[i++] = PACKET3_COMPUTE(PKT3_SET_SH_REG, 4); - ptr_cmd[i++] = 0x244; - ptr_cmd[i++] = 0x22222222; - ptr_cmd[i++] = 0x22222222; - ptr_cmd[i++] = 0x22222222; - ptr_cmd[i++] = 0x22222222; - - /* clear mmCOMPUTE_RESOURCE_LIMITS */ - ptr_cmd[i++] = PACKET3_COMPUTE(PKT3_SET_SH_REG, 1); - ptr_cmd[i++] = 0x215; - ptr_cmd[i++] = 0; - - /* dispatch direct command */ - ptr_cmd[i++] = PACKET3_COMPUTE(PACKET3_DISPATCH_DIRECT, 3); - ptr_cmd[i++] = 0x10; - ptr_cmd[i++] = 1; - ptr_cmd[i++] = 1; - ptr_cmd[i++] = 1; - - while (i & 7) - ptr_cmd[i++] = 0xffff1000; /* type3 nop packet */ - - resources[0] = bo_dst; - resources[1] = bo_shader; - resources[2] = bo_cmd; - r = amdgpu_bo_list_create(device_handle, 3, resources, NULL, &bo_list); - CU_ASSERT_EQUAL(r, 0); - - ib_info.ib_mc_address = mc_address_cmd; - ib_info.size = i; - ibs_request.ip_type = ip_type; - ibs_request.ring = ring; - ibs_request.resources = bo_list; - ibs_request.number_of_ibs = 1; - ibs_request.ibs = &ib_info; - ibs_request.fence_info.handle = NULL; - - /* submit CS */ - r = amdgpu_cs_submit(context_handle, 0, &ibs_request, 1); - CU_ASSERT_EQUAL(r, 0); - - r = amdgpu_bo_list_destroy(bo_list); - CU_ASSERT_EQUAL(r, 0); - - fence_status.ip_type = ip_type; - fence_status.ip_instance = 0; - fence_status.ring = ring; - fence_status.context = context_handle; - fence_status.fence = ibs_request.seq_no; - - /* wait for IB accomplished */ - r = amdgpu_cs_query_fence_status(&fence_status, - AMDGPU_TIMEOUT_INFINITE, - 0, &expired); - CU_ASSERT_EQUAL(r, 0); - CU_ASSERT_EQUAL(expired, true); - - /* verify if memset test result meets with expected */ - i = 0; - while(i < bo_dst_size) { - CU_ASSERT_EQUAL(ptr_dst[i++], 0x22); - } - - r = amdgpu_bo_unmap_and_free(bo_dst, va_dst, mc_address_dst, bo_dst_size); - CU_ASSERT_EQUAL(r, 0); - - r = amdgpu_bo_unmap_and_free(bo_shader, va_shader, mc_address_shader, bo_shader_size); - CU_ASSERT_EQUAL(r, 0); - - r = amdgpu_bo_unmap_and_free(bo_cmd, va_cmd, mc_address_cmd, bo_cmd_size); - CU_ASSERT_EQUAL(r, 0); - - r = amdgpu_cs_ctx_free(context_handle); - CU_ASSERT_EQUAL(r, 0); -} - -static void amdgpu_memcpy_dispatch_test(amdgpu_device_handle device_handle, - uint32_t ip_type, - uint32_t ring, - int hang) -{ - amdgpu_context_handle context_handle; - amdgpu_bo_handle bo_src, bo_dst, bo_shader, bo_cmd, resources[4]; - volatile unsigned char *ptr_dst; - void *ptr_shader; - unsigned char *ptr_src; - uint32_t *ptr_cmd; - uint64_t mc_address_src, mc_address_dst, mc_address_shader, mc_address_cmd; - amdgpu_va_handle va_src, va_dst, va_shader, va_cmd; - int i, r; - int bo_dst_size = 16384; - int bo_shader_size = 4096; - int bo_cmd_size = 4096; - struct amdgpu_cs_request ibs_request = {0}; - struct amdgpu_cs_ib_info ib_info= {0}; - uint32_t expired, hang_state, hangs; - enum cs_type cs_type; - amdgpu_bo_list_handle bo_list; - struct amdgpu_cs_fence fence_status = {0}; - - r = amdgpu_cs_ctx_create(device_handle, &context_handle); - CU_ASSERT_EQUAL(r, 0); - - r = amdgpu_bo_alloc_and_map(device_handle, bo_cmd_size, 4096, - AMDGPU_GEM_DOMAIN_GTT, 0, - &bo_cmd, (void **)&ptr_cmd, - &mc_address_cmd, &va_cmd); - CU_ASSERT_EQUAL(r, 0); - memset(ptr_cmd, 0, bo_cmd_size); - - r = amdgpu_bo_alloc_and_map(device_handle, bo_shader_size, 4096, - AMDGPU_GEM_DOMAIN_VRAM, 0, - &bo_shader, &ptr_shader, - &mc_address_shader, &va_shader); - CU_ASSERT_EQUAL(r, 0); - memset(ptr_shader, 0, bo_shader_size); - - cs_type = hang ? CS_HANG : CS_BUFFERCOPY; - r = amdgpu_dispatch_load_cs_shader(ptr_shader, cs_type); - CU_ASSERT_EQUAL(r, 0); - - r = amdgpu_bo_alloc_and_map(device_handle, bo_dst_size, 4096, - AMDGPU_GEM_DOMAIN_VRAM, 0, - &bo_src, (void **)&ptr_src, - &mc_address_src, &va_src); - CU_ASSERT_EQUAL(r, 0); - - r = amdgpu_bo_alloc_and_map(device_handle, bo_dst_size, 4096, - AMDGPU_GEM_DOMAIN_VRAM, 0, - &bo_dst, (void **)&ptr_dst, - &mc_address_dst, &va_dst); - CU_ASSERT_EQUAL(r, 0); - - memset(ptr_src, 0x55, bo_dst_size); - - i = 0; - i += amdgpu_dispatch_init(ptr_cmd + i, ip_type); - - /* Issue commands to set cu mask used in current dispatch */ - i += amdgpu_dispatch_write_cumask(ptr_cmd + i); - - /* Writes shader state to HW */ - i += amdgpu_dispatch_write2hw(ptr_cmd + i, mc_address_shader); - - /* Write constant data */ - /* Writes the texture resource constants data to the SGPRs */ - ptr_cmd[i++] = PACKET3_COMPUTE(PKT3_SET_SH_REG, 4); - ptr_cmd[i++] = 0x240; - ptr_cmd[i++] = mc_address_src; - ptr_cmd[i++] = (mc_address_src >> 32) | 0x100000; - ptr_cmd[i++] = 0x400; - ptr_cmd[i++] = 0x74fac; - - /* Writes the UAV constant data to the SGPRs. */ - ptr_cmd[i++] = PACKET3_COMPUTE(PKT3_SET_SH_REG, 4); - ptr_cmd[i++] = 0x244; - ptr_cmd[i++] = mc_address_dst; - ptr_cmd[i++] = (mc_address_dst >> 32) | 0x100000; - ptr_cmd[i++] = 0x400; - ptr_cmd[i++] = 0x74fac; - - /* clear mmCOMPUTE_RESOURCE_LIMITS */ - ptr_cmd[i++] = PACKET3_COMPUTE(PKT3_SET_SH_REG, 1); - ptr_cmd[i++] = 0x215; - ptr_cmd[i++] = 0; - - /* dispatch direct command */ - ptr_cmd[i++] = PACKET3_COMPUTE(PACKET3_DISPATCH_DIRECT, 3); - ptr_cmd[i++] = 0x10; - ptr_cmd[i++] = 1; - ptr_cmd[i++] = 1; - ptr_cmd[i++] = 1; - - while (i & 7) - ptr_cmd[i++] = 0xffff1000; /* type3 nop packet */ - - resources[0] = bo_shader; - resources[1] = bo_src; - resources[2] = bo_dst; - resources[3] = bo_cmd; - r = amdgpu_bo_list_create(device_handle, 4, resources, NULL, &bo_list); - CU_ASSERT_EQUAL(r, 0); - - ib_info.ib_mc_address = mc_address_cmd; - ib_info.size = i; - ibs_request.ip_type = ip_type; - ibs_request.ring = ring; - ibs_request.resources = bo_list; - ibs_request.number_of_ibs = 1; - ibs_request.ibs = &ib_info; - ibs_request.fence_info.handle = NULL; - r = amdgpu_cs_submit(context_handle, 0, &ibs_request, 1); - CU_ASSERT_EQUAL(r, 0); - - fence_status.ip_type = ip_type; - fence_status.ip_instance = 0; - fence_status.ring = ring; - fence_status.context = context_handle; - fence_status.fence = ibs_request.seq_no; - - /* wait for IB accomplished */ - r = amdgpu_cs_query_fence_status(&fence_status, - AMDGPU_TIMEOUT_INFINITE, - 0, &expired); - - if (!hang) { - CU_ASSERT_EQUAL(r, 0); - CU_ASSERT_EQUAL(expired, true); - - /* verify if memcpy test result meets with expected */ - i = 0; - while(i < bo_dst_size) { - CU_ASSERT_EQUAL(ptr_dst[i], ptr_src[i]); - i++; - } - } else { - r = amdgpu_cs_query_reset_state(context_handle, &hang_state, &hangs); - CU_ASSERT_EQUAL(r, 0); - CU_ASSERT_EQUAL(hang_state, AMDGPU_CTX_UNKNOWN_RESET); - } - - r = amdgpu_bo_list_destroy(bo_list); - CU_ASSERT_EQUAL(r, 0); - - r = amdgpu_bo_unmap_and_free(bo_src, va_src, mc_address_src, bo_dst_size); - CU_ASSERT_EQUAL(r, 0); - r = amdgpu_bo_unmap_and_free(bo_dst, va_dst, mc_address_dst, bo_dst_size); - CU_ASSERT_EQUAL(r, 0); - - r = amdgpu_bo_unmap_and_free(bo_cmd, va_cmd, mc_address_cmd, bo_cmd_size); - CU_ASSERT_EQUAL(r, 0); - - r = amdgpu_bo_unmap_and_free(bo_shader, va_shader, mc_address_shader, bo_shader_size); - CU_ASSERT_EQUAL(r, 0); - - r = amdgpu_cs_ctx_free(context_handle); - CU_ASSERT_EQUAL(r, 0); -} - static void amdgpu_compute_dispatch_test(void) { - int r; - struct drm_amdgpu_info_hw_ip info; - uint32_t ring_id; - - r = amdgpu_query_hw_ip_info(device_handle, AMDGPU_HW_IP_COMPUTE, 0, &info); - CU_ASSERT_EQUAL(r, 0); - if (!info.available_rings) - printf("SKIP ... as there's no compute ring\n"); - - for (ring_id = 0; (1 << ring_id) & info.available_rings; ring_id++) { - amdgpu_memset_dispatch_test(device_handle, AMDGPU_HW_IP_COMPUTE, ring_id); - amdgpu_memcpy_dispatch_test(device_handle, AMDGPU_HW_IP_COMPUTE, ring_id, 0); - } + amdgpu_test_dispatch_helper(device_handle, AMDGPU_HW_IP_COMPUTE); } - static void amdgpu_gfx_dispatch_test(void) { - int r; - struct drm_amdgpu_info_hw_ip info; - uint32_t ring_id; - - r = amdgpu_query_hw_ip_info(device_handle, AMDGPU_HW_IP_GFX, 0, &info); - CU_ASSERT_EQUAL(r, 0); - if (!info.available_rings) - printf("SKIP ... as there's no graphics ring\n"); - - for (ring_id = 0; (1 << ring_id) & info.available_rings; ring_id++) { - amdgpu_memset_dispatch_test(device_handle, AMDGPU_HW_IP_GFX, ring_id); - amdgpu_memcpy_dispatch_test(device_handle, AMDGPU_HW_IP_GFX, ring_id, 0); - } + amdgpu_test_dispatch_helper(device_handle, AMDGPU_HW_IP_GFX); } -void amdgpu_dispatch_hang_helper(amdgpu_device_handle device_handle, uint32_t ip_type) +static void amdgpu_draw_test(void) { - int r; - struct drm_amdgpu_info_hw_ip info; - uint32_t ring_id; - - r = amdgpu_query_hw_ip_info(device_handle, ip_type, 0, &info); - CU_ASSERT_EQUAL(r, 0); - if (!info.available_rings) - printf("SKIP ... as there's no ring for ip %d\n", ip_type); - - for (ring_id = 0; (1 << ring_id) & info.available_rings; ring_id++) { - amdgpu_memcpy_dispatch_test(device_handle, ip_type, ring_id, 0); - amdgpu_memcpy_dispatch_test(device_handle, ip_type, ring_id, 1); - amdgpu_memcpy_dispatch_test(device_handle, ip_type, ring_id, 0); - } -} - -static void amdgpu_memcpy_dispatch_hang_slow_test(amdgpu_device_handle device_handle, - uint32_t ip_type, uint32_t ring) -{ - amdgpu_context_handle context_handle; - amdgpu_bo_handle bo_src, bo_dst, bo_shader, bo_cmd, resources[4]; - volatile unsigned char *ptr_dst; - void *ptr_shader; - unsigned char *ptr_src; - uint32_t *ptr_cmd; - uint64_t mc_address_src, mc_address_dst, mc_address_shader, mc_address_cmd; - amdgpu_va_handle va_src, va_dst, va_shader, va_cmd; - int i, r; - int bo_dst_size = 0x4000000; - int bo_shader_size = 0x400000; - int bo_cmd_size = 4096; - struct amdgpu_cs_request ibs_request = {0}; - struct amdgpu_cs_ib_info ib_info= {0}; - uint32_t hang_state, hangs, expired; - struct amdgpu_gpu_info gpu_info = {0}; - amdgpu_bo_list_handle bo_list; - struct amdgpu_cs_fence fence_status = {0}; - - r = amdgpu_query_gpu_info(device_handle, &gpu_info); - CU_ASSERT_EQUAL(r, 0); - - r = amdgpu_cs_ctx_create(device_handle, &context_handle); - CU_ASSERT_EQUAL(r, 0); - - r = amdgpu_bo_alloc_and_map(device_handle, bo_cmd_size, 4096, - AMDGPU_GEM_DOMAIN_GTT, 0, - &bo_cmd, (void **)&ptr_cmd, - &mc_address_cmd, &va_cmd); - CU_ASSERT_EQUAL(r, 0); - memset(ptr_cmd, 0, bo_cmd_size); - - r = amdgpu_bo_alloc_and_map(device_handle, bo_shader_size, 4096, - AMDGPU_GEM_DOMAIN_VRAM, 0, - &bo_shader, &ptr_shader, - &mc_address_shader, &va_shader); - CU_ASSERT_EQUAL(r, 0); - memset(ptr_shader, 0, bo_shader_size); - - r = amdgpu_dispatch_load_cs_shader_hang_slow(ptr_shader, gpu_info.family_id); - CU_ASSERT_EQUAL(r, 0); - - r = amdgpu_bo_alloc_and_map(device_handle, bo_dst_size, 4096, - AMDGPU_GEM_DOMAIN_VRAM, 0, - &bo_src, (void **)&ptr_src, - &mc_address_src, &va_src); - CU_ASSERT_EQUAL(r, 0); - - r = amdgpu_bo_alloc_and_map(device_handle, bo_dst_size, 4096, - AMDGPU_GEM_DOMAIN_VRAM, 0, - &bo_dst, (void **)&ptr_dst, - &mc_address_dst, &va_dst); - CU_ASSERT_EQUAL(r, 0); - - memset(ptr_src, 0x55, bo_dst_size); - - i = 0; - i += amdgpu_dispatch_init(ptr_cmd + i, ip_type); - - /* Issue commands to set cu mask used in current dispatch */ - i += amdgpu_dispatch_write_cumask(ptr_cmd + i); - - /* Writes shader state to HW */ - i += amdgpu_dispatch_write2hw(ptr_cmd + i, mc_address_shader); - - /* Write constant data */ - /* Writes the texture resource constants data to the SGPRs */ - ptr_cmd[i++] = PACKET3_COMPUTE(PKT3_SET_SH_REG, 4); - ptr_cmd[i++] = 0x240; - ptr_cmd[i++] = mc_address_src; - ptr_cmd[i++] = (mc_address_src >> 32) | 0x100000; - ptr_cmd[i++] = 0x400000; - ptr_cmd[i++] = 0x74fac; - - /* Writes the UAV constant data to the SGPRs. */ - ptr_cmd[i++] = PACKET3_COMPUTE(PKT3_SET_SH_REG, 4); - ptr_cmd[i++] = 0x244; - ptr_cmd[i++] = mc_address_dst; - ptr_cmd[i++] = (mc_address_dst >> 32) | 0x100000; - ptr_cmd[i++] = 0x400000; - ptr_cmd[i++] = 0x74fac; - - /* clear mmCOMPUTE_RESOURCE_LIMITS */ - ptr_cmd[i++] = PACKET3_COMPUTE(PKT3_SET_SH_REG, 1); - ptr_cmd[i++] = 0x215; - ptr_cmd[i++] = 0; - - /* dispatch direct command */ - ptr_cmd[i++] = PACKET3_COMPUTE(PACKET3_DISPATCH_DIRECT, 3); - ptr_cmd[i++] = 0x10000; - ptr_cmd[i++] = 1; - ptr_cmd[i++] = 1; - ptr_cmd[i++] = 1; - - while (i & 7) - ptr_cmd[i++] = 0xffff1000; /* type3 nop packet */ - - resources[0] = bo_shader; - resources[1] = bo_src; - resources[2] = bo_dst; - resources[3] = bo_cmd; - r = amdgpu_bo_list_create(device_handle, 4, resources, NULL, &bo_list); - CU_ASSERT_EQUAL(r, 0); - - ib_info.ib_mc_address = mc_address_cmd; - ib_info.size = i; - ibs_request.ip_type = ip_type; - ibs_request.ring = ring; - ibs_request.resources = bo_list; - ibs_request.number_of_ibs = 1; - ibs_request.ibs = &ib_info; - ibs_request.fence_info.handle = NULL; - r = amdgpu_cs_submit(context_handle, 0, &ibs_request, 1); - CU_ASSERT_EQUAL(r, 0); - - fence_status.ip_type = ip_type; - fence_status.ip_instance = 0; - fence_status.ring = ring; - fence_status.context = context_handle; - fence_status.fence = ibs_request.seq_no; - - /* wait for IB accomplished */ - r = amdgpu_cs_query_fence_status(&fence_status, - AMDGPU_TIMEOUT_INFINITE, - 0, &expired); - - r = amdgpu_cs_query_reset_state(context_handle, &hang_state, &hangs); - CU_ASSERT_EQUAL(r, 0); - CU_ASSERT_EQUAL(hang_state, AMDGPU_CTX_UNKNOWN_RESET); - - r = amdgpu_bo_list_destroy(bo_list); - CU_ASSERT_EQUAL(r, 0); - - r = amdgpu_bo_unmap_and_free(bo_src, va_src, mc_address_src, bo_dst_size); - CU_ASSERT_EQUAL(r, 0); - r = amdgpu_bo_unmap_and_free(bo_dst, va_dst, mc_address_dst, bo_dst_size); - CU_ASSERT_EQUAL(r, 0); - - r = amdgpu_bo_unmap_and_free(bo_cmd, va_cmd, mc_address_cmd, bo_cmd_size); - CU_ASSERT_EQUAL(r, 0); - - r = amdgpu_bo_unmap_and_free(bo_shader, va_shader, mc_address_shader, bo_shader_size); - CU_ASSERT_EQUAL(r, 0); - - r = amdgpu_cs_ctx_free(context_handle); - CU_ASSERT_EQUAL(r, 0); -} - -void amdgpu_dispatch_hang_slow_helper(amdgpu_device_handle device_handle, uint32_t ip_type) -{ - int r; - struct drm_amdgpu_info_hw_ip info; - uint32_t ring_id; - - r = amdgpu_query_hw_ip_info(device_handle, ip_type, 0, &info); - CU_ASSERT_EQUAL(r, 0); - if (!info.available_rings) - printf("SKIP ... as there's no ring for ip %d\n", ip_type); - - for (ring_id = 0; (1 << ring_id) & info.available_rings; ring_id++) { - amdgpu_memcpy_dispatch_test(device_handle, ip_type, ring_id, 0); - amdgpu_memcpy_dispatch_hang_slow_test(device_handle, ip_type, ring_id); - amdgpu_memcpy_dispatch_test(device_handle, ip_type, ring_id, 0); - } -} - -static int amdgpu_draw_load_ps_shader_hang_slow(uint32_t *ptr, int family) -{ - struct amdgpu_test_shader *shader; - int i, loop = 0x40000; - - switch (family) { - case AMDGPU_FAMILY_AI: - case AMDGPU_FAMILY_RV: - shader = &memcpy_ps_hang_slow_ai; - break; - default: - return -1; - break; - } - - memcpy(ptr, shader->shader, shader->header_length * sizeof(uint32_t)); - - for (i = 0; i < loop; i++) - memcpy(ptr + shader->header_length + shader->body_length * i, - shader->shader + shader->header_length, - shader->body_length * sizeof(uint32_t)); - - memcpy(ptr + shader->header_length + shader->body_length * loop, - shader->shader + shader->header_length + shader->body_length, - shader->foot_length * sizeof(uint32_t)); - - return 0; -} - -static int amdgpu_draw_load_ps_shader(uint8_t *ptr, int ps_type) -{ - int i; - uint32_t shader_offset= 256; - uint32_t mem_offset, patch_code_offset; - uint32_t shader_size, patchinfo_code_size; - const uint32_t *shader; - const uint32_t *patchinfo_code; - const uint32_t *patchcode_offset; - - switch (ps_type) { - case PS_CONST: - shader = ps_const_shader_gfx9; - shader_size = sizeof(ps_const_shader_gfx9); - patchinfo_code = (const uint32_t *)ps_const_shader_patchinfo_code_gfx9; - patchinfo_code_size = ps_const_shader_patchinfo_code_size_gfx9; - patchcode_offset = ps_const_shader_patchinfo_offset_gfx9; - break; - case PS_TEX: - shader = ps_tex_shader_gfx9; - shader_size = sizeof(ps_tex_shader_gfx9); - patchinfo_code = (const uint32_t *)ps_tex_shader_patchinfo_code_gfx9; - patchinfo_code_size = ps_tex_shader_patchinfo_code_size_gfx9; - patchcode_offset = ps_tex_shader_patchinfo_offset_gfx9; - break; - case PS_HANG: - shader = memcpy_ps_hang; - shader_size = sizeof(memcpy_ps_hang); - - memcpy(ptr, shader, shader_size); - return 0; - default: - return -1; - break; - } - - /* write main shader program */ - for (i = 0 ; i < 10; i++) { - mem_offset = i * shader_offset; - memcpy(ptr + mem_offset, shader, shader_size); - } - - /* overwrite patch codes */ - for (i = 0 ; i < 10; i++) { - mem_offset = i * shader_offset + patchcode_offset[0] * sizeof(uint32_t); - patch_code_offset = i * patchinfo_code_size; - memcpy(ptr + mem_offset, - patchinfo_code + patch_code_offset, - patchinfo_code_size * sizeof(uint32_t)); - } - - return 0; -} - -/* load RectPosTexFast_VS */ -static int amdgpu_draw_load_vs_shader(uint8_t *ptr) -{ - const uint32_t *shader; - uint32_t shader_size; - - shader = vs_RectPosTexFast_shader_gfx9; - shader_size = sizeof(vs_RectPosTexFast_shader_gfx9); - - memcpy(ptr, shader, shader_size); - - return 0; + amdgpu_test_draw_helper(device_handle); } - -static int amdgpu_draw_init(uint32_t *ptr) -{ - int i = 0; - const uint32_t *preamblecache_ptr; - uint32_t preamblecache_size; - - /* Write context control and load shadowing register if necessary */ - ptr[i++] = PACKET3(PKT3_CONTEXT_CONTROL, 1); - ptr[i++] = 0x80000000; - ptr[i++] = 0x80000000; - - preamblecache_ptr = preamblecache_gfx9; - preamblecache_size = sizeof(preamblecache_gfx9); - - memcpy(ptr + i, preamblecache_ptr, preamblecache_size); - return i + preamblecache_size/sizeof(uint32_t); -} - -static int amdgpu_draw_setup_and_write_drawblt_surf_info(uint32_t *ptr, - uint64_t dst_addr, - int hang_slow) -{ - int i = 0; - - /* setup color buffer */ - /* offset reg - 0xA318 CB_COLOR0_BASE - 0xA319 CB_COLOR0_BASE_EXT - 0xA31A CB_COLOR0_ATTRIB2 - 0xA31B CB_COLOR0_VIEW - 0xA31C CB_COLOR0_INFO - 0xA31D CB_COLOR0_ATTRIB - 0xA31E CB_COLOR0_DCC_CONTROL - 0xA31F CB_COLOR0_CMASK - 0xA320 CB_COLOR0_CMASK_BASE_EXT - 0xA321 CB_COLOR0_FMASK - 0xA322 CB_COLOR0_FMASK_BASE_EXT - 0xA323 CB_COLOR0_CLEAR_WORD0 - 0xA324 CB_COLOR0_CLEAR_WORD1 - 0xA325 CB_COLOR0_DCC_BASE - 0xA326 CB_COLOR0_DCC_BASE_EXT */ - ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 15); - ptr[i++] = 0x318; - ptr[i++] = dst_addr >> 8; - ptr[i++] = dst_addr >> 40; - ptr[i++] = hang_slow ? 0x1ffc7ff : 0x7c01f; - ptr[i++] = 0; - ptr[i++] = 0x50438; - ptr[i++] = 0x10140000; - i += 9; - - /* mmCB_MRT0_EPITCH */ - ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1); - ptr[i++] = 0x1e8; - ptr[i++] = hang_slow ? 0x7ff : 0x1f; - - /* 0xA32B CB_COLOR1_BASE */ - ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1); - ptr[i++] = 0x32b; - ptr[i++] = 0; - - /* 0xA33A CB_COLOR1_BASE */ - ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1); - ptr[i++] = 0x33a; - ptr[i++] = 0; - - /* SPI_SHADER_COL_FORMAT */ - ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1); - ptr[i++] = 0x1c5; - ptr[i++] = 9; - - /* Setup depth buffer */ - /* mmDB_Z_INFO */ - ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 2); - ptr[i++] = 0xe; - i += 2; - - return i; -} - -static int amdgpu_draw_setup_and_write_drawblt_state(uint32_t *ptr, int hang_slow) -{ - int i = 0; - const uint32_t *cached_cmd_ptr; - uint32_t cached_cmd_size; - - /* mmPA_SC_TILE_STEERING_OVERRIDE */ - ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1); - ptr[i++] = 0xd7; - ptr[i++] = 0; - - ptr[i++] = 0xffff1000; - ptr[i++] = 0xc0021000; - - ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1); - ptr[i++] = 0xd7; - ptr[i++] = 1; - - /* mmPA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_0 */ - ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 16); - ptr[i++] = 0x2fe; - i += 16; - - /* mmPA_SC_CENTROID_PRIORITY_0 */ - ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 2); - ptr[i++] = 0x2f5; - i += 2; - - cached_cmd_ptr = cached_cmd_gfx9; - cached_cmd_size = sizeof(cached_cmd_gfx9); - - memcpy(ptr + i, cached_cmd_ptr, cached_cmd_size); - if (hang_slow) - *(ptr + i + 12) = 0x8000800; - i += cached_cmd_size/sizeof(uint32_t); - - return i; -} - -static int amdgpu_draw_vs_RectPosTexFast_write2hw(uint32_t *ptr, - int ps_type, - uint64_t shader_addr, - int hang_slow) -{ - int i = 0; - - /* mmPA_CL_VS_OUT_CNTL */ - ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1); - ptr[i++] = 0x207; - ptr[i++] = 0; - - /* mmSPI_SHADER_PGM_RSRC3_VS */ - ptr[i++] = PACKET3(PKT3_SET_SH_REG, 1); - ptr[i++] = 0x46; - ptr[i++] = 0xffff; - - /* mmSPI_SHADER_PGM_LO_VS...mmSPI_SHADER_PGM_HI_VS */ - ptr[i++] = PACKET3(PKT3_SET_SH_REG, 2); - ptr[i++] = 0x48; - ptr[i++] = shader_addr >> 8; - ptr[i++] = shader_addr >> 40; - - /* mmSPI_SHADER_PGM_RSRC1_VS */ - ptr[i++] = PACKET3(PKT3_SET_SH_REG, 1); - ptr[i++] = 0x4a; - ptr[i++] = 0xc0081; - /* mmSPI_SHADER_PGM_RSRC2_VS */ - ptr[i++] = PACKET3(PKT3_SET_SH_REG, 1); - ptr[i++] = 0x4b; - ptr[i++] = 0x18; - - /* mmSPI_VS_OUT_CONFIG */ - ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1); - ptr[i++] = 0x1b1; - ptr[i++] = 2; - - /* mmSPI_SHADER_POS_FORMAT */ - ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1); - ptr[i++] = 0x1c3; - ptr[i++] = 4; - - ptr[i++] = PACKET3(PKT3_SET_SH_REG, 4); - ptr[i++] = 0x4c; - i += 2; - ptr[i++] = hang_slow ? 0x45000000 : 0x42000000; - ptr[i++] = hang_slow ? 0x45000000 : 0x42000000; - - ptr[i++] = PACKET3(PKT3_SET_SH_REG, 4); - ptr[i++] = 0x50; - i += 2; - if (ps_type == PS_CONST) { - i += 2; - } else if (ps_type == PS_TEX) { - ptr[i++] = 0x3f800000; - ptr[i++] = 0x3f800000; - } - - ptr[i++] = PACKET3(PKT3_SET_SH_REG, 4); - ptr[i++] = 0x54; - i += 4; - - return i; -} - -static int amdgpu_draw_ps_write2hw(uint32_t *ptr, - int ps_type, - uint64_t shader_addr) -{ - int i, j; - const uint32_t *sh_registers; - const uint32_t *context_registers; - uint32_t num_sh_reg, num_context_reg; - - if (ps_type == PS_CONST) { - sh_registers = (const uint32_t *)ps_const_sh_registers_gfx9; - context_registers = (const uint32_t *)ps_const_context_reg_gfx9; - num_sh_reg = ps_num_sh_registers_gfx9; - num_context_reg = ps_num_context_registers_gfx9; - } else if (ps_type == PS_TEX) { - sh_registers = (const uint32_t *)ps_tex_sh_registers_gfx9; - context_registers = (const uint32_t *)ps_tex_context_reg_gfx9; - num_sh_reg = ps_num_sh_registers_gfx9; - num_context_reg = ps_num_context_registers_gfx9; - } - - i = 0; - - /* 0x2c07 SPI_SHADER_PGM_RSRC3_PS - 0x2c08 SPI_SHADER_PGM_LO_PS - 0x2c09 SPI_SHADER_PGM_HI_PS */ - shader_addr += 256 * 9; - ptr[i++] = PACKET3(PKT3_SET_SH_REG, 3); - ptr[i++] = 0x7; - ptr[i++] = 0xffff; - ptr[i++] = shader_addr >> 8; - ptr[i++] = shader_addr >> 40; - - for (j = 0; j < num_sh_reg; j++) { - ptr[i++] = PACKET3(PKT3_SET_SH_REG, 1); - ptr[i++] = sh_registers[j * 2] - 0x2c00; - ptr[i++] = sh_registers[j * 2 + 1]; - } - - for (j = 0; j < num_context_reg; j++) { - if (context_registers[j * 2] != 0xA1C5) { - ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1); - ptr[i++] = context_registers[j * 2] - 0xa000; - ptr[i++] = context_registers[j * 2 + 1]; - } - - if (context_registers[j * 2] == 0xA1B4) { - ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1); - ptr[i++] = 0x1b3; - ptr[i++] = 2; - } - } - - return i; -} - -static int amdgpu_draw_draw(uint32_t *ptr) -{ - int i = 0; - - /* mmIA_MULTI_VGT_PARAM */ - ptr[i++] = PACKET3(PACKET3_SET_UCONFIG_REG, 1); - ptr[i++] = 0x40000258; - ptr[i++] = 0xd00ff; - - /* mmVGT_PRIMITIVE_TYPE */ - ptr[i++] = PACKET3(PACKET3_SET_UCONFIG_REG, 1); - ptr[i++] = 0x10000242; - ptr[i++] = 0x11; - - ptr[i++] = PACKET3(PACKET3_DRAW_INDEX_AUTO, 1); - ptr[i++] = 3; - ptr[i++] = 2; - - return i; -} - -void amdgpu_memset_draw(amdgpu_device_handle device_handle, - amdgpu_bo_handle bo_shader_ps, - amdgpu_bo_handle bo_shader_vs, - uint64_t mc_address_shader_ps, - uint64_t mc_address_shader_vs, - uint32_t ring_id) -{ - amdgpu_context_handle context_handle; - amdgpu_bo_handle bo_dst, bo_cmd, resources[4]; - volatile unsigned char *ptr_dst; - uint32_t *ptr_cmd; - uint64_t mc_address_dst, mc_address_cmd; - amdgpu_va_handle va_dst, va_cmd; - int i, r; - int bo_dst_size = 16384; - int bo_cmd_size = 4096; - struct amdgpu_cs_request ibs_request = {0}; - struct amdgpu_cs_ib_info ib_info = {0}; - struct amdgpu_cs_fence fence_status = {0}; - uint32_t expired; - amdgpu_bo_list_handle bo_list; - - r = amdgpu_cs_ctx_create(device_handle, &context_handle); - CU_ASSERT_EQUAL(r, 0); - - r = amdgpu_bo_alloc_and_map(device_handle, bo_cmd_size, 4096, - AMDGPU_GEM_DOMAIN_GTT, 0, - &bo_cmd, (void **)&ptr_cmd, - &mc_address_cmd, &va_cmd); - CU_ASSERT_EQUAL(r, 0); - memset(ptr_cmd, 0, bo_cmd_size); - - r = amdgpu_bo_alloc_and_map(device_handle, bo_dst_size, 4096, - AMDGPU_GEM_DOMAIN_VRAM, 0, - &bo_dst, (void **)&ptr_dst, - &mc_address_dst, &va_dst); - CU_ASSERT_EQUAL(r, 0); - - i = 0; - i += amdgpu_draw_init(ptr_cmd + i); - - i += amdgpu_draw_setup_and_write_drawblt_surf_info(ptr_cmd + i, mc_address_dst, 0); - - i += amdgpu_draw_setup_and_write_drawblt_state(ptr_cmd + i, 0); - - i += amdgpu_draw_vs_RectPosTexFast_write2hw(ptr_cmd + i, PS_CONST, mc_address_shader_vs, 0); - - i += amdgpu_draw_ps_write2hw(ptr_cmd + i, PS_CONST, mc_address_shader_ps); - - ptr_cmd[i++] = PACKET3(PKT3_SET_SH_REG, 4); - ptr_cmd[i++] = 0xc; - ptr_cmd[i++] = 0x33333333; - ptr_cmd[i++] = 0x33333333; - ptr_cmd[i++] = 0x33333333; - ptr_cmd[i++] = 0x33333333; - - i += amdgpu_draw_draw(ptr_cmd + i); - - while (i & 7) - ptr_cmd[i++] = 0xffff1000; /* type3 nop packet */ - - resources[0] = bo_dst; - resources[1] = bo_shader_ps; - resources[2] = bo_shader_vs; - resources[3] = bo_cmd; - r = amdgpu_bo_list_create(device_handle, 4, resources, NULL, &bo_list); - CU_ASSERT_EQUAL(r, 0); - - ib_info.ib_mc_address = mc_address_cmd; - ib_info.size = i; - ibs_request.ip_type = AMDGPU_HW_IP_GFX; - ibs_request.ring = ring_id; - ibs_request.resources = bo_list; - ibs_request.number_of_ibs = 1; - ibs_request.ibs = &ib_info; - ibs_request.fence_info.handle = NULL; - - /* submit CS */ - r = amdgpu_cs_submit(context_handle, 0, &ibs_request, 1); - CU_ASSERT_EQUAL(r, 0); - - r = amdgpu_bo_list_destroy(bo_list); - CU_ASSERT_EQUAL(r, 0); - - fence_status.ip_type = AMDGPU_HW_IP_GFX; - fence_status.ip_instance = 0; - fence_status.ring = ring_id; - fence_status.context = context_handle; - fence_status.fence = ibs_request.seq_no; - - /* wait for IB accomplished */ - r = amdgpu_cs_query_fence_status(&fence_status, - AMDGPU_TIMEOUT_INFINITE, - 0, &expired); - CU_ASSERT_EQUAL(r, 0); - CU_ASSERT_EQUAL(expired, true); - - /* verify if memset test result meets with expected */ - i = 0; - while(i < bo_dst_size) { - CU_ASSERT_EQUAL(ptr_dst[i++], 0x33); - } - - r = amdgpu_bo_unmap_and_free(bo_dst, va_dst, mc_address_dst, bo_dst_size); - CU_ASSERT_EQUAL(r, 0); - - r = amdgpu_bo_unmap_and_free(bo_cmd, va_cmd, mc_address_cmd, bo_cmd_size); - CU_ASSERT_EQUAL(r, 0); - - r = amdgpu_cs_ctx_free(context_handle); - CU_ASSERT_EQUAL(r, 0); -} - -static void amdgpu_memset_draw_test(amdgpu_device_handle device_handle, - uint32_t ring) -{ - amdgpu_bo_handle bo_shader_ps, bo_shader_vs; - void *ptr_shader_ps; - void *ptr_shader_vs; - uint64_t mc_address_shader_ps, mc_address_shader_vs; - amdgpu_va_handle va_shader_ps, va_shader_vs; - int r; - int bo_shader_size = 4096; - - r = amdgpu_bo_alloc_and_map(device_handle, bo_shader_size, 4096, - AMDGPU_GEM_DOMAIN_VRAM, 0, - &bo_shader_ps, &ptr_shader_ps, - &mc_address_shader_ps, &va_shader_ps); - CU_ASSERT_EQUAL(r, 0); - memset(ptr_shader_ps, 0, bo_shader_size); - - r = amdgpu_bo_alloc_and_map(device_handle, bo_shader_size, 4096, - AMDGPU_GEM_DOMAIN_VRAM, 0, - &bo_shader_vs, &ptr_shader_vs, - &mc_address_shader_vs, &va_shader_vs); - CU_ASSERT_EQUAL(r, 0); - memset(ptr_shader_vs, 0, bo_shader_size); - - r = amdgpu_draw_load_ps_shader(ptr_shader_ps, PS_CONST); - CU_ASSERT_EQUAL(r, 0); - - r = amdgpu_draw_load_vs_shader(ptr_shader_vs); - CU_ASSERT_EQUAL(r, 0); - - amdgpu_memset_draw(device_handle, bo_shader_ps, bo_shader_vs, - mc_address_shader_ps, mc_address_shader_vs, ring); - - r = amdgpu_bo_unmap_and_free(bo_shader_ps, va_shader_ps, mc_address_shader_ps, bo_shader_size); - CU_ASSERT_EQUAL(r, 0); - - r = amdgpu_bo_unmap_and_free(bo_shader_vs, va_shader_vs, mc_address_shader_vs, bo_shader_size); - CU_ASSERT_EQUAL(r, 0); -} - -static void amdgpu_memcpy_draw(amdgpu_device_handle device_handle, - amdgpu_bo_handle bo_shader_ps, - amdgpu_bo_handle bo_shader_vs, - uint64_t mc_address_shader_ps, - uint64_t mc_address_shader_vs, - uint32_t ring, int hang) -{ - amdgpu_context_handle context_handle; - amdgpu_bo_handle bo_dst, bo_src, bo_cmd, resources[5]; - volatile unsigned char *ptr_dst; - unsigned char *ptr_src; - uint32_t *ptr_cmd; - uint64_t mc_address_dst, mc_address_src, mc_address_cmd; - amdgpu_va_handle va_dst, va_src, va_cmd; - int i, r; - int bo_size = 16384; - int bo_cmd_size = 4096; - struct amdgpu_cs_request ibs_request = {0}; - struct amdgpu_cs_ib_info ib_info= {0}; - uint32_t hang_state, hangs; - uint32_t expired; - amdgpu_bo_list_handle bo_list; - struct amdgpu_cs_fence fence_status = {0}; - - r = amdgpu_cs_ctx_create(device_handle, &context_handle); - CU_ASSERT_EQUAL(r, 0); - - r = amdgpu_bo_alloc_and_map(device_handle, bo_cmd_size, 4096, - AMDGPU_GEM_DOMAIN_GTT, 0, - &bo_cmd, (void **)&ptr_cmd, - &mc_address_cmd, &va_cmd); - CU_ASSERT_EQUAL(r, 0); - memset(ptr_cmd, 0, bo_cmd_size); - - r = amdgpu_bo_alloc_and_map(device_handle, bo_size, 4096, - AMDGPU_GEM_DOMAIN_VRAM, 0, - &bo_src, (void **)&ptr_src, - &mc_address_src, &va_src); - CU_ASSERT_EQUAL(r, 0); - - r = amdgpu_bo_alloc_and_map(device_handle, bo_size, 4096, - AMDGPU_GEM_DOMAIN_VRAM, 0, - &bo_dst, (void **)&ptr_dst, - &mc_address_dst, &va_dst); - CU_ASSERT_EQUAL(r, 0); - - memset(ptr_src, 0x55, bo_size); - - i = 0; - i += amdgpu_draw_init(ptr_cmd + i); - - i += amdgpu_draw_setup_and_write_drawblt_surf_info(ptr_cmd + i, mc_address_dst, 0); - - i += amdgpu_draw_setup_and_write_drawblt_state(ptr_cmd + i, 0); - - i += amdgpu_draw_vs_RectPosTexFast_write2hw(ptr_cmd + i, PS_TEX, mc_address_shader_vs, 0); - - i += amdgpu_draw_ps_write2hw(ptr_cmd + i, PS_TEX, mc_address_shader_ps); - - ptr_cmd[i++] = PACKET3(PKT3_SET_SH_REG, 8); - ptr_cmd[i++] = 0xc; - ptr_cmd[i++] = mc_address_src >> 8; - ptr_cmd[i++] = mc_address_src >> 40 | 0x10e00000; - ptr_cmd[i++] = 0x7c01f; - ptr_cmd[i++] = 0x90500fac; - ptr_cmd[i++] = 0x3e000; - i += 3; - - ptr_cmd[i++] = PACKET3(PKT3_SET_SH_REG, 4); - ptr_cmd[i++] = 0x14; - ptr_cmd[i++] = 0x92; - i += 3; - - ptr_cmd[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1); - ptr_cmd[i++] = 0x191; - ptr_cmd[i++] = 0; - - i += amdgpu_draw_draw(ptr_cmd + i); - - while (i & 7) - ptr_cmd[i++] = 0xffff1000; /* type3 nop packet */ - - resources[0] = bo_dst; - resources[1] = bo_src; - resources[2] = bo_shader_ps; - resources[3] = bo_shader_vs; - resources[4] = bo_cmd; - r = amdgpu_bo_list_create(device_handle, 5, resources, NULL, &bo_list); - CU_ASSERT_EQUAL(r, 0); - - ib_info.ib_mc_address = mc_address_cmd; - ib_info.size = i; - ibs_request.ip_type = AMDGPU_HW_IP_GFX; - ibs_request.ring = ring; - ibs_request.resources = bo_list; - ibs_request.number_of_ibs = 1; - ibs_request.ibs = &ib_info; - ibs_request.fence_info.handle = NULL; - r = amdgpu_cs_submit(context_handle, 0, &ibs_request, 1); - CU_ASSERT_EQUAL(r, 0); - - fence_status.ip_type = AMDGPU_HW_IP_GFX; - fence_status.ip_instance = 0; - fence_status.ring = ring; - fence_status.context = context_handle; - fence_status.fence = ibs_request.seq_no; - - /* wait for IB accomplished */ - r = amdgpu_cs_query_fence_status(&fence_status, - AMDGPU_TIMEOUT_INFINITE, - 0, &expired); - if (!hang) { - CU_ASSERT_EQUAL(r, 0); - CU_ASSERT_EQUAL(expired, true); - - /* verify if memcpy test result meets with expected */ - i = 0; - while(i < bo_size) { - CU_ASSERT_EQUAL(ptr_dst[i], ptr_src[i]); - i++; - } - } else { - r = amdgpu_cs_query_reset_state(context_handle, &hang_state, &hangs); - CU_ASSERT_EQUAL(r, 0); - CU_ASSERT_EQUAL(hang_state, AMDGPU_CTX_UNKNOWN_RESET); - } - - r = amdgpu_bo_list_destroy(bo_list); - CU_ASSERT_EQUAL(r, 0); - - r = amdgpu_bo_unmap_and_free(bo_src, va_src, mc_address_src, bo_size); - CU_ASSERT_EQUAL(r, 0); - r = amdgpu_bo_unmap_and_free(bo_dst, va_dst, mc_address_dst, bo_size); - CU_ASSERT_EQUAL(r, 0); - - r = amdgpu_bo_unmap_and_free(bo_cmd, va_cmd, mc_address_cmd, bo_cmd_size); - CU_ASSERT_EQUAL(r, 0); - - r = amdgpu_cs_ctx_free(context_handle); - CU_ASSERT_EQUAL(r, 0); -} - -void amdgpu_memcpy_draw_test(amdgpu_device_handle device_handle, uint32_t ring, - int hang) -{ - amdgpu_bo_handle bo_shader_ps, bo_shader_vs; - void *ptr_shader_ps; - void *ptr_shader_vs; - uint64_t mc_address_shader_ps, mc_address_shader_vs; - amdgpu_va_handle va_shader_ps, va_shader_vs; - int bo_shader_size = 4096; - enum ps_type ps_type = hang ? PS_HANG : PS_TEX; - int r; - - r = amdgpu_bo_alloc_and_map(device_handle, bo_shader_size, 4096, - AMDGPU_GEM_DOMAIN_VRAM, 0, - &bo_shader_ps, &ptr_shader_ps, - &mc_address_shader_ps, &va_shader_ps); - CU_ASSERT_EQUAL(r, 0); - memset(ptr_shader_ps, 0, bo_shader_size); - - r = amdgpu_bo_alloc_and_map(device_handle, bo_shader_size, 4096, - AMDGPU_GEM_DOMAIN_VRAM, 0, - &bo_shader_vs, &ptr_shader_vs, - &mc_address_shader_vs, &va_shader_vs); - CU_ASSERT_EQUAL(r, 0); - memset(ptr_shader_vs, 0, bo_shader_size); - - r = amdgpu_draw_load_ps_shader(ptr_shader_ps, ps_type); - CU_ASSERT_EQUAL(r, 0); - - r = amdgpu_draw_load_vs_shader(ptr_shader_vs); - CU_ASSERT_EQUAL(r, 0); - - amdgpu_memcpy_draw(device_handle, bo_shader_ps, bo_shader_vs, - mc_address_shader_ps, mc_address_shader_vs, ring, hang); - - r = amdgpu_bo_unmap_and_free(bo_shader_ps, va_shader_ps, mc_address_shader_ps, bo_shader_size); - CU_ASSERT_EQUAL(r, 0); - - r = amdgpu_bo_unmap_and_free(bo_shader_vs, va_shader_vs, mc_address_shader_vs, bo_shader_size); - CU_ASSERT_EQUAL(r, 0); -} - -static void amdgpu_draw_test(void) -{ - int r; - struct drm_amdgpu_info_hw_ip info; - uint32_t ring_id; - - r = amdgpu_query_hw_ip_info(device_handle, AMDGPU_HW_IP_GFX, 0, &info); - CU_ASSERT_EQUAL(r, 0); - if (!info.available_rings) - printf("SKIP ... as there's no graphics ring\n"); - - for (ring_id = 0; (1 << ring_id) & info.available_rings; ring_id++) { - amdgpu_memset_draw_test(device_handle, ring_id); - amdgpu_memcpy_draw_test(device_handle, ring_id, 0); - } -} - -void amdgpu_memcpy_draw_hang_slow_test(amdgpu_device_handle device_handle, uint32_t ring) -{ - amdgpu_context_handle context_handle; - amdgpu_bo_handle bo_shader_ps, bo_shader_vs; - amdgpu_bo_handle bo_dst, bo_src, bo_cmd, resources[5]; - void *ptr_shader_ps; - void *ptr_shader_vs; - volatile unsigned char *ptr_dst; - unsigned char *ptr_src; - uint32_t *ptr_cmd; - uint64_t mc_address_dst, mc_address_src, mc_address_cmd; - uint64_t mc_address_shader_ps, mc_address_shader_vs; - amdgpu_va_handle va_shader_ps, va_shader_vs; - amdgpu_va_handle va_dst, va_src, va_cmd; - struct amdgpu_gpu_info gpu_info = {0}; - int i, r; - int bo_size = 0x4000000; - int bo_shader_ps_size = 0x400000; - int bo_shader_vs_size = 4096; - int bo_cmd_size = 4096; - struct amdgpu_cs_request ibs_request = {0}; - struct amdgpu_cs_ib_info ib_info= {0}; - uint32_t hang_state, hangs, expired; - amdgpu_bo_list_handle bo_list; - struct amdgpu_cs_fence fence_status = {0}; - - r = amdgpu_query_gpu_info(device_handle, &gpu_info); - CU_ASSERT_EQUAL(r, 0); - - r = amdgpu_cs_ctx_create(device_handle, &context_handle); - CU_ASSERT_EQUAL(r, 0); - - r = amdgpu_bo_alloc_and_map(device_handle, bo_cmd_size, 4096, - AMDGPU_GEM_DOMAIN_GTT, 0, - &bo_cmd, (void **)&ptr_cmd, - &mc_address_cmd, &va_cmd); - CU_ASSERT_EQUAL(r, 0); - memset(ptr_cmd, 0, bo_cmd_size); - - r = amdgpu_bo_alloc_and_map(device_handle, bo_shader_ps_size, 4096, - AMDGPU_GEM_DOMAIN_VRAM, 0, - &bo_shader_ps, &ptr_shader_ps, - &mc_address_shader_ps, &va_shader_ps); - CU_ASSERT_EQUAL(r, 0); - memset(ptr_shader_ps, 0, bo_shader_ps_size); - - r = amdgpu_bo_alloc_and_map(device_handle, bo_shader_vs_size, 4096, - AMDGPU_GEM_DOMAIN_VRAM, 0, - &bo_shader_vs, &ptr_shader_vs, - &mc_address_shader_vs, &va_shader_vs); - CU_ASSERT_EQUAL(r, 0); - memset(ptr_shader_vs, 0, bo_shader_vs_size); - - r = amdgpu_draw_load_ps_shader_hang_slow(ptr_shader_ps, gpu_info.family_id); - CU_ASSERT_EQUAL(r, 0); - - r = amdgpu_draw_load_vs_shader(ptr_shader_vs); - CU_ASSERT_EQUAL(r, 0); - - r = amdgpu_bo_alloc_and_map(device_handle, bo_size, 4096, - AMDGPU_GEM_DOMAIN_VRAM, 0, - &bo_src, (void **)&ptr_src, - &mc_address_src, &va_src); - CU_ASSERT_EQUAL(r, 0); - - r = amdgpu_bo_alloc_and_map(device_handle, bo_size, 4096, - AMDGPU_GEM_DOMAIN_VRAM, 0, - &bo_dst, (void **)&ptr_dst, - &mc_address_dst, &va_dst); - CU_ASSERT_EQUAL(r, 0); - - memset(ptr_src, 0x55, bo_size); - - i = 0; - i += amdgpu_draw_init(ptr_cmd + i); - - i += amdgpu_draw_setup_and_write_drawblt_surf_info(ptr_cmd + i, mc_address_dst, 1); - - i += amdgpu_draw_setup_and_write_drawblt_state(ptr_cmd + i, 1); - - i += amdgpu_draw_vs_RectPosTexFast_write2hw(ptr_cmd + i, PS_TEX, - mc_address_shader_vs, 1); - - i += amdgpu_draw_ps_write2hw(ptr_cmd + i, PS_TEX, mc_address_shader_ps); - - ptr_cmd[i++] = PACKET3(PKT3_SET_SH_REG, 8); - ptr_cmd[i++] = 0xc; - ptr_cmd[i++] = mc_address_src >> 8; - ptr_cmd[i++] = mc_address_src >> 40 | 0x10e00000; - ptr_cmd[i++] = 0x1ffc7ff; - ptr_cmd[i++] = 0x90500fac; - ptr_cmd[i++] = 0xffe000; - i += 3; - - ptr_cmd[i++] = PACKET3(PKT3_SET_SH_REG, 4); - ptr_cmd[i++] = 0x14; - ptr_cmd[i++] = 0x92; - i += 3; - - ptr_cmd[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1); - ptr_cmd[i++] = 0x191; - ptr_cmd[i++] = 0; - - i += amdgpu_draw_draw(ptr_cmd + i); - - while (i & 7) - ptr_cmd[i++] = 0xffff1000; /* type3 nop packet */ - - resources[0] = bo_dst; - resources[1] = bo_src; - resources[2] = bo_shader_ps; - resources[3] = bo_shader_vs; - resources[4] = bo_cmd; - r = amdgpu_bo_list_create(device_handle, 5, resources, NULL, &bo_list); - CU_ASSERT_EQUAL(r, 0); - - ib_info.ib_mc_address = mc_address_cmd; - ib_info.size = i; - ibs_request.ip_type = AMDGPU_HW_IP_GFX; - ibs_request.ring = ring; - ibs_request.resources = bo_list; - ibs_request.number_of_ibs = 1; - ibs_request.ibs = &ib_info; - ibs_request.fence_info.handle = NULL; - r = amdgpu_cs_submit(context_handle, 0, &ibs_request, 1); - CU_ASSERT_EQUAL(r, 0); - - fence_status.ip_type = AMDGPU_HW_IP_GFX; - fence_status.ip_instance = 0; - fence_status.ring = ring; - fence_status.context = context_handle; - fence_status.fence = ibs_request.seq_no; - - /* wait for IB accomplished */ - r = amdgpu_cs_query_fence_status(&fence_status, - AMDGPU_TIMEOUT_INFINITE, - 0, &expired); - - r = amdgpu_cs_query_reset_state(context_handle, &hang_state, &hangs); - CU_ASSERT_EQUAL(r, 0); - CU_ASSERT_EQUAL(hang_state, AMDGPU_CTX_UNKNOWN_RESET); - - r = amdgpu_bo_list_destroy(bo_list); - CU_ASSERT_EQUAL(r, 0); - - r = amdgpu_bo_unmap_and_free(bo_dst, va_dst, mc_address_dst, bo_size); - CU_ASSERT_EQUAL(r, 0); - r = amdgpu_bo_unmap_and_free(bo_src, va_src, mc_address_src, bo_size); - CU_ASSERT_EQUAL(r, 0); - - r = amdgpu_bo_unmap_and_free(bo_cmd, va_cmd, mc_address_cmd, bo_cmd_size); - CU_ASSERT_EQUAL(r, 0); - - r = amdgpu_bo_unmap_and_free(bo_shader_ps, va_shader_ps, mc_address_shader_ps, bo_shader_ps_size); - CU_ASSERT_EQUAL(r, 0); - r = amdgpu_bo_unmap_and_free(bo_shader_vs, va_shader_vs, mc_address_shader_vs, bo_shader_vs_size); - CU_ASSERT_EQUAL(r, 0); - - r = amdgpu_cs_ctx_free(context_handle); - CU_ASSERT_EQUAL(r, 0); -} - static void amdgpu_gpu_reset_test(void) { int r; diff -Nru libdrm-2.4.110/tests/amdgpu/cp_dma_tests.c libdrm-2.4.113/tests/amdgpu/cp_dma_tests.c --- libdrm-2.4.110/tests/amdgpu/cp_dma_tests.c 1970-01-01 00:00:00.000000000 +0000 +++ libdrm-2.4.113/tests/amdgpu/cp_dma_tests.c 2022-08-31 14:38:38.000000000 +0000 @@ -0,0 +1,533 @@ +/* + * Copyright 2022 Advanced Micro Devices, Inc. + * + * 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 +#include +#include +#include + +#include "CUnit/Basic.h" + +#include "amdgpu_test.h" +#include "amdgpu_drm.h" +#include "amdgpu_internal.h" + +#define IB_SIZE 4096 +#define MAX_RESOURCES 8 + +#define DMA_SIZE 4097 +#define DMA_DATA_BYTE 0xea + +static bool do_p2p; + +static amdgpu_device_handle executing_device_handle; +static uint32_t executing_device_major_version; +static uint32_t executing_device_minor_version; + +static amdgpu_device_handle peer_exporting_device_handle; +static uint32_t peer_exporting_device_major_version; +static uint32_t peer_exporting_device_minor_version; + +static amdgpu_context_handle context_handle; +static amdgpu_bo_handle ib_handle; +static uint32_t *ib_cpu; +static uint64_t ib_mc_address; +static amdgpu_va_handle ib_va_handle; +static uint32_t num_dword; + +static amdgpu_bo_handle resources[MAX_RESOURCES]; +static unsigned num_resources; + +static uint8_t* reference_data; + +static void amdgpu_cp_dma_host_to_vram(void); +static void amdgpu_cp_dma_vram_to_host(void); +static void amdgpu_cp_dma_p2p_vram_to_vram(void); +static void amdgpu_cp_dma_p2p_host_to_vram(void); +static void amdgpu_cp_dma_p2p_vram_to_host(void); + +/** + * Tests in cp dma test suite + */ +CU_TestInfo cp_dma_tests[] = { + { "CP DMA write Host to VRAM", amdgpu_cp_dma_host_to_vram }, + { "CP DMA write VRAM to Host", amdgpu_cp_dma_vram_to_host }, + + { "Peer to Peer CP DMA write VRAM to VRAM", amdgpu_cp_dma_p2p_vram_to_vram }, + { "Peer to Peer CP DMA write Host to VRAM", amdgpu_cp_dma_p2p_host_to_vram }, + { "Peer to Peer CP DMA write VRAM to Host", amdgpu_cp_dma_p2p_vram_to_host }, + CU_TEST_INFO_NULL, +}; + +struct amdgpu_cp_dma_bo{ + amdgpu_bo_handle buf_handle; + amdgpu_va_handle va_handle; + uint64_t gpu_va; + uint64_t size; +}; + +static int allocate_bo_and_va(amdgpu_device_handle dev, + uint64_t size, uint64_t alignment, + uint32_t heap, uint64_t alloc_flags, + struct amdgpu_cp_dma_bo *bo) { + struct amdgpu_bo_alloc_request request = {}; + amdgpu_bo_handle buf_handle; + amdgpu_va_handle va_handle; + uint64_t vmc_addr; + int r; + + request.alloc_size = size; + request.phys_alignment = alignment; + request.preferred_heap = heap; + request.flags = alloc_flags; + + r = amdgpu_bo_alloc(dev, &request, &buf_handle); + if (r) + goto error_bo_alloc; + + r = amdgpu_va_range_alloc(dev, amdgpu_gpu_va_range_general, + size, alignment, 0, + &vmc_addr, &va_handle, 0); + if (r) + goto error_va_alloc; + + r = amdgpu_bo_va_op(buf_handle, 0, size, vmc_addr, + AMDGPU_VM_PAGE_READABLE | + AMDGPU_VM_PAGE_WRITEABLE | + AMDGPU_VM_PAGE_EXECUTABLE, + AMDGPU_VA_OP_MAP); + if (r) + goto error_va_map; + + bo->buf_handle = buf_handle; + bo->va_handle = va_handle; + bo->gpu_va = vmc_addr; + bo->size = size; + + return 0; + +error_va_map: + amdgpu_bo_va_op(buf_handle, 0, + size, vmc_addr, 0, AMDGPU_VA_OP_UNMAP); + +error_va_alloc: + amdgpu_va_range_free(va_handle); + +error_bo_alloc: + amdgpu_bo_free(buf_handle); + + return r; +} + +static int import_dma_buf_to_bo(amdgpu_device_handle dev, + int dmabuf_fd, struct amdgpu_cp_dma_bo *bo) { + amdgpu_va_handle va_handle; + uint64_t vmc_addr; + int r; + struct amdgpu_bo_import_result bo_import_result = {}; + + r = amdgpu_bo_import(dev, amdgpu_bo_handle_type_dma_buf_fd, + dmabuf_fd, &bo_import_result); + if (r) + goto error_bo_import; + + r = amdgpu_va_range_alloc(dev, amdgpu_gpu_va_range_general, + bo_import_result.alloc_size, 0, 0, + &vmc_addr, &va_handle, 0); + if (r) + goto error_va_alloc; + + r = amdgpu_bo_va_op(bo_import_result.buf_handle, 0, + bo_import_result.alloc_size, vmc_addr, + AMDGPU_VM_PAGE_READABLE | + AMDGPU_VM_PAGE_WRITEABLE | + AMDGPU_VM_PAGE_EXECUTABLE, + AMDGPU_VA_OP_MAP); + if (r) + goto error_va_map; + + bo->buf_handle = bo_import_result.buf_handle; + bo->va_handle = va_handle; + bo->gpu_va = vmc_addr; + bo->size = bo_import_result.alloc_size; + + return 0; + +error_va_map: + amdgpu_bo_va_op(bo_import_result.buf_handle, 0, + bo_import_result.alloc_size, vmc_addr, 0, AMDGPU_VA_OP_UNMAP); + +error_va_alloc: + amdgpu_va_range_free(va_handle); + +error_bo_import: + amdgpu_bo_free(bo_import_result.buf_handle); + + return r; +} + +static int free_bo(struct amdgpu_cp_dma_bo bo) { + int r; + r = amdgpu_bo_va_op(bo.buf_handle, 0, + bo.size, bo.gpu_va, 0, AMDGPU_VA_OP_UNMAP); + if(r) + return r; + + r = amdgpu_va_range_free(bo.va_handle); + if(r) + return r; + + r = amdgpu_bo_free(bo.buf_handle); + if(r) + return r; + + return 0; +} + +static int submit_and_sync() { + struct amdgpu_cs_request ibs_request = {0}; + struct amdgpu_cs_ib_info ib_info = {0}; + struct amdgpu_cs_fence fence_status = {0}; + uint32_t expired; + uint32_t family_id, chip_id, chip_rev; + unsigned gc_ip_type; + int r; + + r = amdgpu_bo_list_create(executing_device_handle, + num_resources, resources, + NULL, &ibs_request.resources); + if (r) + return r; + + family_id = executing_device_handle->info.family_id; + chip_id = executing_device_handle->info.chip_external_rev; + chip_rev = executing_device_handle->info.chip_rev; + + gc_ip_type = (asic_is_gfx_pipe_removed(family_id, chip_id, chip_rev)) ? + AMDGPU_HW_IP_COMPUTE : AMDGPU_HW_IP_GFX; + + ib_info.ib_mc_address = ib_mc_address; + ib_info.size = num_dword; + + ibs_request.ip_type = gc_ip_type; + ibs_request.number_of_ibs = 1; + ibs_request.ibs = &ib_info; + ibs_request.fence_info.handle = NULL; + + r = amdgpu_cs_submit(context_handle, 0, &ibs_request, 1); + if (r) + return r; + + r = amdgpu_bo_list_destroy(ibs_request.resources); + if (r) + return r; + + fence_status.context = context_handle; + fence_status.ip_type = gc_ip_type; + fence_status.fence = ibs_request.seq_no; + + r = amdgpu_cs_query_fence_status(&fence_status, + AMDGPU_TIMEOUT_INFINITE, + 0, &expired); + if (r) + return r; + + return 0; +} + +static void cp_dma_cmd(struct amdgpu_cp_dma_bo src_bo, + struct amdgpu_cp_dma_bo dst_bo) { + _Static_assert(DMA_SIZE < (1 << 26), "DMA size exceeds CP DMA maximium!"); + + ib_cpu[0] = 0xc0055000; + ib_cpu[1] = 0x80000000; + ib_cpu[2] = src_bo.gpu_va & 0x00000000ffffffff; + ib_cpu[3] = (src_bo.gpu_va & 0xffffffff00000000) >> 32; + ib_cpu[4] = dst_bo.gpu_va & 0x00000000ffffffff; + ib_cpu[5] = (dst_bo.gpu_va & 0xffffffff00000000) >> 32; + // size is read from the lower 26bits. + ib_cpu[6] = ((1 << 26) - 1) & DMA_SIZE; + ib_cpu[7] = 0xffff1000; + + num_dword = 8; + + resources[0] = src_bo.buf_handle; + resources[1] = dst_bo.buf_handle; + resources[2] = ib_handle; + num_resources = 3; +} + +static void amdgpu_cp_dma(uint32_t src_heap, uint32_t dst_heap) { + int r; + struct amdgpu_cp_dma_bo src_bo = {0}; + struct amdgpu_cp_dma_bo dst_bo = {0}; + void *src_bo_cpu; + void *dst_bo_cpu; + + /* allocate the src bo, set its data to DMA_DATA_BYTE */ + r = allocate_bo_and_va(executing_device_handle, DMA_SIZE, 4096, + src_heap, AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED, &src_bo); + CU_ASSERT_EQUAL(r, 0); + + r = amdgpu_bo_cpu_map(src_bo.buf_handle, (void **)&src_bo_cpu); + CU_ASSERT_EQUAL(r, 0); + memset(src_bo_cpu, DMA_DATA_BYTE, DMA_SIZE); + + r = amdgpu_bo_cpu_unmap(src_bo.buf_handle); + CU_ASSERT_EQUAL(r, 0); + + /* allocate the dst bo and clear its content to all 0 */ + r = allocate_bo_and_va(executing_device_handle, DMA_SIZE, 4096, + dst_heap, AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED, &dst_bo); + CU_ASSERT_EQUAL(r, 0); + + r = amdgpu_bo_cpu_map(dst_bo.buf_handle, (void **)&dst_bo_cpu); + CU_ASSERT_EQUAL(r, 0); + + _Static_assert(DMA_DATA_BYTE != 0, "Initialization data should be different from DMA data!"); + memset(dst_bo_cpu, 0, DMA_SIZE); + + /* record CP DMA command and dispatch the command */ + cp_dma_cmd(src_bo, dst_bo); + + r = submit_and_sync(); + CU_ASSERT_EQUAL(r, 0); + + /* verify the dst bo is filled with DMA_DATA_BYTE */ + CU_ASSERT_EQUAL(memcmp(dst_bo_cpu, reference_data, DMA_SIZE) == 0, true); + + r = amdgpu_bo_cpu_unmap(dst_bo.buf_handle); + CU_ASSERT_EQUAL(r, 0); + + r = free_bo(src_bo); + CU_ASSERT_EQUAL(r, 0); + + r = free_bo(dst_bo); + CU_ASSERT_EQUAL(r, 0); +} + +static void amdgpu_cp_dma_p2p(uint32_t src_heap, uint32_t dst_heap) { + int r; + struct amdgpu_cp_dma_bo exported_bo = {0}; + int dma_buf_fd; + int dma_buf_fd_dup; + struct amdgpu_cp_dma_bo src_bo = {0}; + struct amdgpu_cp_dma_bo imported_dst_bo = {0}; + void *exported_bo_cpu; + void *src_bo_cpu; + + /* allocate a bo on the peer device and export it to dma-buf */ + r = allocate_bo_and_va(peer_exporting_device_handle, DMA_SIZE, 4096, + src_heap, AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED, &exported_bo); + CU_ASSERT_EQUAL(r, 0); + + /* map the exported bo and clear its content to 0 */ + _Static_assert(DMA_DATA_BYTE != 0, "Initialization data should be different from DMA data!"); + r = amdgpu_bo_cpu_map(exported_bo.buf_handle, (void **)&exported_bo_cpu); + CU_ASSERT_EQUAL(r, 0); + memset(exported_bo_cpu, 0, DMA_SIZE); + + r = amdgpu_bo_export(exported_bo.buf_handle, + amdgpu_bo_handle_type_dma_buf_fd, (uint32_t*)&dma_buf_fd); + CU_ASSERT_EQUAL(r, 0); + + // According to amdgpu_drm: + // "Buffer must be "imported" only using new "fd" + // (different from one used by "exporter")" + dma_buf_fd_dup = dup(dma_buf_fd); + r = close(dma_buf_fd); + CU_ASSERT_EQUAL(r, 0); + + /* import the dma-buf to the executing device, imported bo is the DMA destination */ + r = import_dma_buf_to_bo( + executing_device_handle, dma_buf_fd_dup, &imported_dst_bo); + CU_ASSERT_EQUAL(r, 0); + + r = close(dma_buf_fd_dup); + CU_ASSERT_EQUAL(r, 0); + + /* allocate the src bo and set its content to DMA_DATA_BYTE */ + r = allocate_bo_and_va(executing_device_handle, DMA_SIZE, 4096, + dst_heap, AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED, &src_bo); + CU_ASSERT_EQUAL(r, 0); + + r = amdgpu_bo_cpu_map(src_bo.buf_handle, (void **)&src_bo_cpu); + CU_ASSERT_EQUAL(r, 0); + + memset(src_bo_cpu, DMA_DATA_BYTE, DMA_SIZE); + + r = amdgpu_bo_cpu_unmap(src_bo.buf_handle); + CU_ASSERT_EQUAL(r, 0); + + /* record CP DMA command and dispatch the command */ + cp_dma_cmd(src_bo, imported_dst_bo); + + r = submit_and_sync(); + CU_ASSERT_EQUAL(r, 0); + + /* verify the bo from the peer device is filled with DMA_DATA_BYTE */ + CU_ASSERT_EQUAL(memcmp(exported_bo_cpu, reference_data, DMA_SIZE) == 0, true); + + r = amdgpu_bo_cpu_unmap(exported_bo.buf_handle); + CU_ASSERT_EQUAL(r, 0); + + r = free_bo(exported_bo); + CU_ASSERT_EQUAL(r, 0); + + r = free_bo(imported_dst_bo); + CU_ASSERT_EQUAL(r, 0); + + r = free_bo(src_bo); + CU_ASSERT_EQUAL(r, 0); +} + +static void amdgpu_cp_dma_host_to_vram(void) { + amdgpu_cp_dma(AMDGPU_GEM_DOMAIN_GTT, AMDGPU_GEM_DOMAIN_VRAM); +} + +static void amdgpu_cp_dma_vram_to_host(void) { + amdgpu_cp_dma(AMDGPU_GEM_DOMAIN_VRAM, AMDGPU_GEM_DOMAIN_GTT); +} + +static void amdgpu_cp_dma_p2p_vram_to_vram(void) { + amdgpu_cp_dma_p2p(AMDGPU_GEM_DOMAIN_VRAM, AMDGPU_GEM_DOMAIN_VRAM); +} + +static void amdgpu_cp_dma_p2p_host_to_vram(void) { + amdgpu_cp_dma_p2p(AMDGPU_GEM_DOMAIN_GTT, AMDGPU_GEM_DOMAIN_VRAM); +} + +static void amdgpu_cp_dma_p2p_vram_to_host(void) { + amdgpu_cp_dma_p2p(AMDGPU_GEM_DOMAIN_VRAM, AMDGPU_GEM_DOMAIN_GTT); +} + +int suite_cp_dma_tests_init() { + int r; + + r = amdgpu_device_initialize(drm_amdgpu[0], + &executing_device_major_version, + &executing_device_minor_version, + &executing_device_handle); + if (r) + return CUE_SINIT_FAILED; + + r = amdgpu_cs_ctx_create(executing_device_handle, &context_handle); + if (r) + return CUE_SINIT_FAILED; + + r = amdgpu_bo_alloc_and_map(executing_device_handle, IB_SIZE, 4096, + AMDGPU_GEM_DOMAIN_GTT, 0, + &ib_handle, (void**)&ib_cpu, + &ib_mc_address, &ib_va_handle); + if (r) + return CUE_SINIT_FAILED; + + if (do_p2p) { + r = amdgpu_device_initialize(drm_amdgpu[1], + &peer_exporting_device_major_version, + &peer_exporting_device_minor_version, + &peer_exporting_device_handle); + + if (r) + return CUE_SINIT_FAILED; + } + + reference_data = (uint8_t*)malloc(DMA_SIZE); + if (!reference_data) + return CUE_SINIT_FAILED; + memset(reference_data, DMA_DATA_BYTE, DMA_SIZE); + + return CUE_SUCCESS; +} + +int suite_cp_dma_tests_clean() { + int r; + + free(reference_data); + + r = amdgpu_bo_unmap_and_free(ib_handle, ib_va_handle, + ib_mc_address, IB_SIZE); + if (r) + return CUE_SCLEAN_FAILED; + + r = amdgpu_cs_ctx_free(context_handle); + if (r) + return CUE_SCLEAN_FAILED; + + r = amdgpu_device_deinitialize(executing_device_handle); + if (r) + return CUE_SCLEAN_FAILED; + + if (do_p2p) { + r = amdgpu_device_deinitialize(peer_exporting_device_handle); + if (r) + return CUE_SCLEAN_FAILED; + } + + return CUE_SUCCESS; +} + +CU_BOOL suite_cp_dma_tests_enable(void) { + int r = 0; + + if (amdgpu_device_initialize(drm_amdgpu[0], + &executing_device_major_version, + &executing_device_minor_version, + &executing_device_handle)) + return CU_FALSE; + + if (!(executing_device_handle->info.family_id >= AMDGPU_FAMILY_AI && + executing_device_handle->info.family_id <= AMDGPU_FAMILY_NV)) { + printf("Testing device has ASIC that is not supported by CP-DMA test suite!\n"); + return CU_FALSE; + } + + if (amdgpu_device_deinitialize(executing_device_handle)) + return CU_FALSE; + + if (drm_amdgpu[1] >= 0) { + r = amdgpu_device_initialize(drm_amdgpu[1], + &peer_exporting_device_major_version, + &peer_exporting_device_minor_version, + &peer_exporting_device_handle); + + if (r == 0 && (peer_exporting_device_handle->info.family_id >= AMDGPU_FAMILY_AI && + peer_exporting_device_handle->info.family_id <= AMDGPU_FAMILY_NV)) { + do_p2p = true; + } + + if (r == 0 && amdgpu_device_deinitialize(peer_exporting_device_handle) != 0) { + printf("Deinitialize peer_exporting_device_handle failed!\n"); + return CU_FALSE; + } + } + + if (!do_p2p) { + amdgpu_set_test_active("CP DMA Tests", "Peer to Peer CP DMA write VRAM to VRAM", CU_FALSE); + amdgpu_set_test_active("CP DMA Tests", "Peer to Peer CP DMA write Host to VRAM", CU_FALSE); + amdgpu_set_test_active("CP DMA Tests", "Peer to Peer CP DMA write VRAM to Host", CU_FALSE); + printf("Peer device is not opened or has ASIC not supported by the suite, skip all Peer to Peer tests.\n"); + } + + return CU_TRUE; +} diff -Nru libdrm-2.4.110/tests/amdgpu/deadlock_tests.c libdrm-2.4.113/tests/amdgpu/deadlock_tests.c --- libdrm-2.4.110/tests/amdgpu/deadlock_tests.c 2022-02-16 10:00:13.000000000 +0000 +++ libdrm-2.4.113/tests/amdgpu/deadlock_tests.c 2022-08-31 14:38:38.000000000 +0000 @@ -124,6 +124,8 @@ static void amdgpu_dispatch_hang_slow_compute(void); static void amdgpu_draw_hang_gfx(void); static void amdgpu_draw_hang_slow_gfx(void); +static void amdgpu_hang_sdma(void); +static void amdgpu_hang_slow_sdma(void); CU_BOOL suite_deadlock_tests_enable(void) { @@ -139,11 +141,13 @@ /* * Only enable for ASICs supporting GPU reset and for which it's enabled - * by default (currently GFX8/9 dGPUS) + * by default (currently GFX8+ dGPUS and gfx9+ APUs). Note that Raven1 + * did not support GPU reset, but newer variants do. */ - if (family_id != AMDGPU_FAMILY_VI && - family_id != AMDGPU_FAMILY_AI && - family_id != AMDGPU_FAMILY_CI) { + if (family_id == AMDGPU_FAMILY_SI || + family_id == AMDGPU_FAMILY_KV || + family_id == AMDGPU_FAMILY_CZ || + family_id == AMDGPU_FAMILY_RV) { printf("\n\nGPU reset is not enabled for the ASIC, deadlock suite disabled\n"); enable = CU_FALSE; } @@ -206,6 +210,8 @@ { "compute ring bad slow dispatch test (set amdgpu.lockup_timeout=50,50)", amdgpu_dispatch_hang_slow_compute }, { "gfx ring bad draw test (set amdgpu.lockup_timeout=50)", amdgpu_draw_hang_gfx }, { "gfx ring slow bad draw test (set amdgpu.lockup_timeout=50)", amdgpu_draw_hang_slow_gfx }, + { "sdma ring corrupted header test (set amdgpu.lockup_timeout=50)", amdgpu_hang_sdma }, + { "sdma ring slow linear copy test (set amdgpu.lockup_timeout=50)", amdgpu_hang_slow_sdma }, CU_TEST_INFO_NULL, }; @@ -509,54 +515,182 @@ static void amdgpu_dispatch_hang_gfx(void) { - amdgpu_dispatch_hang_helper(device_handle, AMDGPU_HW_IP_GFX); + amdgpu_test_dispatch_hang_helper(device_handle, AMDGPU_HW_IP_GFX); } - static void amdgpu_dispatch_hang_compute(void) { - amdgpu_dispatch_hang_helper(device_handle, AMDGPU_HW_IP_COMPUTE); + amdgpu_test_dispatch_hang_helper(device_handle, AMDGPU_HW_IP_COMPUTE); } - static void amdgpu_dispatch_hang_slow_gfx(void) { - amdgpu_dispatch_hang_slow_helper(device_handle, AMDGPU_HW_IP_GFX); + amdgpu_test_dispatch_hang_slow_helper(device_handle, AMDGPU_HW_IP_GFX); } - static void amdgpu_dispatch_hang_slow_compute(void) { - amdgpu_dispatch_hang_slow_helper(device_handle, AMDGPU_HW_IP_COMPUTE); + amdgpu_test_dispatch_hang_slow_helper(device_handle, AMDGPU_HW_IP_COMPUTE); } - static void amdgpu_draw_hang_gfx(void) { - int r; - struct drm_amdgpu_info_hw_ip info; - uint32_t ring_id; + amdgpu_test_draw_hang_helper(device_handle); +} +static void amdgpu_draw_hang_slow_gfx(void) +{ + amdgpu_test_draw_hang_slow_helper(device_handle); +} - r = amdgpu_query_hw_ip_info(device_handle, AMDGPU_HW_IP_GFX, 0, &info); +#define DMA_CORRUPTED_HEADER_HANG 1 +#define DMA_SLOW_LINEARCOPY_HANG 2 + +static void amdgpu_hang_sdma_helper(unsigned hang_type) +{ + const int sdma_write_length = 1024; + amdgpu_context_handle context_handle; + amdgpu_bo_handle ib_result_handle; + amdgpu_bo_handle bo1, bo2; + amdgpu_bo_handle resources[3]; + amdgpu_bo_list_handle bo_list; + void *ib_result_cpu; + struct amdgpu_cs_ib_info ib_info; + struct amdgpu_cs_request ibs_request; + struct amdgpu_cs_fence fence_status; + uint64_t bo1_mc, bo2_mc; + uint64_t ib_result_mc_address; + volatile unsigned char *bo1_cpu, *bo2_cpu; + amdgpu_va_handle bo1_va_handle, bo2_va_handle; + amdgpu_va_handle va_handle; + struct drm_amdgpu_info_hw_ip hw_ip_info; + int i, j, r; + uint32_t expired, ib_size; + + r = amdgpu_query_hw_ip_info(device_handle, AMDGPU_HW_IP_DMA, 0, &hw_ip_info); CU_ASSERT_EQUAL(r, 0); - if (!info.available_rings) - printf("SKIP ... as there's no graphic ring\n"); - for (ring_id = 0; (1 << ring_id) & info.available_rings; ring_id++) { - amdgpu_memcpy_draw_test(device_handle, ring_id, 0); - amdgpu_memcpy_draw_test(device_handle, ring_id, 1); - amdgpu_memcpy_draw_test(device_handle, ring_id, 0); - } -} + r = amdgpu_cs_ctx_create(device_handle, &context_handle); + CU_ASSERT_EQUAL(r, 0); -static void amdgpu_draw_hang_slow_gfx(void) -{ - struct drm_amdgpu_info_hw_ip info; - uint32_t ring_id; - int r; + if (hang_type == DMA_CORRUPTED_HEADER_HANG) + ib_size = 4096; + else + ib_size = 4096 * 0x20000; - r = amdgpu_query_hw_ip_info(device_handle, AMDGPU_HW_IP_GFX, 0, &info); + r = amdgpu_bo_alloc_and_map(device_handle, ib_size, 4096, + AMDGPU_GEM_DOMAIN_GTT, 0, + &ib_result_handle, &ib_result_cpu, + &ib_result_mc_address, &va_handle); CU_ASSERT_EQUAL(r, 0); - for (ring_id = 0; (1 << ring_id) & info.available_rings; ring_id++) { - amdgpu_memcpy_draw_test(device_handle, ring_id, 0); - amdgpu_memcpy_draw_hang_slow_test(device_handle, ring_id); - amdgpu_memcpy_draw_test(device_handle, ring_id, 0); + r = amdgpu_bo_alloc_and_map(device_handle, + sdma_write_length, 4096, + AMDGPU_GEM_DOMAIN_GTT, + 0, &bo1, + (void**)&bo1_cpu, &bo1_mc, + &bo1_va_handle); + CU_ASSERT_EQUAL(r, 0); + + /* set bo1 */ + memset((void*)bo1_cpu, 0xaa, sdma_write_length); + + /* allocate UC bo2 for sDMA use */ + r = amdgpu_bo_alloc_and_map(device_handle, + sdma_write_length, 4096, + AMDGPU_GEM_DOMAIN_GTT, + 0, &bo2, + (void**)&bo2_cpu, &bo2_mc, + &bo2_va_handle); + CU_ASSERT_EQUAL(r, 0); + + /* clear bo2 */ + memset((void*)bo2_cpu, 0, sdma_write_length); + + resources[0] = bo1; + resources[1] = bo2; + resources[2] = ib_result_handle; + r = amdgpu_bo_list_create(device_handle, 3, + resources, NULL, &bo_list); + + /* fulfill PM4: with bad copy linear header */ + ptr = ib_result_cpu; + i = 0; + if (hang_type == DMA_CORRUPTED_HEADER_HANG) { + ptr[i++] = 0x23decd3d; + ptr[i++] = sdma_write_length - 1; + ptr[i++] = 0; + ptr[i++] = 0xffffffff & bo1_mc; + ptr[i++] = (0xffffffff00000000 & bo1_mc) >> 32; + ptr[i++] = 0xffffffff & bo2_mc; + ptr[i++] = (0xffffffff00000000 & bo2_mc) >> 32; + } else { + for (j = 1; j < 0x20000; j++) { + ptr[i++] = 0x1; + ptr[i++] = sdma_write_length - 1; + ptr[i++] = 0; + ptr[i++] = 0xffffffff & bo1_mc; + ptr[i++] = (0xffffffff00000000 & bo1_mc) >> 32; + ptr[i++] = 0xffffffff & bo2_mc; + ptr[i++] = (0xffffffff00000000 & bo2_mc) >> 32; + ptr[i++] = 0x1; + ptr[i++] = sdma_write_length - 1; + ptr[i++] = 0; + ptr[i++] = 0xffffffff & bo2_mc; + ptr[i++] = (0xffffffff00000000 & bo2_mc) >> 32; + ptr[i++] = 0xffffffff & bo1_mc; + ptr[i++] = (0xffffffff00000000 & bo1_mc) >> 32; + } } + + /* exec command */ + memset(&ib_info, 0, sizeof(struct amdgpu_cs_ib_info)); + ib_info.ib_mc_address = ib_result_mc_address; + ib_info.size = i; + + memset(&ibs_request, 0, sizeof(struct amdgpu_cs_request)); + ibs_request.ip_type = AMDGPU_HW_IP_DMA; + ibs_request.ring = 0; + ibs_request.number_of_ibs = 1; + ibs_request.ibs = &ib_info; + ibs_request.resources = bo_list; + ibs_request.fence_info.handle = NULL; + + r = amdgpu_cs_submit(context_handle, 0, &ibs_request, 1); + CU_ASSERT_EQUAL(r, 0); + + memset(&fence_status, 0, sizeof(struct amdgpu_cs_fence)); + fence_status.context = context_handle; + fence_status.ip_type = AMDGPU_HW_IP_DMA; + fence_status.ip_instance = 0; + fence_status.ring = 0; + fence_status.fence = ibs_request.seq_no; + + r = amdgpu_cs_query_fence_status(&fence_status, + AMDGPU_TIMEOUT_INFINITE, + 0, &expired); + CU_ASSERT_EQUAL((r == 0 || r == -ECANCELED), 1); + + r = amdgpu_bo_list_destroy(bo_list); + CU_ASSERT_EQUAL(r, 0); + + r = amdgpu_bo_unmap_and_free(ib_result_handle, va_handle, + ib_result_mc_address, 4096); + CU_ASSERT_EQUAL(r, 0); + + r = amdgpu_bo_unmap_and_free(bo1, bo1_va_handle, bo1_mc, + sdma_write_length); + CU_ASSERT_EQUAL(r, 0); + + r = amdgpu_bo_unmap_and_free(bo2, bo2_va_handle, bo2_mc, + sdma_write_length); + CU_ASSERT_EQUAL(r, 0); + + /* end of test */ + r = amdgpu_cs_ctx_free(context_handle); + CU_ASSERT_EQUAL(r, 0); +} + +static void amdgpu_hang_sdma(void) +{ + amdgpu_hang_sdma_helper(DMA_CORRUPTED_HEADER_HANG); +} +static void amdgpu_hang_slow_sdma(void) +{ + amdgpu_hang_sdma_helper(DMA_SLOW_LINEARCOPY_HANG); } diff -Nru libdrm-2.4.110/tests/amdgpu/hotunplug_tests.c libdrm-2.4.113/tests/amdgpu/hotunplug_tests.c --- libdrm-2.4.110/tests/amdgpu/hotunplug_tests.c 2022-02-16 10:00:13.000000000 +0000 +++ libdrm-2.4.113/tests/amdgpu/hotunplug_tests.c 2022-08-31 14:38:38.000000000 +0000 @@ -62,15 +62,13 @@ return CU_FALSE; } - /* Disable until the hot-unplug support in kernel gets into drm-next */ - if (major_version < 0xff) - enable = false; - if (amdgpu_device_initialize(drm_amdgpu[0], &major_version, &minor_version, &device_handle)) return CU_FALSE; - - /* TODO Once DRM version for unplug feature ready compare here agains it*/ + + /* Latest tested amdgpu version to work with all the tests */ + if (minor_version < 46) + enable = false; if (amdgpu_device_deinitialize(device_handle)) return CU_FALSE; diff -Nru libdrm-2.4.110/tests/amdgpu/jpeg_tests.c libdrm-2.4.113/tests/amdgpu/jpeg_tests.c --- libdrm-2.4.110/tests/amdgpu/jpeg_tests.c 2022-02-16 10:00:13.000000000 +0000 +++ libdrm-2.4.113/tests/amdgpu/jpeg_tests.c 2022-08-31 14:38:38.000000000 +0000 @@ -179,12 +179,9 @@ return CU_FALSE; } - if (family_id == AMDGPU_FAMILY_RV) { - if (chip_id >= (chip_rev + 0x91)) - jpeg_direct_reg = true; - else - jpeg_direct_reg = false; - } else if (family_id == AMDGPU_FAMILY_NV) + if (info.hw_ip_version_major == 1) + jpeg_direct_reg = false; + else if (info.hw_ip_version_major > 1 && info.hw_ip_version_major <= 3) jpeg_direct_reg = true; else return CU_FALSE; diff -Nru libdrm-2.4.110/tests/amdgpu/meson.build libdrm-2.4.113/tests/amdgpu/meson.build --- libdrm-2.4.110/tests/amdgpu/meson.build 2022-02-16 10:00:13.000000000 +0000 +++ libdrm-2.4.113/tests/amdgpu/meson.build 2022-08-31 14:38:38.000000000 +0000 @@ -25,7 +25,7 @@ 'amdgpu_test.c', 'basic_tests.c', 'bo_tests.c', 'cs_tests.c', 'vce_tests.c', 'uvd_enc_tests.c', 'vcn_tests.c', 'deadlock_tests.c', 'vm_tests.c', 'ras_tests.c', 'syncobj_tests.c', 'security_tests.c', - 'hotunplug_tests.c', 'jpeg_tests.c' + 'hotunplug_tests.c', 'jpeg_tests.c', 'cp_dma_tests.c', 'shader_test_util.c' ), dependencies : [dep_cunit, dep_threads, dep_atomic_ops], include_directories : [inc_root, inc_drm, include_directories('../../amdgpu')], diff -Nru libdrm-2.4.110/tests/amdgpu/shader_code_gfx10.h libdrm-2.4.113/tests/amdgpu/shader_code_gfx10.h --- libdrm-2.4.110/tests/amdgpu/shader_code_gfx10.h 1970-01-01 00:00:00.000000000 +0000 +++ libdrm-2.4.113/tests/amdgpu/shader_code_gfx10.h 2022-08-31 14:38:38.000000000 +0000 @@ -0,0 +1,202 @@ +/* + * Copyright 2022 Advanced Micro Devices, Inc. + * + * 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 _shader_code_gfx10_h_ +#define _shader_code_gfx10_h_ + +static const uint32_t bufferclear_cs_shader_gfx10[] = { + 0xD7460004, 0x04010C08, 0x7E000204, 0x7E020205, + 0x7E040206, 0x7E060207, 0xE01C2000, 0x80000004, + 0xBF810000 +}; + +static const uint32_t buffercopy_cs_shader_gfx10[] = { + 0xD7460001, 0x04010C08, 0xE00C2000, 0x80000201, + 0xBF8C3F70, 0xE01C2000, 0x80010201, 0xBF810000 +}; + +static const uint32_t ps_const_shader_gfx10[] = { + 0x7E000200, 0x7E020201, 0x7E040202, 0x7E060203, + 0x5E000300, 0x5E020702, 0xBF800000, 0xBF800000, + 0xF8001C0F, 0x00000100, 0xBF810000 +}; + +static const uint32_t ps_const_shader_patchinfo_code_size_gfx10 = 6; + +static const uint32_t ps_const_shader_patchinfo_code_gfx10[][10][6] = { + {{ 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xF8001890, 0x00000000 }, + { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xF8001801, 0x00000000 }, + { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xF8001803, 0x00000100 }, + { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xF8001803, 0x00000300 }, + { 0x5E000300, 0x5E020702, 0xBF800000, 0xBF800000, 0xF8001C0F, 0x00000100 }, + { 0xD7690000, 0x00020300, 0xD7690001, 0x00020702, 0xF8001C0F, 0x00000100 }, + { 0xD7680000, 0x00020300, 0xD7680001, 0x00020702, 0xF8001C0F, 0x00000100 }, + { 0xD76A0000, 0x00020300, 0xD76A0001, 0x00020702, 0xF8001C0F, 0x00000100 }, + { 0xD76B0000, 0x00020300, 0xD76B0001, 0x00020702, 0xF8001C0F, 0x00000100 }, + { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xF800180F, 0x03020100 } + } +}; + +static const uint32_t ps_const_shader_patchinfo_offset_gfx10[] = { + 0x00000004 +}; + +static const uint32_t ps_const_num_sh_registers_gfx10 = 2; + +static const struct reg_info ps_const_sh_registers_gfx10[] = { + {0x2C0A, 0x000C0000},//{ mmSPI_SHADER_PGM_RSRC1_PS, 0x000C0000 }, + {0x2C0B, 0x00000008}, //{ mmSPI_SHADER_PGM_RSRC2_PS, 0x00000008 } +}; + +static const struct reg_info ps_const_context_registers_gfx10[] = +{ + {0xA1B4, 0x00000002}, //{ mmSPI_PS_INPUT_ADDR, 0x00000002 }, + {0xA1B6, 0x00000000}, //{ mmSPI_PS_IN_CONTROL, 0x00000000 }, + {0xA08F, 0x0000000F}, //{ mmCB_SHADER_MASK, 0x0000000F }, + {0xA203, 0x00000010}, //{ mmDB_SHADER_CONTROL, 0x00000010 }, + {0xA1C4, 0x00000000}, //{ mmSPI_SHADER_Z_FORMAT, 0x00000000 }, + {0xA1B8, 0x00000000}, //{ mmSPI_BARYC_CNTL, 0x00000000 /* Always 0 for now */}, + {0xA1C5, 0x00000004}, //{ mmSPI_SHADER_COL_FORMAT, 0x00000004 /* SI_EXPORT_FMT_FP16_ABGR */ } +}; + +static const uint32_t ps_const_num_context_registers_gfx10 = 7; + +static const uint32_t ps_tex_shader_gfx10[] = { + 0xBEFC030C, 0xBE8E047E, 0xBEFE0A7E, 0xC8080000, + 0xC80C0100, 0xC8090001, 0xC80D0101, 0xF0800F0A, + 0x00400402, 0x00000003, 0xBEFE040E, 0xBF8C0F70, + 0x5E000B04, 0x5E020F06, 0xBF800000, 0xBF800000, + 0xF8001C0F, 0x00000100, 0xBF810000 +}; + +static const uint32_t ps_tex_shader_patchinfo_offset_gfx10[] = { + 0x0000000C +}; + +static const uint32_t ps_tex_shader_patchinfo_code_size_gfx10 = 6; + +static const uint32_t ps_tex_shader_patchinfo_code_gfx10[][10][6] = { + {{ 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xF8001890, 0x00000000 }, + { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xF8001801, 0x00000004 }, + { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xF8001803, 0x00000504 }, + { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xF8001803, 0x00000704 }, + { 0x5E000B04, 0x5E020F06, 0xBF800000, 0xBF800000, 0xF8001C0F, 0x00000100 }, + { 0xD7690000, 0x00020B04, 0xD7690001, 0x00020F06, 0xF8001C0F, 0x00000100 }, + { 0xD7680000, 0x00020B04, 0xD7680001, 0x00020F06, 0xF8001C0F, 0x00000100 }, + { 0xD76A0000, 0x00020B04, 0xD76A0001, 0x00020F06, 0xF8001C0F, 0x00000100 }, + { 0xD76B0000, 0x00020B04, 0xD76B0001, 0x00020F06, 0xF8001C0F, 0x00000100 }, + { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xF800180F, 0x07060504 } + } +}; + +static const struct reg_info ps_tex_sh_registers_gfx10[] = +{ + {0x2C0A, 0xc0081}, //0x020C0080 }, //{ mmSPI_SHADER_PGM_RSRC1_PS, 0x020C0080 }, + {0x2C0B, 0x00000018 }, //{ mmSPI_SHADER_PGM_RSRC2_PS, 0x00000018 } +}; + +static const uint32_t ps_tex_num_sh_registers_gfx10 = 2; + +// Holds Context Register Information +static const struct reg_info ps_tex_context_registers_gfx10[] = +{ + {0xA1B4, 0x00000002}, //{ mmSPI_PS_INPUT_ADDR, 0x00000002 }, + {0xA1B6, 0x00000001}, //{ mmSPI_PS_IN_CONTROL, 0x00000001 }, + {0xA08F, 0x0000000F}, //{ mmCB_SHADER_MASK, 0x0000000F }, + {0xA203, 0x00000010}, //{ mmDB_SHADER_CONTROL, 0x00000010 }, + {0xA1C4, 0x00000000}, //{ mmSPI_SHADER_Z_FORMAT, 0x00000000 }, + {0xA1B8, 0x00000000}, //{ mmSPI_BARYC_CNTL, 0x00000000 /* Always 0 for now */}, + {0xA1C5, 0x00000004}, //{ mmSPI_SHADER_COL_FORMAT, 0x00000004 /* SI_EXPORT_FMT_FP16_ABGR */ } +}; + +static const uint32_t ps_tex_num_context_registers_gfx10 = 7; + +static const uint32_t vs_RectPosTexFast_shader_gfx10[] = { + 0x7E000B00, 0x060000F3, 0x7E020202, 0x7E040206, + 0x7C040080, 0x060000F3, 0xD5010001, 0x01AA0200, + 0x7E060203, 0xD5010002, 0x01AA0404, 0x7E080207, + 0x7C040080, 0xD5010000, 0x01A80101, 0xD5010001, + 0x01AA0601, 0x7E060208, 0x7E0A02F2, 0xD5010002, + 0x01A80902, 0xD5010004, 0x01AA0805, 0x7E0C0209, + 0xF80008CF, 0x05030100, 0xF800020F, 0x05060402, + 0xBF810000 +}; + +static const struct reg_info vs_RectPosTexFast_sh_registers_gfx10[] = +{ + {0x2C4A, 0x080C0041 }, //{ mmSPI_SHADER_PGM_RSRC1_VS, 0x080C0041 }, + {0x2C4B, 0x00000018 }, //{ mmSPI_SHADER_PGM_RSRC2_VS, 0x00000018 } +}; + +static const uint32_t vs_RectPosTexFast_num_sh_registers_gfx10 = 2; + +// Holds Context Register Information +static const struct reg_info vs_RectPosTexFast_context_registers_gfx10[] = +{ + {0xA1B1, 0x00000000}, //{ mmSPI_VS_OUT_CONFIG, 0x00000000 }, + {0xA1C3, 0x00000000}, //{ mmSPI_SHADER_POS_FORMAT, 0x00000000 /* Always 0 for now */} +}; + +static const uint32_t vs_RectPosTexFast_num_context_registers_gfx10 = 2; + +static const uint32_t preamblecache_gfx10[] = { + 0xc0026900, 0x81, 0x80000000, 0x40004000, 0xc0026900, 0x8c, 0xaa99aaaa, 0x0, + 0xc0026900, 0x90, 0x80000000, 0x40004000, 0xc0026900, 0x94, 0x80000000, 0x40004000, + 0xc0026900, 0xb4, 0x0, 0x3f800000, 0xc0016900, 0x103, 0x0, + 0xc0016900, 0x208, 0x0, 0xc0016900, 0x290, 0x0, + 0xc0016900, 0x2a1, 0x0, 0xc0026900, 0x2ad, 0x0, 0x0, + 0xc0016900, 0x2d5, 0x10000, 0xc0016900, 0x2dc, 0x0, + 0xc0066900, 0x2de, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0026900, 0x2e5, 0x0, 0x0, + 0xc0056900, 0x2f9, 0x5, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, + 0xc0046900, 0x310, 0, 0x3, 0, 0x100000, 0xc0026900, 0x316, 0xe, 0x20, + 0xc0016900, 0x349, 0x0, 0xc0016900, 0x358, 0x0, 0xc0016900, 0x367, 0x0, + 0xc0016900, 0x376, 0x0, 0xc0016900, 0x385, 0x0, 0xc0016900, 0x6, 0x0, + 0xc0056900, 0xe8, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc0076900, 0x1e1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc0026900, 0x204, 0x90000, 0x4, 0xc0046900, 0x20c, 0x0, 0x0, 0x0, 0x0, + 0xc0016900, 0x2b2, 0x0, 0xc0026900, 0x30e, 0xffffffff, 0xffffffff, + 0xc0016900, 0x314, 0x0, 0xc0016900, 0x10a, 0, 0xc0016900, 0x2a6, 0, 0xc0016900, 0x210, 0, + 0xc0016900, 0x2db, 0, 0xc0016900, 0x1d4, 0, 0xc0002f00, 0x1, 0xc0016900, 0x1, 0x1, 0xc0016900, 0xe, 0x2, + 0xc0016900, 0x206, 0x300, 0xc0016900, 0x212, 0x200, 0xc0017900, 0x7b, 0x20, 0xc0017a00, 0x20000243, 0x0, + 0xc0017900, 0x249, 0, 0xc0017900, 0x24a, 0, 0xc0017900, 0x24b, 0, 0xc0017900, 0x259, 0xffffffff, + 0xc0017900, 0x25f, 0, 0xc0017900, 0x260, 0, 0xc0017900, 0x262, 0, + 0xc0017600, 0x45, 0x0, 0xc0017600, 0x6, 0x0, + 0xc0067600, 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc0067600, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 +}; + +static const uint32_t cached_cmd_gfx10[] = { + 0xc0016900, 0x0, 0x0, 0xc0026900, 0x3, 0x2a, 0x0, + 0xc0046900, 0xa, 0x0, 0x0, 0x0, 0x200020, + 0xc0016900, 0x83, 0xffff, 0xc0026900, 0x8e, 0xf, 0xf, + 0xc0056900, 0x105, 0x0, 0x0, 0x0, 0x0, 0x18, + 0xc0026900, 0x10b, 0x0, 0x0, 0xc0016900, 0x1e0, 0x0, + 0xc0036900, 0x200, 0x0, 0x10000, 0xcc0011, + 0xc0026900, 0x292, 0x20, 0x6020000, + 0xc0026900, 0x2b0, 0x0, 0x0, 0xc0016900, 0x2f8, 0x0 +}; + +static const uint32_t sh_reg_base_gfx10 = 0x2C00; +static const uint32_t context_reg_base_gfx10 = 0xA000; + +#endif diff -Nru libdrm-2.4.110/tests/amdgpu/shader_code_gfx11.h libdrm-2.4.113/tests/amdgpu/shader_code_gfx11.h --- libdrm-2.4.110/tests/amdgpu/shader_code_gfx11.h 1970-01-01 00:00:00.000000000 +0000 +++ libdrm-2.4.113/tests/amdgpu/shader_code_gfx11.h 2022-08-31 14:38:38.000000000 +0000 @@ -0,0 +1,320 @@ +/* + * Copyright 2022 Advanced Micro Devices, Inc. + * + * 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 _shader_code_gfx11_h_ +#define _shader_code_gfx11_h_ + +static const uint32_t bufferclear_cs_shader_gfx11[] = { + 0xB0802006, 0xBF840003, 0x360000FF, 0x000003FF, + 0x7E020205, 0x7E040206, 0x7E060207, 0xBF870004, + 0xD6460004, 0x04010C08, 0x7E000204, 0xE01C0000, + 0x80800004, 0xBFB60003, 0xBFB00000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000 +}; + +static const struct reg_info bufferclear_cs_shader_registers_gfx11[] = { + {0x2e12, 0x600C0041}, //{ mmCOMPUTE_PGM_RSRC1, 0x600C0041 }, + {0x2e13, 0x00000090}, //{ mmCOMPUTE_PGM_RSRC2, 0x00000090 }, + {0x2e07, 0x00000040}, //{ mmCOMPUTE_NUM_THREAD_X, 0x00000040 }, + {0x2e08, 0x00000001}, //{ mmCOMPUTE_NUM_THREAD_Y, 0x00000001 }, + {0x2e09, 0x00000001}, //{ mmCOMPUTE_NUM_THREAD_Z, 0x00000001 } +}; + +static const uint32_t buffercopy_cs_shader_gfx11[] = { + 0xB0802006, 0xBF840003, 0x360000FF, 0x000003FF, + 0xBF870001, 0xD6460001, 0x04010C08, 0xE00C0000, + 0x80800201, 0xBF8903F7, 0xE01C0000, 0x80810201, + 0xBFB60003, 0xBFB00000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000 +}; + +static const uint32_t ps_const_shader_gfx11[] = { + 0xB0802006, 0xBF840003, 0x7E000200, 0x7E020201, + 0x7E040202, 0x7E060203, 0x5E000300, 0x5E020702, + 0xBF800000, 0xBF800000, 0xF8000803, 0x00000100, + 0xBFB00000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000 +}; + +static const uint32_t ps_const_shader_patchinfo_code_size_gfx11 = 6; + +static const uint32_t ps_const_shader_patchinfo_code_gfx11[][10][6] = { + {{ 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xF8000890, 0x00000000 }, // SI_EXPORT_FMT_ZERO + { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xF8000801, 0x00000000 }, // SI_EXPORT_FMT_32_R + { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xF8000803, 0x00000100 }, // SI_EXPORT_FMT_32_GR + { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xF8000803, 0x00000300 }, // SI_EXPORT_FMT_32_AR + { 0x5E000300, 0x5E020702, 0xBF800000, 0xBF800000, 0xF8000803, 0x00000100 }, // SI_EXPORT_FMT_FP16_ABGR + { 0xD7220000, 0x00020300, 0xD7220001, 0x00020702, 0xF8000803, 0x00000100 }, // SI_EXPORT_FMT_UNORM16_ABGR + { 0xD7210000, 0x00020300, 0xD7210001, 0x00020702, 0xF8000803, 0x00000100 }, // SI_EXPORT_FMT_SNORM16_ABGR + { 0xD7230000, 0x00020300, 0xD7230001, 0x00020702, 0xF8000803, 0x00000100 }, // SI_EXPORT_FMT_uint32_t16_ABGR + { 0xD7240000, 0x00020300, 0xD7240001, 0x00020702, 0xF8000803, 0x00000100 }, // SI_EXPORT_FMT_SINT16_ABGR + { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xF800080F, 0x03020100 } // SI_EXPORT_FMT_32_ABGR + } +}; + +static const uint32_t ps_const_shader_patchinfo_offset_gfx11[] = { + 0x00000006 +}; + +static const uint32_t ps_const_num_sh_registers_gfx11 = 2; + +static const struct reg_info ps_const_sh_registers_gfx11[] = { + {0x2C0A, 0x020C0000}, //{ mmSPI_SHADER_PGM_RSRC1_PS, 0x020C0000 }, + {0x2C0B, 0x00000008}, //{ mmSPI_SHADER_PGM_RSRC2_PS, 0x00000008 } +}; + +static const struct reg_info ps_const_context_registers_gfx11[] = { + {0xA1B4, 0x00000002 }, //{ mmSPI_PS_INPUT_ADDR, 0x00000002 }, + {0xA1B6, 0x00000000 }, //{ mmSPI_PS_IN_CONTROL, 0x00000000 }, + {0xA08F, 0x0000000F }, //{ mmCB_SHADER_MASK, 0x0000000F }, + {0xA203, 0x00000010 }, //{ mmDB_SHADER_CONTROL, 0x00000010 }, + {0xA1C4, 0x00000000 }, //{ mmSPI_SHADER_Z_FORMAT, 0x00000000 }, + {0xA1B8, 0x00000000 }, //{ mmSPI_BARYC_CNTL, 0x00000000 /* Always 0 for now */}, + {0xA1C5, 0x00000004 }, //{ mmSPI_SHADER_COL_FORMAT, 0x00000004 /* SI_EXPORT_FMT_FP16_ABGR */ } +}; + +static const uint32_t ps_const_num_context_registers_gfx11 = 7; + +static const uint32_t ps_tex_shader_gfx11[] = +{ + 0xB0802006, 0xBF840003, 0xBEFD000C, 0xBE8E017E, + 0xBEFE1D7E, 0xCE000003, 0xCE000102, 0xCD000104, + 0x040E0103, 0xCD000000, 0x040A0102, 0xBF870112, + 0xCD010703, 0x04120303, 0xCD010700, 0x04020302, + 0x8BFE0E7E, 0xF06C0F05, 0x08000003, 0x00000000, + 0xBEFE010E, 0xBF8903F7, 0x5E000300, 0x5E020702, + 0xBF800000, 0xBF800000, 0xF8000803, 0x00000100, + 0xBFB00000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000 +}; + +static const uint32_t ps_tex_shader_patchinfo_offset_gfx11[] = +{ + 0x00000016 +}; + +// Denotes the Patch Info Code Length +static const uint32_t ps_tex_shader_patchinfo_code_size_gfx11 = 6; + +static const uint32_t ps_tex_shader_patchinfo_code_gfx11[][10][6] = +{ + {{ 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xF8000890, 0x00000000 }, // SI_EXPORT_FMT_ZERO + { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xF8000801, 0x00000000 }, // SI_EXPORT_FMT_32_R + { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xF8000803, 0x00000100 }, // SI_EXPORT_FMT_32_GR + { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xF8000803, 0x00000300 }, // SI_EXPORT_FMT_32_AR + { 0x5E000300, 0x5E020702, 0xBF800000, 0xBF800000, 0xF8000803, 0x00000100 }, // SI_EXPORT_FMT_FP16_ABGR + { 0xD7220000, 0x00020300, 0xD7220001, 0x00020702, 0xF8000803, 0x00000100 }, // SI_EXPORT_FMT_UNORM16_ABGR + { 0xD7210000, 0x00020300, 0xD7210001, 0x00020702, 0xF8000803, 0x00000100 }, // SI_EXPORT_FMT_SNORM16_ABGR + { 0xD7230000, 0x00020300, 0xD7230001, 0x00020702, 0xF8000803, 0x00000100 }, // SI_EXPORT_FMT_uint32_t16_ABGR + { 0xD7240000, 0x00020300, 0xD7240001, 0x00020702, 0xF8000803, 0x00000100 }, // SI_EXPORT_FMT_SINT16_ABGR + { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xF800080F, 0x03020100 } // SI_EXPORT_FMT_32_ABGR + } +}; +// Holds Sh Register Information +static const struct reg_info ps_tex_sh_registers_gfx11[] = +{ + {0x2C0A, 0x020C0081 }, //{ mmSPI_SHADER_PGM_RSRC1_PS, 0x020C0081 }, + {0x2C0B, 0x00000018 } //{ mmSPI_SHADER_PGM_RSRC2_PS, 0x00000018 } +}; + +static const uint32_t ps_tex_num_sh_registers_gfx11 = 2; + +// Holds Context Register Information +static const struct reg_info ps_tex_context_registers_gfx11[] = +{ + {0xA1B4, 0x00000002 }, //{ mmSPI_PS_INPUT_ADDR, 0x00000002 }, + {0xA1B6, 0x00000001 }, //{ mmSPI_PS_IN_CONTROL, 0x00000001 }, + {0xA08F, 0x0000000F }, //{ mmCB_SHADER_MASK, 0x0000000F }, + {0xA203, 0x00000010 }, //{ mmDB_SHADER_CONTROL, 0x00000010 }, + {0xA1C4, 0x00000000 }, //{ mmSPI_SHADER_Z_FORMAT, 0x00000000 }, + {0xA1B8, 0x00000000 }, //{ mmSPI_BARYC_CNTL, 0x00000000 /* Always 0 for now */}, + {0xA1C5, 0x00000004 } //{ mmSPI_SHADER_COL_FORMAT, 0x00000004 /* SI_EXPORT_FMT_FP16_ABGR */ } +}; + +static const uint32_t ps_tex_num_context_registers_gfx11 = 7; + + +static const uint32_t vs_RectPosTexFast_shader_gfx11[] = +{ + 0xB0802006, 0xBEFE01C1, 0xBF840003, 0xF408050A, + 0xF80000B0, 0xD71F0001, 0x000100C1, 0x9300FF03, + 0x00040018, 0x9301FF02, 0x0009000C, 0xBF870091, + 0xD7200001, 0x000202C1, 0xD60B0001, 0x04058000, + 0xBF870001, 0xD4490000, 0x00000301, 0xBE862100, + 0x7E040B05, 0xBFA5001C, 0x7E06020A, 0x7E08020E, + 0x7E0A020F, 0xBF8701B4, 0x060404F3, 0x7E140211, + 0x7E0E0210, 0x7C240480, 0x060404F3, 0xD5010003, + 0x01AA0608, 0xD5010004, 0x01AA080C, 0xBF870003, + 0xD4120012, 0x00010102, 0x7E04020B, 0xBEEA1F12, + 0xBF870483, 0xD5010008, 0x01AA080C, 0xD5010006, + 0x01AA0608, 0xBF870003, 0xD5010004, 0x004A0409, + 0xD5010009, 0x004A0A0D, 0xBEFE0106, 0x9302FF02, + 0x00090016, 0xBF870009, 0xD4C9007E, 0x00000501, + 0xBFA50002, 0xF8000941, 0x00000000, 0xBF89FFF0, + 0x8BFE0006, 0xD71F0000, 0x000100C1, 0xBFA50013, + 0x7E1602F2, 0x9300FF03, 0x00040018, 0x8B01FF05, + 0x00007FFF, 0xBF8704B2, 0xD7200000, 0x000200C1, + 0x7E0202F2, 0x84018901, 0x80018001, 0xBF870002, + 0xD60B0000, 0x04018000, 0xF80008CF, 0x01070406, + 0xBF89FC07, 0xE0744000, 0x01850800, 0xBFB00000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, + 0xBF9F0000, 0xBF9F0000, 0xBF9F0000, 0xBF9F0000 +}; + +static const struct reg_info vs_RectPosTexFast_sh_registers_gfx11[] = +{ + {0x2C8A, 0x020C00C2}, //{ mmSPI_SHADER_PGM_RSRC1_GS, 0x020C00C2 }, + {0x2C8B, 0x0008001C}, //{ mmSPI_SHADER_PGM_RSRC2_GS, 0x0008001C } +}; + +static const uint32_t vs_RectPosTexFast_num_sh_registers_gfx11 = 2; + +// Holds Context Register Information +static const struct reg_info vs_RectPosTexFast_context_registers_gfx11[] = +{ + {0xA1B1, 0x00000000}, //{ mmSPI_VS_OUT_CONFIG, 0x00000000 }, + {0xA1C2, 0x00000001}, //{ mmSPI_SHADER_IDX_FORMAT, 0x00000001 }, + {0xA1C3, 0x00000000}, //{ mmSPI_SHADER_POS_FORMAT, 0x00000000 /* Always 0 for now */}, + {0xA2E4, 0x00000000}, //{ mmVGT_GS_INSTANCE_CNT, 0x00000000 }, + {0xA2AB, 0x00000004}, //{ mmVGT_ESGS_RING_ITEMSIZE, 0x00000004 }, + {0xA2CE, 0x00000001}, //{ mmVGT_GS_MAX_VERT_OUT, 0x00000001 } +}; + +static const uint32_t vs_RectPosTexFast_num_context_registers_gfx11 = 6; + +static const uint32_t preamblecache_gfx11[] = { + 0xc0026900, 0x81, 0x80000000, 0x40004000, 0xc0026900, 0x8c, 0xaa99aaaa, 0x0, + 0xc0026900, 0x90, 0x80000000, 0x40004000, 0xc0026900, 0x94, 0x80000000, 0x40004000, + 0xc0026900, 0xb4, 0x0, 0x3f800000, 0xc0016900, 0x103, 0x0, 0xc0016900, 0x208, 0x0, + 0xc0016900, 0x2a1, 0x0, 0xc0016900, 0x2ad, 0x0, 0xc0016900, 0x2dc, 0x0, + 0xc0066900, 0x2de, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc0056900, 0x2f9, 0x5, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, + 0xc0046900, 0x310, 0x0, 0x3, 0x0, 0x100000, 0xc0016900, 0x349, 0x0, + 0xc0016900, 0x358, 0x0, 0xc0016900, 0x367, 0x0, 0xc0016900, 0x376, 0x0, + 0xc0016900, 0x385, 0x0, 0xc0076900, 0x1e1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc0026900, 0x204, 0x90000, 0x4, 0xc0016900, 0x20c, 0x0, 0xc0026900, 0x20e, 0x0, 0x0, + 0xc0016900, 0x2b2, 0x0, 0xc0026900, 0x30e, 0xffffffff, 0xffffffff, + 0xc0016900, 0x314, 0x0, 0xc0016900, 0x10a, 0x0, 0xc0016900, 0x2a6, 0x0, + 0xc0016900, 0x210, 0x0, 0xc0016900, 0x2db, 0x0, 0xc0016900, 0x2e4, 0x0, + 0xc0002f00, 0x1, 0xc0016900, 0x1, 0x0, 0xc0016900, 0x206, 0x300, + 0xc0016900, 0x212, 0x200, 0xc0016900, 0xf4, 0x0, 0xc0016900, 0x18, 0x0, + 0xc0016900, 0x1d4, 0xff, 0xc0016900, 0x2ce, 0x1, 0xc0016900, 0x2d3, 0x20001, + 0xc0016900, 0x1ff, 0x80, 0xc0016900, 0x2d5, 0x6012010, 0xc0017a00, 0x20000243, 0x0, + 0xc0017900, 0x249, 0x0, 0xc0017900, 0x24a, 0x0, 0xc0017900, 0x24b, 0x0, + 0xc0017900, 0x259, 0xffffffff, 0xc0017900, 0x25f, 0x0, 0xc0017900, 0x260, 0x0, + 0xc0017900, 0x262, 0x0, 0xc0017900, 0x444, 0x0, 0xc0017900, 0x445, 0x0, + 0xc0017600, 0x6, 0x0, 0xc0017600, 0x80, 0x0, 0xc0017600, 0xb0, 0x0, + 0xc0047600, 0xb2, 0x0, 0x0, 0x0, 0x0, 0xc0017600, 0x30, 0x0, + 0xc0047600, 0x32, 0x0, 0x0, 0x0, 0x0 +}; + +static const uint32_t cached_cmd_gfx11[] = { + 0xc0016900, 0x0, 0x0, 0xc0026900, 0x3, 0x2a, 0x0, + 0xc0046900, 0xa, 0x0, 0x0, 0x0, 0x200020, + 0xc0016900, 0x83, 0xffff, 0xc0026900, 0x8e, 0xf, 0xf, + 0xc0056900, 0x105, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc0026900, 0x10b, 0x0, 0x0, 0xc0016900, 0x1e0, 0x0, + 0xc0036900, 0x200, 0x0, 0x10000, 0xcc0011, + 0xc0026900, 0x292, 0x20, 0x6020000, + 0xc0026900, 0x2b0, 0x0, 0x0, 0xc0016900, 0x2f8, 0x0, + 0xc0046900, 0x1d5, 0x0, 0x0, 0x0, 0x0, 0xc0016900, 0x104, 0x4a00005, + 0xc0016900, 0x1f, 0xf2a0055, 0xc0017900, 0x266, 0x4 +}; +static const uint32_t sh_reg_base_gfx11 = 0x2C00; +static const uint32_t context_reg_base_gfx11 = 0xA000; + +#endif diff -Nru libdrm-2.4.110/tests/amdgpu/shader_code_gfx9.h libdrm-2.4.113/tests/amdgpu/shader_code_gfx9.h --- libdrm-2.4.110/tests/amdgpu/shader_code_gfx9.h 1970-01-01 00:00:00.000000000 +0000 +++ libdrm-2.4.113/tests/amdgpu/shader_code_gfx9.h 2022-08-31 14:38:38.000000000 +0000 @@ -0,0 +1,204 @@ +/* + * Copyright 2022 Advanced Micro Devices, Inc. + * + * 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 _shader_code_gfx9_h_ +#define _shader_code_gfx9_h_ + +static const uint32_t bufferclear_cs_shader_gfx9[] = { + 0x260000ff, 0x000003ff, 0xd1fd0000, 0x04010c08, + 0x7e020280, 0x7e040204, 0x7e060205, 0x7e080206, + 0x7e0a0207, 0xe01c2000, 0x80000200, 0xbf8c0000, + 0xbf810000 +}; + +static const struct reg_info bufferclear_cs_shader_registers_gfx9[] = { + {0x2e12, 0x000C0041}, //{ mmCOMPUTE_PGM_RSRC1, 0x000C0041 }, + {0x2e13, 0x00000090}, //{ mmCOMPUTE_PGM_RSRC2, 0x00000090 }, + {0x2e07, 0x00000040}, //{ mmCOMPUTE_NUM_THREAD_X, 0x00000040 }, + {0x2e08, 0x00000001}, //{ mmCOMPUTE_NUM_THREAD_Y, 0x00000001 }, + {0x2e09, 0x00000001}, //{ mmCOMPUTE_NUM_THREAD_Z, 0x00000001 } +}; + +static const uint32_t buffercopy_cs_shader_gfx9[] = { + 0x260000ff, 0x000003ff, 0xd1fd0000, 0x04010c08, + 0x7e020280, 0xe00c2000, 0x80000200, 0xbf8c0f70, + 0xe01c2000, 0x80010200, 0xbf810000 +}; + +static const uint32_t ps_const_shader_gfx9[] = { + 0x7E000200, 0x7E020201, 0x7E040202, 0x7E060203, + 0xD2960000, 0x00020300, 0xD2960001, 0x00020702, + 0xC4001C0F, 0x00000100, 0xBF810000 +}; + +static const uint32_t ps_const_shader_patchinfo_code_size_gfx9 = 6; + +static const uint32_t ps_const_shader_patchinfo_code_gfx9[][10][6] = { + {{ 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xC4001890, 0x00000000 }, + { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xC4001801, 0x00000000 }, + { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xC4001803, 0x00000100 }, + { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xC4001803, 0x00000300 }, + { 0xD2960000, 0x00020300, 0xD2960001, 0x00020702, 0xC4001C0F, 0x00000100 }, + { 0xD2950000, 0x00020300, 0xD2950001, 0x00020702, 0xC4001C0F, 0x00000100 }, + { 0xD2940000, 0x00020300, 0xD2940001, 0x00020702, 0xC4001C0F, 0x00000100 }, + { 0xD2970000, 0x00020300, 0xD2970001, 0x00020702, 0xC4001C0F, 0x00000100 }, + { 0xD2980000, 0x00020300, 0xD2980001, 0x00020702, 0xC4001C0F, 0x00000100 }, + { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xC400180F, 0x03020100 } + } +}; + +static const uint32_t ps_const_shader_patchinfo_offset_gfx9[] = { + 0x00000004 +}; + +static const uint32_t ps_const_num_sh_registers_gfx9 = 2; + +static const struct reg_info ps_const_sh_registers_gfx9[] = { + {0x2C0A, 0x000C0040},//{ mmSPI_SHADER_PGM_RSRC1_PS, 0x000C0040 }, + {0x2C0B, 0x00000008}, //{ mmSPI_SHADER_PGM_RSRC2_PS, 0x00000008 } +}; + +static const uint32_t ps_const_num_context_registers_gfx9 = 7; + +static const struct reg_info ps_const_context_registers_gfx9[] = { + {0xA1B4, 0x00000002}, //{ mmSPI_PS_INPUT_ADDR, 0x00000002 }, + {0xA1B6, 0x00000000}, //{ mmSPI_PS_IN_CONTROL, 0x00000000 }, + {0xA08F, 0x0000000F}, //{ mmCB_SHADER_MASK, 0x0000000F }, + {0xA203, 0x00000010}, //{ mmDB_SHADER_CONTROL, 0x00000010 }, + {0xA1C4, 0x00000000}, //{ mmSPI_SHADER_Z_FORMAT, 0x00000000 }, + {0xA1B8, 0x00000000}, //{ mmSPI_BARYC_CNTL, 0x00000000 /* Always 0 for now */}, + {0xA1C5, 0x00000004}, //{ mmSPI_SHADER_COL_FORMAT, 0x00000004 } +}; + +static const uint32_t ps_tex_shader_gfx9[] = { + 0xBEFC000C, 0xBE8E017E, 0xBEFE077E, 0xD4180000, + 0xD4190001, 0xD41C0100, 0xD41D0101, 0xF0800F00, + 0x00400206, 0xBEFE010E, 0xBF8C0F70, 0xD2960000, + 0x00020702, 0xD2960001, 0x00020B04, 0xC4001C0F, + 0x00000100, 0xBF810000 +}; + +static const uint32_t ps_tex_shader_patchinfo_offset_gfx9[] = { + 0x0000000B +}; + +static const uint32_t ps_tex_shader_patchinfo_code_size_gfx9 = 6; + +static const uint32_t ps_tex_shader_patchinfo_code_gfx9[][10][6] = { + {{ 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xC4001890, 0x00000000 }, + { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xC4001801, 0x00000002 }, + { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xC4001803, 0x00000302 }, + { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xC4001803, 0x00000502 }, + { 0xD2960000, 0x00020702, 0xD2960001, 0x00020B04, 0xC4001C0F, 0x00000100 }, + { 0xD2950000, 0x00020702, 0xD2950001, 0x00020B04, 0xC4001C0F, 0x00000100 }, + { 0xD2940000, 0x00020702, 0xD2940001, 0x00020B04, 0xC4001C0F, 0x00000100 }, + { 0xD2970000, 0x00020702, 0xD2970001, 0x00020B04, 0xC4001C0F, 0x00000100 }, + { 0xD2980000, 0x00020702, 0xD2980001, 0x00020B04, 0xC4001C0F, 0x00000100 }, + { 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xC400180F, 0x05040302 } + } +}; + +static const uint32_t ps_tex_num_sh_registers_gfx9 = 2; +static const struct reg_info ps_tex_sh_registers_gfx9[] = { + {0x2C0A, 0x000C0081},//{ mmSPI_SHADER_PGM_RSRC1_PS, 0x000C0081 }, + {0x2C0B, 0x00000018}, //{ mmSPI_SHADER_PGM_RSRC2_PS, 0x00000018 } +}; + +static const uint32_t ps_tex_num_context_registers_gfx9 = 7; + +static const struct reg_info ps_tex_context_registers_gfx9[] = { + {0xA1B4, 0x00000002}, //{ mmSPI_PS_INPUT_ADDR, 0x00000002 }, + {0xA1B6, 0x00000001}, //{ mmSPI_PS_IN_CONTROL, 0x00000001 }, + {0xA08F, 0x0000000F}, //{ mmCB_SHADER_MASK, 0x0000000F }, + {0xA203, 0x00000010}, //{ mmDB_SHADER_CONTROL, 0x00000010 }, + {0xA1C4, 0x00000000}, //{ mmSPI_SHADER_Z_FORMAT, 0x00000000 }, + {0xA1B8, 0x00000000}, //{ mmSPI_BARYC_CNTL, 0x00000000 /* Always 0 for now */}, + {0xA1C5, 0x00000004}, //{ mmSPI_SHADER_COL_FORMAT, 0x00000004 } +}; + +static const uint32_t vs_RectPosTexFast_shader_gfx9[] = { + 0x7E000B00, 0x020000F3, 0xD042000A, 0x00010100, + 0x7E020202, 0x7E040200, 0x020000F3, 0x7E060206, + 0x7E080204, 0xD1000001, 0x002A0302, 0x7C840080, + 0x7E000200, 0x7E040203, 0x7E0A0201, 0xD1000003, + 0x002A0704, 0x7E0C0207, 0x7E0E0205, 0x00000101, + 0x00020505, 0x7E040208, 0x7E0A02F2, 0x00060903, + 0x00080D07, 0x7E0C0209, 0xC40008CF, 0x05020100, + 0xC400020F, 0x05060403, 0xBF810000 +}; + +static const struct reg_info vs_RectPosTexFast_sh_registers_gfx9[] = +{ + {0x2C4A, 0x000C0081}, //{ mmSPI_SHADER_PGM_RSRC1_VS, 0x000C0081 }, + {0x2C4B, 0x00000018}, //{ mmSPI_SHADER_PGM_RSRC2_VS, 0x00000018 } +}; + +static const uint32_t vs_RectPosTexFast_num_sh_registers_gfx9 = 2; + +// Holds Context Register Information +static const struct reg_info vs_RectPosTexFast_context_registers_gfx9[] = +{ + {0xA1B1, 0x00000000}, //{ mmSPI_VS_OUT_CONFIG, 0x00000000 }, + {0xA1C3, 0x00000000}, //{ mmSPI_SHADER_POS_FORMAT, 0x00000000 /* Always 0 for now */} +}; + +static const uint32_t vs_RectPosTexFast_num_context_registers_gfx9 = 2; + +static const uint32_t preamblecache_gfx9[] = { + 0xc0026900, 0x81, 0x80000000, 0x40004000, 0xc0026900, 0x8c, 0xaa99aaaa, 0x0, + 0xc0026900, 0x90, 0x80000000, 0x40004000, 0xc0026900, 0x94, 0x80000000, 0x40004000, + 0xc0026900, 0xb4, 0x0, 0x3f800000, 0xc0016900, 0x103, 0x0, + 0xc0016900, 0x208, 0x0, 0xc0016900, 0x290, 0x0, + 0xc0016900, 0x2a1, 0x0, 0xc0026900, 0x2ad, 0x0, 0x0, + 0xc0016900, 0x2d5, 0x10000, 0xc0016900, 0x2dc, 0x0, + 0xc0066900, 0x2de, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0026900, 0x2e5, 0x0, 0x0, + 0xc0056900, 0x2f9, 0x5, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, + 0xc0036900, 0x311, 0x3, 0, 0x100000, 0xc0026900, 0x316, 0x1e, 0x20, + 0xc0016900, 0x349, 0x0, 0xc0016900, 0x358, 0x0, 0xc0016900, 0x367, 0x0, + 0xc0016900, 0x376, 0x0, 0xc0016900, 0x385, 0x0, 0xc0016900, 0x19, 0x0, + 0xc0056900, 0xe8, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc0076900, 0x1e1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc0026900, 0x204, 0x90000, 0x4, 0xc0046900, 0x20c, 0x0, 0x0, 0x0, 0x0, + 0xc0016900, 0x2b2, 0x0, 0xc0026900, 0x30e, 0xffffffff, 0xffffffff, + 0xc0016900, 0x314, 0x0, 0xc0016900, 0x2a6, 0, 0xc0016900, 0x210, 0, + 0xc0002f00, 0x1, 0xc0016900, 0x1, 0x1, + 0xc0016900, 0x18, 0x2, 0xc0016900, 0x206, 0x300, 0xc0017900, 0x20000243, 0x0, + 0xc0017900, 0x248, 0xffffffff, 0xc0017900, 0x249, 0x0, 0xc0017900, 0x24a, 0x0, + 0xc0017900, 0x24b, 0x0 +}; + +static const uint32_t cached_cmd_gfx9[] = { + 0xc0016900, 0x0, 0x0, 0xc0026900, 0x3, 0x2a, 0x0, + 0xc0046900, 0xa, 0x0, 0x0, 0x0, 0x200020, + 0xc0016900, 0x83, 0xffff, 0xc0026900, 0x8e, 0xf, 0xf, + 0xc0056900, 0x105, 0x0, 0x0, 0x0, 0x0, 0x12, + 0xc0026900, 0x10b, 0x0, 0x0, 0xc0016900, 0x1e0, 0x0, + 0xc0036900, 0x200, 0x0, 0x10000, 0xcc0011, + 0xc0026900, 0x292, 0x20, 0x60201b8, + 0xc0026900, 0x2b0, 0x0, 0x0, 0xc0016900, 0x2f8, 0x0 +}; + +static const uint32_t sh_reg_base_gfx9 = 0x2C00; +static const uint32_t context_reg_base_gfx9 = 0xA000; + +#endif diff -Nru libdrm-2.4.110/tests/amdgpu/shader_code.h libdrm-2.4.113/tests/amdgpu/shader_code.h --- libdrm-2.4.110/tests/amdgpu/shader_code.h 1970-01-01 00:00:00.000000000 +0000 +++ libdrm-2.4.113/tests/amdgpu/shader_code.h 2022-08-31 14:38:38.000000000 +0000 @@ -0,0 +1,153 @@ +/* + * Copyright 2022 Advanced Micro Devices, Inc. + * + * 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 _shader_code_h_ +#define _shader_code_h_ + +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) +#endif + +enum amdgpu_test_gfx_version { + AMDGPU_TEST_GFX_V9 = 0, + AMDGPU_TEST_GFX_V10, + AMDGPU_TEST_GFX_V11, + AMDGPU_TEST_GFX_MAX, +}; + +enum cs_type { + CS_BUFFERCLEAR = 0, + CS_BUFFERCOPY, + CS_HANG, + CS_HANG_SLOW, +}; + +enum ps_type { + PS_CONST, + PS_TEX, + PS_HANG, + PS_HANG_SLOW +}; + +enum vs_type { + VS_RECTPOSTEXFAST, +}; + +struct reg_info { + uint32_t reg_offset; ///< Memory mapped register offset + uint32_t reg_value; ///< register value +}; + +#include "shader_code_hang.h" +#include "shader_code_gfx9.h" +#include "shader_code_gfx10.h" +#include "shader_code_gfx11.h" + +struct shader_test_cs_shader { + const uint32_t *shader; + uint32_t shader_size; + const struct reg_info *sh_reg; + uint32_t num_sh_reg; + const struct reg_info *context_reg; + uint32_t num_context_reg; +}; + +struct shader_test_ps_shader { + const uint32_t *shader; + unsigned shader_size; + const uint32_t patchinfo_code_size; + const uint32_t *patchinfo_code; + const uint32_t *patchinfo_code_offset; + const struct reg_info *sh_reg; + const uint32_t num_sh_reg; + const struct reg_info *context_reg; + const uint32_t num_context_reg; +}; + +struct shader_test_vs_shader { + const uint32_t *shader; + uint32_t shader_size; + const struct reg_info *sh_reg; + uint32_t num_sh_reg; + const struct reg_info *context_reg; + uint32_t num_context_reg; +}; + +static const struct shader_test_cs_shader shader_test_cs[AMDGPU_TEST_GFX_MAX][2] = { + // gfx9, cs_bufferclear + {{bufferclear_cs_shader_gfx9, sizeof(bufferclear_cs_shader_gfx9), bufferclear_cs_shader_registers_gfx9, ARRAY_SIZE(bufferclear_cs_shader_registers_gfx9)}, + // gfx9, cs_buffercopy + {buffercopy_cs_shader_gfx9, sizeof(buffercopy_cs_shader_gfx9), bufferclear_cs_shader_registers_gfx9, ARRAY_SIZE(bufferclear_cs_shader_registers_gfx9)}}, + // gfx10, cs_bufferclear + {{bufferclear_cs_shader_gfx10, sizeof(bufferclear_cs_shader_gfx10), bufferclear_cs_shader_registers_gfx9, ARRAY_SIZE(bufferclear_cs_shader_registers_gfx9)}, + // gfx10, cs_buffercopy + {buffercopy_cs_shader_gfx10, sizeof(bufferclear_cs_shader_gfx10), bufferclear_cs_shader_registers_gfx9, ARRAY_SIZE(bufferclear_cs_shader_registers_gfx9)}}, + // gfx11, cs_bufferclear + {{bufferclear_cs_shader_gfx11, sizeof(bufferclear_cs_shader_gfx11), bufferclear_cs_shader_registers_gfx11, ARRAY_SIZE(bufferclear_cs_shader_registers_gfx11)}, + // gfx11, cs_buffercopy + {buffercopy_cs_shader_gfx11, sizeof(bufferclear_cs_shader_gfx11), bufferclear_cs_shader_registers_gfx11, ARRAY_SIZE(bufferclear_cs_shader_registers_gfx11)}}, +}; + +#define SHADER_PS_INFO(_ps, _n) \ + {ps_##_ps##_shader_gfx##_n, sizeof(ps_##_ps##_shader_gfx##_n), \ + ps_##_ps##_shader_patchinfo_code_size_gfx##_n, \ + ps_##_ps##_shader_patchinfo_code_gfx##_n, \ + ps_##_ps##_shader_patchinfo_offset_gfx##_n, \ + ps_##_ps##_sh_registers_gfx##_n, ps_##_ps##_num_sh_registers_gfx##_n, \ + ps_##_ps##_context_registers_gfx##_n, ps_##_ps##_num_context_registers_gfx##_n} +static const struct shader_test_ps_shader shader_test_ps[AMDGPU_TEST_GFX_MAX][2] = { + {SHADER_PS_INFO(const, 9), SHADER_PS_INFO(tex, 9)}, + {SHADER_PS_INFO(const, 10), SHADER_PS_INFO(tex, 10)}, + {SHADER_PS_INFO(const, 11), SHADER_PS_INFO(tex, 11)}, +}; + +#define SHADER_VS_INFO(_vs, _n) \ + {vs_##_vs##_shader_gfx##_n, sizeof(vs_##_vs##_shader_gfx##_n), \ + vs_##_vs##_sh_registers_gfx##_n, vs_##_vs##_num_sh_registers_gfx##_n, \ + vs_##_vs##_context_registers_gfx##_n, vs_##_vs##_num_context_registers_gfx##_n} +static const struct shader_test_vs_shader shader_test_vs[AMDGPU_TEST_GFX_MAX][1] = { + {SHADER_VS_INFO(RectPosTexFast, 9)}, + {SHADER_VS_INFO(RectPosTexFast, 10)}, + {SHADER_VS_INFO(RectPosTexFast, 11)}, +}; + +struct shader_test_gfx_info { + const uint32_t *preamble_cache; + uint32_t size_preamble_cache; + const uint32_t *cached_cmd; + uint32_t size_cached_cmd; + uint32_t sh_reg_base; + uint32_t context_reg_base; +}; + +#define SHADER_TEST_GFX_INFO(_n) \ + preamblecache_gfx##_n, sizeof(preamblecache_gfx##_n), \ + cached_cmd_gfx##_n, sizeof(cached_cmd_gfx##_n), \ + sh_reg_base_gfx##_n, context_reg_base_gfx##_n + +static struct shader_test_gfx_info shader_test_gfx_info[AMDGPU_TEST_GFX_MAX] = { + {SHADER_TEST_GFX_INFO(9),}, + {SHADER_TEST_GFX_INFO(10),}, + {SHADER_TEST_GFX_INFO(11),}, +}; +#endif diff -Nru libdrm-2.4.110/tests/amdgpu/shader_code_hang.h libdrm-2.4.113/tests/amdgpu/shader_code_hang.h --- libdrm-2.4.110/tests/amdgpu/shader_code_hang.h 1970-01-01 00:00:00.000000000 +0000 +++ libdrm-2.4.113/tests/amdgpu/shader_code_hang.h 2022-08-31 14:38:38.000000000 +0000 @@ -0,0 +1,104 @@ +/* + * Copyright 2022 Advanced Micro Devices, Inc. + * + * 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 _shader_code_hang_h_ +#define _shader_code_hang_h_ + +static const unsigned int memcpy_shader_hang[] = { + 0xFFFFFFFF, 0xBEFE0A7E, 0xBEFC0304, 0xC0C20100, + 0xC0800300, 0xC8080000, 0xC80C0100, 0xC8090001, + 0xC80D0101, 0xBF8C007F, 0xF0800F00, 0x00010002, + 0xBEFE040C, 0xBF8C0F70, 0xBF800000, 0xBF800000, + 0xF800180F, 0x03020100, 0xBF810000 +}; + +struct shader_test_shader_bin { + const uint32_t *shader; + uint32_t header_length; + uint32_t body_length; + uint32_t foot_length; +}; + +static const unsigned int memcpy_cs_hang_slow_ai_codes[] = { + 0xd1fd0000, 0x04010c08, 0xe00c2000, 0x80000100, + 0xbf8c0f70, 0xe01c2000, 0x80010100, 0xbf810000 +}; + +static struct shader_test_shader_bin memcpy_cs_hang_slow_ai = { + memcpy_cs_hang_slow_ai_codes, 4, 3, 1 +}; + +static const unsigned int memcpy_cs_hang_slow_rv_codes[] = { + 0x8e00860c, 0x32000000, 0xe00c2000, 0x80010100, + 0xbf8c0f70, 0xe01c2000, 0x80020100, 0xbf810000 +}; + +static struct shader_test_shader_bin memcpy_cs_hang_slow_rv = { + memcpy_cs_hang_slow_rv_codes, 4, 3, 1 +}; + +static const unsigned int memcpy_cs_hang_slow_nv_codes[] = { + 0xd7460000, 0x04010c08, 0xe00c2000, 0x80000100, + 0xbf8c0f70, 0xe01ca000, 0x80010100, 0xbf810000 +}; + +static struct shader_test_shader_bin memcpy_cs_hang_slow_nv = { + memcpy_cs_hang_slow_nv_codes, 4, 3, 1 +}; + + +static const unsigned int memcpy_ps_hang_slow_ai_codes[] = { + 0xbefc000c, 0xbe8e017e, 0xbefe077e, 0xd4080000, + 0xd4090001, 0xd40c0100, 0xd40d0101, 0xf0800f00, + 0x00400002, 0xbefe010e, 0xbf8c0f70, 0xbf800000, + 0xbf800000, 0xbf800000, 0xbf800000, 0xc400180f, + 0x03020100, 0xbf810000 +}; + +static struct shader_test_shader_bin memcpy_ps_hang_slow_ai = { + memcpy_ps_hang_slow_ai_codes, 7, 2, 9 +}; + +static const unsigned int memcpy_ps_hang_slow_navi10_codes[] = { + 0xBEFC030C,0xBE8E047E,0xBEFE0A7E,0xC8080000, + 0xC80C0100,0xC8090001,0xC80D0101,0xF0800F0A, + 0x00400402,0x00000003,0xBEFE040E,0xBF8C0F70, + 0xBF800000,0xBF800000,0xBF800000,0xBF800000, + 0xF800180F,0x07060504,0xBF810000 +}; + +static struct shader_test_shader_bin memcpy_ps_hang_slow_navi10 = { + memcpy_ps_hang_slow_navi10_codes, 7, 3, 9 +}; + +static const unsigned int memcpy_ps_hang_slow_navi21_codes[] = { + 0xBEFC030C, 0xBE8E047E, 0xBEFE0A7E, 0xC8080000, 0xC8000100, 0xC8090001, 0xC8010101, 0x87FE0E7E, // header + 0xF0800F0A, 0x00400002, 0x00000000, // body - image_sample instruction + 0xBFA3FFE3, 0xBEFE040E, 0xBF8C3F70, 0xBF800000, 0xBF800000, 0xBF800000, 0xBF800000, 0xF800180F, 0x03020100, 0xBF810000 // footer +}; + +static struct shader_test_shader_bin memcpy_ps_hang_slow_navi21 = { + memcpy_ps_hang_slow_navi21_codes, 8, 3, 10 +}; + +#endif diff -Nru libdrm-2.4.110/tests/amdgpu/shader_test_util.c libdrm-2.4.113/tests/amdgpu/shader_test_util.c --- libdrm-2.4.110/tests/amdgpu/shader_test_util.c 1970-01-01 00:00:00.000000000 +0000 +++ libdrm-2.4.113/tests/amdgpu/shader_test_util.c 2022-08-31 14:38:38.000000000 +0000 @@ -0,0 +1,2156 @@ +#include +#include +#include +#include +#include +#include + +#include "CUnit/Basic.h" +#include "amdgpu_test.h" +#include "shader_code.h" + +#define PACKET3_DISPATCH_DIRECT 0x15 +#define PACKET3_CONTEXT_CONTROL 0x28 +#define PACKET3_DRAW_INDEX_AUTO 0x2D +#define PACKET3_SET_CONTEXT_REG 0x69 +#define PACKET3_SET_SH_REG 0x76 +#define PACKET3_SET_SH_REG_OFFSET 0x77 +#define PACKET3_SET_UCONFIG_REG 0x79 +#define PACKET3_SET_SH_REG_INDEX 0x9B + +#define PACKET_TYPE3 3 +#define PACKET3(op, n) ((PACKET_TYPE3 << 30) | \ + (((op) & 0xFF) << 8) | \ + ((n) & 0x3FFF) << 16) +#define PACKET3_COMPUTE(op, n) PACKET3(op, n) | (1 << 1) + + +struct shader_test_bo { + amdgpu_bo_handle bo; + unsigned size; + unsigned heap; + void *ptr; + uint64_t mc_address; + amdgpu_va_handle va; +}; + +struct shader_test_draw { + struct shader_test_bo ps_bo; + enum ps_type ps_type; + struct shader_test_bo vs_bo; + enum vs_type vs_type; +}; +struct shader_test_dispatch { + struct shader_test_bo cs_bo; + enum cs_type cs_type; +}; + +struct shader_test_info { + amdgpu_device_handle device_handle; + enum amdgpu_test_gfx_version version; + unsigned ip; + unsigned ring; + int hang; + int hang_slow; +}; + +struct shader_test_priv { + const struct shader_test_info *info; + unsigned cmd_curr; + + union { + struct shader_test_draw shader_draw; + struct shader_test_dispatch shader_dispatch; + }; + struct shader_test_bo vtx_attributes_mem; + struct shader_test_bo cmd; + struct shader_test_bo src; + struct shader_test_bo dst; +}; + +static int shader_test_bo_alloc(amdgpu_device_handle device_handle, + struct shader_test_bo *shader_test_bo) +{ + return amdgpu_bo_alloc_and_map(device_handle, shader_test_bo->size, 4096, + shader_test_bo->heap, 0, + &(shader_test_bo->bo), (void **)&(shader_test_bo->ptr), + &(shader_test_bo->mc_address), &(shader_test_bo->va)); +} + +static int shader_test_bo_free(struct shader_test_bo *shader_test_bo) +{ + return amdgpu_bo_unmap_and_free(shader_test_bo->bo, shader_test_bo->va, + shader_test_bo->mc_address, + shader_test_bo->size); +} + +void shader_test_for_each(amdgpu_device_handle device_handle, unsigned ip, + void (*fn)(struct shader_test_info *test_info)) +{ + int r; + uint32_t ring_id; + struct shader_test_info test_info = {0}; + struct drm_amdgpu_info_hw_ip info = {0}; + + r = amdgpu_query_hw_ip_info(device_handle, ip, 0, &info); + CU_ASSERT_EQUAL(r, 0); + if (!info.available_rings) { + printf("SKIP ... as there's no %s ring\n", + (ip == AMDGPU_HW_IP_GFX) ? "graphics": "compute"); + return; + } + + switch (info.hw_ip_version_major) { + case 9: + test_info.version = AMDGPU_TEST_GFX_V9; + break; + case 10: + test_info.version = AMDGPU_TEST_GFX_V10; + break; + case 11: + test_info.version = AMDGPU_TEST_GFX_V11; + break; + default: + printf("SKIP ... unsupported gfx version %d\n", info.hw_ip_version_major); + return; + } + + test_info.device_handle = device_handle; + test_info.ip = ip; + + printf("\n"); + for (ring_id = 0; (1 << ring_id) & info.available_rings; ring_id++) { + printf("%s ring %d\n", (ip == AMDGPU_HW_IP_GFX) ? "graphics": "compute", + ring_id); + test_info.ring = ring_id; + fn(&test_info); + } +} + +static void write_context_control(struct shader_test_priv *test_priv) +{ + int i = test_priv->cmd_curr; + uint32_t *ptr = test_priv->cmd.ptr; + + if (test_priv->info->ip == AMDGPU_HW_IP_GFX) { + ptr[i++] = PACKET3(PACKET3_CONTEXT_CONTROL, 1); + ptr[i++] = 0x80000000; + ptr[i++] = 0x80000000; + } + + test_priv->cmd_curr = i; +} + +static void shader_test_load_shader_hang_slow(struct shader_test_bo *shader_bo, + struct shader_test_shader_bin *shader_bin) +{ + int i, j, loop; + + loop = (shader_bo->size / sizeof(uint32_t) - shader_bin->header_length + - shader_bin->foot_length) / shader_bin->body_length; + + memcpy(shader_bo->ptr, shader_bin->shader, shader_bin->header_length * sizeof(uint32_t)); + + j = shader_bin->header_length; + for (i = 0; i < loop; i++) { + memcpy(shader_bo->ptr + j, + shader_bin->shader + shader_bin->header_length, + shader_bin->body_length * sizeof(uint32_t)); + j += shader_bin->body_length; + } + + memcpy(shader_bo->ptr + j, + shader_bin->shader + shader_bin->header_length + shader_bin->body_length, + shader_bin->foot_length * sizeof(uint32_t)); +} + +static void amdgpu_dispatch_load_cs_shader_hang_slow(struct shader_test_priv *test_priv) +{ + struct amdgpu_gpu_info gpu_info = {0}; + struct shader_test_shader_bin *cs_shader_bin; + int r; + + r = amdgpu_query_gpu_info(test_priv->info->device_handle, &gpu_info); + CU_ASSERT_EQUAL(r, 0); + + switch (gpu_info.family_id) { + case AMDGPU_FAMILY_AI: + cs_shader_bin = &memcpy_cs_hang_slow_ai; + break; + case AMDGPU_FAMILY_RV: + cs_shader_bin = &memcpy_cs_hang_slow_rv; + break; + default: + cs_shader_bin = &memcpy_cs_hang_slow_nv; + break; + } + + shader_test_load_shader_hang_slow(&test_priv->shader_dispatch.cs_bo, cs_shader_bin); +} + +static void amdgpu_dispatch_load_cs_shader(struct shader_test_priv *test_priv) +{ + if (test_priv->info->hang) { + if (test_priv->info->hang_slow) + amdgpu_dispatch_load_cs_shader_hang_slow(test_priv); + else + memcpy(test_priv->shader_dispatch.cs_bo.ptr, memcpy_shader_hang, + sizeof(memcpy_shader_hang)); + } else { + memcpy(test_priv->shader_dispatch.cs_bo.ptr, + shader_test_cs[test_priv->info->version][test_priv->shader_dispatch.cs_type].shader, + shader_test_cs[test_priv->info->version][test_priv->shader_dispatch.cs_type].shader_size); + } +} + +static void amdgpu_dispatch_init_gfx9(struct shader_test_priv *test_priv) +{ + int i; + uint32_t *ptr = test_priv->cmd.ptr; + + /* Write context control and load shadowing register if necessary */ + write_context_control(test_priv); + + i = test_priv->cmd_curr; + + /* Issue commands to set default compute state. */ + /* clear mmCOMPUTE_START_Z - mmCOMPUTE_START_X */ + ptr[i++] = PACKET3_COMPUTE(PACKET3_SET_SH_REG, 3); + ptr[i++] = 0x204; + i += 3; + + /* clear mmCOMPUTE_TMPRING_SIZE */ + ptr[i++] = PACKET3_COMPUTE(PACKET3_SET_SH_REG, 1); + ptr[i++] = 0x218; + ptr[i++] = 0; + + test_priv->cmd_curr = i; +} + +static void amdgpu_dispatch_init_gfx10(struct shader_test_priv *test_priv) +{ + int i; + uint32_t *ptr = test_priv->cmd.ptr; + + amdgpu_dispatch_init_gfx9(test_priv); + + i = test_priv->cmd_curr; + + /* mmCOMPUTE_SHADER_CHKSUM */ + ptr[i++] = PACKET3_COMPUTE(PACKET3_SET_SH_REG, 1); + ptr[i++] = 0x22a; + ptr[i++] = 0; + /* mmCOMPUTE_REQ_CTRL */ + ptr[i++] = PACKET3_COMPUTE(PACKET3_SET_SH_REG, 6); + ptr[i++] = 0x222; + i += 6; + /* mmCP_COHER_START_DELAY */ + ptr[i++] = PACKET3(PACKET3_SET_UCONFIG_REG, 1); + ptr[i++] = 0x7b; + ptr[i++] = 0x20; + + test_priv->cmd_curr = i; +} + +static void amdgpu_dispatch_init_gfx11(struct shader_test_priv *test_priv) +{ + int i; + uint32_t *ptr = test_priv->cmd.ptr; + + /* Write context control and load shadowing register if necessary */ + write_context_control(test_priv); + + i = test_priv->cmd_curr; + + /* Issue commands to set default compute state. */ + /* clear mmCOMPUTE_START_Z - mmCOMPUTE_START_X */ + ptr[i++] = PACKET3_COMPUTE(PACKET3_SET_SH_REG, 3); + ptr[i++] = 0x204; + i += 3; + + /* clear mmCOMPUTE_TMPRING_SIZE */ + ptr[i++] = PACKET3_COMPUTE(PACKET3_SET_SH_REG, 1); + ptr[i++] = 0x218; + ptr[i++] = 0; + + /* mmCOMPUTE_REQ_CTRL */ + ptr[i++] = PACKET3_COMPUTE(PACKET3_SET_SH_REG, 1); + ptr[i++] = 0x222; + ptr[i++] = 0; + + /* mmCOMPUTE_USER_ACCUM_0 .. 3*/ + ptr[i++] = PACKET3_COMPUTE(PACKET3_SET_SH_REG, 4); + ptr[i++] = 0x224; + i += 4; + + /* mmCOMPUTE_SHADER_CHKSUM */ + ptr[i++] = PACKET3(PACKET3_SET_UCONFIG_REG, 1); + ptr[i++] = 0x22a; + ptr[i++] = 0; + + test_priv->cmd_curr = i; +} + +static void amdgpu_dispatch_init(struct shader_test_priv *test_priv) +{ + switch (test_priv->info->version) { + case AMDGPU_TEST_GFX_V9: + amdgpu_dispatch_init_gfx9(test_priv); + break; + case AMDGPU_TEST_GFX_V10: + amdgpu_dispatch_init_gfx10(test_priv); + break; + case AMDGPU_TEST_GFX_V11: + amdgpu_dispatch_init_gfx11(test_priv); + break; + } +} + +static void amdgpu_dispatch_write_cumask(struct shader_test_priv *test_priv) +{ + int i = test_priv->cmd_curr; + uint32_t *ptr = test_priv->cmd.ptr; + + /* Issue commands to set cu mask used in current dispatch */ + switch (test_priv->info->version) { + case AMDGPU_TEST_GFX_V9: + /* set mmCOMPUTE_STATIC_THREAD_MGMT_SE1 - mmCOMPUTE_STATIC_THREAD_MGMT_SE0 */ + ptr[i++] = PACKET3_COMPUTE(PACKET3_SET_SH_REG, 2); + ptr[i++] = 0x216; + ptr[i++] = 0xffffffff; + ptr[i++] = 0xffffffff; + /* set mmCOMPUTE_STATIC_THREAD_MGMT_SE3 - mmCOMPUTE_STATIC_THREAD_MGMT_SE2 */ + ptr[i++] = PACKET3_COMPUTE(PACKET3_SET_SH_REG, 2); + ptr[i++] = 0x219; + ptr[i++] = 0xffffffff; + ptr[i++] = 0xffffffff; + break; + case AMDGPU_TEST_GFX_V10: + case AMDGPU_TEST_GFX_V11: + /* set mmCOMPUTE_STATIC_THREAD_MGMT_SE1 - mmCOMPUTE_STATIC_THREAD_MGMT_SE0 */ + ptr[i++] = PACKET3_COMPUTE(PACKET3_SET_SH_REG_INDEX, 2); + ptr[i++] = 0x30000216; + ptr[i++] = 0xffffffff; + ptr[i++] = 0xffffffff; + /* set mmCOMPUTE_STATIC_THREAD_MGMT_SE3 - mmCOMPUTE_STATIC_THREAD_MGMT_SE2 */ + ptr[i++] = PACKET3_COMPUTE(PACKET3_SET_SH_REG_INDEX, 2); + ptr[i++] = 0x30000219; + ptr[i++] = 0xffffffff; + ptr[i++] = 0xffffffff; + break; + } + + test_priv->cmd_curr = i; +} + +static void amdgpu_dispatch_write2hw_gfx9(struct shader_test_priv *test_priv) +{ + const struct shader_test_cs_shader *cs_shader = &shader_test_cs[test_priv->info->version][test_priv->shader_dispatch.cs_type]; + int j, i = test_priv->cmd_curr; + uint32_t *ptr = test_priv->cmd.ptr; + uint64_t shader_addr = test_priv->shader_dispatch.cs_bo.mc_address; + + /* Writes shader state to HW */ + /* set mmCOMPUTE_PGM_HI - mmCOMPUTE_PGM_LO */ + ptr[i++] = PACKET3_COMPUTE(PACKET3_SET_SH_REG, 2); + ptr[i++] = 0x20c; + ptr[i++] = (shader_addr >> 8); + ptr[i++] = (shader_addr >> 40); + /* write sh regs*/ + for (j = 0; j < cs_shader->num_sh_reg; j++) { + ptr[i++] = PACKET3_COMPUTE(PACKET3_SET_SH_REG, 1); + /* - Gfx9ShRegBase */ + ptr[i++] = cs_shader->sh_reg[j].reg_offset - shader_test_gfx_info[test_priv->info->version].sh_reg_base; + ptr[i++] = cs_shader->sh_reg[j].reg_value; + } + + /* Write constant data */ + if (CS_BUFFERCLEAR == test_priv->shader_dispatch.cs_type) { + ptr[i++] = PACKET3_COMPUTE(PACKET3_SET_SH_REG, 4); + ptr[i++] = 0x240; + ptr[i++] = test_priv->dst.mc_address; + ptr[i++] = (test_priv->dst.mc_address >> 32) | 0x100000; + ptr[i++] = test_priv->dst.size / 16; + ptr[i++] = 0x74fac; + + /* Sets a range of pixel shader constants */ + ptr[i++] = PACKET3_COMPUTE(PACKET3_SET_SH_REG, 4); + ptr[i++] = 0x244; + ptr[i++] = 0x22222222; + ptr[i++] = 0x22222222; + ptr[i++] = 0x22222222; + ptr[i++] = 0x22222222; + } else { + ptr[i++] = PACKET3_COMPUTE(PACKET3_SET_SH_REG, 4); + ptr[i++] = 0x240; + ptr[i++] = test_priv->src.mc_address; + ptr[i++] = (test_priv->src.mc_address >> 32) | 0x100000; + ptr[i++] = test_priv->src.size / 16; + ptr[i++] = 0x74fac; + + /* Writes the UAV constant data to the SGPRs. */ + ptr[i++] = PACKET3_COMPUTE(PACKET3_SET_SH_REG, 4); + ptr[i++] = 0x244; + ptr[i++] = test_priv->dst.mc_address; + ptr[i++] = (test_priv->dst.mc_address >> 32) | 0x100000; + ptr[i++] = test_priv->dst.size / 16; + ptr[i++] = 0x74fac; + } + + test_priv->cmd_curr = i; +} + +static void amdgpu_dispatch_write2hw_gfx10(struct shader_test_priv *test_priv) +{ + int i = test_priv->cmd_curr; + uint32_t *ptr = test_priv->cmd.ptr; + const struct shader_test_cs_shader *cs_shader = &shader_test_cs[test_priv->info->version][test_priv->shader_dispatch.cs_type]; + int j; + uint64_t shader_addr = test_priv->shader_dispatch.cs_bo.mc_address; + + /* Writes shader state to HW */ + /* set mmCOMPUTE_PGM_HI - mmCOMPUTE_PGM_LO */ + ptr[i++] = PACKET3_COMPUTE(PACKET3_SET_SH_REG, 2); + ptr[i++] = 0x20c; + ptr[i++] = (shader_addr >> 8); + ptr[i++] = (shader_addr >> 40); + /* write sh regs*/ + for (j = 0; j < cs_shader->num_sh_reg; j++) { + ptr[i++] = PACKET3_COMPUTE(PACKET3_SET_SH_REG, 1); + /* - Gfx9ShRegBase */ + ptr[i++] = cs_shader->sh_reg[j].reg_offset - shader_test_gfx_info[test_priv->info->version].sh_reg_base; + ptr[i++] = cs_shader->sh_reg[j].reg_value; + } + + /* mmCOMPUTE_PGM_RSRC3 */ + ptr[i++] = PACKET3_COMPUTE(PACKET3_SET_SH_REG, 1); + ptr[i++] = 0x228; + ptr[i++] = 0; + + if (CS_BUFFERCLEAR == test_priv->shader_dispatch.cs_type) { + ptr[i++] = PACKET3_COMPUTE(PACKET3_SET_SH_REG, 4); + ptr[i++] = 0x240; + ptr[i++] = test_priv->dst.mc_address; + ptr[i++] = (test_priv->dst.mc_address >> 32) | 0x100000; + ptr[i++] = test_priv->dst.size / 16; + ptr[i++] = 0x1104bfac; + + /* Sets a range of pixel shader constants */ + ptr[i++] = PACKET3_COMPUTE(PACKET3_SET_SH_REG, 4); + ptr[i++] = 0x244; + ptr[i++] = 0x22222222; + ptr[i++] = 0x22222222; + ptr[i++] = 0x22222222; + ptr[i++] = 0x22222222; + } else { + ptr[i++] = PACKET3_COMPUTE(PACKET3_SET_SH_REG, 4); + ptr[i++] = 0x240; + ptr[i++] = test_priv->src.mc_address; + ptr[i++] = (test_priv->src.mc_address >> 32) | 0x100000; + ptr[i++] = test_priv->src.size / 16; + ptr[i++] = 0x1104bfac; + + /* Writes the UAV constant data to the SGPRs. */ + ptr[i++] = PACKET3_COMPUTE(PACKET3_SET_SH_REG, 4); + ptr[i++] = 0x244; + ptr[i++] = test_priv->dst.mc_address; + ptr[i++] = (test_priv->dst.mc_address>> 32) | 0x100000; + ptr[i++] = test_priv->dst.size / 16; + ptr[i++] = 0x1104bfac; + } + + test_priv->cmd_curr = i; +} + +static void amdgpu_dispatch_write2hw_gfx11(struct shader_test_priv *test_priv) +{ + enum amdgpu_test_gfx_version version = test_priv->info->version; + const struct shader_test_cs_shader *cs_shader = &shader_test_cs[version][test_priv->shader_dispatch.cs_type]; + int j, i = test_priv->cmd_curr; + uint32_t *ptr = test_priv->cmd.ptr; + uint64_t shader_addr = test_priv->shader_dispatch.cs_bo.mc_address; + + /* Writes shader state to HW */ + /* set mmCOMPUTE_PGM_HI - mmCOMPUTE_PGM_LO */ + ptr[i++] = PACKET3_COMPUTE(PACKET3_SET_SH_REG, 2); + ptr[i++] = 0x20c; + ptr[i++] = (shader_addr >> 8); + ptr[i++] = (shader_addr >> 40); + + /* write sh regs*/ + for (j = 0; j < cs_shader->num_sh_reg; j++) { + ptr[i++] = PACKET3_COMPUTE(PACKET3_SET_SH_REG, 1); + /* - Gfx9ShRegBase */ + ptr[i++] = cs_shader->sh_reg[j].reg_offset - shader_test_gfx_info[version].sh_reg_base; + ptr[i++] = cs_shader->sh_reg[j].reg_value; + if (cs_shader->sh_reg[j].reg_offset == 0x2E12) + ptr[i-1] &= ~(1<<29); + } + + /* mmCOMPUTE_PGM_RSRC3 */ + ptr[i++] = PACKET3_COMPUTE(PACKET3_SET_SH_REG, 1); + ptr[i++] = 0x228; + ptr[i++] = 0x3f0; + + /* Write constant data */ + /* Writes the texture resource constants data to the SGPRs */ + if (CS_BUFFERCLEAR == test_priv->shader_dispatch.cs_type) { + ptr[i++] = PACKET3_COMPUTE(PACKET3_SET_SH_REG, 4); + ptr[i++] = 0x240; + ptr[i++] = test_priv->dst.mc_address; + ptr[i++] = (test_priv->dst.mc_address >> 32) | 0x100000; + ptr[i++] = test_priv->dst.size / 16; + ptr[i++] = 0x1003dfac; + + /* Sets a range of pixel shader constants */ + ptr[i++] = PACKET3_COMPUTE(PACKET3_SET_SH_REG, 4); + ptr[i++] = 0x244; + ptr[i++] = 0x22222222; + ptr[i++] = 0x22222222; + ptr[i++] = 0x22222222; + ptr[i++] = 0x22222222; + } else { + ptr[i++] = PACKET3_COMPUTE(PACKET3_SET_SH_REG, 4); + ptr[i++] = 0x240; + ptr[i++] = test_priv->src.mc_address; + ptr[i++] = (test_priv->src.mc_address >> 32) | 0x100000; + ptr[i++] = test_priv->src.size / 16; + ptr[i++] = 0x1003dfac; + + /* Writes the UAV constant data to the SGPRs. */ + ptr[i++] = PACKET3_COMPUTE(PACKET3_SET_SH_REG, 4); + ptr[i++] = 0x244; + ptr[i++] = test_priv->dst.mc_address; + ptr[i++] = (test_priv->dst.mc_address>> 32) | 0x100000; + ptr[i++] = test_priv->dst.size / 16; + ptr[i++] = 0x1003dfac; + } + + test_priv->cmd_curr = i; +} + +static void amdgpu_dispatch_write2hw(struct shader_test_priv *test_priv) +{ + switch (test_priv->info->version) { + case AMDGPU_TEST_GFX_V9: + amdgpu_dispatch_write2hw_gfx9(test_priv); + break; + case AMDGPU_TEST_GFX_V10: + amdgpu_dispatch_write2hw_gfx10(test_priv); + break; + case AMDGPU_TEST_GFX_V11: + amdgpu_dispatch_write2hw_gfx11(test_priv); + break; + } +} + +static void amdgpu_dispatch_write_dispatch_cmd(struct shader_test_priv *test_priv) +{ + int i = test_priv->cmd_curr; + uint32_t *ptr = test_priv->cmd.ptr; + + /* clear mmCOMPUTE_RESOURCE_LIMITS */ + ptr[i++] = PACKET3_COMPUTE(PACKET3_SET_SH_REG, 1); + ptr[i++] = 0x215; + ptr[i++] = 0; + + /* dispatch direct command */ + ptr[i++] = PACKET3_COMPUTE(PACKET3_DISPATCH_DIRECT, 3); + ptr[i++] = (test_priv->dst.size / 16 + 0x40 - 1 ) / 0x40;//0x10; + ptr[i++] = 1; + ptr[i++] = 1; + ptr[i++] = 1; + + test_priv->cmd_curr = i; +} +static void amdgpu_test_dispatch_memset(struct shader_test_info *test_info) +{ + amdgpu_context_handle context_handle; + amdgpu_bo_handle resources[3]; + struct shader_test_priv test_priv; + struct shader_test_bo *cmd = &(test_priv.cmd); + struct shader_test_bo *dst = &(test_priv.dst); + struct shader_test_bo *shader = &(test_priv.shader_dispatch.cs_bo); + uint32_t *ptr_cmd; + uint8_t *ptr_dst; + int i, r; + struct amdgpu_cs_request ibs_request = {0}; + struct amdgpu_cs_ib_info ib_info= {0}; + amdgpu_bo_list_handle bo_list; + struct amdgpu_cs_fence fence_status = {0}; + uint32_t expired; + uint8_t cptr[16]; + + memset(&test_priv, 0, sizeof(test_priv)); + test_priv.info = test_info; + test_priv.shader_dispatch.cs_type = CS_BUFFERCLEAR; + r = amdgpu_cs_ctx_create(test_info->device_handle, &context_handle); + CU_ASSERT_EQUAL(r, 0); + + cmd->size = 4096; + cmd->heap = AMDGPU_GEM_DOMAIN_GTT; + r = shader_test_bo_alloc(test_info->device_handle, cmd); + CU_ASSERT_EQUAL(r, 0); + ptr_cmd = cmd->ptr; + memset(ptr_cmd, 0, cmd->size); + + shader->size = 4096; + shader->heap = AMDGPU_GEM_DOMAIN_VRAM; + r = shader_test_bo_alloc(test_info->device_handle, shader); + CU_ASSERT_EQUAL(r, 0); + memset(shader->ptr, 0, shader->size); + amdgpu_dispatch_load_cs_shader(&test_priv); + + dst->size = 0x4000; + dst->heap = AMDGPU_GEM_DOMAIN_VRAM; + r = shader_test_bo_alloc(test_info->device_handle, dst); + CU_ASSERT_EQUAL(r, 0); + + amdgpu_dispatch_init(&test_priv); + + /* Issue commands to set cu mask used in current dispatch */ + amdgpu_dispatch_write_cumask(&test_priv); + + /* Writes shader state to HW */ + amdgpu_dispatch_write2hw(&test_priv); + + amdgpu_dispatch_write_dispatch_cmd(&test_priv); + + i = test_priv.cmd_curr; + while (i & 7) + ptr_cmd[i++] = 0xffff1000; /* type3 nop packet */ + test_priv.cmd_curr = i; + + resources[0] = dst->bo; + resources[1] = shader->bo; + resources[2] = cmd->bo; + r = amdgpu_bo_list_create(test_info->device_handle, 3, resources, NULL, &bo_list); + CU_ASSERT_EQUAL(r, 0); + + ib_info.ib_mc_address = cmd->mc_address; + ib_info.size = test_priv.cmd_curr; + ibs_request.ip_type = test_info->ip; + ibs_request.ring = test_info->ring; + ibs_request.resources = bo_list; + ibs_request.number_of_ibs = 1; + ibs_request.ibs = &ib_info; + ibs_request.fence_info.handle = NULL; + + /* submit CS */ + r = amdgpu_cs_submit(context_handle, 0, &ibs_request, 1); + CU_ASSERT_EQUAL(r, 0); + + r = amdgpu_bo_list_destroy(bo_list); + CU_ASSERT_EQUAL(r, 0); + + fence_status.ip_type = test_info->ip; + fence_status.ip_instance = 0; + fence_status.ring = test_info->ring; + fence_status.context = context_handle; + fence_status.fence = ibs_request.seq_no; + + /* wait for IB accomplished */ + r = amdgpu_cs_query_fence_status(&fence_status, + AMDGPU_TIMEOUT_INFINITE, + 0, &expired); + CU_ASSERT_EQUAL(r, 0); + CU_ASSERT_EQUAL(expired, true); + + /* verify if memset test result meets with expected */ + i = 0; + ptr_dst = (uint8_t *)(dst->ptr); + memset(cptr, 0x22, 16); + CU_ASSERT_EQUAL(memcmp(ptr_dst + i, cptr, 16), 0); + i = dst->size - 16; + CU_ASSERT_EQUAL(memcmp(ptr_dst + i, cptr, 16), 0); + i = dst->size / 2; + CU_ASSERT_EQUAL(memcmp(ptr_dst + i, cptr, 16), 0); + + r = shader_test_bo_free(dst); + CU_ASSERT_EQUAL(r, 0); + + r = shader_test_bo_free(shader); + CU_ASSERT_EQUAL(r, 0); + + r = shader_test_bo_free(cmd); + CU_ASSERT_EQUAL(r, 0); + + r = amdgpu_cs_ctx_free(context_handle); + CU_ASSERT_EQUAL(r, 0); +} + +static +void amdgpu_test_dispatch_memcpy(struct shader_test_info *test_info) +{ + struct shader_test_priv test_priv; + amdgpu_context_handle context_handle; + amdgpu_bo_handle resources[4]; + struct shader_test_bo *cmd = &(test_priv.cmd); + struct shader_test_bo *src = &(test_priv.src); + struct shader_test_bo *dst = &(test_priv.dst); + struct shader_test_bo *shader = &(test_priv.shader_dispatch.cs_bo); + uint32_t *ptr_cmd; + uint8_t *ptr_src; + uint8_t *ptr_dst; + int i, r; + struct amdgpu_cs_request ibs_request = {0}; + struct amdgpu_cs_ib_info ib_info= {0}; + uint32_t expired, hang_state, hangs; + amdgpu_bo_list_handle bo_list; + struct amdgpu_cs_fence fence_status = {0}; + + memset(&test_priv, 0, sizeof(test_priv)); + test_priv.info = test_info; + test_priv.cmd.size = 4096; + test_priv.cmd.heap = AMDGPU_GEM_DOMAIN_GTT; + + test_priv.shader_dispatch.cs_bo.heap = AMDGPU_GEM_DOMAIN_VRAM; + test_priv.shader_dispatch.cs_type = CS_BUFFERCOPY; + test_priv.src.heap = AMDGPU_GEM_DOMAIN_VRAM; + test_priv.dst.heap = AMDGPU_GEM_DOMAIN_VRAM; + if (test_info->hang_slow) { + test_priv.shader_dispatch.cs_bo.size = 0x4000000; + test_priv.src.size = 0x4000000; + test_priv.dst.size = 0x4000000; + } else { + test_priv.shader_dispatch.cs_bo.size = 4096; + test_priv.src.size = 0x4000; + test_priv.dst.size = 0x4000; + } + + r = amdgpu_cs_ctx_create(test_info->device_handle, &context_handle); + CU_ASSERT_EQUAL(r, 0); + + r = shader_test_bo_alloc(test_info->device_handle, cmd); + CU_ASSERT_EQUAL(r, 0); + ptr_cmd = cmd->ptr; + memset(ptr_cmd, 0, cmd->size); + + r = shader_test_bo_alloc(test_info->device_handle, shader); + CU_ASSERT_EQUAL(r, 0); + memset(shader->ptr, 0, shader->size); + amdgpu_dispatch_load_cs_shader(&test_priv); + + r = shader_test_bo_alloc(test_info->device_handle, src); + CU_ASSERT_EQUAL(r, 0); + ptr_src = (uint8_t *)(src->ptr); + memset(ptr_src, 0x55, src->size); + + r = shader_test_bo_alloc(test_info->device_handle, dst); + CU_ASSERT_EQUAL(r, 0); + + amdgpu_dispatch_init(&test_priv); + + /* Issue commands to set cu mask used in current dispatch */ + amdgpu_dispatch_write_cumask(&test_priv); + + /* Writes shader state to HW */ + amdgpu_dispatch_write2hw(&test_priv); + + amdgpu_dispatch_write_dispatch_cmd(&test_priv); + + i = test_priv.cmd_curr; + while (i & 7) + ptr_cmd[i++] = 0xffff1000; /* type3 nop packet */ + test_priv.cmd_curr = i; + + resources[0] = shader->bo; + resources[1] = src->bo; + resources[2] = dst->bo; + resources[3] = cmd->bo; + r = amdgpu_bo_list_create(test_info->device_handle, 4, resources, NULL, &bo_list); + CU_ASSERT_EQUAL(r, 0); + + ib_info.ib_mc_address = cmd->mc_address; + ib_info.size = test_priv.cmd_curr; + ibs_request.ip_type = test_info->ip; + ibs_request.ring = test_info->ring; + ibs_request.resources = bo_list; + ibs_request.number_of_ibs = 1; + ibs_request.ibs = &ib_info; + ibs_request.fence_info.handle = NULL; + r = amdgpu_cs_submit(context_handle, 0, &ibs_request, 1); + CU_ASSERT_EQUAL(r, 0); + + fence_status.ip_type = test_info->ip; + fence_status.ip_instance = 0; + fence_status.ring = test_info->ring; + fence_status.context = context_handle; + fence_status.fence = ibs_request.seq_no; + + /* wait for IB accomplished */ + r = amdgpu_cs_query_fence_status(&fence_status, + AMDGPU_TIMEOUT_INFINITE, + 0, &expired); + + if (!test_info->hang) { + CU_ASSERT_EQUAL(r, 0); + CU_ASSERT_EQUAL(expired, true); + + /* verify if memcpy test result meets with expected */ + i = 0; + ptr_dst = (uint8_t *)dst->ptr; + CU_ASSERT_EQUAL(memcmp(ptr_dst + i, ptr_src + i, 16), 0); + i = dst->size - 16; + CU_ASSERT_EQUAL(memcmp(ptr_dst + i, ptr_src + i, 16), 0); + i = dst->size / 2; + CU_ASSERT_EQUAL(memcmp(ptr_dst + i, ptr_src + i, 16), 0); + } else { + r = amdgpu_cs_query_reset_state(context_handle, &hang_state, &hangs); + CU_ASSERT_EQUAL(r, 0); + CU_ASSERT_EQUAL(hang_state, AMDGPU_CTX_UNKNOWN_RESET); + } + + r = amdgpu_bo_list_destroy(bo_list); + CU_ASSERT_EQUAL(r, 0); + + r = shader_test_bo_free(src); + CU_ASSERT_EQUAL(r, 0); + r = shader_test_bo_free(dst); + CU_ASSERT_EQUAL(r, 0); + + r = shader_test_bo_free(shader); + CU_ASSERT_EQUAL(r, 0); + + r = shader_test_bo_free(cmd); + + r = amdgpu_cs_ctx_free(context_handle); + CU_ASSERT_EQUAL(r, 0); +} + +static void shader_test_dispatch_cb(struct shader_test_info *test_info) +{ + amdgpu_test_dispatch_memset(test_info); + amdgpu_test_dispatch_memcpy(test_info); +} +static void shader_test_dispatch_hang_cb(struct shader_test_info *test_info) +{ + test_info->hang = 0; + amdgpu_test_dispatch_memcpy(test_info); + + test_info->hang = 1; + amdgpu_test_dispatch_memcpy(test_info); + + test_info->hang = 0; + amdgpu_test_dispatch_memcpy(test_info); +} + +static void shader_test_dispatch_hang_slow_cb(struct shader_test_info *test_info) +{ + test_info->hang = 0; + test_info->hang_slow = 0; + amdgpu_test_dispatch_memcpy(test_info); + + test_info->hang = 1; + test_info->hang_slow = 1; + amdgpu_test_dispatch_memcpy(test_info); + + test_info->hang = 0; + test_info->hang_slow = 0; + amdgpu_test_dispatch_memcpy(test_info); +} + +void amdgpu_test_dispatch_helper(amdgpu_device_handle device_handle, unsigned ip) +{ + shader_test_for_each(device_handle, ip, shader_test_dispatch_cb); +} + +void amdgpu_test_dispatch_hang_helper(amdgpu_device_handle device_handle, uint32_t ip) +{ + shader_test_for_each(device_handle, ip, shader_test_dispatch_hang_cb); +} + +void amdgpu_test_dispatch_hang_slow_helper(amdgpu_device_handle device_handle, uint32_t ip) +{ + shader_test_for_each(device_handle, ip, shader_test_dispatch_hang_slow_cb); +} + +static void amdgpu_draw_load_ps_shader_hang_slow(struct shader_test_priv *test_priv) +{ + struct amdgpu_gpu_info gpu_info = {0}; + struct shader_test_shader_bin *ps_shader_bin = &memcpy_ps_hang_slow_navi21; + int r; + + r = amdgpu_query_gpu_info(test_priv->info->device_handle, &gpu_info); + CU_ASSERT_EQUAL(r, 0); + + switch (gpu_info.family_id) { + case AMDGPU_FAMILY_AI: + case AMDGPU_FAMILY_RV: + ps_shader_bin = &memcpy_ps_hang_slow_ai; + break; + case AMDGPU_FAMILY_NV: + if (gpu_info.chip_external_rev < 40) + ps_shader_bin = &memcpy_ps_hang_slow_navi10; + break; + } + + shader_test_load_shader_hang_slow(&test_priv->shader_draw.ps_bo, ps_shader_bin); +} + +static uint32_t round_up_size(uint32_t size) +{ + return (size + 255) & ~255; +} +static void amdgpu_draw_load_ps_shader(struct shader_test_priv *test_priv) +{ + uint8_t *ptr_shader = test_priv->shader_draw.ps_bo.ptr; + const struct shader_test_ps_shader *shader; + uint32_t shader_offset, num_export_fmt; + uint32_t mem_offset, patch_code_offset; + int i; + + if (test_priv->info->hang) { + if (test_priv->info->hang_slow) + amdgpu_draw_load_ps_shader_hang_slow(test_priv); + else + memcpy(ptr_shader, memcpy_shader_hang, sizeof(memcpy_shader_hang)); + + return; + } + + shader = &shader_test_ps[test_priv->info->version][test_priv->shader_draw.ps_type]; + num_export_fmt = 10; + shader_offset = round_up_size(shader->shader_size); + /* write main shader program */ + for (i = 0 ; i < num_export_fmt; i++) { + mem_offset = i * shader_offset; + memcpy(ptr_shader + mem_offset, shader->shader, shader->shader_size); + } + + /* overwrite patch codes */ + for (i = 0 ; i < num_export_fmt; i++) { + mem_offset = i * shader_offset + shader->patchinfo_code_offset[0] * sizeof(uint32_t); + patch_code_offset = i * shader->patchinfo_code_size; + memcpy(ptr_shader + mem_offset, + shader->patchinfo_code + patch_code_offset, + shader->patchinfo_code_size * sizeof(uint32_t)); + } +} + +/* load RectPosTexFast_VS */ +static void amdgpu_draw_load_vs_shader(struct shader_test_priv *test_priv) +{ + uint8_t *ptr_shader = test_priv->shader_draw.vs_bo.ptr; + const struct shader_test_vs_shader *shader = &shader_test_vs[test_priv->info->version][test_priv->shader_draw.vs_type]; + + memcpy(ptr_shader, shader->shader, shader->shader_size); +} + +static void amdgpu_draw_init(struct shader_test_priv *test_priv) +{ + int i; + uint32_t *ptr = test_priv->cmd.ptr; + const struct shader_test_gfx_info *gfx_info = &shader_test_gfx_info[test_priv->info->version]; + + /* Write context control and load shadowing register if necessary */ + write_context_control(test_priv); + i = test_priv->cmd_curr; + + if (test_priv->info->version == AMDGPU_TEST_GFX_V11) { + ptr[i++] = PACKET3(PACKET3_SET_UCONFIG_REG, 1); + ptr[i++] = 0x446; + ptr[i++] = (test_priv->vtx_attributes_mem.mc_address >> 16); + // mmSPI_ATTRIBUTE_RING_SIZE + ptr[i++] = PACKET3(PACKET3_SET_UCONFIG_REG, 1); + ptr[i++] = 0x447; + ptr[i++] = 0x20001; + } + memcpy(ptr + i, gfx_info->preamble_cache, gfx_info->size_preamble_cache); + + test_priv->cmd_curr = i + gfx_info->size_preamble_cache/sizeof(uint32_t); +} + +static void amdgpu_draw_setup_and_write_drawblt_surf_info_gfx9(struct shader_test_priv *test_priv) +{ + int i = test_priv->cmd_curr; + uint32_t *ptr = test_priv->cmd.ptr; + + /* setup color buffer */ + /* offset reg + 0xA318 CB_COLOR0_BASE + 0xA319 CB_COLOR0_BASE_EXT + 0xA31A CB_COLOR0_ATTRIB2 + 0xA31B CB_COLOR0_VIEW + 0xA31C CB_COLOR0_INFO + 0xA31D CB_COLOR0_ATTRIB + 0xA31E CB_COLOR0_DCC_CONTROL + 0xA31F CB_COLOR0_CMASK + 0xA320 CB_COLOR0_CMASK_BASE_EXT + 0xA321 CB_COLOR0_FMASK + 0xA322 CB_COLOR0_FMASK_BASE_EXT + 0xA323 CB_COLOR0_CLEAR_WORD0 + 0xA324 CB_COLOR0_CLEAR_WORD1 + 0xA325 CB_COLOR0_DCC_BASE + 0xA326 CB_COLOR0_DCC_BASE_EXT */ + ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 15); + ptr[i++] = 0x318; + ptr[i++] = test_priv->dst.mc_address >> 8; + ptr[i++] = test_priv->dst.mc_address >> 40; + ptr[i++] = test_priv->info->hang_slow ? 0x3ffc7ff : 0x7c01f; + ptr[i++] = 0; + ptr[i++] = 0x50438; + ptr[i++] = 0x10140000; + i += 9; + + /* mmCB_MRT0_EPITCH */ + ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1); + ptr[i++] = 0x1e8; + ptr[i++] = test_priv->info->hang_slow ? 0xfff : 0x1f; + + /* 0xA32B CB_COLOR1_BASE */ + ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1); + ptr[i++] = 0x32b; + ptr[i++] = 0; + + /* 0xA33A CB_COLOR1_BASE */ + ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1); + ptr[i++] = 0x33a; + ptr[i++] = 0; + + /* SPI_SHADER_COL_FORMAT */ + ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1); + ptr[i++] = 0x1c5; + ptr[i++] = 9; + + /* Setup depth buffer */ + /* mmDB_Z_INFO */ + ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 2); + ptr[i++] = 0xe; + i += 2; + + test_priv->cmd_curr = i; +} +static void amdgpu_draw_setup_and_write_drawblt_surf_info_gfx10(struct shader_test_priv *test_priv) +{ + int i = test_priv->cmd_curr; + uint32_t *ptr = test_priv->cmd.ptr; + + /* setup color buffer */ + /* 0xA318 CB_COLOR0_BASE + 0xA319 CB_COLOR0_PITCH + 0xA31A CB_COLOR0_SLICE + 0xA31B CB_COLOR0_VIEW + 0xA31C CB_COLOR0_INFO + 0xA31D CB_COLOR0_ATTRIB + 0xA31E CB_COLOR0_DCC_CONTROL + 0xA31F CB_COLOR0_CMASK + 0xA320 CB_COLOR0_CMASK_SLICE + 0xA321 CB_COLOR0_FMASK + 0xA322 CB_COLOR0_FMASK_SLICE + 0xA323 CB_COLOR0_CLEAR_WORD0 + 0xA324 CB_COLOR0_CLEAR_WORD1 + 0xA325 CB_COLOR0_DCC_BASE */ + ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 14); + ptr[i++] = 0x318; + ptr[i++] = test_priv->dst.mc_address >> 8; + i += 3; + ptr[i++] = 0x50438; + i += 9; + + /* 0xA390 CB_COLOR0_BASE_EXT */ + ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1); + ptr[i++] = 0x390; + ptr[i++] = test_priv->dst.mc_address >> 40; + + /* 0xA398 CB_COLOR0_CMASK_BASE_EXT */ + ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1); + ptr[i++] = 0x398; + ptr[i++] = 0; + + /* 0xA3A0 CB_COLOR0_FMASK_BASE_EXT */ + ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1); + ptr[i++] = 0x3a0; + ptr[i++] = 0; + + /* 0xA3A8 CB_COLOR0_DCC_BASE_EXT */ + ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1); + ptr[i++] = 0x3a8; + ptr[i++] = 0; + + /* 0xA3B0 CB_COLOR0_ATTRIB2 */ + ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1); + ptr[i++] = 0x3b0; + ptr[i++] = test_priv->info->hang_slow ? 0x3ffc7ff : 0x7c01f; + + /* 0xA3B8 CB_COLOR0_ATTRIB3 */ + ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1); + ptr[i++] = 0x3b8; + ptr[i++] = 0x9014000; + + /* 0xA32B CB_COLOR1_BASE */ + ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1); + ptr[i++] = 0x32b; + ptr[i++] = 0; + + /* 0xA33A CB_COLOR1_BASE */ + ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1); + ptr[i++] = 0x33a; + ptr[i++] = 0; + + /* SPI_SHADER_COL_FORMAT */ + ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1); + ptr[i++] = 0x1c5; + ptr[i++] = 9; + + /* Setup depth buffer */ + /* mmDB_Z_INFO */ + ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 2); + ptr[i++] = 0x10; + i += 2; + + test_priv->cmd_curr = i; +} + +static void amdgpu_draw_setup_and_write_drawblt_surf_info_gfx11(struct shader_test_priv *test_priv) +{ + int i = test_priv->cmd_curr; + uint32_t *ptr = test_priv->cmd.ptr; + + /* mmCB_COLOR0_BASE */ + ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1); + ptr[i++] = 0x318; + ptr[i++] = test_priv->dst.mc_address >> 8; + /* mmCB_COLOR0_VIEW .. mmCB_COLOR0_DCC_CONTROL */ + ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 4); + ptr[i++] = 0x31b; + i++; + ptr[i++] = 0x5040e; + i += 2; + /* mmCB_COLOR0_DCC_BASE */ + ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1); + ptr[i++] = 0x325; + ptr[i++] = 0; + /* mmCB_COLOR0_BASE_EXT */ + ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1); + ptr[i++] = 0x390; + ptr[i++] = (test_priv->dst.mc_address >> 40) & 0xFF; + /* mmCB_COLOR0_DCC_BASE_EXT */ + ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1); + ptr[i++] = 0x3a8; + ptr[i++] = 0; + /* mmCB_COLOR0_ATTRIB2 */ + ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1); + ptr[i++] = 0x3b0; + ptr[i++] = test_priv->info->hang_slow ? 0x1ffc7ff : 0x7c01f; + /* mmCB_COLOR0_ATTRIB3 */ + ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1); + ptr[i++] = 0x3b8; + ptr[i++] = test_priv->info->hang_slow ? 0x1028000 : 0x1018000; + /* mmCB_COLOR0_INFO */ + ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1); + ptr[i++] = 0x32b; + ptr[i++] = 0; + ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1); + ptr[i++] = 0x33a; + ptr[i++] = 0; + /* mmSPI_SHADER_COL_FORMAT */ + ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1); + ptr[i++] = 0x1c5; + ptr[i++] = 0x9; + /* mmDB_Z_INFO */ + ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 2); + ptr[i++] = 0x10; + i += 2; + + test_priv->cmd_curr = i; +} + +static void amdgpu_draw_setup_and_write_drawblt_surf_info(struct shader_test_priv *test_priv) +{ + switch (test_priv->info->version) { + case AMDGPU_TEST_GFX_V9: + amdgpu_draw_setup_and_write_drawblt_surf_info_gfx9(test_priv); + break; + case AMDGPU_TEST_GFX_V10: + amdgpu_draw_setup_and_write_drawblt_surf_info_gfx10(test_priv); + break; + case AMDGPU_TEST_GFX_V11: + amdgpu_draw_setup_and_write_drawblt_surf_info_gfx11(test_priv); + break; + } +} + +static void amdgpu_draw_setup_and_write_drawblt_state_gfx9(struct shader_test_priv *test_priv) +{ + int i = test_priv->cmd_curr; + uint32_t *ptr = test_priv->cmd.ptr; + const struct shader_test_gfx_info *gfx_info = &shader_test_gfx_info[test_priv->info->version]; + + /* mmPA_SC_TILE_STEERING_OVERRIDE */ + ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1); + ptr[i++] = 0xd7; + ptr[i++] = 0; + + ptr[i++] = 0xffff1000; + ptr[i++] = 0xc0021000; + + ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1); + ptr[i++] = 0xd7; + ptr[i++] = 1; + + /* mmPA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_0 */ + ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 16); + ptr[i++] = 0x2fe; + i += 16; + + /* mmPA_SC_CENTROID_PRIORITY_0 */ + ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 2); + ptr[i++] = 0x2f5; + i += 2; + + memcpy(ptr + i, gfx_info->cached_cmd, gfx_info->size_cached_cmd); + if (test_priv->info->hang_slow) + *(ptr + i + 12) = 0x8000800; + + test_priv->cmd_curr = i + gfx_info->size_cached_cmd/sizeof(uint32_t); +} + +static void amdgpu_draw_setup_and_write_drawblt_state_gfx10(struct shader_test_priv *test_priv) +{ + int i = test_priv->cmd_curr; + uint32_t *ptr = test_priv->cmd.ptr; + const struct shader_test_gfx_info *gfx_info = &shader_test_gfx_info[test_priv->info->version]; + + /* mmPA_SC_TILE_STEERING_OVERRIDE */ + ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1); + ptr[i++] = 0xd7; + ptr[i++] = 0; + + ptr[i++] = 0xffff1000; + ptr[i++] = 0xc0021000; + + ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1); + ptr[i++] = 0xd7; + ptr[i++] = 0; + + /* mmPA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_0 */ + ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 16); + ptr[i++] = 0x2fe; + i += 16; + + /* mmPA_SC_CENTROID_PRIORITY_0 */ + ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 2); + ptr[i++] = 0x2f5; + i += 2; + + memcpy(ptr + i, gfx_info->cached_cmd, gfx_info->size_cached_cmd); + if (test_priv->info->hang_slow) + *(ptr + i + 12) = 0x8000800; + i += gfx_info->size_cached_cmd/sizeof(uint32_t); + + /* mmCB_RMI_GL2_CACHE_CONTROL */ + ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1); + ptr[i++] = 0x104; + ptr[i++] = 0x40aa0055; + /* mmDB_RMI_L2_CACHE_CONTROL */ + ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1); + ptr[i++] = 0x1f; + ptr[i++] = 0x2a0055; + + test_priv->cmd_curr = i; +} + +static void amdgpu_draw_setup_and_write_drawblt_state_gfx11(struct shader_test_priv *test_priv) +{ + int i = test_priv->cmd_curr; + uint32_t *ptr = test_priv->cmd.ptr; + const struct shader_test_gfx_info *gfx_info = &shader_test_gfx_info[test_priv->info->version]; + + /* mmPA_SC_TILE_STEERING_OVERRIDE */ + ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1); + ptr[i++] = 0xd7; + ptr[i++] = 0; + + ptr[i++] = 0xffff1000; + ptr[i++] = 0xc0021000; + + ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1); + ptr[i++] = 0xd7; + i++; + + /* mmPA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_0 */ + ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 16); + ptr[i++] = 0x2fe; + i += 16; + + /* mmPA_SC_CENTROID_PRIORITY_0 */ + ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 2); + ptr[i++] = 0x2f5; + i += 2; + + memcpy(ptr + i, gfx_info->cached_cmd, gfx_info->size_cached_cmd); + if (test_priv->info->hang_slow) + *(ptr + i + 12) = 0x8000800; + + test_priv->cmd_curr = i + gfx_info->size_cached_cmd/sizeof(uint32_t); +} + +static void amdgpu_draw_setup_and_write_drawblt_state(struct shader_test_priv *test_priv) +{ + switch (test_priv->info->version) { + case AMDGPU_TEST_GFX_V9: + amdgpu_draw_setup_and_write_drawblt_state_gfx9(test_priv); + break; + case AMDGPU_TEST_GFX_V10: + amdgpu_draw_setup_and_write_drawblt_state_gfx10(test_priv); + break; + case AMDGPU_TEST_GFX_V11: + amdgpu_draw_setup_and_write_drawblt_state_gfx11(test_priv); + break; + } +} + +static void amdgpu_draw_vs_RectPosTexFast_write2hw_gfx9(struct shader_test_priv *test_priv) +{ + int i = test_priv->cmd_curr; + uint32_t *ptr = test_priv->cmd.ptr; + uint64_t shader_addr = test_priv->shader_draw.vs_bo.mc_address; + enum ps_type ps = test_priv->shader_draw.ps_type; + + /* mmPA_CL_VS_OUT_CNTL */ + ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1); + ptr[i++] = 0x207; + ptr[i++] = 0; + + /* mmSPI_SHADER_PGM_RSRC3_VS */ + ptr[i++] = PACKET3(PACKET3_SET_SH_REG, 1); + ptr[i++] = 0x46; + ptr[i++] = 0xffff; + + /* mmSPI_SHADER_PGM_LO_VS...mmSPI_SHADER_PGM_HI_VS */ + ptr[i++] = PACKET3(PACKET3_SET_SH_REG, 2); + ptr[i++] = 0x48; + ptr[i++] = shader_addr >> 8; + ptr[i++] = shader_addr >> 40; + + /* mmSPI_SHADER_PGM_RSRC1_VS */ + ptr[i++] = PACKET3(PACKET3_SET_SH_REG, 1); + ptr[i++] = 0x4a; + ptr[i++] = 0xc0081; + + /* mmSPI_SHADER_PGM_RSRC2_VS */ + ptr[i++] = PACKET3(PACKET3_SET_SH_REG, 1); + ptr[i++] = 0x4b; + ptr[i++] = 0x18; + + /* mmSPI_VS_OUT_CONFIG */ + ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1); + ptr[i++] = 0x1b1; + ptr[i++] = 2; + + /* mmSPI_SHADER_POS_FORMAT */ + ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1); + ptr[i++] = 0x1c3; + ptr[i++] = 4; + + ptr[i++] = PACKET3(PACKET3_SET_SH_REG, 4); + ptr[i++] = 0x4c; + i += 2; + ptr[i++] = test_priv->info->hang_slow ? 0x45000000 : 0x42000000; + ptr[i++] = test_priv->info->hang_slow ? 0x45000000 : 0x42000000; + + ptr[i++] = PACKET3(PACKET3_SET_SH_REG, 4); + ptr[i++] = 0x50; + i += 2; + if (ps == PS_CONST) { + i += 2; + } else if (ps == PS_TEX) { + ptr[i++] = 0x3f800000; + ptr[i++] = 0x3f800000; + } + + ptr[i++] = PACKET3(PACKET3_SET_SH_REG, 4); + ptr[i++] = 0x54; + i += 4; + + test_priv->cmd_curr = i; +} + +static void amdgpu_draw_vs_RectPosTexFast_write2hw_gfx10(struct shader_test_priv *test_priv) +{ + int i = test_priv->cmd_curr; + uint32_t *ptr = test_priv->cmd.ptr; + uint64_t shader_addr = test_priv->shader_draw.vs_bo.mc_address; + enum ps_type ps = test_priv->shader_draw.ps_type; + + /* mmPA_CL_VS_OUT_CNTL */ + ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1); + ptr[i++] = 0x207; + ptr[i++] = 0; + + /* mmSPI_SHADER_PGM_RSRC3_VS */ + ptr[i++] = PACKET3(PACKET3_SET_SH_REG_INDEX, 1); + ptr[i++] = 0x30000046; + ptr[i++] = 0xffff; + /* mmSPI_SHADER_PGM_RSRC4_VS */ + ptr[i++] = PACKET3(PACKET3_SET_SH_REG_INDEX, 1); + ptr[i++] = 0x30000041; + ptr[i++] = 0xffff; + + /* mmSPI_SHADER_PGM_LO_VS...mmSPI_SHADER_PGM_HI_VS */ + ptr[i++] = PACKET3(PACKET3_SET_SH_REG, 2); + ptr[i++] = 0x48; + ptr[i++] = shader_addr >> 8; + ptr[i++] = shader_addr >> 40; + + /* mmSPI_SHADER_PGM_RSRC1_VS */ + ptr[i++] = PACKET3(PACKET3_SET_SH_REG, 1); + ptr[i++] = 0x4a; + ptr[i++] = 0xc0041; + /* mmSPI_SHADER_PGM_RSRC2_VS */ + ptr[i++] = PACKET3(PACKET3_SET_SH_REG, 1); + ptr[i++] = 0x4b; + ptr[i++] = 0x18; + + /* mmSPI_VS_OUT_CONFIG */ + ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1); + ptr[i++] = 0x1b1; + ptr[i++] = 2; + + /* mmSPI_SHADER_POS_FORMAT */ + ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1); + ptr[i++] = 0x1c3; + ptr[i++] = 4; + + ptr[i++] = PACKET3(PACKET3_SET_SH_REG, 4); + ptr[i++] = 0x4c; + i += 2; + ptr[i++] = test_priv->info->hang_slow ? 0x45000000 : 0x42000000; + ptr[i++] = test_priv->info->hang_slow ? 0x45000000 : 0x42000000; + + ptr[i++] = PACKET3(PACKET3_SET_SH_REG, 4); + ptr[i++] = 0x50; + i += 2; + if (ps == PS_CONST) { + i += 2; + } else if (ps == PS_TEX) { + ptr[i++] = 0x3f800000; + ptr[i++] = 0x3f800000; + } + + ptr[i++] = PACKET3(PACKET3_SET_SH_REG, 4); + ptr[i++] = 0x54; + i += 4; + + test_priv->cmd_curr = i; +} + + +static void amdgpu_draw_vs_RectPosTexFast_write2hw_gfx11(struct shader_test_priv *test_priv) +{ + int i = test_priv->cmd_curr; + uint32_t *ptr = test_priv->cmd.ptr; + const struct shader_test_gfx_info *gfx_info = &shader_test_gfx_info[test_priv->info->version]; + uint64_t shader_addr = test_priv->shader_draw.vs_bo.mc_address; + const struct shader_test_vs_shader *shader = &shader_test_vs[test_priv->info->version][test_priv->shader_draw.vs_type]; + enum ps_type ps = test_priv->shader_draw.ps_type; + int j, offset; + + /* mmPA_CL_VS_OUT_CNTL */ + ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1); + ptr[i++] = 0x207; + ptr[i++] = 0; + + /* mmSPI_SHADER_PGM_RSRC3_GS */ + ptr[i++] = PACKET3(PACKET3_SET_SH_REG_INDEX, 1); + ptr[i++] = 0x30000087; + ptr[i++] = 0xffff; + /* mmSPI_SHADER_PGM_RSRC4_GS */ + ptr[i++] = PACKET3(PACKET3_SET_SH_REG_INDEX, 1); + ptr[i++] = 0x30000081; + ptr[i++] = 0x1fff0001; + + /* mmSPI_SHADER_PGM_LO_ES */ + ptr[i++] = PACKET3(PACKET3_SET_SH_REG, 2); + ptr[i++] = 0xc8; + ptr[i++] = shader_addr >> 8; + ptr[i++] = shader_addr >> 40; + + /* write sh reg */ + for (j = 0; j < shader->num_sh_reg; j++) { + ptr[i++] = PACKET3(PACKET3_SET_SH_REG, 1); + ptr[i++] = shader->sh_reg[j].reg_offset - gfx_info->sh_reg_base; + ptr[i++] = shader->sh_reg[j].reg_value; + } + /* write context reg */ + for (j = 0; j < shader->num_context_reg; j++) { + switch (shader->context_reg[j].reg_offset) { + case 0xA1B1: //mmSPI_VS_OUT_CONFIG + ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1); + ptr[i++] = shader->context_reg[j].reg_offset - gfx_info->context_reg_base; + ptr[i++] = 2; + break; + case 0xA1C3: //mmSPI_SHADER_POS_FORMAT + ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1); + ptr[i++] = shader->context_reg[j].reg_offset - gfx_info->context_reg_base; + ptr[i++] = 4; + break; + case 0xA2E4: //mmVGT_GS_INSTANCE_CNT + case 0xA2CE: //mmVGT_GS_MAX_VERT_OUT + break; + default: + ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1); + ptr[i++] = shader->context_reg[j].reg_offset - gfx_info->context_reg_base; + ptr[i++] = shader->context_reg[j].reg_value; + break; + } + } + + // write constant + // dst rect + ptr[i++] = PACKET3(PACKET3_SET_SH_REG, 4); + ptr[i++] = 0x8c; + i += 2; + ptr[i++] = test_priv->info->hang_slow ? 0x45000000 : 0x42000000; + ptr[i++] = test_priv->info->hang_slow ? 0x45000000 : 0x42000000; + // src rect + ptr[i++] = PACKET3(PACKET3_SET_SH_REG, 4); + ptr[i++] = 0x90; + i += 2; + if (ps == PS_CONST) { + i += 2; + } else if (ps == PS_TEX) { + ptr[i++] = 0x3f800000; + ptr[i++] = 0x3f800000; + } + + ptr[i++] = PACKET3(PACKET3_SET_SH_REG, 4); + ptr[i++] = 0x94; + i += 4; + // vtx_attributes_mem + ptr[i++] = 0xc02f1000; + offset = i * sizeof(uint32_t); + i += 44; + ptr[i++] = test_priv->vtx_attributes_mem.mc_address & 0xffffffff; + ptr[i++] = 0xc0100000 | ((test_priv->vtx_attributes_mem.mc_address >> 32) & 0xffff); + ptr[i++] = test_priv->vtx_attributes_mem.size / 16; + ptr[i++] = 0x2043ffac; + ptr[i++] = PACKET3(PACKET3_SET_SH_REG_OFFSET, 2); + ptr[i++] = 0x98; + ptr[i++] = offset; + i++; + + test_priv->cmd_curr = i; +} + +static void amdgpu_draw_vs_RectPosTexFast_write2hw(struct shader_test_priv *test_priv) +{ + switch (test_priv->info->version) { + case AMDGPU_TEST_GFX_V9: + amdgpu_draw_vs_RectPosTexFast_write2hw_gfx9(test_priv); + break; + case AMDGPU_TEST_GFX_V10: + amdgpu_draw_vs_RectPosTexFast_write2hw_gfx10(test_priv); + break; + case AMDGPU_TEST_GFX_V11: + amdgpu_draw_vs_RectPosTexFast_write2hw_gfx11(test_priv); + break; + } +} + +static void amdgpu_draw_ps_write2hw_gfx9_10(struct shader_test_priv *test_priv) +{ + int i, j; + uint64_t shader_addr = test_priv->shader_draw.ps_bo.mc_address; + const struct shader_test_ps_shader *ps = &shader_test_ps[test_priv->info->version][test_priv->shader_draw.ps_type]; + uint32_t *ptr = test_priv->cmd.ptr; + + i = test_priv->cmd_curr; + + if (test_priv->info->version == AMDGPU_TEST_GFX_V9) { + /* 0x2c07 SPI_SHADER_PGM_RSRC3_PS + 0x2c08 SPI_SHADER_PGM_LO_PS + 0x2c09 SPI_SHADER_PGM_HI_PS */ + /* multiplicator 9 is from SPI_SHADER_COL_FORMAT */ + if (!test_priv->info->hang) + shader_addr += 256 * 9; + ptr[i++] = PACKET3(PACKET3_SET_SH_REG, 3); + ptr[i++] = 0x7; + ptr[i++] = 0xffff; + ptr[i++] = shader_addr >> 8; + ptr[i++] = shader_addr >> 40; + } else { + //if (!test_priv->info->hang) + shader_addr += 256 * 9; + /* 0x2c08 SPI_SHADER_PGM_LO_PS + 0x2c09 SPI_SHADER_PGM_HI_PS */ + ptr[i++] = PACKET3(PACKET3_SET_SH_REG, 2); + ptr[i++] = 0x8; + ptr[i++] = shader_addr >> 8; + ptr[i++] = shader_addr >> 40; + + /* mmSPI_SHADER_PGM_RSRC3_PS */ + ptr[i++] = PACKET3(PACKET3_SET_SH_REG_INDEX, 1); + ptr[i++] = 0x30000007; + ptr[i++] = 0xffff; + /* mmSPI_SHADER_PGM_RSRC4_PS */ + ptr[i++] = PACKET3(PACKET3_SET_SH_REG_INDEX, 1); + ptr[i++] = 0x30000001; + ptr[i++] = 0xffff; + } + + for (j = 0; j < ps->num_sh_reg; j++) { + ptr[i++] = PACKET3(PACKET3_SET_SH_REG, 1); + ptr[i++] = ps->sh_reg[j].reg_offset - 0x2c00; + ptr[i++] = ps->sh_reg[j].reg_value; + } + + for (j = 0; j < ps->num_context_reg; j++) { + if (ps->context_reg[j].reg_offset != 0xA1C5) { + ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1); + ptr[i++] = ps->context_reg[j].reg_offset - 0xa000; + ptr[i++] = ps->context_reg[j].reg_value; + } + + if (ps->context_reg[j].reg_offset == 0xA1B4) { + ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1); + ptr[i++] = 0x1b3; + ptr[i++] = 2; + } + } + + test_priv->cmd_curr = i; +} + +static void amdgpu_draw_ps_write2hw_gfx11(struct shader_test_priv *test_priv) +{ + int i, j; + uint64_t shader_addr = test_priv->shader_draw.ps_bo.mc_address; + enum amdgpu_test_gfx_version version = test_priv->info->version; + const struct shader_test_ps_shader *ps = &shader_test_ps[version][test_priv->shader_draw.ps_type]; + uint32_t *ptr = test_priv->cmd.ptr; + uint32_t export_shader_offset; + + i = test_priv->cmd_curr; + + /* SPI_SHADER_PGM_LO_PS + SPI_SHADER_PGM_HI_PS */ + shader_addr >>= 8; + if (!test_priv->info->hang) { + export_shader_offset = (round_up_size(ps->shader_size) * 9) >> 8; + shader_addr += export_shader_offset; + } + ptr[i++] = PACKET3(PACKET3_SET_SH_REG, 2); + ptr[i++] = 0x8; + ptr[i++] = shader_addr & 0xffffffff; + ptr[i++] = (shader_addr >> 32) & 0xffffffff; + /* mmSPI_SHADER_PGM_RSRC3_PS */ + ptr[i++] = PACKET3(PACKET3_SET_SH_REG_INDEX, 1); + ptr[i++] = 0x30000007; + ptr[i++] = 0xffff; + /* mmSPI_SHADER_PGM_RSRC4_PS */ + ptr[i++] = PACKET3(PACKET3_SET_SH_REG_INDEX, 1); + ptr[i++] = 0x30000001; + ptr[i++] = 0x3fffff; + + for (j = 0; j < ps->num_sh_reg; j++) { + ptr[i++] = PACKET3(PACKET3_SET_SH_REG, 1); + ptr[i++] = ps->sh_reg[j].reg_offset - shader_test_gfx_info[version].sh_reg_base; + ptr[i++] = ps->sh_reg[j].reg_value; + } + + for (j = 0; j < ps->num_context_reg; j++) { + /* !mmSPI_SHADER_COL_FORMAT */ + if (ps->context_reg[j].reg_offset != 0xA1C5) { + ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1); + ptr[i++] = ps->context_reg[j].reg_offset - shader_test_gfx_info[version].context_reg_base; + ptr[i++] = ps->context_reg[j].reg_value; + } + + /* mmSPI_PS_INPUT_ADDR */ + if (ps->context_reg[j].reg_offset == 0xA1B4) { + ptr[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1); + ptr[i++] = 0x1b3; + ptr[i++] = 2; + } + } + + test_priv->cmd_curr = i; +} + +static void amdgpu_draw_ps_write2hw(struct shader_test_priv *test_priv) +{ + switch (test_priv->info->version) { + case AMDGPU_TEST_GFX_V9: + case AMDGPU_TEST_GFX_V10: + amdgpu_draw_ps_write2hw_gfx9_10(test_priv); + break; + case AMDGPU_TEST_GFX_V11: + amdgpu_draw_ps_write2hw_gfx11(test_priv); + break; + } +} + +static void amdgpu_draw_draw(struct shader_test_priv *test_priv) +{ + int i = test_priv->cmd_curr; + uint32_t *ptr = test_priv->cmd.ptr; + + switch (test_priv->info->version) { + case AMDGPU_TEST_GFX_V9: + /* mmIA_MULTI_VGT_PARAM */ + ptr[i++] = PACKET3(PACKET3_SET_UCONFIG_REG, 1); + ptr[i++] = 0x40000258; + ptr[i++] = 0xd00ff; + /* mmVGT_PRIMITIVE_TYPE */ + ptr[i++] = PACKET3(PACKET3_SET_UCONFIG_REG, 1); + ptr[i++] = 0x10000242; + ptr[i++] = 0x11; + break; + case AMDGPU_TEST_GFX_V10: + /* mmGE_CNTL */ + ptr[i++] = PACKET3(PACKET3_SET_UCONFIG_REG, 1); + ptr[i++] = 0x25b; + ptr[i++] = 0xff; + /* mmVGT_PRIMITIVE_TYPE */ + ptr[i++] = PACKET3(PACKET3_SET_UCONFIG_REG, 1); + ptr[i++] = 0x242; + ptr[i++] = 0x11; + break; + case AMDGPU_TEST_GFX_V11: + /* mmGE_CNTL */ + ptr[i++] = PACKET3(PACKET3_SET_UCONFIG_REG, 1); + ptr[i++] = 0x25b; + ptr[i++] = 0x80fc80; + /* mmVGT_PRIMITIVE_TYPE */ + ptr[i++] = PACKET3(PACKET3_SET_UCONFIG_REG, 1); + ptr[i++] = 0x242; + ptr[i++] = 0x11; + break; + } + + ptr[i++] = PACKET3(PACKET3_DRAW_INDEX_AUTO, 1); + ptr[i++] = 3; + ptr[i++] = 2; + + test_priv->cmd_curr = i; +} + +static void amdgpu_memset_draw_test(struct shader_test_info *test_info) +{ + struct shader_test_priv test_priv; + amdgpu_context_handle context_handle; + struct shader_test_bo *ps_bo = &(test_priv.shader_draw.ps_bo); + struct shader_test_bo *vs_bo = &(test_priv.shader_draw.vs_bo); + struct shader_test_bo *dst = &(test_priv.dst); + struct shader_test_bo *cmd = &(test_priv.cmd); + struct shader_test_bo *vtx_attributes_mem = &(test_priv.vtx_attributes_mem); + amdgpu_bo_handle resources[5]; + uint8_t *ptr_dst; + uint32_t *ptr_cmd; + int i, r; + struct amdgpu_cs_request ibs_request = {0}; + struct amdgpu_cs_ib_info ib_info = {0}; + struct amdgpu_cs_fence fence_status = {0}; + uint32_t expired; + amdgpu_bo_list_handle bo_list; + uint8_t cptr[16]; + + memset(&test_priv, 0, sizeof(test_priv)); + test_priv.info = test_info; + + r = amdgpu_cs_ctx_create(test_info->device_handle, &context_handle); + CU_ASSERT_EQUAL(r, 0); + + ps_bo->size = 0x2000; + ps_bo->heap = AMDGPU_GEM_DOMAIN_VRAM; + r = shader_test_bo_alloc(test_info->device_handle, ps_bo); + CU_ASSERT_EQUAL(r, 0); + memset(ps_bo->ptr, 0, ps_bo->size); + + vs_bo->size = 4096; + vs_bo->heap = AMDGPU_GEM_DOMAIN_VRAM; + r = shader_test_bo_alloc(test_info->device_handle, vs_bo); + CU_ASSERT_EQUAL(r, 0); + memset(vs_bo->ptr, 0, vs_bo->size); + + test_priv.shader_draw.ps_type = PS_CONST; + amdgpu_draw_load_ps_shader(&test_priv); + + test_priv.shader_draw.vs_type = VS_RECTPOSTEXFAST; + amdgpu_draw_load_vs_shader(&test_priv); + + cmd->size = 4096; + cmd->heap = AMDGPU_GEM_DOMAIN_GTT; + r = shader_test_bo_alloc(test_info->device_handle, cmd); + CU_ASSERT_EQUAL(r, 0); + ptr_cmd = cmd->ptr; + memset(ptr_cmd, 0, cmd->size); + + dst->size = 0x4000; + dst->heap = AMDGPU_GEM_DOMAIN_VRAM; + r = shader_test_bo_alloc(test_info->device_handle, dst); + CU_ASSERT_EQUAL(r, 0); + + if (test_info->version == AMDGPU_TEST_GFX_V11) { + vtx_attributes_mem->size = 0x4040000; + vtx_attributes_mem->heap = AMDGPU_GEM_DOMAIN_VRAM; + + r = shader_test_bo_alloc(test_info->device_handle, vtx_attributes_mem); + CU_ASSERT_EQUAL(r, 0); + } + + amdgpu_draw_init(&test_priv); + + amdgpu_draw_setup_and_write_drawblt_surf_info(&test_priv); + + amdgpu_draw_setup_and_write_drawblt_state(&test_priv); + + amdgpu_draw_vs_RectPosTexFast_write2hw(&test_priv); + + amdgpu_draw_ps_write2hw(&test_priv); + + i = test_priv.cmd_curr; + /* ps constant data */ + ptr_cmd[i++] = PACKET3(PACKET3_SET_SH_REG, 4); + ptr_cmd[i++] = 0xc; + ptr_cmd[i++] = 0x33333333; + ptr_cmd[i++] = 0x33333333; + ptr_cmd[i++] = 0x33333333; + ptr_cmd[i++] = 0x33333333; + test_priv.cmd_curr = i; + + amdgpu_draw_draw(&test_priv); + + i = test_priv.cmd_curr; + while (i & 7) + ptr_cmd[i++] = 0xffff1000; /* type3 nop packet */ + test_priv.cmd_curr = i; + + i = 0; + resources[i++] = dst->bo; + resources[i++] = ps_bo->bo; + resources[i++] = vs_bo->bo; + resources[i++] = cmd->bo; + if (vtx_attributes_mem->size) + resources[i++] = vtx_attributes_mem->bo; + r = amdgpu_bo_list_create(test_info->device_handle, i, resources, NULL, &bo_list); + CU_ASSERT_EQUAL(r, 0); + + ib_info.ib_mc_address = cmd->mc_address; + ib_info.size = test_priv.cmd_curr; + ibs_request.ip_type = test_info->ip; + ibs_request.ring = test_info->ring; + ibs_request.resources = bo_list; + ibs_request.number_of_ibs = 1; + ibs_request.ibs = &ib_info; + ibs_request.fence_info.handle = NULL; + + /* submit CS */ + r = amdgpu_cs_submit(context_handle, 0, &ibs_request, 1); + CU_ASSERT_EQUAL(r, 0); + + r = amdgpu_bo_list_destroy(bo_list); + CU_ASSERT_EQUAL(r, 0); + + fence_status.ip_type = test_info->ip; + fence_status.ip_instance = 0; + fence_status.ring = test_info->ring; + fence_status.context = context_handle; + fence_status.fence = ibs_request.seq_no; + + /* wait for IB accomplished */ + r = amdgpu_cs_query_fence_status(&fence_status, + AMDGPU_TIMEOUT_INFINITE, + 0, &expired); + CU_ASSERT_EQUAL(r, 0); + CU_ASSERT_EQUAL(expired, true); + + /* verify if memset test result meets with expected */ + i = 0; + ptr_dst = dst->ptr; + memset(cptr, 0x33, 16); + CU_ASSERT_EQUAL(memcmp(ptr_dst + i, cptr, 16), 0); + i = dst->size - 16; + CU_ASSERT_EQUAL(memcmp(ptr_dst + i, cptr, 16), 0); + i = dst->size / 2; + CU_ASSERT_EQUAL(memcmp(ptr_dst + i, cptr, 16), 0); + + if (vtx_attributes_mem->size) { + r = shader_test_bo_free(vtx_attributes_mem); + CU_ASSERT_EQUAL(r, 0); + } + + r = shader_test_bo_free(dst); + CU_ASSERT_EQUAL(r, 0); + + r = shader_test_bo_free(cmd); + CU_ASSERT_EQUAL(r, 0); + + r = shader_test_bo_free(ps_bo); + CU_ASSERT_EQUAL(r, 0); + + r = shader_test_bo_free(vs_bo); + CU_ASSERT_EQUAL(r, 0); + + r = amdgpu_cs_ctx_free(context_handle); + CU_ASSERT_EQUAL(r, 0); +} + +static void amdgpu_memcpy_draw_test(struct shader_test_info *test_info) +{ + struct shader_test_priv test_priv; + amdgpu_context_handle context_handle; + struct shader_test_bo *ps_bo = &(test_priv.shader_draw.ps_bo); + struct shader_test_bo *vs_bo = &(test_priv.shader_draw.vs_bo); + struct shader_test_bo *src = &(test_priv.src); + struct shader_test_bo *dst = &(test_priv.dst); + struct shader_test_bo *cmd = &(test_priv.cmd); + struct shader_test_bo *vtx_attributes_mem = &(test_priv.vtx_attributes_mem); + amdgpu_bo_handle resources[6]; + uint8_t *ptr_dst; + uint8_t *ptr_src; + uint32_t *ptr_cmd; + int i, r; + struct amdgpu_cs_request ibs_request = {0}; + struct amdgpu_cs_ib_info ib_info = {0}; + uint32_t hang_state, hangs; + uint32_t expired; + amdgpu_bo_list_handle bo_list; + struct amdgpu_cs_fence fence_status = {0}; + + memset(&test_priv, 0, sizeof(test_priv)); + test_priv.info = test_info; + test_priv.cmd.size = 4096; + test_priv.cmd.heap = AMDGPU_GEM_DOMAIN_GTT; + + ps_bo->heap = AMDGPU_GEM_DOMAIN_VRAM; + test_priv.shader_draw.ps_type = PS_TEX; + vs_bo->size = 4096; + vs_bo->heap = AMDGPU_GEM_DOMAIN_VRAM; + test_priv.shader_draw.vs_type = VS_RECTPOSTEXFAST; + test_priv.src.heap = AMDGPU_GEM_DOMAIN_VRAM; + test_priv.dst.heap = AMDGPU_GEM_DOMAIN_VRAM; + if (test_info->hang_slow) { + test_priv.shader_draw.ps_bo.size = 16*1024*1024; + test_priv.src.size = 0x4000000; + test_priv.dst.size = 0x4000000; + } else { + test_priv.shader_draw.ps_bo.size = 0x2000; + test_priv.src.size = 0x4000; + test_priv.dst.size = 0x4000; + } + + r = amdgpu_cs_ctx_create(test_info->device_handle, &context_handle); + CU_ASSERT_EQUAL(r, 0); + + r = shader_test_bo_alloc(test_info->device_handle, ps_bo); + CU_ASSERT_EQUAL(r, 0); + memset(ps_bo->ptr, 0, ps_bo->size); + + r = shader_test_bo_alloc(test_info->device_handle, vs_bo); + CU_ASSERT_EQUAL(r, 0); + memset(vs_bo->ptr, 0, vs_bo->size); + + amdgpu_draw_load_ps_shader(&test_priv); + amdgpu_draw_load_vs_shader(&test_priv); + + r = shader_test_bo_alloc(test_info->device_handle, cmd); + CU_ASSERT_EQUAL(r, 0); + ptr_cmd = cmd->ptr; + memset(ptr_cmd, 0, cmd->size); + + r = shader_test_bo_alloc(test_info->device_handle, src); + CU_ASSERT_EQUAL(r, 0); + ptr_src = src->ptr; + memset(ptr_src, 0x55, src->size); + + r = shader_test_bo_alloc(test_info->device_handle, dst); + CU_ASSERT_EQUAL(r, 0); + + if (test_info->version == AMDGPU_TEST_GFX_V11) { + vtx_attributes_mem->size = 0x4040000; + vtx_attributes_mem->heap = AMDGPU_GEM_DOMAIN_VRAM; + + r = shader_test_bo_alloc(test_info->device_handle, vtx_attributes_mem); + CU_ASSERT_EQUAL(r, 0); + } + + amdgpu_draw_init(&test_priv); + + amdgpu_draw_setup_and_write_drawblt_surf_info(&test_priv); + + amdgpu_draw_setup_and_write_drawblt_state(&test_priv); + + amdgpu_draw_vs_RectPosTexFast_write2hw(&test_priv); + + amdgpu_draw_ps_write2hw(&test_priv); + + // write ps user constant data + i = test_priv.cmd_curr; + ptr_cmd[i++] = PACKET3(PACKET3_SET_SH_REG, 8); + switch (test_info->version) { + case AMDGPU_TEST_GFX_V9: + ptr_cmd[i++] = 0xc; + ptr_cmd[i++] = src->mc_address >> 8; + ptr_cmd[i++] = src->mc_address >> 40 | 0x10e00000; + ptr_cmd[i++] = test_info->hang_slow ? 0x1ffcfff : 0x7c01f; + ptr_cmd[i++] = 0x90500fac; + ptr_cmd[i++] = test_info->hang_slow ? 0x1ffe000 : 0x3e000; + i += 3; + break; + case AMDGPU_TEST_GFX_V10: + ptr_cmd[i++] = 0xc; + ptr_cmd[i++] = src->mc_address >> 8; + ptr_cmd[i++] = src->mc_address >> 40 | 0xc4b00000; + ptr_cmd[i++] = test_info->hang_slow ? 0x81ffc1ff : 0x8007c007; + ptr_cmd[i++] = 0x90500fac; + i += 2; + ptr_cmd[i++] = test_info->hang_slow ? 0 : 0x400; + i++; + break; + case AMDGPU_TEST_GFX_V11: + ptr_cmd[i++] = 0xc; + ptr_cmd[i++] = src->mc_address >> 8; + ptr_cmd[i++] = src->mc_address >> 40 | 0xc4b00000; + ptr_cmd[i++] = test_info->hang_slow ? 0x1ffc1ff : 0x7c007; + ptr_cmd[i++] = test_info->hang_slow ? 0x90a00fac : 0x90600fac; + i += 2; + ptr_cmd[i++] = 0x400; + i++; + break; + } + + ptr_cmd[i++] = PACKET3(PACKET3_SET_SH_REG, 4); + ptr_cmd[i++] = 0x14; + ptr_cmd[i++] = 0x92; + i += 3; + + ptr_cmd[i++] = PACKET3(PACKET3_SET_CONTEXT_REG, 1); + ptr_cmd[i++] = 0x191; + ptr_cmd[i++] = 0; + test_priv.cmd_curr = i; + + amdgpu_draw_draw(&test_priv); + + i = test_priv.cmd_curr; + while (i & 7) + ptr_cmd[i++] = 0xffff1000; /* type3 nop packet */ + test_priv.cmd_curr = i; + + i = 0; + resources[i++] = dst->bo; + resources[i++] = src->bo; + resources[i++] = ps_bo->bo; + resources[i++] = vs_bo->bo; + resources[i++] = cmd->bo; + if (vtx_attributes_mem->size) + resources[i++] = vtx_attributes_mem->bo; + r = amdgpu_bo_list_create(test_info->device_handle, i, resources, NULL, &bo_list); + CU_ASSERT_EQUAL(r, 0); + + ib_info.ib_mc_address = cmd->mc_address; + ib_info.size = test_priv.cmd_curr; + ibs_request.ip_type = test_info->ip; + ibs_request.ring = test_info->ring; + ibs_request.resources = bo_list; + ibs_request.number_of_ibs = 1; + ibs_request.ibs = &ib_info; + ibs_request.fence_info.handle = NULL; + r = amdgpu_cs_submit(context_handle, 0, &ibs_request, 1); + CU_ASSERT_EQUAL(r, 0); + + fence_status.ip_type = test_info->ip; + fence_status.ip_instance = 0; + fence_status.ring = test_info->ring; + fence_status.context = context_handle; + fence_status.fence = ibs_request.seq_no; + + /* wait for IB accomplished */ + r = amdgpu_cs_query_fence_status(&fence_status, + AMDGPU_TIMEOUT_INFINITE, + 0, &expired); + if (!test_info->hang) { + CU_ASSERT_EQUAL(r, 0); + CU_ASSERT_EQUAL(expired, true); + + /* verify if memcpy test result meets with expected */ + i = 0; + ptr_dst = dst->ptr; + CU_ASSERT_EQUAL(memcmp(ptr_dst + i, ptr_src + i, 16), 0); + i = dst->size - 16; + CU_ASSERT_EQUAL(memcmp(ptr_dst + i, ptr_src + i, 16), 0); + i = dst->size / 2; + CU_ASSERT_EQUAL(memcmp(ptr_dst + i, ptr_src + i, 16), 0); + } else { + r = amdgpu_cs_query_reset_state(context_handle, &hang_state, &hangs); + CU_ASSERT_EQUAL(r, 0); + CU_ASSERT_EQUAL(hang_state, AMDGPU_CTX_UNKNOWN_RESET); + } + + r = amdgpu_bo_list_destroy(bo_list); + CU_ASSERT_EQUAL(r, 0); + + if (vtx_attributes_mem->size) { + r = shader_test_bo_free(vtx_attributes_mem); + CU_ASSERT_EQUAL(r, 0); + } + + r = shader_test_bo_free(src); + CU_ASSERT_EQUAL(r, 0); + + r = shader_test_bo_free(dst); + CU_ASSERT_EQUAL(r, 0); + + r = shader_test_bo_free(cmd); + CU_ASSERT_EQUAL(r, 0); + + r = shader_test_bo_free(ps_bo); + CU_ASSERT_EQUAL(r, 0); + + r = shader_test_bo_free(vs_bo); + CU_ASSERT_EQUAL(r, 0); + + r = amdgpu_cs_ctx_free(context_handle); + CU_ASSERT_EQUAL(r, 0); +} + +static void shader_test_draw_cb(struct shader_test_info *test_info) +{ + amdgpu_memset_draw_test(test_info); + amdgpu_memcpy_draw_test(test_info); +} + +static void shader_test_draw_hang_cb(struct shader_test_info *test_info) +{ + test_info->hang = 0; + amdgpu_memcpy_draw_test(test_info); + + test_info->hang = 1; + amdgpu_memcpy_draw_test(test_info); + + test_info->hang = 0; + amdgpu_memcpy_draw_test(test_info); +} + +static void shader_test_draw_hang_slow_cb(struct shader_test_info *test_info) +{ + test_info->hang = 0; + test_info->hang_slow = 0; + amdgpu_memcpy_draw_test(test_info); + + test_info->hang = 1; + test_info->hang_slow = 1; + amdgpu_memcpy_draw_test(test_info); + + test_info->hang = 0; + test_info->hang_slow = 0; + amdgpu_memcpy_draw_test(test_info); +} + + +void amdgpu_test_draw_helper(amdgpu_device_handle device_handle) +{ + shader_test_for_each(device_handle, AMDGPU_HW_IP_GFX, shader_test_draw_cb); +} + +void amdgpu_test_draw_hang_helper(amdgpu_device_handle device_handle) +{ + shader_test_for_each(device_handle, AMDGPU_HW_IP_GFX, shader_test_draw_hang_cb); +} + +void amdgpu_test_draw_hang_slow_helper(amdgpu_device_handle device_handle) +{ + shader_test_for_each(device_handle, AMDGPU_HW_IP_GFX, shader_test_draw_hang_slow_cb); +} diff -Nru libdrm-2.4.110/tests/amdgpu/vce_tests.c libdrm-2.4.113/tests/amdgpu/vce_tests.c --- libdrm-2.4.110/tests/amdgpu/vce_tests.c 2022-02-16 10:00:13.000000000 +0000 +++ libdrm-2.4.113/tests/amdgpu/vce_tests.c 2022-08-31 14:38:38.000000000 +0000 @@ -96,7 +96,7 @@ CU_BOOL suite_vce_tests_enable(void) { - uint32_t version, feature, asic_id; + uint32_t version, feature; CU_BOOL ret_mv = CU_FALSE; if (amdgpu_device_initialize(drm_amdgpu[0], &major_version, @@ -107,7 +107,6 @@ chip_rev = device_handle->info.chip_rev; chip_id = device_handle->info.chip_external_rev; ids_flags = device_handle->info.ids_flags; - asic_id = device_handle->info.asic_id; amdgpu_query_firmware_version(device_handle, AMDGPU_INFO_FW_VCE, 0, 0, &version, &feature); diff -Nru libdrm-2.4.110/tests/amdgpu/vcn_tests.c libdrm-2.4.113/tests/amdgpu/vcn_tests.c --- libdrm-2.4.110/tests/amdgpu/vcn_tests.c 2022-02-16 10:00:13.000000000 +0000 +++ libdrm-2.4.113/tests/amdgpu/vcn_tests.c 2022-08-31 14:38:38.000000000 +0000 @@ -22,20 +22,65 @@ */ #include +#include #include +#include #include "CUnit/Basic.h" +#include #include "util_math.h" #include "amdgpu_test.h" #include "amdgpu_drm.h" #include "amdgpu_internal.h" #include "decode_messages.h" +#include "frame.h" #define IB_SIZE 4096 #define MAX_RESOURCES 16 +#define DECODE_CMD_MSG_BUFFER 0x00000000 +#define DECODE_CMD_DPB_BUFFER 0x00000001 +#define DECODE_CMD_DECODING_TARGET_BUFFER 0x00000002 +#define DECODE_CMD_FEEDBACK_BUFFER 0x00000003 +#define DECODE_CMD_PROB_TBL_BUFFER 0x00000004 +#define DECODE_CMD_SESSION_CONTEXT_BUFFER 0x00000005 +#define DECODE_CMD_BITSTREAM_BUFFER 0x00000100 +#define DECODE_CMD_IT_SCALING_TABLE_BUFFER 0x00000204 +#define DECODE_CMD_CONTEXT_BUFFER 0x00000206 + +#define DECODE_IB_PARAM_DECODE_BUFFER (0x00000001) + +#define DECODE_CMDBUF_FLAGS_MSG_BUFFER (0x00000001) +#define DECODE_CMDBUF_FLAGS_DPB_BUFFER (0x00000002) +#define DECODE_CMDBUF_FLAGS_BITSTREAM_BUFFER (0x00000004) +#define DECODE_CMDBUF_FLAGS_DECODING_TARGET_BUFFER (0x00000008) +#define DECODE_CMDBUF_FLAGS_FEEDBACK_BUFFER (0x00000010) +#define DECODE_CMDBUF_FLAGS_IT_SCALING_BUFFER (0x00000200) +#define DECODE_CMDBUF_FLAGS_CONTEXT_BUFFER (0x00000800) +#define DECODE_CMDBUF_FLAGS_PROB_TBL_BUFFER (0x00001000) +#define DECODE_CMDBUF_FLAGS_SESSION_CONTEXT_BUFFER (0x00100000) + +static bool vcn_dec_sw_ring = false; +static bool vcn_unified_ring = false; + +#define H264_NAL_TYPE_NON_IDR_SLICE 1 +#define H264_NAL_TYPE_DP_A_SLICE 2 +#define H264_NAL_TYPE_DP_B_SLICE 3 +#define H264_NAL_TYPE_DP_C_SLICE 0x4 +#define H264_NAL_TYPE_IDR_SLICE 0x5 +#define H264_NAL_TYPE_SEI 0x6 +#define H264_NAL_TYPE_SEQ_PARAM 0x7 +#define H264_NAL_TYPE_PIC_PARAM 0x8 +#define H264_NAL_TYPE_ACCESS_UNIT 0x9 +#define H264_NAL_TYPE_END_OF_SEQ 0xa +#define H264_NAL_TYPE_END_OF_STREAM 0xb +#define H264_NAL_TYPE_FILLER_DATA 0xc +#define H264_NAL_TYPE_SEQ_EXTENSION 0xd + +#define H264_START_CODE 0x000001 + struct amdgpu_vcn_bo { amdgpu_bo_handle handle; amdgpu_va_handle va_handle; @@ -44,6 +89,48 @@ uint8_t *ptr; }; +typedef struct rvcn_decode_buffer_s { + unsigned int valid_buf_flag; + unsigned int msg_buffer_address_hi; + unsigned int msg_buffer_address_lo; + unsigned int dpb_buffer_address_hi; + unsigned int dpb_buffer_address_lo; + unsigned int target_buffer_address_hi; + unsigned int target_buffer_address_lo; + unsigned int session_contex_buffer_address_hi; + unsigned int session_contex_buffer_address_lo; + unsigned int bitstream_buffer_address_hi; + unsigned int bitstream_buffer_address_lo; + unsigned int context_buffer_address_hi; + unsigned int context_buffer_address_lo; + unsigned int feedback_buffer_address_hi; + unsigned int feedback_buffer_address_lo; + unsigned int luma_hist_buffer_address_hi; + unsigned int luma_hist_buffer_address_lo; + unsigned int prob_tbl_buffer_address_hi; + unsigned int prob_tbl_buffer_address_lo; + unsigned int sclr_coeff_buffer_address_hi; + unsigned int sclr_coeff_buffer_address_lo; + unsigned int it_sclr_table_buffer_address_hi; + unsigned int it_sclr_table_buffer_address_lo; + unsigned int sclr_target_buffer_address_hi; + unsigned int sclr_target_buffer_address_lo; + unsigned int cenc_size_info_buffer_address_hi; + unsigned int cenc_size_info_buffer_address_lo; + unsigned int mpeg2_pic_param_buffer_address_hi; + unsigned int mpeg2_pic_param_buffer_address_lo; + unsigned int mpeg2_mb_control_buffer_address_hi; + unsigned int mpeg2_mb_control_buffer_address_lo; + unsigned int mpeg2_idct_coeff_buffer_address_hi; + unsigned int mpeg2_idct_coeff_buffer_address_lo; +} rvcn_decode_buffer_t; + +typedef struct rvcn_decode_ib_package_s { + unsigned int package_size; + unsigned int package_type; +} rvcn_decode_ib_package_t; + + struct amdgpu_vcn_reg { uint32_t data0; uint32_t data1; @@ -52,6 +139,23 @@ uint32_t cntl; }; +typedef struct BufferInfo_t { + uint32_t numOfBitsInBuffer; + const uint8_t *decBuffer; + uint8_t decData; + uint32_t decBufferSize; + const uint8_t *end; +} bufferInfo; + +typedef struct h264_decode_t { + uint8_t profile; + uint8_t level_idc; + uint8_t nal_ref_idc; + uint8_t nal_unit_type; + uint32_t pic_width, pic_height; + uint32_t slice_type; +} h264_decode; + static amdgpu_device_handle device_handle; static uint32_t major_version; static uint32_t minor_version; @@ -60,18 +164,33 @@ static uint32_t chip_id; static uint32_t asic_id; static uint32_t chip_rev; -static uint32_t chip_id; +static struct amdgpu_vcn_bo enc_buf; +static struct amdgpu_vcn_bo cpb_buf; +static uint32_t enc_task_id; static amdgpu_context_handle context_handle; static amdgpu_bo_handle ib_handle; static amdgpu_va_handle ib_va_handle; static uint64_t ib_mc_address; static uint32_t *ib_cpu; +static uint32_t *ib_checksum; +static uint32_t *ib_size_in_dw; + +static rvcn_decode_buffer_t *decode_buffer; static amdgpu_bo_handle resources[MAX_RESOURCES]; static unsigned num_resources; -static struct amdgpu_vcn_reg reg; +static uint8_t vcn_reg_index; +static struct amdgpu_vcn_reg reg[] = { + {0x81c4, 0x81c5, 0x81c3, 0x81ff, 0x81c6}, + {0x504, 0x505, 0x503, 0x53f, 0x506}, + {0x10, 0x11, 0xf, 0x29, 0x26d}, +}; + +uint32_t gWidth, gHeight, gSliceType; +static uint32_t vcn_ip_version_major; +static uint32_t vcn_ip_version_minor; static void amdgpu_cs_vcn_dec_create(void); static void amdgpu_cs_vcn_dec_decode(void); static void amdgpu_cs_vcn_dec_destroy(void); @@ -80,6 +199,22 @@ static void amdgpu_cs_vcn_enc_encode(void); static void amdgpu_cs_vcn_enc_destroy(void); +static void amdgpu_cs_sq_head(uint32_t *base, int *offset, bool enc); +static void amdgpu_cs_sq_ib_tail(uint32_t *end); +static void h264_check_0s (bufferInfo * bufInfo, int count); +static int32_t h264_se (bufferInfo * bufInfo); +static inline uint32_t bs_read_u1(bufferInfo *bufinfo); +static inline int bs_eof(bufferInfo *bufinfo); +static inline uint32_t bs_read_u(bufferInfo* bufinfo, int n); +static inline uint32_t bs_read_ue(bufferInfo* bufinfo); +static uint32_t remove_03 (uint8_t *bptr, uint32_t len); +static void scaling_list (uint32_t ix, uint32_t sizeOfScalingList, bufferInfo *bufInfo); +static void h264_parse_sequence_parameter_set (h264_decode * dec, bufferInfo *bufInfo); +static void h264_slice_header (h264_decode *dec, bufferInfo *bufInfo); +static uint8_t h264_parse_nal (h264_decode *dec, bufferInfo *bufInfo); +static uint32_t h264_find_next_start_code (uint8_t *pBuf, uint32_t bufLen); +static int verify_checksum(uint8_t *buffer, uint32_t buffer_size); + CU_TestInfo vcn_tests[] = { { "VCN DEC create", amdgpu_cs_vcn_dec_create }, @@ -87,7 +222,7 @@ { "VCN DEC destroy", amdgpu_cs_vcn_dec_destroy }, { "VCN ENC create", amdgpu_cs_vcn_enc_create }, - { "VCN ENC decode", amdgpu_cs_vcn_enc_encode }, + { "VCN ENC encode", amdgpu_cs_vcn_enc_encode }, { "VCN ENC destroy", amdgpu_cs_vcn_enc_destroy }, CU_TEST_INFO_NULL, }; @@ -95,6 +230,7 @@ CU_BOOL suite_vcn_tests_enable(void) { struct drm_amdgpu_info_hw_ip info; + bool enc_ring, dec_ring; int r; if (amdgpu_device_initialize(drm_amdgpu[0], &major_version, @@ -106,12 +242,31 @@ chip_rev = device_handle->info.chip_rev; chip_id = device_handle->info.chip_external_rev; - r = amdgpu_query_hw_ip_info(device_handle, AMDGPU_HW_IP_VCN_DEC, 0, &info); + r = amdgpu_query_hw_ip_info(device_handle, AMDGPU_HW_IP_VCN_ENC, 0, &info); + if (!r) { + vcn_ip_version_major = info.hw_ip_version_major; + vcn_ip_version_minor = info.hw_ip_version_minor; + enc_ring = !!info.available_rings; + /* in vcn 4.0 it re-uses encoding queue as unified queue */ + if (vcn_ip_version_major >= 4) { + vcn_unified_ring = true; + vcn_dec_sw_ring = true; + dec_ring = enc_ring; + } else { + r = amdgpu_query_hw_ip_info(device_handle, AMDGPU_HW_IP_VCN_DEC, 0, &info); + dec_ring = !!info.available_rings; + } + } if (amdgpu_device_deinitialize(device_handle)) - return CU_FALSE; + return CU_FALSE; - if (r != 0 || !info.available_rings || + if (r) { + printf("\n\nASIC query hw info failed\n"); + return CU_FALSE; + } + + if (!(dec_ring || enc_ring) || (family_id < AMDGPU_FAMILY_RV && (family_id == AMDGPU_FAMILY_AI && (chip_id - chip_rev) < 0x32))) { /* Arcturus */ @@ -119,52 +274,25 @@ return CU_FALSE; } - if (family_id == AMDGPU_FAMILY_AI) { + if (!dec_ring) { + amdgpu_set_test_active("VCN Tests", "VCN DEC create", CU_FALSE); + amdgpu_set_test_active("VCN Tests", "VCN DEC decode", CU_FALSE); + amdgpu_set_test_active("VCN Tests", "VCN DEC destroy", CU_FALSE); + } + + if (family_id == AMDGPU_FAMILY_AI || !enc_ring) { amdgpu_set_test_active("VCN Tests", "VCN ENC create", CU_FALSE); - amdgpu_set_test_active("VCN Tests", "VCN ENC decode", CU_FALSE); + amdgpu_set_test_active("VCN Tests", "VCN ENC encode", CU_FALSE); amdgpu_set_test_active("VCN Tests", "VCN ENC destroy", CU_FALSE); } - if (family_id == AMDGPU_FAMILY_RV) { - if (chip_id >= (chip_rev + 0x91)) { - reg.data0 = 0x504; - reg.data1 = 0x505; - reg.cmd = 0x503; - reg.nop = 0x53f; - reg.cntl = 0x506; - } else { - reg.data0 = 0x81c4; - reg.data1 = 0x81c5; - reg.cmd = 0x81c3; - reg.nop = 0x81ff; - reg.cntl = 0x81c6; - } - } else if (family_id == AMDGPU_FAMILY_NV) { - if (chip_id == (chip_rev + 0x28) || - chip_id == (chip_rev + 0x32) || - chip_id == (chip_rev + 0x3c) || - chip_id == (chip_rev + 0x46)) { - reg.data0 = 0x10; - reg.data1 = 0x11; - reg.cmd = 0xf; - reg.nop = 0x29; - reg.cntl = 0x26d; - } - else { - reg.data0 = 0x504; - reg.data1 = 0x505; - reg.cmd = 0x503; - reg.nop = 0x53f; - reg.cntl = 0x506; - } - } else if (family_id == AMDGPU_FAMILY_AI) { - reg.data0 = 0x10; - reg.data1 = 0x11; - reg.cmd = 0xf; - reg.nop = 0x29; - reg.cntl = 0x26d; - } else - return CU_FALSE; + if (vcn_ip_version_major == 1) + vcn_reg_index = 0; + else if (vcn_ip_version_major == 2 && vcn_ip_version_minor == 0) + vcn_reg_index = 1; + else if ((vcn_ip_version_major == 2 && vcn_ip_version_minor >= 5) || + vcn_ip_version_major == 3) + vcn_reg_index = 2; return CU_TRUE; } @@ -214,6 +342,43 @@ return CUE_SUCCESS; } +static void amdgpu_cs_sq_head(uint32_t *base, int *offset, bool enc) +{ + /* signature */ + *(base + (*offset)++) = 0x00000010; + *(base + (*offset)++) = 0x30000002; + ib_checksum = base + (*offset)++; + ib_size_in_dw = base + (*offset)++; + + /* engine info */ + *(base + (*offset)++) = 0x00000010; + *(base + (*offset)++) = 0x30000001; + *(base + (*offset)++) = enc ? 2 : 3; + *(base + (*offset)++) = 0x00000000; +} + +static void amdgpu_cs_sq_ib_tail(uint32_t *end) +{ + uint32_t size_in_dw; + uint32_t checksum = 0; + + /* if the pointers are invalid, no need to process */ + if (ib_checksum == NULL || ib_size_in_dw == NULL) + return; + + size_in_dw = end - ib_size_in_dw - 1; + *ib_size_in_dw = size_in_dw; + *(ib_size_in_dw + 4) = size_in_dw * sizeof(uint32_t); + + for (int i = 0; i < size_in_dw; i++) + checksum += *(ib_checksum + 2 + i); + + *ib_checksum = checksum; + + ib_checksum = NULL; + ib_size_in_dw = NULL; +} + static int submit(unsigned ndw, unsigned ip) { struct amdgpu_cs_request ibs_request = {0}; @@ -307,17 +472,91 @@ static void vcn_dec_cmd(uint64_t addr, unsigned cmd, int *idx) { - ib_cpu[(*idx)++] = reg.data0; - ib_cpu[(*idx)++] = addr; - ib_cpu[(*idx)++] = reg.data1; - ib_cpu[(*idx)++] = addr >> 32; - ib_cpu[(*idx)++] = reg.cmd; - ib_cpu[(*idx)++] = cmd << 1; + if (vcn_dec_sw_ring == false) { + ib_cpu[(*idx)++] = reg[vcn_reg_index].data0; + ib_cpu[(*idx)++] = addr; + ib_cpu[(*idx)++] = reg[vcn_reg_index].data1; + ib_cpu[(*idx)++] = addr >> 32; + ib_cpu[(*idx)++] = reg[vcn_reg_index].cmd; + ib_cpu[(*idx)++] = cmd << 1; + return; + } + + /* Support decode software ring message */ + if (!(*idx)) { + rvcn_decode_ib_package_t *ib_header; + + if (vcn_unified_ring) + amdgpu_cs_sq_head(ib_cpu, idx, false); + + ib_header = (rvcn_decode_ib_package_t *)&ib_cpu[*idx]; + ib_header->package_size = sizeof(struct rvcn_decode_buffer_s) + + sizeof(struct rvcn_decode_ib_package_s); + + (*idx)++; + ib_header->package_type = (DECODE_IB_PARAM_DECODE_BUFFER); + (*idx)++; + + decode_buffer = (rvcn_decode_buffer_t *)&(ib_cpu[*idx]); + *idx += sizeof(struct rvcn_decode_buffer_s) / 4; + memset(decode_buffer, 0, sizeof(struct rvcn_decode_buffer_s)); + } + + switch(cmd) { + case DECODE_CMD_MSG_BUFFER: + decode_buffer->valid_buf_flag |= DECODE_CMDBUF_FLAGS_MSG_BUFFER; + decode_buffer->msg_buffer_address_hi = (addr >> 32); + decode_buffer->msg_buffer_address_lo = (addr); + break; + case DECODE_CMD_DPB_BUFFER: + decode_buffer->valid_buf_flag |= (DECODE_CMDBUF_FLAGS_DPB_BUFFER); + decode_buffer->dpb_buffer_address_hi = (addr >> 32); + decode_buffer->dpb_buffer_address_lo = (addr); + break; + case DECODE_CMD_DECODING_TARGET_BUFFER: + decode_buffer->valid_buf_flag |= (DECODE_CMDBUF_FLAGS_DECODING_TARGET_BUFFER); + decode_buffer->target_buffer_address_hi = (addr >> 32); + decode_buffer->target_buffer_address_lo = (addr); + break; + case DECODE_CMD_FEEDBACK_BUFFER: + decode_buffer->valid_buf_flag |= (DECODE_CMDBUF_FLAGS_FEEDBACK_BUFFER); + decode_buffer->feedback_buffer_address_hi = (addr >> 32); + decode_buffer->feedback_buffer_address_lo = (addr); + break; + case DECODE_CMD_PROB_TBL_BUFFER: + decode_buffer->valid_buf_flag |= (DECODE_CMDBUF_FLAGS_PROB_TBL_BUFFER); + decode_buffer->prob_tbl_buffer_address_hi = (addr >> 32); + decode_buffer->prob_tbl_buffer_address_lo = (addr); + break; + case DECODE_CMD_SESSION_CONTEXT_BUFFER: + decode_buffer->valid_buf_flag |= (DECODE_CMDBUF_FLAGS_SESSION_CONTEXT_BUFFER); + decode_buffer->session_contex_buffer_address_hi = (addr >> 32); + decode_buffer->session_contex_buffer_address_lo = (addr); + break; + case DECODE_CMD_BITSTREAM_BUFFER: + decode_buffer->valid_buf_flag |= (DECODE_CMDBUF_FLAGS_BITSTREAM_BUFFER); + decode_buffer->bitstream_buffer_address_hi = (addr >> 32); + decode_buffer->bitstream_buffer_address_lo = (addr); + break; + case DECODE_CMD_IT_SCALING_TABLE_BUFFER: + decode_buffer->valid_buf_flag |= (DECODE_CMDBUF_FLAGS_IT_SCALING_BUFFER); + decode_buffer->it_sclr_table_buffer_address_hi = (addr >> 32); + decode_buffer->it_sclr_table_buffer_address_lo = (addr); + break; + case DECODE_CMD_CONTEXT_BUFFER: + decode_buffer->valid_buf_flag |= (DECODE_CMDBUF_FLAGS_CONTEXT_BUFFER); + decode_buffer->context_buffer_address_hi = (addr >> 32); + decode_buffer->context_buffer_address_lo = (addr); + break; + default: + printf("Not Support!\n"); + } } static void amdgpu_cs_vcn_dec_create(void) { struct amdgpu_vcn_bo msg_buf; + unsigned ip; int len, r; num_resources = 0; @@ -332,18 +571,29 @@ memcpy(msg_buf.ptr, vcn_dec_create_msg, sizeof(vcn_dec_create_msg)); len = 0; - ib_cpu[len++] = reg.data0; - ib_cpu[len++] = msg_buf.addr; - ib_cpu[len++] = reg.data1; - ib_cpu[len++] = msg_buf.addr >> 32; - ib_cpu[len++] = reg.cmd; - ib_cpu[len++] = 0; - for (; len % 16; ) { - ib_cpu[len++] = reg.nop; + if (vcn_dec_sw_ring == true) + vcn_dec_cmd(msg_buf.addr, 0, &len); + else { + ib_cpu[len++] = reg[vcn_reg_index].data0; + ib_cpu[len++] = msg_buf.addr; + ib_cpu[len++] = reg[vcn_reg_index].data1; + ib_cpu[len++] = msg_buf.addr >> 32; + ib_cpu[len++] = reg[vcn_reg_index].cmd; ib_cpu[len++] = 0; + for (; len % 16; ) { + ib_cpu[len++] = reg[vcn_reg_index].nop; + ib_cpu[len++] = 0; + } } - r = submit(len, AMDGPU_HW_IP_VCN_DEC); + if (vcn_unified_ring) { + amdgpu_cs_sq_ib_tail(ib_cpu + len); + ip = AMDGPU_HW_IP_VCN_ENC; + } else + ip = AMDGPU_HW_IP_VCN_DEC; + + r = submit(len, ip); + CU_ASSERT_EQUAL(r, 0); free_resource(&msg_buf); @@ -355,6 +605,7 @@ uint64_t msg_addr, fb_addr, bs_addr, dpb_addr, ctx_addr, dt_addr, it_addr, sum; struct amdgpu_vcn_bo dec_buf; int size, len, i, r; + unsigned ip; uint8_t *dec; size = 4*1024; /* msg */ @@ -364,7 +615,7 @@ size += ALIGN(dpb_size, 4*1024); size += ALIGN(dt_size, 4*1024); - num_resources = 0; + num_resources = 0; alloc_resource(&dec_buf, size, AMDGPU_GEM_DOMAIN_GTT); resources[num_resources++] = dec_buf.handle; resources[num_resources++] = ib_handle; @@ -407,14 +658,22 @@ vcn_dec_cmd(it_addr, 0x204, &len); vcn_dec_cmd(ctx_addr, 0x206, &len); - ib_cpu[len++] = reg.cntl; - ib_cpu[len++] = 0x1; - for (; len % 16; ) { - ib_cpu[len++] = reg.nop; - ib_cpu[len++] = 0; + if (vcn_dec_sw_ring == false) { + ib_cpu[len++] = reg[vcn_reg_index].cntl; + ib_cpu[len++] = 0x1; + for (; len % 16; ) { + ib_cpu[len++] = reg[vcn_reg_index].nop; + ib_cpu[len++] = 0; + } } - r = submit(len, AMDGPU_HW_IP_VCN_DEC); + if (vcn_unified_ring) { + amdgpu_cs_sq_ib_tail(ib_cpu + len); + ip = AMDGPU_HW_IP_VCN_ENC; + } else + ip = AMDGPU_HW_IP_VCN_DEC; + + r = submit(len, ip); CU_ASSERT_EQUAL(r, 0); for (i = 0, sum = 0; i < dt_size; ++i) @@ -428,9 +687,10 @@ static void amdgpu_cs_vcn_dec_destroy(void) { struct amdgpu_vcn_bo msg_buf; + unsigned ip; int len, r; - num_resources = 0; + num_resources = 0; alloc_resource(&msg_buf, 1024, AMDGPU_GEM_DOMAIN_GTT); resources[num_resources++] = msg_buf.handle; resources[num_resources++] = ib_handle; @@ -442,18 +702,28 @@ memcpy(msg_buf.ptr, vcn_dec_destroy_msg, sizeof(vcn_dec_destroy_msg)); len = 0; - ib_cpu[len++] = reg.data0; - ib_cpu[len++] = msg_buf.addr; - ib_cpu[len++] = reg.data1; - ib_cpu[len++] = msg_buf.addr >> 32; - ib_cpu[len++] = reg.cmd; - ib_cpu[len++] = 0; - for (; len % 16; ) { - ib_cpu[len++] = reg.nop; + if (vcn_dec_sw_ring == true) + vcn_dec_cmd(msg_buf.addr, 0, &len); + else { + ib_cpu[len++] = reg[vcn_reg_index].data0; + ib_cpu[len++] = msg_buf.addr; + ib_cpu[len++] = reg[vcn_reg_index].data1; + ib_cpu[len++] = msg_buf.addr >> 32; + ib_cpu[len++] = reg[vcn_reg_index].cmd; ib_cpu[len++] = 0; + for (; len % 16; ) { + ib_cpu[len++] = reg[vcn_reg_index].nop; + ib_cpu[len++] = 0; + } } - r = submit(len, AMDGPU_HW_IP_VCN_DEC); + if (vcn_unified_ring) { + amdgpu_cs_sq_ib_tail(ib_cpu + len); + ip = AMDGPU_HW_IP_VCN_ENC; + } else + ip = AMDGPU_HW_IP_VCN_DEC; + + r = submit(len, ip); CU_ASSERT_EQUAL(r, 0); free_resource(&msg_buf); @@ -461,15 +731,905 @@ static void amdgpu_cs_vcn_enc_create(void) { - /* TODO */ + int len, r; + uint32_t *p_task_size = NULL; + uint32_t task_offset = 0, st_offset; + uint32_t *st_size = NULL; + unsigned width = 160, height = 128, buf_size; + uint32_t fw_maj = 1, fw_min = 9; + + if (vcn_ip_version_major == 2) { + fw_maj = 1; + fw_min = 1; + } else if (vcn_ip_version_major == 3) { + fw_maj = 1; + fw_min = 0; + } + + gWidth = width; + gHeight = height; + buf_size = ALIGN(width, 256) * ALIGN(height, 32) * 3 / 2; + enc_task_id = 1; + + num_resources = 0; + alloc_resource(&enc_buf, 128 * 1024, AMDGPU_GEM_DOMAIN_GTT); + alloc_resource(&cpb_buf, buf_size * 2, AMDGPU_GEM_DOMAIN_GTT); + resources[num_resources++] = enc_buf.handle; + resources[num_resources++] = cpb_buf.handle; + resources[num_resources++] = ib_handle; + + r = amdgpu_bo_cpu_map(enc_buf.handle, (void**)&enc_buf.ptr); + memset(enc_buf.ptr, 0, 128 * 1024); + r = amdgpu_bo_cpu_unmap(enc_buf.handle); + + r = amdgpu_bo_cpu_map(cpb_buf.handle, (void**)&enc_buf.ptr); + memset(enc_buf.ptr, 0, buf_size * 2); + r = amdgpu_bo_cpu_unmap(cpb_buf.handle); + + len = 0; + + if (vcn_unified_ring) + amdgpu_cs_sq_head(ib_cpu, &len, true); + + /* session info */ + st_offset = len; + st_size = &ib_cpu[len++]; /* size */ + ib_cpu[len++] = 0x00000001; /* RENCODE_IB_PARAM_SESSION_INFO */ + ib_cpu[len++] = ((fw_maj << 16) | (fw_min << 0)); + ib_cpu[len++] = enc_buf.addr >> 32; + ib_cpu[len++] = enc_buf.addr; + ib_cpu[len++] = 1; /* RENCODE_ENGINE_TYPE_ENCODE; */ + *st_size = (len - st_offset) * 4; + + /* task info */ + task_offset = len; + st_offset = len; + st_size = &ib_cpu[len++]; /* size */ + ib_cpu[len++] = 0x00000002; /* RENCODE_IB_PARAM_TASK_INFO */ + p_task_size = &ib_cpu[len++]; + ib_cpu[len++] = enc_task_id++; /* task_id */ + ib_cpu[len++] = 0; /* feedback */ + *st_size = (len - st_offset) * 4; + + /* op init */ + st_offset = len; + st_size = &ib_cpu[len++]; /* size */ + ib_cpu[len++] = 0x01000001; /* RENCODE_IB_OP_INITIALIZE */ + *st_size = (len - st_offset) * 4; + + /* session_init */ + st_offset = len; + st_size = &ib_cpu[len++]; /* size */ + ib_cpu[len++] = 0x00000003; /* RENCODE_IB_PARAM_SESSION_INIT */ + ib_cpu[len++] = 1; /* RENCODE_ENCODE_STANDARD_H264 */ + ib_cpu[len++] = width; + ib_cpu[len++] = height; + ib_cpu[len++] = 0; + ib_cpu[len++] = 0; + ib_cpu[len++] = 0; /* pre encode mode */ + ib_cpu[len++] = 0; /* chroma enabled : false */ + *st_size = (len - st_offset) * 4; + + /* slice control */ + st_offset = len; + st_size = &ib_cpu[len++]; /* size */ + ib_cpu[len++] = 0x00200001; /* RENCODE_H264_IB_PARAM_SLICE_CONTROL */ + ib_cpu[len++] = 0; /* RENCODE_H264_SLICE_CONTROL_MODE_FIXED_MBS */ + ib_cpu[len++] = ALIGN(width, 16) / 16 * ALIGN(height, 16) / 16; + *st_size = (len - st_offset) * 4; + + /* enc spec misc */ + st_offset = len; + st_size = &ib_cpu[len++]; /* size */ + ib_cpu[len++] = 0x00200002; /* RENCODE_H264_IB_PARAM_SPEC_MISC */ + ib_cpu[len++] = 0; /* constrained intra pred flag */ + ib_cpu[len++] = 0; /* cabac enable */ + ib_cpu[len++] = 0; /* cabac init idc */ + ib_cpu[len++] = 1; /* half pel enabled */ + ib_cpu[len++] = 1; /* quarter pel enabled */ + ib_cpu[len++] = 100; /* BASELINE profile */ + ib_cpu[len++] = 11; /* level */ + if (vcn_ip_version_major == 3) { + ib_cpu[len++] = 0; /* b_picture_enabled */ + ib_cpu[len++] = 0; /* weighted_bipred_idc */ + } + *st_size = (len - st_offset) * 4; + + /* deblocking filter */ + st_offset = len; + st_size = &ib_cpu[len++]; /* size */ + ib_cpu[len++] = 0x00200004; /* RENCODE_H264_IB_PARAM_DEBLOCKING_FILTER */ + ib_cpu[len++] = 0; /* disable deblocking filter idc */ + ib_cpu[len++] = 0; /* alpha c0 offset */ + ib_cpu[len++] = 0; /* tc offset */ + ib_cpu[len++] = 0; /* cb offset */ + ib_cpu[len++] = 0; /* cr offset */ + *st_size = (len - st_offset) * 4; + + /* layer control */ + st_offset = len; + st_size = &ib_cpu[len++]; /* size */ + ib_cpu[len++] = 0x00000004; /* RENCODE_IB_PARAM_LAYER_CONTROL */ + ib_cpu[len++] = 1; /* max temporal layer */ + ib_cpu[len++] = 1; /* no of temporal layer */ + *st_size = (len - st_offset) * 4; + + /* rc_session init */ + st_offset = len; + st_size = &ib_cpu[len++]; /* size */ + ib_cpu[len++] = 0x00000006; /* RENCODE_IB_PARAM_RATE_CONTROL_SESSION_INIT */ + ib_cpu[len++] = 0; /* rate control */ + ib_cpu[len++] = 48; /* vbv buffer level */ + *st_size = (len - st_offset) * 4; + + /* quality params */ + st_offset = len; + st_size = &ib_cpu[len++]; /* size */ + ib_cpu[len++] = 0x00000009; /* RENCODE_IB_PARAM_QUALITY_PARAMS */ + ib_cpu[len++] = 0; /* vbaq mode */ + ib_cpu[len++] = 0; /* scene change sensitivity */ + ib_cpu[len++] = 0; /* scene change min idr interval */ + ib_cpu[len++] = 0; + if (vcn_ip_version_major == 3) + ib_cpu[len++] = 0; + *st_size = (len - st_offset) * 4; + + /* layer select */ + st_offset = len; + st_size = &ib_cpu[len++]; /* size */ + ib_cpu[len++] = 0x00000005; /* RENCODE_IB_PARAM_LAYER_SELECT */ + ib_cpu[len++] = 0; /* temporal layer */ + *st_size = (len - st_offset) * 4; + + /* rc layer init */ + st_offset = len; + st_size = &ib_cpu[len++]; /* size */ + ib_cpu[len++] = 0x00000007; /* RENCODE_IB_PARAM_RATE_CONTROL_LAYER_INIT */ + ib_cpu[len++] = 0; + ib_cpu[len++] = 0; + ib_cpu[len++] = 25; + ib_cpu[len++] = 1; + ib_cpu[len++] = 0x01312d00; + ib_cpu[len++] = 0; + ib_cpu[len++] = 0; + ib_cpu[len++] = 0; + *st_size = (len - st_offset) * 4; + + /* layer select */ + st_offset = len; + st_size = &ib_cpu[len++]; /* size */ + ib_cpu[len++] = 0x00000005; /* RENCODE_IB_PARAM_LAYER_SELECT */ + ib_cpu[len++] = 0; /* temporal layer */ + *st_size = (len - st_offset) * 4; + + /* rc per pic */ + st_offset = len; + st_size = &ib_cpu[len++]; /* size */ + ib_cpu[len++] = 0x00000008; /* RENCODE_IB_PARAM_RATE_CONTROL_PER_PICTURE */ + ib_cpu[len++] = 20; + ib_cpu[len++] = 0; + ib_cpu[len++] = 51; + ib_cpu[len++] = 0; + ib_cpu[len++] = 1; + ib_cpu[len++] = 0; + ib_cpu[len++] = 1; + *st_size = (len - st_offset) * 4; + + /* op init rc */ + st_offset = len; + st_size = &ib_cpu[len++]; /* size */ + ib_cpu[len++] = 0x01000004; /* RENCODE_IB_OP_INIT_RC */ + *st_size = (len - st_offset) * 4; + + /* op init rc vbv */ + st_offset = len; + st_size = &ib_cpu[len++]; /* size */ + ib_cpu[len++] = 0x01000005; /* RENCODE_IB_OP_INIT_RC_VBV_BUFFER_LEVEL */ + *st_size = (len - st_offset) * 4; + + *p_task_size = (len - task_offset) * 4; + + if (vcn_unified_ring) + amdgpu_cs_sq_ib_tail(ib_cpu + len); + + r = submit(len, AMDGPU_HW_IP_VCN_ENC); + CU_ASSERT_EQUAL(r, 0); +} + +static int32_t h264_se (bufferInfo * bufInfo) +{ + uint32_t ret; + + ret = bs_read_ue (bufInfo); + if ((ret & 0x1) == 0) { + ret >>= 1; + int32_t temp = 0 - ret; + return temp; + } + + return (ret + 1) >> 1; +} + +static void h264_check_0s (bufferInfo * bufInfo, int count) +{ + uint32_t val; + + val = bs_read_u (bufInfo, count); + if (val != 0) { + printf ("field error - %d bits should be 0 is %x\n", count, val); + } +} + +static inline int bs_eof(bufferInfo * bufinfo) +{ + if (bufinfo->decBuffer >= bufinfo->end) + return 1; + else + return 0; +} + +static inline uint32_t bs_read_u1(bufferInfo *bufinfo) +{ + uint32_t r = 0; + uint32_t temp = 0; + + bufinfo->numOfBitsInBuffer--; + if (! bs_eof(bufinfo)) { + temp = (((bufinfo->decData)) >> bufinfo->numOfBitsInBuffer); + r = temp & 0x01; + } + + if (bufinfo->numOfBitsInBuffer == 0) { + bufinfo->decBuffer++; + bufinfo->decData = *bufinfo->decBuffer; + bufinfo->numOfBitsInBuffer = 8; + } + + return r; +} + +static inline uint32_t bs_read_u(bufferInfo* bufinfo, int n) +{ + uint32_t r = 0; + int i; + + for (i = 0; i < n; i++) { + r |= ( bs_read_u1(bufinfo) << ( n - i - 1 ) ); + } + + return r; +} + +static inline uint32_t bs_read_ue(bufferInfo* bufinfo) +{ + int32_t r = 0; + int i = 0; + + while( (bs_read_u1(bufinfo) == 0) && (i < 32) && (!bs_eof(bufinfo))) { + i++; + } + r = bs_read_u(bufinfo, i); + r += (1 << i) - 1; + return r; +} + +static uint32_t remove_03 (uint8_t * bptr, uint32_t len) +{ + uint32_t nal_len = 0; + while (nal_len + 2 < len) { + if (bptr[0] == 0 && bptr[1] == 0 && bptr[2] == 3) { + bptr += 2; + nal_len += 2; + len--; + memmove (bptr, bptr + 1, len - nal_len); + } else { + bptr++; + nal_len++; + } + } + return len; +} + +static void scaling_list (uint32_t ix, uint32_t sizeOfScalingList, bufferInfo * bufInfo) +{ + uint32_t lastScale = 8, nextScale = 8; + uint32_t jx; + int deltaScale; + + for (jx = 0; jx < sizeOfScalingList; jx++) { + if (nextScale != 0) { + deltaScale = h264_se (bufInfo); + nextScale = (lastScale + deltaScale + 256) % 256; + } + if (nextScale == 0) { + lastScale = lastScale; + } else { + lastScale = nextScale; + } + } +} + +static void h264_parse_sequence_parameter_set (h264_decode * dec, bufferInfo * bufInfo) +{ + uint32_t temp; + + dec->profile = bs_read_u (bufInfo, 8); + bs_read_u (bufInfo, 1); /* constaint_set0_flag */ + bs_read_u (bufInfo, 1); /* constaint_set1_flag */ + bs_read_u (bufInfo, 1); /* constaint_set2_flag */ + bs_read_u (bufInfo, 1); /* constaint_set3_flag */ + bs_read_u (bufInfo, 1); /* constaint_set4_flag */ + bs_read_u (bufInfo, 1); /* constaint_set5_flag */ + + + h264_check_0s (bufInfo, 2); + dec->level_idc = bs_read_u (bufInfo, 8); + bs_read_ue (bufInfo); /* SPS id*/ + + if (dec->profile == 100 || dec->profile == 110 || + dec->profile == 122 || dec->profile == 144) { + uint32_t chroma_format_idc = bs_read_ue (bufInfo); + if (chroma_format_idc == 3) { + bs_read_u (bufInfo, 1); /* residual_colour_transform_flag */ + } + bs_read_ue (bufInfo); /* bit_depth_luma_minus8 */ + bs_read_ue (bufInfo); /* bit_depth_chroma_minus8 */ + bs_read_u (bufInfo, 1); /* qpprime_y_zero_transform_bypass_flag */ + uint32_t seq_scaling_matrix_present_flag = bs_read_u (bufInfo, 1); + + if (seq_scaling_matrix_present_flag) { + for (uint32_t ix = 0; ix < 8; ix++) { + temp = bs_read_u (bufInfo, 1); + if (temp) { + scaling_list (ix, ix < 6 ? 16 : 64, bufInfo); + } + } + } + } + + bs_read_ue (bufInfo); /* log2_max_frame_num_minus4 */ + uint32_t pic_order_cnt_type = bs_read_ue (bufInfo); + + if (pic_order_cnt_type == 0) { + bs_read_ue (bufInfo); /* log2_max_pic_order_cnt_lsb_minus4 */ + } else if (pic_order_cnt_type == 1) { + bs_read_u (bufInfo, 1); /* delta_pic_order_always_zero_flag */ + h264_se (bufInfo); /* offset_for_non_ref_pic */ + h264_se (bufInfo); /* offset_for_top_to_bottom_field */ + temp = bs_read_ue (bufInfo); + for (uint32_t ix = 0; ix < temp; ix++) { + h264_se (bufInfo); /* offset_for_ref_frame[index] */ + } + } + bs_read_ue (bufInfo); /* num_ref_frames */ + bs_read_u (bufInfo, 1); /* gaps_in_frame_num_flag */ + uint32_t PicWidthInMbs = bs_read_ue (bufInfo) + 1; + + dec->pic_width = PicWidthInMbs * 16; + uint32_t PicHeightInMapUnits = bs_read_ue (bufInfo) + 1; + + dec->pic_height = PicHeightInMapUnits * 16; + uint32_t frame_mbs_only_flag = bs_read_u (bufInfo, 1); + if (!frame_mbs_only_flag) { + bs_read_u (bufInfo, 1); /* mb_adaptive_frame_field_flag */ + } + bs_read_u (bufInfo, 1); /* direct_8x8_inference_flag */ + temp = bs_read_u (bufInfo, 1); + if (temp) { + bs_read_ue (bufInfo); /* frame_crop_left_offset */ + bs_read_ue (bufInfo); /* frame_crop_right_offset */ + bs_read_ue (bufInfo); /* frame_crop_top_offset */ + bs_read_ue (bufInfo); /* frame_crop_bottom_offset */ + } + temp = bs_read_u (bufInfo, 1); /* VUI Parameters */ +} + +static void h264_slice_header (h264_decode * dec, bufferInfo * bufInfo) +{ + uint32_t temp; + + bs_read_ue (bufInfo); /* first_mb_in_slice */ + temp = bs_read_ue (bufInfo); + dec->slice_type = ((temp > 5) ? (temp - 5) : temp); +} + +static uint8_t h264_parse_nal (h264_decode * dec, bufferInfo * bufInfo) +{ + uint8_t type = 0; + + h264_check_0s (bufInfo, 1); + dec->nal_ref_idc = bs_read_u (bufInfo, 2); + dec->nal_unit_type = type = bs_read_u (bufInfo, 5); + switch (type) + { + case H264_NAL_TYPE_NON_IDR_SLICE: + case H264_NAL_TYPE_IDR_SLICE: + h264_slice_header (dec, bufInfo); + break; + case H264_NAL_TYPE_SEQ_PARAM: + h264_parse_sequence_parameter_set (dec, bufInfo); + break; + case H264_NAL_TYPE_PIC_PARAM: + case H264_NAL_TYPE_SEI: + case H264_NAL_TYPE_ACCESS_UNIT: + case H264_NAL_TYPE_SEQ_EXTENSION: + /* NOP */ + break; + default: + printf ("Nal type unknown %d \n ", type); + break; + } + return type; +} + +static uint32_t h264_find_next_start_code (uint8_t * pBuf, uint32_t bufLen) +{ + uint32_t val; + uint32_t offset, startBytes; + + offset = startBytes = 0; + if (pBuf[0] == 0 && pBuf[1] == 0 && pBuf[2] == 0 && pBuf[3] == 1) { + pBuf += 4; + offset = 4; + startBytes = 1; + } else if (pBuf[0] == 0 && pBuf[1] == 0 && pBuf[2] == 1) { + pBuf += 3; + offset = 3; + startBytes = 1; + } + val = 0xffffffff; + while (offset < bufLen - 3) { + val <<= 8; + val |= *pBuf++; + offset++; + if (val == H264_START_CODE) + return offset - 4; + + if ((val & 0x00ffffff) == H264_START_CODE) + return offset - 3; + } + if (bufLen - offset <= 3 && startBytes == 0) { + startBytes = 0; + return 0; + } + + return offset; +} + +static int verify_checksum(uint8_t *buffer, uint32_t buffer_size) +{ + uint32_t buffer_pos = 0; + int done = 0; + h264_decode dec; + + memset(&dec, 0, sizeof(h264_decode)); + do { + uint32_t ret; + + ret = h264_find_next_start_code (buffer + buffer_pos, + buffer_size - buffer_pos); + if (ret == 0) { + done = 1; + if (buffer_pos == 0) { + fprintf (stderr, + "couldn't find start code in buffer from 0\n"); + } + } else { + /* have a complete NAL from buffer_pos to end */ + if (ret > 3) { + uint32_t nal_len; + bufferInfo bufinfo; + + nal_len = remove_03 (buffer + buffer_pos, ret); + bufinfo.decBuffer = buffer + buffer_pos + (buffer[buffer_pos + 2] == 1 ? 3 : 4); + bufinfo.decBufferSize = (nal_len - (buffer[buffer_pos + 2] == 1 ? 3 : 4)) * 8; + bufinfo.end = buffer + buffer_pos + nal_len; + bufinfo.numOfBitsInBuffer = 8; + bufinfo.decData = *bufinfo.decBuffer; + h264_parse_nal (&dec, &bufinfo); + } + buffer_pos += ret; /* buffer_pos points to next code */ + } + } while (done == 0); + + if ((dec.pic_width == gWidth) && + (dec.pic_height == gHeight) && + (dec.slice_type == gSliceType)) + return 0; + else + return -1; +} + +static void check_result(struct amdgpu_vcn_bo fb_buf, struct amdgpu_vcn_bo bs_buf, int frame_type) +{ + uint32_t *fb_ptr; + uint8_t *bs_ptr; + uint32_t size; + int r; +/* uint64_t s[3] = {0, 1121279001727, 1059312481445}; */ + + r = amdgpu_bo_cpu_map(fb_buf.handle, (void **)&fb_buf.ptr); + CU_ASSERT_EQUAL(r, 0); + fb_ptr = (uint32_t*)fb_buf.ptr; + size = fb_ptr[6]; + r = amdgpu_bo_cpu_unmap(fb_buf.handle); + CU_ASSERT_EQUAL(r, 0); + r = amdgpu_bo_cpu_map(bs_buf.handle, (void **)&bs_buf.ptr); + CU_ASSERT_EQUAL(r, 0); + + bs_ptr = (uint8_t*)bs_buf.ptr; + r = verify_checksum(bs_ptr, size); + CU_ASSERT_EQUAL(r, 0); + r = amdgpu_bo_cpu_unmap(bs_buf.handle); + + CU_ASSERT_EQUAL(r, 0); +} + +static void amdgpu_cs_vcn_enc_encode_frame(int frame_type) +{ + struct amdgpu_vcn_bo bs_buf, fb_buf, vbv_buf; + int len, r, i; + unsigned width = 160, height = 128, buf_size; + uint32_t *p_task_size = NULL; + uint32_t task_offset = 0, st_offset; + uint32_t *st_size = NULL; + uint32_t fw_maj = 1, fw_min = 9; + + if (vcn_ip_version_major == 2) { + fw_maj = 1; + fw_min = 1; + } else if (vcn_ip_version_major == 3) { + fw_maj = 1; + fw_min = 0; + } + gSliceType = frame_type; + buf_size = ALIGN(width, 256) * ALIGN(height, 32) * 3 / 2; + + num_resources = 0; + alloc_resource(&bs_buf, 4096, AMDGPU_GEM_DOMAIN_GTT); + alloc_resource(&fb_buf, 4096, AMDGPU_GEM_DOMAIN_GTT); + alloc_resource(&vbv_buf, buf_size, AMDGPU_GEM_DOMAIN_GTT); + resources[num_resources++] = enc_buf.handle; + resources[num_resources++] = cpb_buf.handle; + resources[num_resources++] = bs_buf.handle; + resources[num_resources++] = fb_buf.handle; + resources[num_resources++] = vbv_buf.handle; + resources[num_resources++] = ib_handle; + + + r = amdgpu_bo_cpu_map(bs_buf.handle, (void**)&bs_buf.ptr); + memset(bs_buf.ptr, 0, 4096); + r = amdgpu_bo_cpu_unmap(bs_buf.handle); + + r = amdgpu_bo_cpu_map(fb_buf.handle, (void**)&fb_buf.ptr); + memset(fb_buf.ptr, 0, 4096); + r = amdgpu_bo_cpu_unmap(fb_buf.handle); + + r = amdgpu_bo_cpu_map(vbv_buf.handle, (void **)&vbv_buf.ptr); + CU_ASSERT_EQUAL(r, 0); + + for (int i = 0; i < ALIGN(height, 32) * 3 / 2; i++) + memcpy(vbv_buf.ptr + i * ALIGN(width, 256), frame + i * width, width); + + r = amdgpu_bo_cpu_unmap(vbv_buf.handle); + CU_ASSERT_EQUAL(r, 0); + + len = 0; + + if (vcn_unified_ring) + amdgpu_cs_sq_head(ib_cpu, &len, true); + + /* session info */ + st_offset = len; + st_size = &ib_cpu[len++]; /* size */ + ib_cpu[len++] = 0x00000001; /* RENCODE_IB_PARAM_SESSION_INFO */ + ib_cpu[len++] = ((fw_maj << 16) | (fw_min << 0)); + ib_cpu[len++] = enc_buf.addr >> 32; + ib_cpu[len++] = enc_buf.addr; + ib_cpu[len++] = 1; /* RENCODE_ENGINE_TYPE_ENCODE */; + *st_size = (len - st_offset) * 4; + + /* task info */ + task_offset = len; + st_offset = len; + st_size = &ib_cpu[len++]; /* size */ + ib_cpu[len++] = 0x00000002; /* RENCODE_IB_PARAM_TASK_INFO */ + p_task_size = &ib_cpu[len++]; + ib_cpu[len++] = enc_task_id++; /* task_id */ + ib_cpu[len++] = 1; /* feedback */ + *st_size = (len - st_offset) * 4; + + if (frame_type == 2) { + /* sps */ + st_offset = len; + st_size = &ib_cpu[len++]; /* size */ + if(vcn_ip_version_major == 1) + ib_cpu[len++] = 0x00000020; /* RENCODE_IB_PARAM_DIRECT_OUTPUT_NALU vcn 1 */ + else + ib_cpu[len++] = 0x0000000a; /* RENCODE_IB_PARAM_DIRECT_OUTPUT_NALU vcn 2,3 */ + ib_cpu[len++] = 0x00000002; /* RENCODE_DIRECT_OUTPUT_NALU_TYPE_SPS */ + ib_cpu[len++] = 0x00000011; /* sps len */ + ib_cpu[len++] = 0x00000001; /* start code */ + ib_cpu[len++] = 0x6764440b; + ib_cpu[len++] = 0xac54c284; + ib_cpu[len++] = 0x68078442; + ib_cpu[len++] = 0x37000000; + *st_size = (len - st_offset) * 4; + + /* pps */ + st_offset = len; + st_size = &ib_cpu[len++]; /* size */ + if(vcn_ip_version_major == 1) + ib_cpu[len++] = 0x00000020; /* RENCODE_IB_PARAM_DIRECT_OUTPUT_NALU vcn 1*/ + else + ib_cpu[len++] = 0x0000000a; /* RENCODE_IB_PARAM_DIRECT_OUTPUT_NALU vcn 2,3*/ + ib_cpu[len++] = 0x00000003; /* RENCODE_DIRECT_OUTPUT_NALU_TYPE_PPS */ + ib_cpu[len++] = 0x00000008; /* pps len */ + ib_cpu[len++] = 0x00000001; /* start code */ + ib_cpu[len++] = 0x68ce3c80; + *st_size = (len - st_offset) * 4; + } + + /* slice header */ + st_offset = len; + st_size = &ib_cpu[len++]; /* size */ + if(vcn_ip_version_major == 1) + ib_cpu[len++] = 0x0000000a; /* RENCODE_IB_PARAM_SLICE_HEADER vcn 1 */ + else + ib_cpu[len++] = 0x0000000b; /* RENCODE_IB_PARAM_SLICE_HEADER vcn 2,3 */ + if (frame_type == 2) { + ib_cpu[len++] = 0x65000000; + ib_cpu[len++] = 0x11040000; + } else { + ib_cpu[len++] = 0x41000000; + ib_cpu[len++] = 0x34210000; + } + ib_cpu[len++] = 0xe0000000; + for(i = 0; i < 13; i++) + ib_cpu[len++] = 0x00000000; + + ib_cpu[len++] = 0x00000001; + ib_cpu[len++] = 0x00000008; + ib_cpu[len++] = 0x00020000; + ib_cpu[len++] = 0x00000000; + ib_cpu[len++] = 0x00000001; + ib_cpu[len++] = 0x00000015; + ib_cpu[len++] = 0x00020001; + ib_cpu[len++] = 0x00000000; + ib_cpu[len++] = 0x00000001; + ib_cpu[len++] = 0x00000003; + for(i = 0; i < 22; i++) + ib_cpu[len++] = 0x00000000; + + *st_size = (len - st_offset) * 4; + + /* encode params */ + st_offset = len; + st_size = &ib_cpu[len++]; /* size */ + if(vcn_ip_version_major == 1) + ib_cpu[len++] = 0x0000000b; /* RENCODE_IB_PARAM_ENCODE_PARAMS vcn 1*/ + else + ib_cpu[len++] = 0x0000000f; /* RENCODE_IB_PARAM_ENCODE_PARAMS vcn 2,3*/ + ib_cpu[len++] = frame_type; + ib_cpu[len++] = 0x0001f000; + ib_cpu[len++] = vbv_buf.addr >> 32; + ib_cpu[len++] = vbv_buf.addr; + ib_cpu[len++] = (vbv_buf.addr + ALIGN(width, 256) * ALIGN(height, 32)) >> 32; + ib_cpu[len++] = vbv_buf.addr + ALIGN(width, 256) * ALIGN(height, 32); + ib_cpu[len++] = 0x00000100; + ib_cpu[len++] = 0x00000080; + ib_cpu[len++] = 0x00000000; + ib_cpu[len++] = 0xffffffff; + ib_cpu[len++] = 0x00000000; + *st_size = (len - st_offset) * 4; + + /* encode params h264 */ + st_offset = len; + st_size = &ib_cpu[len++]; /* size */ + ib_cpu[len++] = 0x00200003; /* RENCODE_H264_IB_PARAM_ENCODE_PARAMS */ + if (vcn_ip_version_major != 3) { + ib_cpu[len++] = 0x00000000; + ib_cpu[len++] = 0x00000000; + ib_cpu[len++] = 0x00000000; + ib_cpu[len++] = 0xffffffff; + } else { + ib_cpu[len++] = 0x00000000; + ib_cpu[len++] = 0x00000000; + ib_cpu[len++] = 0x00000000; + ib_cpu[len++] = 0x00000000; + ib_cpu[len++] = 0x00000000; + ib_cpu[len++] = 0x00000000; + ib_cpu[len++] = 0x00000000; + ib_cpu[len++] = 0xffffffff; + ib_cpu[len++] = 0x00000000; + ib_cpu[len++] = 0x00000000; + ib_cpu[len++] = 0x00000000; + ib_cpu[len++] = 0x00000000; + ib_cpu[len++] = 0xffffffff; + ib_cpu[len++] = 0x00000000; + ib_cpu[len++] = 0x00000000; + ib_cpu[len++] = 0x00000000; + ib_cpu[len++] = 0x00000000; + } + *st_size = (len - st_offset) * 4; + + /* encode context */ + st_offset = len; + st_size = &ib_cpu[len++]; /* size */ + if(vcn_ip_version_major == 1) + ib_cpu[len++] = 0x0000000d; /* ENCODE_CONTEXT_BUFFER vcn 1 */ + else + ib_cpu[len++] = 0x00000011; /* ENCODE_CONTEXT_BUFFER vcn 2,3 */ + ib_cpu[len++] = cpb_buf.addr >> 32; + ib_cpu[len++] = cpb_buf.addr; + ib_cpu[len++] = 0x00000000; /* swizzle mode */ + ib_cpu[len++] = 0x00000100; /* luma pitch */ + ib_cpu[len++] = 0x00000100; /* chroma pitch */ + ib_cpu[len++] = 0x00000003; /* no reconstructed picture */ + ib_cpu[len++] = 0x00000000; /* reconstructed pic 1 luma offset */ + ib_cpu[len++] = ALIGN(width, 256) * ALIGN(height, 32); /* pic1 chroma offset */ + ib_cpu[len++] = ALIGN(width, 256) * ALIGN(height, 32) * 3 / 2; /* pic2 luma offset */ + ib_cpu[len++] = ALIGN(width, 256) * ALIGN(height, 32) * 5 / 2; /* pic2 chroma offset */ + + for (int i = 0; i < 136; i++) + ib_cpu[len++] = 0x00000000; + *st_size = (len - st_offset) * 4; + + /* bitstream buffer */ + st_offset = len; + st_size = &ib_cpu[len++]; /* size */ + if(vcn_ip_version_major == 1) + ib_cpu[len++] = 0x0000000e; /* VIDEO_BITSTREAM_BUFFER vcn 1 */ + else + ib_cpu[len++] = 0x00000012; /* VIDEO_BITSTREAM_BUFFER vcn 2,3 */ + ib_cpu[len++] = 0x00000000; /* mode */ + ib_cpu[len++] = bs_buf.addr >> 32; + ib_cpu[len++] = bs_buf.addr; + ib_cpu[len++] = 0x0001f000; + ib_cpu[len++] = 0x00000000; + *st_size = (len - st_offset) * 4; + + /* feedback */ + st_offset = len; + st_size = &ib_cpu[len++]; /* size */ + if(vcn_ip_version_major == 1) + ib_cpu[len++] = 0x00000010; /* FEEDBACK_BUFFER vcn 1 */ + else + ib_cpu[len++] = 0x00000015; /* FEEDBACK_BUFFER vcn 2,3 */ + ib_cpu[len++] = 0x00000000; + ib_cpu[len++] = fb_buf.addr >> 32; + ib_cpu[len++] = fb_buf.addr; + ib_cpu[len++] = 0x00000010; + ib_cpu[len++] = 0x00000028; + *st_size = (len - st_offset) * 4; + + /* intra refresh */ + st_offset = len; + st_size = &ib_cpu[len++]; + if(vcn_ip_version_major == 1) + ib_cpu[len++] = 0x0000000c; /* INTRA_REFRESH vcn 1 */ + else + ib_cpu[len++] = 0x00000010; /* INTRA_REFRESH vcn 2,3 */ + ib_cpu[len++] = 0x00000000; + ib_cpu[len++] = 0x00000000; + ib_cpu[len++] = 0x00000000; + *st_size = (len - st_offset) * 4; + + if(vcn_ip_version_major != 1) { + /* Input Format */ + st_offset = len; + st_size = &ib_cpu[len++]; + ib_cpu[len++] = 0x0000000c; + ib_cpu[len++] = 0x00000000; /* RENCODE_COLOR_VOLUME_G22_BT709 */ + ib_cpu[len++] = 0x00000000; + ib_cpu[len++] = 0x00000000; + ib_cpu[len++] = 0x00000000; + ib_cpu[len++] = 0x00000000; + ib_cpu[len++] = 0x00000000; /* RENCODE_COLOR_BIT_DEPTH_8_BIT */ + ib_cpu[len++] = 0x00000000; /* RENCODE_COLOR_PACKING_FORMAT_NV12 */ + *st_size = (len - st_offset) * 4; + + /* Output Format */ + st_offset = len; + st_size = &ib_cpu[len++]; + ib_cpu[len++] = 0x0000000d; + ib_cpu[len++] = 0x00000000; /* RENCODE_COLOR_VOLUME_G22_BT709 */ + ib_cpu[len++] = 0x00000000; + ib_cpu[len++] = 0x00000000; + ib_cpu[len++] = 0x00000000; /* RENCODE_COLOR_BIT_DEPTH_8_BIT */ + *st_size = (len - st_offset) * 4; + } + /* op_speed */ + st_offset = len; + st_size = &ib_cpu[len++]; + ib_cpu[len++] = 0x01000006; /* SPEED_ENCODING_MODE */ + *st_size = (len - st_offset) * 4; + + /* op_enc */ + st_offset = len; + st_size = &ib_cpu[len++]; + ib_cpu[len++] = 0x01000003; + *st_size = (len - st_offset) * 4; + + *p_task_size = (len - task_offset) * 4; + + if (vcn_unified_ring) + amdgpu_cs_sq_ib_tail(ib_cpu + len); + + r = submit(len, AMDGPU_HW_IP_VCN_ENC); + CU_ASSERT_EQUAL(r, 0); + + /* check result */ + check_result(fb_buf, bs_buf, frame_type); + + free_resource(&fb_buf); + free_resource(&bs_buf); + free_resource(&vbv_buf); } static void amdgpu_cs_vcn_enc_encode(void) { - /* TODO */ + amdgpu_cs_vcn_enc_encode_frame(2); /* IDR frame */ } static void amdgpu_cs_vcn_enc_destroy(void) { - /* TODO */ + int len = 0, r; + uint32_t *p_task_size = NULL; + uint32_t task_offset = 0, st_offset; + uint32_t *st_size = NULL; + uint32_t fw_maj = 1, fw_min = 9; + + if (vcn_ip_version_major == 2) { + fw_maj = 1; + fw_min = 1; + } else if (vcn_ip_version_major == 3) { + fw_maj = 1; + fw_min = 0; + } + + num_resources = 0; +/* alloc_resource(&enc_buf, 128 * 1024, AMDGPU_GEM_DOMAIN_GTT); */ + resources[num_resources++] = enc_buf.handle; + resources[num_resources++] = ib_handle; + + if (vcn_unified_ring) + amdgpu_cs_sq_head(ib_cpu, &len, true); + + /* session info */ + st_offset = len; + st_size = &ib_cpu[len++]; /* size */ + ib_cpu[len++] = 0x00000001; /* RENCODE_IB_PARAM_SESSION_INFO */ + ib_cpu[len++] = ((fw_maj << 16) | (fw_min << 0)); + ib_cpu[len++] = enc_buf.addr >> 32; + ib_cpu[len++] = enc_buf.addr; + ib_cpu[len++] = 1; /* RENCODE_ENGINE_TYPE_ENCODE; */ + *st_size = (len - st_offset) * 4; + + /* task info */ + task_offset = len; + st_offset = len; + st_size = &ib_cpu[len++]; /* size */ + ib_cpu[len++] = 0x00000002; /* RENCODE_IB_PARAM_TASK_INFO */ + p_task_size = &ib_cpu[len++]; + ib_cpu[len++] = enc_task_id++; /* task_id */ + ib_cpu[len++] = 0; /* feedback */ + *st_size = (len - st_offset) * 4; + + /* op close */ + st_offset = len; + st_size = &ib_cpu[len++]; + ib_cpu[len++] = 0x01000002; /* RENCODE_IB_OP_CLOSE_SESSION */ + *st_size = (len - st_offset) * 4; + + *p_task_size = (len - task_offset) * 4; + + if (vcn_unified_ring) + amdgpu_cs_sq_ib_tail(ib_cpu + len); + + r = submit(len, AMDGPU_HW_IP_VCN_ENC); + CU_ASSERT_EQUAL(r, 0); + + free_resource(&cpb_buf); + free_resource(&enc_buf); } diff -Nru libdrm-2.4.110/tests/drmdevice.c libdrm-2.4.113/tests/drmdevice.c --- libdrm-2.4.110/tests/drmdevice.c 2022-02-16 10:00:13.000000000 +0000 +++ libdrm-2.4.113/tests/drmdevice.c 2022-08-31 14:38:38.000000000 +0000 @@ -142,7 +142,7 @@ for (int j = 0; j < DRM_NODE_MAX; j++) { if (devices[i]->available_nodes & 1 << j) { printf("--- Opening device node %s ---\n", devices[i]->nodes[j]); - fd = open(devices[i]->nodes[j], O_RDONLY | O_CLOEXEC, 0); + fd = open(devices[i]->nodes[j], O_RDONLY | O_CLOEXEC); if (fd < 0) { printf("Failed - %s (%d)\n", strerror(errno), errno); continue; diff -Nru libdrm-2.4.110/tests/exynos/exynos_fimg2d_test.c libdrm-2.4.113/tests/exynos/exynos_fimg2d_test.c --- libdrm-2.4.110/tests/exynos/exynos_fimg2d_test.c 2022-02-16 10:00:13.000000000 +0000 +++ libdrm-2.4.113/tests/exynos/exynos_fimg2d_test.c 2022-08-31 14:38:38.000000000 +0000 @@ -35,7 +35,6 @@ #include #include -#include #include #include "exynos_drm.h" diff -Nru libdrm-2.4.110/tests/exynos/meson.build libdrm-2.4.113/tests/exynos/meson.build --- libdrm-2.4.110/tests/exynos/meson.build 2022-02-16 10:00:13.000000000 +0000 +++ libdrm-2.4.113/tests/exynos/meson.build 2022-08-31 14:38:38.000000000 +0000 @@ -20,18 +20,15 @@ inc_exynos = include_directories('../../exynos') -if with_libkms - exynos_fimg2d_test = executable( - 'exynos_fimg2d_test', - files('exynos_fimg2d_test.c'), - c_args : libdrm_c_args, - include_directories : [inc_root, inc_drm, inc_exynos, - include_directories('../../libkms')], - link_with : [libdrm, libkms, libdrm_exynos], - dependencies : dep_threads, - install : with_install_tests, - ) -endif +exynos_fimg2d_test = executable( + 'exynos_fimg2d_test', + files('exynos_fimg2d_test.c'), + c_args : libdrm_c_args, + include_directories : [inc_root, inc_drm, inc_exynos], + link_with : [libdrm, libdrm_exynos], + dependencies : dep_threads, + install : with_install_tests, +) exynos_fimg2d_perf = executable( 'exynos_fimg2d_perf', diff -Nru libdrm-2.4.110/tests/kms/kms-steal-crtc.c libdrm-2.4.113/tests/kms/kms-steal-crtc.c --- libdrm-2.4.110/tests/kms/kms-steal-crtc.c 2022-02-16 10:00:13.000000000 +0000 +++ libdrm-2.4.113/tests/kms/kms-steal-crtc.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,161 +0,0 @@ -/* - * Copyright © 2014 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#if HAVE_SYS_SELECT_H -#include -#endif - -#include - -#include "util/pattern.h" -#include "libkms-test.h" - -static void signal_handler(int signum) -{ -} - -int main(int argc, char *argv[]) -{ - struct kms_framebuffer *fb; - struct kms_screen *screen; - struct kms_device *device; - unsigned int index = 0; - struct sigaction sa; - int fd, err; - void *ptr; - - if (argc < 2) { - fprintf(stderr, "usage: %s DEVICE\n", argv[0]); - return 1; - } - - memset(&sa, 0, sizeof(sa)); - sa.sa_handler = signal_handler; - - err = sigaction(SIGINT, &sa, NULL); - if (err < 0) { - fprintf(stderr, "sigaction() failed: %m\n"); - return 1; - } - - fd = open(argv[1], O_RDWR); - if (fd < 0) { - fprintf(stderr, "open() failed: %m\n"); - return 1; - } - - device = kms_device_open(fd); - if (!device) { - fprintf(stderr, "kms_device_open() failed: %m\n"); - return 1; - } - - if (device->num_screens < 1) { - fprintf(stderr, "no screens found\n"); - kms_device_close(device); - close(fd); - return 1; - } - - /* TODO: allow command-line to override */ - screen = device->screens[0]; - - printf("Using screen %s, resolution %ux%u\n", screen->name, - screen->width, screen->height); - - fb = kms_framebuffer_create(device, screen->width, screen->height, - DRM_FORMAT_XRGB8888); - if (!fb) { - fprintf(stderr, "kms_framebuffer_create() failed\n"); - return 1; - } - - err = kms_framebuffer_map(fb, &ptr); - if (err < 0) { - fprintf(stderr, "kms_framebuffer_map() failed: %d\n", err); - return 1; - } - - util_fill_pattern(fb->format, UTIL_PATTERN_SMPTE, &ptr, fb->width, - fb->height, fb->pitch); - - kms_framebuffer_unmap(fb); - - err = kms_screen_set(screen, device->crtcs[index++], fb); - if (err < 0) { - fprintf(stderr, "kms_screen_set() failed: %d\n", err); - return 1; - } - - while (true) { - int nfds = STDIN_FILENO + 1; - struct timeval timeout; - fd_set fds; - - memset(&timeout, 0, sizeof(timeout)); - timeout.tv_sec = 5; - timeout.tv_usec = 0; - - FD_ZERO(&fds); - FD_SET(STDIN_FILENO, &fds); - - err = select(nfds, &fds, NULL, NULL, &timeout); - if (err < 0) { - if (errno == EINTR) - break; - - fprintf(stderr, "select() failed: %d\n", errno); - break; - } - - if (err > 0) { - if (FD_ISSET(STDIN_FILENO, &fds)) - break; - } - - /* switch CRTC */ - if (index >= device->num_crtcs) - index = 0; - - err = kms_screen_set(screen, device->crtcs[index], fb); - if (err < 0) { - fprintf(stderr, "kms_screen_set() failed: %d\n", err); - break; - } - - index++; - } - - kms_framebuffer_free(fb); - kms_device_close(device); - close(fd); - - return 0; -} diff -Nru libdrm-2.4.110/tests/kms/kms-universal-planes.c libdrm-2.4.113/tests/kms/kms-universal-planes.c --- libdrm-2.4.110/tests/kms/kms-universal-planes.c 2022-02-16 10:00:13.000000000 +0000 +++ libdrm-2.4.113/tests/kms/kms-universal-planes.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,357 +0,0 @@ -/* - * Copyright © 2014 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#if HAVE_SYS_SELECT_H -#include -#endif - -#include -#include "xf86drm.h" - -#include "util/common.h" -#include "libkms-test.h" - -static const uint32_t formats[] = { - DRM_FORMAT_XRGB8888, - DRM_FORMAT_XBGR8888, - DRM_FORMAT_RGBA8888, -}; - -static uint32_t choose_format(struct kms_plane *plane) -{ - unsigned int i; - - for (i = 0; i < ARRAY_SIZE(formats); i++) - if (kms_plane_supports_format(plane, formats[i])) - return formats[i]; - - return 0; -} - -static void prepare_framebuffer(struct kms_framebuffer *fb, bool invert) -{ - const unsigned int block_size = 16; - uint32_t colors[2]; - unsigned int i, j; - uint32_t *buf; - void *ptr; - int err; - - switch (fb->format) { - case DRM_FORMAT_XRGB8888: - printf("using XRGB8888 format\n"); - /* XXRRGGBB */ - colors[0] = 0xffff0000; - colors[1] = 0xff0000ff; - break; - - case DRM_FORMAT_XBGR8888: - printf("using XBGR8888 format\n"); - /* XXBBGGRR */ - colors[0] = 0xff0000ff; - colors[1] = 0xffff0000; - break; - - case DRM_FORMAT_RGBA8888: - printf("using RGBA8888 format\n"); - /* RRGGBBAA */ - colors[0] = 0xff0000ff; - colors[1] = 0x0000ffff; - break; - - default: - colors[0] = 0xffffffff; - colors[1] = 0xffffffff; - break; - } - - err = kms_framebuffer_map(fb, &ptr); - if (err < 0) { - fprintf(stderr, "kms_framebuffer_map() failed: %s\n", - strerror(-err)); - return; - } - - buf = ptr; - - for (j = 0; j < fb->height; j++) { - for (i = 0; i < fb->width; i++) { - unsigned int color = (j / block_size) ^ - (i / block_size); - - if (invert) - color ^= color; - - *buf++ = colors[color & 1]; - } - } - - kms_framebuffer_unmap(fb); -} - -int main(int argc, char *argv[]) -{ - static const char opts[] = "chopv"; - static struct option options[] = { - { "cursor", 0, 0, 'c' }, - { "help", 0, 0, 'h' }, - { "overlay", 0, 0, 'o' }, - { "primary", 0, 0, 'p' }, - { "verbose", 0, 0, 'v' }, - { 0, 0, 0, 0 }, - }; - struct kms_framebuffer *cursor = NULL; - struct kms_framebuffer *root = NULL; - struct kms_framebuffer *fb = NULL; - struct kms_device *device; - bool use_overlay = false; - bool use_primary = false; - struct kms_plane *plane; - bool use_cursor = false; - bool verbose = false; - unsigned int i; - int opt, idx; - int fd, err; - - while ((opt = getopt_long(argc, argv, opts, options, &idx)) != -1) { - switch (opt) { - case 'c': - use_cursor = true; - break; - - case 'h': - break; - - case 'o': - use_overlay = true; - break; - - case 'p': - use_primary = true; - break; - - case 'v': - verbose = true; - break; - - default: - printf("unknown option \"%c\"\n", opt); - return 1; - } - } - - if (optind >= argc) { - fprintf(stderr, "usage: %s [options] DEVICE\n", argv[0]); - return 1; - } - - fd = open(argv[optind], O_RDWR); - if (fd < 0) { - fprintf(stderr, "open() failed: %m\n"); - return 1; - } - - err = drmSetClientCap(fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1); - if (err < 0) { - fprintf(stderr, "drmSetClientCap() failed: %d\n", err); - return 1; - } - - device = kms_device_open(fd); - if (!device) - return 1; - - if (verbose) { - printf("Screens: %u\n", device->num_screens); - - for (i = 0; i < device->num_screens; i++) { - struct kms_screen *screen = device->screens[i]; - const char *status = "disconnected"; - - if (screen->connected) - status = "connected"; - - printf(" %u: %x\n", i, screen->id); - printf(" Status: %s\n", status); - printf(" Name: %s\n", screen->name); - printf(" Resolution: %ux%u\n", screen->width, - screen->height); - } - - printf("Planes: %u\n", device->num_planes); - - for (i = 0; i < device->num_planes; i++) { - const char *type = NULL; - - plane = device->planes[i]; - switch (plane->type) { - case DRM_PLANE_TYPE_OVERLAY: - type = "overlay"; - break; - - case DRM_PLANE_TYPE_PRIMARY: - type = "primary"; - break; - - case DRM_PLANE_TYPE_CURSOR: - type = "cursor"; - break; - } - - printf(" %u: %p\n", i, plane); - printf(" ID: %x\n", plane->id); - printf(" CRTC: %x\n", plane->crtc->id); - printf(" Type: %x (%s)\n", plane->type, type); - } - } - - if (use_cursor) { - unsigned int x, y; - uint32_t format; - - plane = kms_device_find_plane_by_type(device, - DRM_PLANE_TYPE_CURSOR, - 0); - if (!plane) { - fprintf(stderr, "no cursor plane found\n"); - return 1; - } - - format = choose_format(plane); - if (!format) { - fprintf(stderr, "no matching format found\n"); - return 1; - } - - cursor = kms_framebuffer_create(device, 32, 32, format); - if (!cursor) { - fprintf(stderr, "failed to create cursor buffer\n"); - return 1; - } - - prepare_framebuffer(cursor, false); - - x = (device->screens[0]->width - cursor->width) / 2; - y = (device->screens[0]->height - cursor->height) / 2; - - kms_plane_set(plane, cursor, x, y); - } - - if (use_overlay) { - uint32_t format; - - plane = kms_device_find_plane_by_type(device, - DRM_PLANE_TYPE_OVERLAY, - 0); - if (!plane) { - fprintf(stderr, "no overlay plane found\n"); - return 1; - } - - format = choose_format(plane); - if (!format) { - fprintf(stderr, "no matching format found\n"); - return 1; - } - - fb = kms_framebuffer_create(device, 320, 240, format); - if (!fb) - return 1; - - prepare_framebuffer(fb, false); - - kms_plane_set(plane, fb, 0, 0); - } - - if (use_primary) { - unsigned int x, y; - uint32_t format; - - plane = kms_device_find_plane_by_type(device, - DRM_PLANE_TYPE_PRIMARY, - 0); - if (!plane) { - fprintf(stderr, "no primary plane found\n"); - return 1; - } - - format = choose_format(plane); - if (!format) { - fprintf(stderr, "no matching format found\n"); - return 1; - } - - root = kms_framebuffer_create(device, 640, 480, format); - if (!root) - return 1; - - prepare_framebuffer(root, true); - - x = (device->screens[0]->width - root->width) / 2; - y = (device->screens[0]->height - root->height) / 2; - - kms_plane_set(plane, root, x, y); - } - - while (1) { - struct timeval timeout = { 1, 0 }; - fd_set fds; - - FD_ZERO(&fds); - FD_SET(STDIN_FILENO, &fds); - - err = select(STDIN_FILENO + 1, &fds, NULL, NULL, &timeout); - if (err < 0) { - fprintf(stderr, "select() failed: %m\n"); - break; - } - - /* timeout */ - if (err == 0) - continue; - - if (FD_ISSET(STDIN_FILENO, &fds)) - break; - } - - if (cursor) - kms_framebuffer_free(cursor); - - if (root) - kms_framebuffer_free(root); - - if (fb) - kms_framebuffer_free(fb); - - kms_device_close(device); - close(fd); - - return 0; -} diff -Nru libdrm-2.4.110/tests/kms/libkms-test-crtc.c libdrm-2.4.113/tests/kms/libkms-test-crtc.c --- libdrm-2.4.110/tests/kms/libkms-test-crtc.c 2022-02-16 10:00:13.000000000 +0000 +++ libdrm-2.4.113/tests/kms/libkms-test-crtc.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,43 +0,0 @@ -/* - * Copyright © 2014 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. - */ - -#include "libkms-test.h" - -struct kms_crtc *kms_crtc_create(struct kms_device *device, uint32_t id) -{ - struct kms_crtc *crtc; - - crtc = calloc(1, sizeof(*crtc)); - if (!crtc) - return NULL; - - crtc->device = device; - crtc->id = id; - - return crtc; -} - -void kms_crtc_free(struct kms_crtc *crtc) -{ - free(crtc); -} diff -Nru libdrm-2.4.110/tests/kms/libkms-test-device.c libdrm-2.4.113/tests/kms/libkms-test-device.c --- libdrm-2.4.110/tests/kms/libkms-test-device.c 2022-02-16 10:00:13.000000000 +0000 +++ libdrm-2.4.113/tests/kms/libkms-test-device.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,217 +0,0 @@ -/* - * Copyright © 2014 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. - */ - -#include -#include -#include - -#include "util/common.h" -#include "libkms-test.h" - -static const char *const connector_names[] = { - "Unknown", - "VGA", - "DVI-I", - "DVI-D", - "DVI-A", - "Composite", - "SVIDEO", - "LVDS", - "Component", - "9PinDIN", - "DisplayPort", - "HDMI-A", - "HDMI-B", - "TV", - "eDP", - "Virtual", - "DSI", -}; - -static void kms_device_probe_screens(struct kms_device *device) -{ - unsigned int counts[ARRAY_SIZE(connector_names)]; - struct kms_screen *screen; - drmModeRes *res; - int i; - - memset(counts, 0, sizeof(counts)); - - res = drmModeGetResources(device->fd); - if (!res) - return; - - device->screens = calloc(res->count_connectors, sizeof(screen)); - if (!device->screens) - goto err_free_resources; - - for (i = 0; i < res->count_connectors; i++) { - unsigned int *count; - const char *type; - int len; - - screen = kms_screen_create(device, res->connectors[i]); - if (!screen) - continue; - - /* assign a unique name to this screen */ - type = connector_names[screen->type]; - count = &counts[screen->type]; - - len = snprintf(NULL, 0, "%s-%u", type, *count); - - screen->name = malloc(len + 1); - if (!screen->name) { - free(screen); - continue; - } - - snprintf(screen->name, len + 1, "%s-%u", type, *count); - (*count)++; - - device->screens[i] = screen; - device->num_screens++; - } - -err_free_resources: - drmModeFreeResources(res); -} - -static void kms_device_probe_crtcs(struct kms_device *device) -{ - struct kms_crtc *crtc; - drmModeRes *res; - int i; - - res = drmModeGetResources(device->fd); - if (!res) - return; - - device->crtcs = calloc(res->count_crtcs, sizeof(crtc)); - if (!device->crtcs) - goto err_free_resources; - - for (i = 0; i < res->count_crtcs; i++) { - crtc = kms_crtc_create(device, res->crtcs[i]); - if (!crtc) - continue; - - device->crtcs[i] = crtc; - device->num_crtcs++; - } - -err_free_resources: - drmModeFreeResources(res); -} - -static void kms_device_probe_planes(struct kms_device *device) -{ - struct kms_plane *plane; - drmModePlaneRes *res; - unsigned int i; - - res = drmModeGetPlaneResources(device->fd); - if (!res) - return; - - device->planes = calloc(res->count_planes, sizeof(plane)); - if (!device->planes) - goto err_free_resources; - - for (i = 0; i < res->count_planes; i++) { - plane = kms_plane_create(device, res->planes[i]); - if (!plane) - continue; - - device->planes[i] = plane; - device->num_planes++; - } - -err_free_resources: - drmModeFreePlaneResources(res); -} - -static void kms_device_probe(struct kms_device *device) -{ - kms_device_probe_screens(device); - kms_device_probe_crtcs(device); - kms_device_probe_planes(device); -} - -struct kms_device *kms_device_open(int fd) -{ - struct kms_device *device; - - device = calloc(1, sizeof(*device)); - if (!device) - return NULL; - - device->fd = fd; - - kms_device_probe(device); - - return device; -} - -void kms_device_close(struct kms_device *device) -{ - unsigned int i; - - for (i = 0; i < device->num_planes; i++) - kms_plane_free(device->planes[i]); - - free(device->planes); - - for (i = 0; i < device->num_crtcs; i++) - kms_crtc_free(device->crtcs[i]); - - free(device->crtcs); - - for (i = 0; i < device->num_screens; i++) - kms_screen_free(device->screens[i]); - - free(device->screens); - - if (device->fd >= 0) - close(device->fd); - - free(device); -} - -struct kms_plane *kms_device_find_plane_by_type(struct kms_device *device, - uint32_t type, - unsigned int index) -{ - unsigned int i; - - for (i = 0; i < device->num_planes; i++) { - if (device->planes[i]->type == type) { - if (index == 0) - return device->planes[i]; - - index--; - } - } - - return NULL; -} diff -Nru libdrm-2.4.110/tests/kms/libkms-test-framebuffer.c libdrm-2.4.113/tests/kms/libkms-test-framebuffer.c --- libdrm-2.4.110/tests/kms/libkms-test-framebuffer.c 2022-02-16 10:00:13.000000000 +0000 +++ libdrm-2.4.113/tests/kms/libkms-test-framebuffer.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,153 +0,0 @@ -/* - * Copyright © 2014 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. - */ - -#include -#include - -#include - -#include - -#include "xf86drm.h" - -#include "libkms-test.h" - -struct kms_framebuffer *kms_framebuffer_create(struct kms_device *device, - unsigned int width, - unsigned int height, - uint32_t format) -{ - uint32_t handles[4], pitches[4], offsets[4]; - struct drm_mode_create_dumb args; - struct kms_framebuffer *fb; - int err; - - fb = calloc(1, sizeof(*fb)); - if (!fb) - return NULL; - - fb->device = device; - fb->width = width; - fb->height = height; - fb->format = format; - - memset(&args, 0, sizeof(args)); - args.width = width; - args.height = height; - - switch (format) { - case DRM_FORMAT_XRGB8888: - case DRM_FORMAT_XBGR8888: - case DRM_FORMAT_RGBA8888: - args.bpp = 32; - break; - - default: - free(fb); - return NULL; - } - - err = drmIoctl(device->fd, DRM_IOCTL_MODE_CREATE_DUMB, &args); - if (err < 0) { - free(fb); - return NULL; - } - - fb->handle = args.handle; - fb->pitch = args.pitch; - fb->size = args.size; - - handles[0] = fb->handle; - pitches[0] = fb->pitch; - offsets[0] = 0; - - err = drmModeAddFB2(device->fd, width, height, format, handles, - pitches, offsets, &fb->id, 0); - if (err < 0) { - kms_framebuffer_free(fb); - return NULL; - } - - return fb; -} - -void kms_framebuffer_free(struct kms_framebuffer *fb) -{ - struct kms_device *device = fb->device; - struct drm_mode_destroy_dumb args; - int err; - - if (fb->id) { - err = drmModeRmFB(device->fd, fb->id); - if (err < 0) { - /* not much we can do now */ - } - } - - memset(&args, 0, sizeof(args)); - args.handle = fb->handle; - - err = drmIoctl(device->fd, DRM_IOCTL_MODE_DESTROY_DUMB, &args); - if (err < 0) { - /* not much we can do now */ - } - - free(fb); -} - -int kms_framebuffer_map(struct kms_framebuffer *fb, void **ptrp) -{ - struct kms_device *device = fb->device; - struct drm_mode_map_dumb args; - void *ptr; - int err; - - if (fb->ptr) { - *ptrp = fb->ptr; - return 0; - } - - memset(&args, 0, sizeof(args)); - args.handle = fb->handle; - - err = drmIoctl(device->fd, DRM_IOCTL_MODE_MAP_DUMB, &args); - if (err < 0) - return -errno; - - ptr = mmap(0, fb->size, PROT_READ | PROT_WRITE, MAP_SHARED, - device->fd, args.offset); - if (ptr == MAP_FAILED) - return -errno; - - *ptrp = fb->ptr = ptr; - - return 0; -} - -void kms_framebuffer_unmap(struct kms_framebuffer *fb) -{ - if (fb->ptr) { - munmap(fb->ptr, fb->size); - fb->ptr = NULL; - } -} diff -Nru libdrm-2.4.110/tests/kms/libkms-test.h libdrm-2.4.113/tests/kms/libkms-test.h --- libdrm-2.4.110/tests/kms/libkms-test.h 2022-02-16 10:00:13.000000000 +0000 +++ libdrm-2.4.113/tests/kms/libkms-test.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,120 +0,0 @@ -/* - * Copyright © 2014 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. - */ - -#ifndef LIBKMS_TEST_H -#define LIBKMS_TEST_H - -#include -#include -#include - -#include - -struct kms_device { - int fd; - - struct kms_screen **screens; - unsigned int num_screens; - - struct kms_crtc **crtcs; - unsigned int num_crtcs; - - struct kms_plane **planes; - unsigned int num_planes; -}; - -struct kms_device *kms_device_open(int fd); -void kms_device_close(struct kms_device *device); - -struct kms_plane *kms_device_find_plane_by_type(struct kms_device *device, - uint32_t type, - unsigned int index); - -struct kms_crtc { - struct kms_device *device; - uint32_t id; -}; - -struct kms_crtc *kms_crtc_create(struct kms_device *device, uint32_t id); -void kms_crtc_free(struct kms_crtc *crtc); - -struct kms_framebuffer { - struct kms_device *device; - - unsigned int width; - unsigned int height; - unsigned int pitch; - uint32_t format; - size_t size; - - uint32_t handle; - uint32_t id; - - void *ptr; -}; - -struct kms_framebuffer *kms_framebuffer_create(struct kms_device *device, - unsigned int width, - unsigned int height, - uint32_t format); -void kms_framebuffer_free(struct kms_framebuffer *fb); -int kms_framebuffer_map(struct kms_framebuffer *fb, void **ptrp); -void kms_framebuffer_unmap(struct kms_framebuffer *fb); - -struct kms_screen { - struct kms_device *device; - bool connected; - uint32_t type; - uint32_t id; - - unsigned int width; - unsigned int height; - char *name; - - drmModeModeInfo mode; -}; - -struct kms_screen *kms_screen_create(struct kms_device *device, uint32_t id); -void kms_screen_free(struct kms_screen *screen); - -int kms_screen_set(struct kms_screen *screen, struct kms_crtc *crtc, - struct kms_framebuffer *fb); - -struct kms_plane { - struct kms_device *device; - struct kms_crtc *crtc; - unsigned int type; - uint32_t id; - - uint32_t *formats; - unsigned int num_formats; -}; - -struct kms_plane *kms_plane_create(struct kms_device *device, uint32_t id); -void kms_plane_free(struct kms_plane *plane); - -int kms_plane_set(struct kms_plane *plane, struct kms_framebuffer *fb, - unsigned int x, unsigned int y); -bool kms_plane_supports_format(struct kms_plane *plane, uint32_t format); - -#endif diff -Nru libdrm-2.4.110/tests/kms/libkms-test-plane.c libdrm-2.4.113/tests/kms/libkms-test-plane.c --- libdrm-2.4.110/tests/kms/libkms-test-plane.c 2022-02-16 10:00:13.000000000 +0000 +++ libdrm-2.4.113/tests/kms/libkms-test-plane.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,137 +0,0 @@ -/* - * Copyright © 2014 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. - */ - -#include -#include - -#include "libkms-test.h" - -static int kms_plane_probe(struct kms_plane *plane) -{ - struct kms_device *device = plane->device; - drmModeObjectPropertiesPtr props; - drmModePlane *p; - unsigned int i; - - p = drmModeGetPlane(device->fd, plane->id); - if (!p) - return -ENODEV; - - /* TODO: allow dynamic assignment to CRTCs */ - if (p->crtc_id == 0) { - for (i = 0; i < device->num_crtcs; i++) { - if (p->possible_crtcs & (1 << i)) { - p->crtc_id = device->crtcs[i]->id; - break; - } - } - } - - for (i = 0; i < device->num_crtcs; i++) { - if (device->crtcs[i]->id == p->crtc_id) { - plane->crtc = device->crtcs[i]; - break; - } - } - - plane->formats = calloc(p->count_formats, sizeof(uint32_t)); - if (!plane->formats) { - drmModeFreePlane(p); - return -ENOMEM; - } - - for (i = 0; i < p->count_formats; i++) - plane->formats[i] = p->formats[i]; - - plane->num_formats = p->count_formats; - - drmModeFreePlane(p); - - props = drmModeObjectGetProperties(device->fd, plane->id, - DRM_MODE_OBJECT_PLANE); - if (!props) - return -ENODEV; - - for (i = 0; i < props->count_props; i++) { - drmModePropertyPtr prop; - - prop = drmModeGetProperty(device->fd, props->props[i]); - if (prop) { - if (strcmp(prop->name, "type") == 0) - plane->type = props->prop_values[i]; - - drmModeFreeProperty(prop); - } - } - - drmModeFreeObjectProperties(props); - - return 0; -} - -struct kms_plane *kms_plane_create(struct kms_device *device, uint32_t id) -{ - struct kms_plane *plane; - - plane = calloc(1, sizeof(*plane)); - if (!plane) - return NULL; - - plane->device = device; - plane->id = id; - - kms_plane_probe(plane); - - return plane; -} - -void kms_plane_free(struct kms_plane *plane) -{ - free(plane); -} - -int kms_plane_set(struct kms_plane *plane, struct kms_framebuffer *fb, - unsigned int x, unsigned int y) -{ - struct kms_device *device = plane->device; - int err; - - err = drmModeSetPlane(device->fd, plane->id, plane->crtc->id, fb->id, - 0, x, y, fb->width, fb->height, 0 << 16, - 0 << 16, fb->width << 16, fb->height << 16); - if (err < 0) - return -errno; - - return 0; -} - -bool kms_plane_supports_format(struct kms_plane *plane, uint32_t format) -{ - unsigned int i; - - for (i = 0; i < plane->num_formats; i++) - if (plane->formats[i] == format) - return true; - - return false; -} diff -Nru libdrm-2.4.110/tests/kms/libkms-test-screen.c libdrm-2.4.113/tests/kms/libkms-test-screen.c --- libdrm-2.4.110/tests/kms/libkms-test-screen.c 2022-02-16 10:00:13.000000000 +0000 +++ libdrm-2.4.113/tests/kms/libkms-test-screen.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,90 +0,0 @@ -/* - * Copyright © 2014 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. - */ - -#include -#include - -#include "libkms-test.h" - -static void kms_screen_probe(struct kms_screen *screen) -{ - struct kms_device *device = screen->device; - drmModeConnector *con; - - con = drmModeGetConnector(device->fd, screen->id); - if (!con) - return; - - screen->type = con->connector_type; - - if (con->connection == DRM_MODE_CONNECTED) - screen->connected = true; - else - screen->connected = false; - - if (con->modes) - memcpy(&screen->mode, &con->modes[0], sizeof(drmModeModeInfo)); - - screen->width = screen->mode.hdisplay; - screen->height = screen->mode.vdisplay; - - drmModeFreeConnector(con); -} - -struct kms_screen *kms_screen_create(struct kms_device *device, uint32_t id) -{ - struct kms_screen *screen; - - screen = calloc(1, sizeof(*screen)); - if (!screen) - return NULL; - - screen->device = device; - screen->id = id; - - kms_screen_probe(screen); - - return screen; -} - -void kms_screen_free(struct kms_screen *screen) -{ - if (screen) - free(screen->name); - - free(screen); -} - -int kms_screen_set(struct kms_screen *screen, struct kms_crtc *crtc, - struct kms_framebuffer *fb) -{ - struct kms_device *device = screen->device; - int err; - - err = drmModeSetCrtc(device->fd, crtc->id, fb->id, 0, 0, &screen->id, - 1, &screen->mode); - if (err < 0) - return -errno; - - return 0; -} diff -Nru libdrm-2.4.110/tests/kms/meson.build libdrm-2.4.113/tests/kms/meson.build --- libdrm-2.4.110/tests/kms/meson.build 2022-02-16 10:00:13.000000000 +0000 +++ libdrm-2.4.113/tests/kms/meson.build 1970-01-01 00:00:00.000000000 +0000 @@ -1,49 +0,0 @@ -# Copyright © 2017-2018 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 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. - - -libkms_test = static_library( - 'kms-test', - files( - 'libkms-test-crtc.c', 'libkms-test-device.c', 'libkms-test-framebuffer.c', - 'libkms-test-plane.c', 'libkms-test-screen.c', - ), - include_directories : [inc_root, inc_tests, inc_drm], - link_with : libdrm, - c_args : libdrm_c_args, -) - -kms_steal_crtc = executable( - 'kms-steal-crtc', - files('kms-steal-crtc.c'), - dependencies : dep_cairo, - include_directories : [inc_root, inc_tests, inc_drm], - link_with : [libkms_test, libutil], - install : with_install_tests, -) - -kms_universal_planes = executable( - 'kms-universal-planes', - files('kms-universal-planes.c'), - dependencies : dep_cairo, - include_directories : [inc_root, inc_tests, inc_drm], - link_with : [libkms_test], - install : with_install_tests, -) diff -Nru libdrm-2.4.110/tests/kmstest/main.c libdrm-2.4.113/tests/kmstest/main.c --- libdrm-2.4.110/tests/kmstest/main.c 2022-02-16 10:00:13.000000000 +0000 +++ libdrm-2.4.113/tests/kmstest/main.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,109 +0,0 @@ -/************************************************************************** - * - * Copyright © 2009 VMware, Inc., Palo Alto, CA., USA - * All Rights Reserved. - * - * 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, sub license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS 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 -#include -#include -#include "xf86drm.h" -#include "libkms.h" - -#include "util/kms.h" - -#define CHECK_RET_RETURN(ret, str) \ - if (ret < 0) { \ - printf("%s: %s (%s)\n", __func__, str, strerror(-ret)); \ - return ret; \ - } - -static int test_bo(struct kms_driver *kms) -{ - struct kms_bo *bo; - int ret; - unsigned attrs[7] = { - KMS_WIDTH, 1024, - KMS_HEIGHT, 768, - KMS_BO_TYPE, KMS_BO_TYPE_SCANOUT_X8R8G8B8, - KMS_TERMINATE_PROP_LIST, - }; - - ret = kms_bo_create(kms, attrs, &bo); - CHECK_RET_RETURN(ret, "Could not create bo"); - - kms_bo_destroy(&bo); - - return 0; -} - -static void usage(const char *program) -{ - fprintf(stderr, "Usage: %s [options]\n", program); - fprintf(stderr, "\n"); - fprintf(stderr, " -D DEVICE open the given device\n"); - fprintf(stderr, " -M MODULE open the given module\n"); -} - -int main(int argc, char** argv) -{ - static const char optstr[] = "D:M:"; - struct kms_driver *kms; - int c, fd, ret; - char *device = NULL; - char *module = NULL; - - while ((c = getopt(argc, argv, optstr)) != -1) { - switch (c) { - case 'D': - device = optarg; - break; - case 'M': - module = optarg; - break; - default: - usage(argv[0]); - return 0; - } - } - - fd = util_open(device, module); - CHECK_RET_RETURN(fd, "Could not open device"); - - ret = kms_create(fd, &kms); - CHECK_RET_RETURN(ret, "Failed to create kms driver"); - - ret = test_bo(kms); - if (ret) - goto err; - - printf("%s: All ok!\n", __func__); - - kms_destroy(&kms); - return 0; - -err: - kms_destroy(&kms); - return ret; -} diff -Nru libdrm-2.4.110/tests/kmstest/meson.build libdrm-2.4.113/tests/kmstest/meson.build --- libdrm-2.4.110/tests/kmstest/meson.build 2022-02-16 10:00:13.000000000 +0000 +++ libdrm-2.4.113/tests/kmstest/meson.build 1970-01-01 00:00:00.000000000 +0000 @@ -1,30 +0,0 @@ -# Copyright © 2017 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 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. - -kmstest = executable( - 'kmstest', - files('main.c'), - c_args : libdrm_c_args, - include_directories : [ - inc_root, inc_tests, include_directories('../../libkms'), inc_drm, - ], - link_with : [libutil, libkms, libdrm], - install : with_install_tests, -) diff -Nru libdrm-2.4.110/tests/meson.build libdrm-2.4.113/tests/meson.build --- libdrm-2.4.110/tests/meson.build 2022-02-16 10:00:13.000000000 +0000 +++ libdrm-2.4.113/tests/meson.build 2022-08-31 14:38:38.000000000 +0000 @@ -21,14 +21,10 @@ inc_tests = include_directories('.') subdir('util') -subdir('kms') subdir('modeprint') subdir('proptest') subdir('modetest') subdir('vbltest') -if with_libkms - subdir('kmstest') -endif if with_radeon subdir('radeon') endif diff -Nru libdrm-2.4.110/tests/modeprint/modeprint.c libdrm-2.4.113/tests/modeprint/modeprint.c --- libdrm-2.4.110/tests/modeprint/modeprint.c 2022-02-16 10:00:13.000000000 +0000 +++ libdrm-2.4.113/tests/modeprint/modeprint.c 2022-08-31 14:38:38.000000000 +0000 @@ -113,7 +113,7 @@ } else { for (j = 0; j < props->count_enums; j++) { - printf("\t\t%" PRId64 " = %s\n", props->enums[j].value, props->enums[j].name); + printf("\t\t%" PRIu64" = %s\n", (uint64_t)props->enums[j].value, props->enums[j].name); if (props->enums[j].value == value) name = props->enums[j].name; } @@ -135,7 +135,7 @@ drmModePropertyPtr props; const char *connector_type_name = NULL; - connector_type_name = util_lookup_connector_type_name(connector->connector_type); + connector_type_name = drmModeGetConnectorTypeName(connector->connector_type); if (connector_type_name) printf("Connector: %s-%d\n", connector_type_name, diff -Nru libdrm-2.4.110/tests/modetest/modetest.c libdrm-2.4.113/tests/modetest/modetest.c --- libdrm-2.4.110/tests/modetest/modetest.c 2022-02-16 10:00:13.000000000 +0000 +++ libdrm-2.4.113/tests/modetest/modetest.c 2022-08-31 14:38:38.000000000 +0000 @@ -187,11 +187,9 @@ static void dump_fourcc(uint32_t fourcc) { - printf(" %c%c%c%c", - fourcc, - fourcc >> 8, - fourcc >> 16, - fourcc >> 24); + char *name = drmGetFormatName(fourcc); + printf(" %s", name); + free(name); } static void dump_encoders(struct device *dev) @@ -376,7 +374,7 @@ printf("\t\tenums:"); for (i = 0; i < prop->count_enums; i++) printf(" %s=%"PRIu64, prop->enums[i].name, - prop->enums[i].value); + (uint64_t)prop->enums[i].value); printf("\n"); } else if (drm_property_type_is(prop, DRM_MODE_PROP_BITMASK)) { printf("\t\tvalues:"); @@ -656,7 +654,7 @@ int num; num = asprintf(&connector->name, "%s-%u", - util_lookup_connector_type_name(conn->connector_type), + drmModeGetConnectorTypeName(conn->connector_type), conn->connector_type_id); if (num < 0) goto error; diff -Nru libdrm-2.4.110/tests/proptest/proptest.c libdrm-2.4.113/tests/proptest/proptest.c --- libdrm-2.4.110/tests/proptest/proptest.c 2022-02-16 10:00:13.000000000 +0000 +++ libdrm-2.4.113/tests/proptest/proptest.c 2022-08-31 14:38:38.000000000 +0000 @@ -127,7 +127,7 @@ printf("\t\tenums:"); for (i = 0; i < prop->count_enums; i++) printf(" %s=%"PRIu64, prop->enums[i].name, - prop->enums[i].value); + (uint64_t)prop->enums[i].value); printf("\n"); } else if (drm_property_type_is(prop, DRM_MODE_PROP_BITMASK)) { printf("\t\tvalues:"); @@ -192,7 +192,7 @@ } printf("Connector %u (%s-%u)\n", c->connector_id, - util_lookup_connector_type_name(c->connector_type), + drmModeGetConnectorTypeName(c->connector_type), c->connector_type_id); listObjectProperties(c->connector_id, diff -Nru libdrm-2.4.110/tests/tegra/drm-test.c libdrm-2.4.113/tests/tegra/drm-test.c --- libdrm-2.4.110/tests/tegra/drm-test.c 1970-01-01 00:00:00.000000000 +0000 +++ libdrm-2.4.113/tests/tegra/drm-test.c 2022-08-31 14:38:38.000000000 +0000 @@ -0,0 +1,248 @@ +/* + * Copyright © 2014 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. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "xf86drm.h" +#include "xf86drmMode.h" +#include "drm_fourcc.h" + +#include "drm-test.h" + +static int drm_screen_probe_connector(struct drm_screen *screen, + drmModeConnectorPtr connector) +{ + drmModeEncoderPtr encoder; + drmModeCrtcPtr crtc; + drmModeFBPtr fb; + + encoder = drmModeGetEncoder(screen->fd, connector->encoder_id); + if (!encoder) + return -ENODEV; + + crtc = drmModeGetCrtc(screen->fd, encoder->crtc_id); + if (!crtc) { + drmModeFreeEncoder(encoder); + return -ENODEV; + } + + screen->old_fb = crtc->buffer_id; + + fb = drmModeGetFB(screen->fd, crtc->buffer_id); + if (!fb) { + /* TODO: create new framebuffer */ + drmModeFreeEncoder(encoder); + drmModeFreeCrtc(crtc); + return -ENOSYS; + } + + screen->connector = connector->connector_id; + screen->old_fb = crtc->buffer_id; + screen->crtc = encoder->crtc_id; + /* TODO: check crtc->mode_valid */ + screen->mode = crtc->mode; + + screen->width = fb->width; + screen->height = fb->height; + screen->pitch = fb->pitch; + screen->depth = fb->depth; + screen->bpp = fb->bpp; + + drmModeFreeEncoder(encoder); + drmModeFreeCrtc(crtc); + drmModeFreeFB(fb); + + return 0; +} + +int drm_screen_open(struct drm_screen **screenp, int fd) +{ + drmModeConnectorPtr connector; + struct drm_screen *screen; + bool found = false; + drmModeResPtr res; + unsigned int i; + int err; + + if (!screenp || fd < 0) + return -EINVAL; + + screen = calloc(1, sizeof(*screen)); + if (!screen) + return -ENOMEM; + + screen->format = DRM_FORMAT_XRGB8888; + screen->fd = fd; + + res = drmModeGetResources(fd); + if (!res) { + free(screen); + return -ENOMEM; + } + + for (i = 0; i < (unsigned int)res->count_connectors; i++) { + connector = drmModeGetConnector(fd, res->connectors[i]); + if (!connector) + continue; + + if (connector->connection != DRM_MODE_CONNECTED) { + drmModeFreeConnector(connector); + continue; + } + + err = drm_screen_probe_connector(screen, connector); + if (err < 0) { + drmModeFreeConnector(connector); + continue; + } + + drmModeFreeConnector(connector); + found = true; + break; + } + + drmModeFreeResources(res); + + if (!found) { + free(screen); + return -ENODEV; + } + + *screenp = screen; + + return 0; +} + +int drm_screen_close(struct drm_screen *screen) +{ + int err; + + err = drmModeSetCrtc(screen->fd, screen->crtc, screen->old_fb, 0, 0, + &screen->connector, 1, &screen->mode); + if (err < 0) { + fprintf(stderr, "drmModeSetCrtc() failed: %m\n"); + return -errno; + } + + free(screen); + + return 0; +} + +int drm_framebuffer_new(struct drm_framebuffer **fbp, + struct drm_screen *screen, uint32_t handle, + unsigned int width, unsigned int height, + unsigned int pitch, uint32_t format, + void *data) +{ + struct drm_framebuffer *fb; + uint32_t handles[4]; + uint32_t pitches[4]; + uint32_t offsets[4]; + int err; + + fb = calloc(1, sizeof(*fb)); + if (!fb) + return -ENOMEM; + + fb->fd = screen->fd; + fb->width = width; + fb->height = height; + fb->pitch = pitch; + fb->format = format; + fb->data = data; + + handles[0] = handle; + pitches[0] = pitch; + offsets[0] = 0; + + err = drmModeAddFB2(screen->fd, width, height, format, handles, + pitches, offsets, &fb->handle, 0); + if (err < 0) + return -errno; + + *fbp = fb; + + return 0; +} + +int drm_framebuffer_free(struct drm_framebuffer *fb) +{ + int err; + + err = drmModeRmFB(fb->fd, fb->handle); + if (err < 0) + return -errno; + + free(fb); + + return 0; +} + +int drm_screen_set_framebuffer(struct drm_screen *screen, + struct drm_framebuffer *fb) +{ + int err; + + err = drmModeSetCrtc(screen->fd, screen->crtc, fb->handle, 0, 0, + &screen->connector, 1, &screen->mode); + if (err < 0) + return -errno; + + return 0; +} + +int drm_open(const char *path) +{ + int fd, err; + + fd = open(path, O_RDWR); + if (fd < 0) + return -errno; + + err = drmSetMaster(fd); + if (err < 0) { + close(fd); + return -errno; + } + + return fd; +} + +void drm_close(int fd) +{ + drmDropMaster(fd); + close(fd); +} diff -Nru libdrm-2.4.110/tests/tegra/drm-test.h libdrm-2.4.113/tests/tegra/drm-test.h --- libdrm-2.4.110/tests/tegra/drm-test.h 1970-01-01 00:00:00.000000000 +0000 +++ libdrm-2.4.113/tests/tegra/drm-test.h 2022-08-31 14:38:38.000000000 +0000 @@ -0,0 +1,72 @@ +/* + * Copyright © 2014 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 TEGRA_DRM_TEST_H +#define TEGRA_DRM_TEST_H + +#include +#include + +#include "xf86drmMode.h" + +struct drm_screen { + int fd; + + unsigned int width; + unsigned int height; + unsigned int pitch; + unsigned int depth; + unsigned int bpp; + + drmModeModeInfo mode; + uint32_t connector; + uint32_t old_fb; + uint32_t format; + uint32_t crtc; +}; + +struct drm_framebuffer { + unsigned int width; + unsigned int height; + unsigned int pitch; + uint32_t format; + uint32_t handle; + void *data; + int fd; +}; + +int drm_screen_open(struct drm_screen **screenp, int fd); +int drm_screen_close(struct drm_screen *screen); +int drm_screen_set_framebuffer(struct drm_screen *screen, + struct drm_framebuffer *fb); + +int drm_framebuffer_new(struct drm_framebuffer **fbp, + struct drm_screen *screen, uint32_t handle, + unsigned int width, unsigned int height, + unsigned int pitch, uint32_t format, + void *data); +int drm_framebuffer_free(struct drm_framebuffer *fb); + +int drm_open(const char *path); +void drm_close(int fd); + +#endif diff -Nru libdrm-2.4.110/tests/tegra/drm-test-tegra.c libdrm-2.4.113/tests/tegra/drm-test-tegra.c --- libdrm-2.4.110/tests/tegra/drm-test-tegra.c 1970-01-01 00:00:00.000000000 +0000 +++ libdrm-2.4.113/tests/tegra/drm-test-tegra.c 2022-08-31 14:38:38.000000000 +0000 @@ -0,0 +1,147 @@ +/* + * Copyright © 2014 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. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#include "drm-test-tegra.h" +#include "tegra.h" + +int drm_tegra_gr2d_open(struct drm_tegra *drm, struct drm_tegra_gr2d **gr2dp) +{ + struct drm_tegra_gr2d *gr2d; + int err; + + gr2d = calloc(1, sizeof(*gr2d)); + if (!gr2d) + return -ENOMEM; + + gr2d->drm = drm; + + err = drm_tegra_channel_open(drm, DRM_TEGRA_GR2D, &gr2d->channel); + if (err < 0) { + free(gr2d); + return err; + } + + *gr2dp = gr2d; + + return 0; +} + +int drm_tegra_gr2d_close(struct drm_tegra_gr2d *gr2d) +{ + if (!gr2d) + return -EINVAL; + + drm_tegra_channel_close(gr2d->channel); + free(gr2d); + + return 0; +} + +int drm_tegra_gr2d_fill(struct drm_tegra_gr2d *gr2d, struct drm_framebuffer *fb, + unsigned int x, unsigned int y, unsigned int width, + unsigned int height, uint32_t color) +{ + struct drm_tegra_bo *fbo = fb->data; + struct drm_tegra_pushbuf *pushbuf; + struct drm_tegra_mapping *map; + struct drm_tegra_job *job; + uint32_t *ptr; + int err; + + err = drm_tegra_job_new(gr2d->channel, &job); + if (err < 0) + return err; + + err = drm_tegra_channel_map(gr2d->channel, fbo, 0, &map); + if (err < 0) + return err; + + err = drm_tegra_job_get_pushbuf(job, &pushbuf); + if (err < 0) + return err; + + err = drm_tegra_pushbuf_begin(pushbuf, 32, &ptr); + if (err < 0) + return err; + + *ptr++ = HOST1X_OPCODE_SETCL(0, HOST1X_CLASS_GR2D, 0); + + *ptr++ = HOST1X_OPCODE_MASK(0x9, 0x9); + *ptr++ = 0x0000003a; + *ptr++ = 0x00000000; + + *ptr++ = HOST1X_OPCODE_MASK(0x1e, 0x7); + *ptr++ = 0x00000000; + *ptr++ = (2 << 16) | (1 << 6) | (1 << 2); + *ptr++ = 0x000000cc; + + *ptr++ = HOST1X_OPCODE_MASK(0x2b, 0x9); + + /* relocate destination buffer */ + err = drm_tegra_pushbuf_relocate(pushbuf, &ptr, map, 0, 0, 0); + if (err < 0) { + fprintf(stderr, "failed to relocate buffer object: %d\n", err); + return err; + } + + *ptr++ = fb->pitch; + + *ptr++ = HOST1X_OPCODE_NONINCR(0x35, 1); + *ptr++ = color; + + *ptr++ = HOST1X_OPCODE_NONINCR(0x46, 1); + *ptr++ = 0x00000000; + + *ptr++ = HOST1X_OPCODE_MASK(0x38, 0x5); + *ptr++ = height << 16 | width; + *ptr++ = y << 16 | x; + + err = drm_tegra_pushbuf_end(pushbuf, ptr); + if (err < 0) { + fprintf(stderr, "failed to update push buffer: %d\n", -err); + return err; + } + + err = drm_tegra_job_submit(job, NULL); + if (err < 0) { + fprintf(stderr, "failed to submit job: %d\n", err); + return err; + } + + err = drm_tegra_job_wait(job, 0); + if (err < 0) { + fprintf(stderr, "failed to wait for fence: %d\n", err); + return err; + } + + drm_tegra_channel_unmap(map); + drm_tegra_job_free(job); + + return 0; +} diff -Nru libdrm-2.4.110/tests/tegra/drm-test-tegra.h libdrm-2.4.113/tests/tegra/drm-test-tegra.h --- libdrm-2.4.110/tests/tegra/drm-test-tegra.h 1970-01-01 00:00:00.000000000 +0000 +++ libdrm-2.4.113/tests/tegra/drm-test-tegra.h 2022-08-31 14:38:38.000000000 +0000 @@ -0,0 +1,55 @@ +/* + * Copyright © 2014 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 TEGRA_DRM_TEST_TEGRA_H +#define TEGRA_DRM_TEST_TEGRA_H + +#include "drm-test.h" +#include "tegra.h" + +#define HOST1X_OPCODE_SETCL(offset, classid, mask) \ + ((0x0 << 28) | (((offset) & 0xfff) << 16) | (((classid) & 0x3ff) << 6) | ((mask) & 0x3f)) +#define HOST1X_OPCODE_INCR(offset, count) \ + ((0x1 << 28) | (((offset) & 0xfff) << 16) | ((count) & 0xffff)) +#define HOST1X_OPCODE_NONINCR(offset, count) \ + ((0x2 << 28) | (((offset) & 0xfff) << 16) | ((count) & 0xffff)) +#define HOST1X_OPCODE_MASK(offset, mask) \ + ((0x3 << 28) | (((offset) & 0xfff) << 16) | ((mask) & 0xffff)) +#define HOST1X_OPCODE_IMM(offset, data) \ + ((0x4 << 28) | (((offset) & 0xfff) << 16) | ((data) & 0xffff)) +#define HOST1X_OPCODE_EXTEND(subop, value) \ + ((0xe << 28) | (((subop) & 0xf) << 24) | ((value) & 0xffffff)) + +#define HOST1X_CLASS_GR2D 0x51 + +struct drm_tegra_gr2d { + struct drm_tegra *drm; + struct drm_tegra_channel *channel; +}; + +int drm_tegra_gr2d_open(struct drm_tegra *drm, struct drm_tegra_gr2d **gr2dp); +int drm_tegra_gr2d_close(struct drm_tegra_gr2d *gr2d); +int drm_tegra_gr2d_fill(struct drm_tegra_gr2d *gr2d, struct drm_framebuffer *fb, + unsigned int x, unsigned int y, unsigned int width, + unsigned int height, uint32_t color); + +#endif diff -Nru libdrm-2.4.110/tests/tegra/.gitignore libdrm-2.4.113/tests/tegra/.gitignore --- libdrm-2.4.110/tests/tegra/.gitignore 2022-02-16 10:00:13.000000000 +0000 +++ libdrm-2.4.113/tests/tegra/.gitignore 2022-08-31 14:38:38.000000000 +0000 @@ -1 +1,2 @@ -openclose +tegra-gr2d-fill +tegra-openclose diff -Nru libdrm-2.4.110/tests/tegra/gr2d-fill.c libdrm-2.4.113/tests/tegra/gr2d-fill.c --- libdrm-2.4.110/tests/tegra/gr2d-fill.c 1970-01-01 00:00:00.000000000 +0000 +++ libdrm-2.4.113/tests/tegra/gr2d-fill.c 2022-08-31 14:38:38.000000000 +0000 @@ -0,0 +1,146 @@ +/* + * Copyright © 2014 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. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "xf86drm.h" +#include "xf86drmMode.h" +#include "drm_fourcc.h" + +#include "drm-test-tegra.h" +#include "tegra.h" + +int main(int argc, char *argv[]) +{ + uint32_t format = DRM_FORMAT_XRGB8888; + struct drm_tegra_gr2d *gr2d; + struct drm_framebuffer *fb; + struct drm_screen *screen; + unsigned int pitch, size; + struct drm_tegra_bo *bo; + struct drm_tegra *drm; + uint32_t handle; + int fd, err; + void *ptr; + + fd = drm_open(argv[1]); + if (fd < 0) { + fprintf(stderr, "failed to open DRM device %s: %s\n", argv[1], + strerror(errno)); + return 1; + } + + err = drm_screen_open(&screen, fd); + if (err < 0) { + fprintf(stderr, "failed to open screen: %s\n", strerror(-err)); + return 1; + } + + err = drm_tegra_new(fd, &drm); + if (err < 0) { + fprintf(stderr, "failed to create Tegra DRM context: %s\n", + strerror(-err)); + return 1; + } + + err = drm_tegra_gr2d_open(drm, &gr2d); + if (err < 0) { + fprintf(stderr, "failed to open gr2d channel: %s\n", + strerror(-err)); + return 1; + } + + pitch = screen->width * screen->bpp / 8; + size = pitch * screen->height; + + err = drm_tegra_bo_new(drm, 0, size, &bo); + if (err < 0) { + fprintf(stderr, "failed to create buffer object: %s\n", + strerror(-err)); + return 1; + } + + err = drm_tegra_bo_get_handle(bo, &handle); + if (err < 0) { + fprintf(stderr, "failed to get handle to buffer object: %s\n", + strerror(-err)); + return 1; + } + + err = drm_tegra_bo_map(bo, &ptr); + if (err < 0) { + fprintf(stderr, "failed to map buffer object: %s\n", + strerror(-err)); + return 1; + } + + memset(ptr, 0xff, size); + + err = drm_framebuffer_new(&fb, screen, handle, screen->width, + screen->height, pitch, format, bo); + if (err < 0) { + fprintf(stderr, "failed to create framebuffer: %s\n", + strerror(-err)); + return 1; + } + + err = drm_screen_set_framebuffer(screen, fb); + if (err < 0) { + fprintf(stderr, "failed to display framebuffer: %s\n", + strerror(-err)); + return 1; + } + + sleep(1); + + err = drm_tegra_gr2d_fill(gr2d, fb, fb->width / 4, fb->height / 4, + fb->width / 2, fb->height / 2, 0x00000000); + if (err < 0) { + fprintf(stderr, "failed to fill rectangle: %s\n", + strerror(-err)); + return 1; + } + + sleep(1); + + drm_framebuffer_free(fb); + drm_tegra_bo_unref(bo); + drm_tegra_gr2d_close(gr2d); + drm_tegra_close(drm); + drm_screen_close(screen); + drm_close(fd); + + return 0; +} diff -Nru libdrm-2.4.110/tests/tegra/host1x.h libdrm-2.4.113/tests/tegra/host1x.h --- libdrm-2.4.110/tests/tegra/host1x.h 1970-01-01 00:00:00.000000000 +0000 +++ libdrm-2.4.113/tests/tegra/host1x.h 2022-08-31 14:38:38.000000000 +0000 @@ -0,0 +1,34 @@ +/* + * 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 HOST1X_H +#define HOST1X_H + +#define HOST1X_OPCODE_SETCL(offset, classid, mask) \ + ((0x0 << 28) | (((offset) & 0xfff) << 16) | (((classid) & 0x3ff) << 6) | ((mask) & 0x3f)) + +#define HOST1X_OPCODE_INCR(offset, count) \ + ((0x1 << 28) | (((offset) & 0xfff) << 16) | ((count) & 0xffff)) + +#define HOST1X_CLASS_VIC 0x5d + +#endif diff -Nru libdrm-2.4.110/tests/tegra/meson.build libdrm-2.4.113/tests/tegra/meson.build --- libdrm-2.4.110/tests/tegra/meson.build 2022-02-16 10:00:13.000000000 +0000 +++ libdrm-2.4.113/tests/tegra/meson.build 2022-08-31 14:38:38.000000000 +0000 @@ -18,10 +18,94 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +inc_tegra = include_directories('../../tegra') + +libdrm_test = static_library( + 'drm-test', + [files('drm-test.c', 'drm-test.h'), config_file ], + include_directories : [inc_root, inc_drm, inc_tegra], + link_with : libdrm, +) + +libdrm_test_tegra = static_library( + 'drm-test-tegra', + [files( + 'drm-test-tegra.c', + 'drm-test-tegra.h', + 'vic.c', + 'vic.h', + 'vic30.c', + 'vic30.h', + 'vic40.c', + 'vic40.h', + 'vic41.c', + 'vic41.h', + 'vic42.c', + 'vic42.h', + ), config_file ], + include_directories : [inc_root, inc_drm, inc_tegra], + link_with : libdrm, +) + openclose = executable( - 'openclose', + 'tegra-openclose', files('openclose.c'), - include_directories : [inc_root, inc_drm, include_directories('../../tegra')], + include_directories : [inc_root, inc_drm, inc_tegra], c_args : libdrm_c_args, link_with : [libdrm, libdrm_tegra], + install : with_install_tests, +) + +gr2d_fill = executable( + 'tegra-gr2d-fill', + files('gr2d-fill.c'), + include_directories : [inc_root, inc_drm, inc_tegra], + c_args : libdrm_c_args, + link_with : [libdrm, libdrm_tegra, libdrm_test, libdrm_test_tegra], + install : with_install_tests, +) + +syncpt_wait = executable( + 'tegra-syncpt-wait', + files('syncpt-wait.c'), + include_directories : [inc_root, inc_drm, inc_tegra], + c_args : libdrm_c_args, + link_with : [libdrm, libdrm_tegra, libdrm_test, libdrm_test_tegra], + install : with_install_tests, +) + +syncpt_timeout = executable( + 'tegra-syncpt-timeout', + files('syncpt-timeout.c'), + include_directories : [inc_root, inc_drm, inc_tegra], + c_args : libdrm_c_args, + link_with : [libdrm, libdrm_tegra, libdrm_test, libdrm_test_tegra], + install : with_install_tests, +) + +vic_clear = executable( + 'tegra-vic-clear', + files('vic-clear.c'), + include_directories : [inc_root, inc_drm, inc_tegra], + c_args : libdrm_c_args, + link_with : [libdrm, libdrm_tegra, libdrm_test, libdrm_test_tegra], + install : with_install_tests, +) + +vic_blit = executable( + 'tegra-vic-blit', + files('vic-blit.c'), + include_directories : [inc_root, inc_drm, inc_tegra], + c_args : libdrm_c_args, + link_with : [libdrm, libdrm_tegra, libdrm_test, libdrm_test_tegra], + install : with_install_tests, +) + +vic_flip = executable( + 'tegra-vic-flip', + files('vic-flip.c'), + include_directories : [inc_root, inc_drm, inc_tegra], + c_args : libdrm_c_args, + link_with : [libdrm, libdrm_tegra, libdrm_test, libdrm_test_tegra], + install : with_install_tests, ) diff -Nru libdrm-2.4.110/tests/tegra/openclose.c libdrm-2.4.113/tests/tegra/openclose.c --- libdrm-2.4.110/tests/tegra/openclose.c 2022-02-16 10:00:13.000000000 +0000 +++ libdrm-2.4.113/tests/tegra/openclose.c 2022-08-31 14:38:38.000000000 +0000 @@ -31,37 +31,37 @@ int main(int argc, char *argv[]) { - struct drm_tegra *tegra; - drmVersionPtr version; - const char *device; - int err, fd; - - if (argc < 2) - device = default_device; - else - device = argv[1]; - - fd = open(device, O_RDWR); - if (fd < 0) - return 1; - - version = drmGetVersion(fd); - if (version) { - printf("Version: %d.%d.%d\n", version->version_major, - version->version_minor, version->version_patchlevel); - printf(" Name: %s\n", version->name); - printf(" Date: %s\n", version->date); - printf(" Description: %s\n", version->desc); - - drmFreeVersion(version); - } - - err = drm_tegra_new(&tegra, fd); - if (err < 0) - return 1; + struct drm_tegra *tegra; + drmVersionPtr version; + const char *device; + int err, fd; + + if (argc < 2) + device = default_device; + else + device = argv[1]; + + fd = open(device, O_RDWR); + if (fd < 0) + return 1; + + version = drmGetVersion(fd); + if (version) { + printf("Version: %d.%d.%d\n", version->version_major, + version->version_minor, version->version_patchlevel); + printf(" Name: %s\n", version->name); + printf(" Date: %s\n", version->date); + printf(" Description: %s\n", version->desc); + + drmFreeVersion(version); + } + + err = drm_tegra_new(fd, &tegra); + if (err < 0) + return 1; - drm_tegra_close(tegra); - close(fd); + drm_tegra_close(tegra); + close(fd); - return 0; + return 0; } diff -Nru libdrm-2.4.110/tests/tegra/syncpt-timeout.c libdrm-2.4.113/tests/tegra/syncpt-timeout.c --- libdrm-2.4.110/tests/tegra/syncpt-timeout.c 1970-01-01 00:00:00.000000000 +0000 +++ libdrm-2.4.113/tests/tegra/syncpt-timeout.c 2022-08-31 14:38:38.000000000 +0000 @@ -0,0 +1,163 @@ +/* + * 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 +#include +#include +#include +#include + +#include "tegra.h" + +#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) + +static int channel_open(struct drm_tegra *drm, + struct drm_tegra_channel **channel) +{ + static const struct { + enum drm_tegra_class class; + const char *name; + } classes[] = { + { DRM_TEGRA_VIC, "VIC" }, + { DRM_TEGRA_GR2D, "GR2D" }, + }; + unsigned int i; + int err; + + for (i = 0; i < ARRAY_SIZE(classes); i++) { + err = drm_tegra_channel_open(drm, classes[i].class, channel); + if (err < 0) { + fprintf(stderr, "failed to open channel to %s: %s\n", + classes[i].name, strerror(-err)); + continue; + } + + break; + } + + return err; +} + +int main(int argc, char *argv[]) +{ + const char *device = "/dev/dri/renderD128"; + struct drm_tegra_syncpoint *syncpt; + struct drm_tegra_channel *channel; + struct drm_tegra_pushbuf *pushbuf; + struct drm_tegra_job *job; + struct drm_tegra *drm; + uint32_t *ptr; + int fd, err; + + if (argc > 1) + device = argv[1]; + + fd = open(device, O_RDWR); + if (fd < 0) { + fprintf(stderr, "open() failed: %s\n", strerror(errno)); + return 1; + } + + err = drm_tegra_new(fd, &drm); + if (err < 0) { + fprintf(stderr, "failed to open Tegra device: %s\n", strerror(-err)); + close(fd); + return 1; + } + + err = drm_tegra_syncpoint_new(drm, &syncpt); + if (err < 0) { + fprintf(stderr, "failed to allocate syncpoint: %s\n", strerror(-err)); + drm_tegra_close(drm); + close(fd); + return 1; + } + + err = channel_open(drm, &channel); + if (err < 0) { + fprintf(stderr, "failed to open channel: %s\n", strerror(-err)); + return 1; + } + + err = drm_tegra_job_new(channel, &job); + if (err < 0) { + fprintf(stderr, "failed to create job: %s\n", strerror(-err)); + return 1; + } + + err = drm_tegra_job_get_pushbuf(job, &pushbuf); + if (err < 0) { + fprintf(stderr, "failed to create push buffer: %s\n", strerror(-err)); + return 1; + } + + err = drm_tegra_pushbuf_begin(pushbuf, 8, &ptr); + if (err < 0) { + fprintf(stderr, "failed to prepare push buffer: %s\n", strerror(-err)); + return 1; + } + + /* + * Empty command streams will be rejected, so we use this as an easy way + * to add something to the command stream. But this could be any other, + * valid command stream. + */ + err = drm_tegra_pushbuf_sync_cond(pushbuf, &ptr, syncpt, + DRM_TEGRA_SYNC_COND_IMMEDIATE); + if (err < 0) { + fprintf(stderr, "failed to push syncpoint: %s\n", strerror(-err)); + return 1; + } + + /* pretend that the syncpoint was incremented a second time */ + err = drm_tegra_pushbuf_sync(pushbuf, syncpt, 1); + if (err < 0) { + fprintf(stderr, "failed to push syncpoint: %s\n", strerror(-err)); + return 1; + } + + err = drm_tegra_pushbuf_end(pushbuf, ptr); + if (err < 0) { + fprintf(stderr, "failed to update push buffer: %s\n", strerror(-err)); + return 1; + } + + err = drm_tegra_job_submit(job, NULL); + if (err < 0) { + fprintf(stderr, "failed to submit job: %s\n", strerror(-err)); + return 1; + } + + err = drm_tegra_job_wait(job, 250000); + if (err < 0) { + fprintf(stderr, "failed to wait for job: %s\n", strerror(-err)); + return 1; + } + + drm_tegra_job_free(job); + drm_tegra_channel_close(channel); + drm_tegra_syncpoint_free(syncpt); + drm_tegra_close(drm); + close(fd); + + return 0; +} diff -Nru libdrm-2.4.110/tests/tegra/syncpt-wait.c libdrm-2.4.113/tests/tegra/syncpt-wait.c --- libdrm-2.4.110/tests/tegra/syncpt-wait.c 1970-01-01 00:00:00.000000000 +0000 +++ libdrm-2.4.113/tests/tegra/syncpt-wait.c 2022-08-31 14:38:38.000000000 +0000 @@ -0,0 +1,151 @@ +/* + * 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 +#include +#include +#include +#include + +#include "tegra.h" + +#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) + +static int channel_open(struct drm_tegra *drm, + struct drm_tegra_channel **channel) +{ + static const struct { + enum drm_tegra_class class; + const char *name; + } classes[] = { + { DRM_TEGRA_VIC, "VIC" }, + { DRM_TEGRA_GR2D, "GR2D" }, + }; + unsigned int i; + int err; + + for (i = 0; i < ARRAY_SIZE(classes); i++) { + err = drm_tegra_channel_open(drm, classes[i].class, channel); + if (err < 0) { + fprintf(stderr, "failed to open channel to %s: %s\n", + classes[i].name, strerror(-err)); + continue; + } + + break; + } + + return err; +} + +int main(int argc, char *argv[]) +{ + const char *device = "/dev/dri/renderD128"; + struct drm_tegra_syncpoint *syncpt; + struct drm_tegra_channel *channel; + struct drm_tegra_pushbuf *pushbuf; + struct drm_tegra_job *job; + struct drm_tegra *drm; + uint32_t *ptr; + int fd, err; + + if (argc > 1) + device = argv[1]; + + fd = open(device, O_RDWR); + if (fd < 0) { + fprintf(stderr, "open() failed: %s\n", strerror(errno)); + return 1; + } + + err = drm_tegra_new(fd, &drm); + if (err < 0) { + fprintf(stderr, "failed to open Tegra device: %s\n", strerror(-err)); + close(fd); + return 1; + } + + err = drm_tegra_syncpoint_new(drm, &syncpt); + if (err < 0) { + fprintf(stderr, "failed to allocate syncpoint: %s\n", strerror(-err)); + drm_tegra_close(drm); + close(fd); + return 1; + } + + err = channel_open(drm, &channel); + if (err < 0) { + fprintf(stderr, "failed to open channel: %s\n", strerror(-err)); + return 1; + } + + err = drm_tegra_job_new(channel, &job); + if (err < 0) { + fprintf(stderr, "failed to create job: %s\n", strerror(-err)); + return 1; + } + + err = drm_tegra_job_get_pushbuf(job, &pushbuf); + if (err < 0) { + fprintf(stderr, "failed to create push buffer: %s\n", strerror(-err)); + return 1; + } + + err = drm_tegra_pushbuf_begin(pushbuf, 4, &ptr); + if (err < 0) { + fprintf(stderr, "failed to prepare push buffer: %s\n", strerror(-err)); + return 1; + } + + err = drm_tegra_pushbuf_sync_cond(pushbuf, &ptr, syncpt, + DRM_TEGRA_SYNC_COND_IMMEDIATE); + if (err < 0) { + fprintf(stderr, "failed to push syncpoint: %s\n", strerror(-err)); + return 1; + } + + err = drm_tegra_pushbuf_end(pushbuf, ptr); + if (err < 0) { + fprintf(stderr, "failed to update push buffer: %s\n", strerror(-err)); + return 1; + } + + err = drm_tegra_job_submit(job, NULL); + if (err < 0) { + fprintf(stderr, "failed to submit job: %s\n", strerror(-err)); + return 1; + } + + err = drm_tegra_job_wait(job, 250000000); + if (err < 0) { + fprintf(stderr, "failed to wait for job: %s\n", strerror(-err)); + return 1; + } + + drm_tegra_job_free(job); + drm_tegra_channel_close(channel); + drm_tegra_syncpoint_free(syncpt); + drm_tegra_close(drm); + close(fd); + + return 0; +} diff -Nru libdrm-2.4.110/tests/tegra/vic30.c libdrm-2.4.113/tests/tegra/vic30.c --- libdrm-2.4.110/tests/tegra/vic30.c 1970-01-01 00:00:00.000000000 +0000 +++ libdrm-2.4.113/tests/tegra/vic30.c 2022-08-31 14:38:38.000000000 +0000 @@ -0,0 +1,458 @@ +/* + * 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 +#include + +#include "private.h" +#include "tegra.h" +#include "vic.h" +#include "vic30.h" + +struct vic30 { + struct vic base; + + struct { + struct drm_tegra_mapping *map; + struct drm_tegra_bo *bo; + } config; + + struct { + struct drm_tegra_mapping *map; + struct drm_tegra_bo *bo; + } filter; + + struct { + struct drm_tegra_mapping *map; + struct drm_tegra_bo *bo; + } hist; +}; + +static int vic30_fill(struct vic *v, struct vic_image *output, + unsigned int left, unsigned int top, + unsigned int right, unsigned int bottom, + unsigned int alpha, unsigned int red, + unsigned int green, unsigned int blue) +{ + struct vic30 *vic = container_of(v, struct vic30, base); + ConfigStruct *c; + int err; + + err = drm_tegra_bo_map(vic->config.bo, (void **)&c); + if (err < 0) { + fprintf(stderr, "failed to map configuration structure: %s\n", + strerror(-err)); + return err; + } + + memset(c, 0, sizeof(*c)); + + c->surfaceList0Struct.TargetRectLeft = left; + c->surfaceList0Struct.TargetRectTop = top; + c->surfaceList0Struct.TargetRectRight = right; + c->surfaceList0Struct.TargetRectBottom = bottom; + + c->blending0Struct.PixelFormat = output->format; + c->blending0Struct.BackgroundAlpha = alpha; + c->blending0Struct.BackgroundR = red; + c->blending0Struct.BackgroundG = green; + c->blending0Struct.BackgroundB = blue; + c->blending0Struct.LumaWidth = output->stride - 1; + c->blending0Struct.LumaHeight = output->height - 1; + c->blending0Struct.ChromaWidth = 16383; + c->blending0Struct.ChromaWidth = 16383; + c->blending0Struct.TargetRectLeft = left; + c->blending0Struct.TargetRectTop = top; + c->blending0Struct.TargetRectRight = right; + c->blending0Struct.TargetRectBottom = bottom; + c->blending0Struct.SurfaceWidth = output->width - 1; + c->blending0Struct.SurfaceHeight = output->height - 1; + c->blending0Struct.BlkKind = output->kind; + c->blending0Struct.BlkHeight = 0; + + c->fetchControl0Struct.TargetRectLeft = left; + c->fetchControl0Struct.TargetRectTop = top; + c->fetchControl0Struct.TargetRectRight = right; + c->fetchControl0Struct.TargetRectBottom = bottom; + + drm_tegra_bo_unmap(vic->config.bo); + + return 0; +} + +static int vic30_blit(struct vic *v, struct vic_image *output, + struct vic_image *input) +{ + struct vic30 *vic = container_of(v, struct vic30, base); + ColorConversionLumaAlphaStruct *ccla; + ColorConversionMatrixStruct *ccm; + ColorConversionClampStruct *ccc; + SurfaceListSurfaceStruct *s; + BlendingSurfaceStruct *b; + SurfaceCache0Struct *sc; + ConfigStruct *c; + int err; + + err = drm_tegra_bo_map(vic->config.bo, (void **)&c); + if (err < 0) { + fprintf(stderr, "failed to map configuration structure: %s\n", + strerror(-err)); + return err; + } + + memset(c, 0, sizeof(*c)); + + c->surfaceList0Struct.TargetRectLeft = 0; + c->surfaceList0Struct.TargetRectTop = 0; + c->surfaceList0Struct.TargetRectRight = output->width - 1; + c->surfaceList0Struct.TargetRectBottom = output->height - 1; + + c->blending0Struct.PixelFormat = output->format; + c->blending0Struct.BackgroundAlpha = 0; + c->blending0Struct.BackgroundR = 0; + c->blending0Struct.BackgroundG = 0; + c->blending0Struct.BackgroundB = 0; + c->blending0Struct.LumaWidth = output->stride - 1; + c->blending0Struct.LumaHeight = output->height - 1; + c->blending0Struct.ChromaWidth = 16383; + c->blending0Struct.ChromaWidth = 16383; + c->blending0Struct.TargetRectLeft = 0; + c->blending0Struct.TargetRectTop = 0; + c->blending0Struct.TargetRectRight = output->width - 1; + c->blending0Struct.TargetRectBottom = output->height - 1; + c->blending0Struct.SurfaceWidth = output->width - 1; + c->blending0Struct.SurfaceHeight = output->height - 1; + c->blending0Struct.BlkKind = output->kind; + c->blending0Struct.BlkHeight = 0; + + c->fetchControl0Struct.TargetRectLeft = 0; + c->fetchControl0Struct.TargetRectTop = 0; + c->fetchControl0Struct.TargetRectRight = output->width - 1; + c->fetchControl0Struct.TargetRectBottom = output->height - 1; + + /* setup fetch parameters for slot 0 */ + c->fetchControl0Struct.Enable0 = 0x1; + c->fetchControl0Struct.Iir0 = 0x300; + + /* setup cache parameters for slot 0 */ + sc = &c->surfaceCache0Struct; + sc->PixelFormat0 = input->format; + + /* setup surface configuration for slot 0 */ + s = &c->surfaceListSurfaceStruct[0]; + s->Enable = 1; + s->FrameFormat = DXVAHD_FRAME_FORMAT_PROGRESSIVE; + s->PixelFormat = input->format; + s->SurfaceWidth = input->width - 1; + s->SurfaceHeight = input->height - 1; + s->LumaWidth = input->stride - 1; + s->LumaHeight = input->height - 1; + s->ChromaWidth = 16383; + s->ChromaHeight = 16383; + s->CacheWidth = VIC_CACHE_WIDTH_256Bx1; //VIC_CACHE_WIDTH_16Bx16; + s->BlkKind = input->kind; + s->BlkHeight = 0; + s->DestRectLeft = 0; + s->DestRectTop = 0; + s->DestRectRight = output->width - 1; + s->DestRectBottom = output->height - 1; + s->SourceRectLeft = 0 << 16; + s->SourceRectTop = 0 << 16; + s->SourceRectRight = (input->width - 1) << 16; + s->SourceRectBottom = (input->height - 1) << 16; + + /* setup color conversion for slot 0 */ + ccla = &c->colorConversionLumaAlphaStruct[0]; + ccla->PlanarAlpha = 1023; + ccla->ConstantAlpha = 0; + + ccm = &c->colorConversionMatrixStruct[0]; + ccm->c00 = 1023; + ccm->c11 = 1023; + ccm->c22 = 1023; + + ccc = &c->colorConversionClampStruct[0]; + ccc->low = 0; + ccc->high = 1023; + + /* setup blending for slot 0 */ + b = &c->blendingSurfaceStruct[0]; + b->AlphaK1 = 1023; + b->SrcFactCMatchSelect = VIC_BLEND_SRCFACTC_K1; + b->SrcFactAMatchSelect = VIC_BLEND_SRCFACTA_K1; + b->DstFactCMatchSelect = VIC_BLEND_DSTFACTC_NEG_K1_TIMES_SRC; + b->DstFactAMatchSelect = VIC_BLEND_DSTFACTA_NEG_K1_TIMES_SRC; + + drm_tegra_bo_unmap(vic->config.bo); + + return 0; +} + +static int vic30_flip(struct vic *v, struct vic_image *output, + struct vic_image *input) +{ + struct vic30 *vic = container_of(v, struct vic30, base); + ColorConversionLumaAlphaStruct *ccla; + ColorConversionMatrixStruct *ccm; + ColorConversionClampStruct *ccc; + SurfaceListSurfaceStruct *s; + BlendingSurfaceStruct *b; + SurfaceCache0Struct *sc; + ConfigStruct *c; + int err; + + err = drm_tegra_bo_map(vic->config.bo, (void **)&c); + if (err < 0) { + fprintf(stderr, "failed to map configuration structure: %s\n", + strerror(-err)); + return err; + } + + memset(c, 0, sizeof(*c)); + + c->surfaceList0Struct.TargetRectLeft = 0; + c->surfaceList0Struct.TargetRectTop = 0; + c->surfaceList0Struct.TargetRectRight = output->width - 1; + c->surfaceList0Struct.TargetRectBottom = output->height - 1; + + c->blending0Struct.PixelFormat = output->format; + c->blending0Struct.BackgroundAlpha = 0; + c->blending0Struct.BackgroundR = 0; + c->blending0Struct.BackgroundG = 0; + c->blending0Struct.BackgroundB = 0; + c->blending0Struct.LumaWidth = output->stride - 1; + c->blending0Struct.LumaHeight = output->height - 1; + c->blending0Struct.ChromaWidth = 16383; + c->blending0Struct.ChromaWidth = 16383; + c->blending0Struct.TargetRectLeft = 0; + c->blending0Struct.TargetRectTop = 0; + c->blending0Struct.TargetRectRight = output->width - 1; + c->blending0Struct.TargetRectBottom = output->height - 1; + c->blending0Struct.SurfaceWidth = output->width - 1; + c->blending0Struct.SurfaceHeight = output->height - 1; + c->blending0Struct.BlkKind = output->kind; + c->blending0Struct.BlkHeight = 0; + c->blending0Struct.OutputFlipY = 1; + + c->fetchControl0Struct.TargetRectLeft = 0; + c->fetchControl0Struct.TargetRectTop = 0; + c->fetchControl0Struct.TargetRectRight = output->width - 1; + c->fetchControl0Struct.TargetRectBottom = output->height - 1; + + /* setup fetch parameters for slot 0 */ + c->fetchControl0Struct.Enable0 = 0x1; + c->fetchControl0Struct.Iir0 = 0x300; + + /* setup cache parameters for slot 0 */ + sc = &c->surfaceCache0Struct; + sc->PixelFormat0 = input->format; + + /* setup surface configuration for slot 0 */ + s = &c->surfaceListSurfaceStruct[0]; + s->Enable = 1; + s->FrameFormat = DXVAHD_FRAME_FORMAT_PROGRESSIVE; + s->PixelFormat = input->format; + s->SurfaceWidth = input->width - 1; + s->SurfaceHeight = input->height - 1; + s->LumaWidth = input->stride - 1; + s->LumaHeight = input->height - 1; + s->ChromaWidth = 16383; + s->ChromaHeight = 16383; + s->CacheWidth = VIC_CACHE_WIDTH_256Bx1; + s->BlkKind = input->kind; + s->BlkHeight = 0; + s->DestRectLeft = 0; + s->DestRectTop = 0; + s->DestRectRight = output->width - 1; + s->DestRectBottom = output->height - 1; + s->SourceRectLeft = 0 << 16; + s->SourceRectTop = 0 << 16; + s->SourceRectRight = (input->width - 1) << 16; + s->SourceRectBottom = (input->height - 1) << 16; + + /* setup color conversion for slot 0 */ + ccla = &c->colorConversionLumaAlphaStruct[0]; + ccla->PlanarAlpha = 1023; + ccla->ConstantAlpha = 0; + + ccm = &c->colorConversionMatrixStruct[0]; + ccm->c00 = 1023; + ccm->c11 = 1023; + ccm->c22 = 1023; + + ccc = &c->colorConversionClampStruct[0]; + ccc->low = 0; + ccc->high = 1023; + + /* setup blending for slot 0 */ + b = &c->blendingSurfaceStruct[0]; + b->AlphaK1 = 1023; + b->SrcFactCMatchSelect = VIC_BLEND_SRCFACTC_K1; + b->SrcFactAMatchSelect = VIC_BLEND_SRCFACTA_K1; + b->DstFactCMatchSelect = VIC_BLEND_DSTFACTC_NEG_K1_TIMES_SRC; + b->DstFactAMatchSelect = VIC_BLEND_DSTFACTA_NEG_K1_TIMES_SRC; + + drm_tegra_bo_unmap(vic->config.bo); + + return 0; +} + +static int vic30_execute(struct vic *v, struct drm_tegra_pushbuf *pushbuf, + uint32_t **ptrp, struct vic_image *output, + struct vic_image **inputs, unsigned int num_inputs) +{ + struct vic30 *vic = container_of(v, struct vic30, base); + unsigned int i; + + if (num_inputs > 1) + return -EINVAL; + + VIC_PUSH_METHOD(pushbuf, ptrp, NVA0B6_VIDEO_COMPOSITOR_SET_APPLICATION_ID, 1); + VIC_PUSH_METHOD(pushbuf, ptrp, NVA0B6_VIDEO_COMPOSITOR_SET_CONTROL_PARAMS, (sizeof(ConfigStruct) / 16) << 16); + VIC_PUSH_BUFFER(pushbuf, ptrp, NVA0B6_VIDEO_COMPOSITOR_SET_CONFIG_STRUCT_OFFSET, vic->config.map, 0, 0); + VIC_PUSH_BUFFER(pushbuf, ptrp, NVA0B6_VIDEO_COMPOSITOR_SET_HIST_OFFSET, vic->hist.map, 0, 0); + VIC_PUSH_BUFFER(pushbuf, ptrp, NVA0B6_VIDEO_COMPOSITOR_SET_OUTPUT_SURFACE_LUMA_OFFSET, output->map, 0, 0); + + for (i = 0; i < num_inputs; i++) + VIC_PUSH_BUFFER(pushbuf, ptrp, NVA0B6_VIDEO_COMPOSITOR_SET_SURFACE0_SLOT0_LUMA_OFFSET, inputs[i]->map, 0, 0); + + VIC_PUSH_METHOD(pushbuf, ptrp, NVA0B6_VIDEO_COMPOSITOR_EXECUTE, 1 << 8); + + return 0; +} + +static void vic30_free(struct vic *v) +{ + struct vic30 *vic = container_of(v, struct vic30, base); + + drm_tegra_channel_unmap(vic->hist.map); + drm_tegra_bo_unref(vic->hist.bo); + + drm_tegra_channel_unmap(vic->filter.map); + drm_tegra_bo_unref(vic->filter.bo); + + drm_tegra_channel_unmap(vic->config.map); + drm_tegra_bo_unref(vic->config.bo); + + drm_tegra_syncpoint_free(v->syncpt); + + free(vic); +} + +static const struct vic_ops vic30_ops = { + .fill = vic30_fill, + .blit = vic30_blit, + .flip = vic30_flip, + .execute = vic30_execute, + .free = vic30_free, +}; + +int vic30_new(struct drm_tegra *drm, struct drm_tegra_channel *channel, + struct vic **vicp) +{ + struct vic30 *vic; + void *ptr; + int err; + + vic = calloc(1, sizeof(*vic)); + if (!vic) + return -ENOMEM; + + vic->base.drm = drm; + vic->base.channel = channel; + vic->base.ops = &vic30_ops; + vic->base.version = 0x40; + + err = drm_tegra_syncpoint_new(drm, &vic->base.syncpt); + if (err < 0) { + fprintf(stderr, "failed to allocate syncpoint: %s\n", strerror(-err)); + return err; + } + + err = drm_tegra_bo_new(drm, 0, 16384, &vic->config.bo); + if (err < 0) { + fprintf(stderr, "failed to allocate configuration structure: %s\n", + strerror(-err)); + return err; + } + + err = drm_tegra_channel_map(channel, vic->config.bo, DRM_TEGRA_CHANNEL_MAP_READ, + &vic->config.map); + if (err < 0) { + fprintf(stderr, "failed to map configuration structure: %s\n", + strerror(-err)); + return err; + } + + err = drm_tegra_bo_new(drm, 0, 16384, &vic->filter.bo); + if (err < 0) { + fprintf(stderr, "failed to allocate filter buffer: %s\n", + strerror(-err)); + return err; + } + + err = drm_tegra_bo_map(vic->filter.bo, &ptr); + if (err < 0) { + fprintf(stderr, "failed to map filter buffer: %s\n", strerror(-err)); + return err; + } + + memset(ptr, 0, 16384); + drm_tegra_bo_unmap(vic->filter.bo); + + err = drm_tegra_channel_map(channel, vic->filter.bo, DRM_TEGRA_CHANNEL_MAP_READ, + &vic->filter.map); + if (err < 0) { + fprintf(stderr, "failed to map filter buffer: %s\n", + strerror(-err)); + return err; + } + + err = drm_tegra_bo_new(drm, 0, 4096, &vic->hist.bo); + if (err < 0) { + fprintf(stderr, "failed to allocate history buffer: %s\n", + strerror(-err)); + return err; + } + + err = drm_tegra_bo_map(vic->hist.bo, &ptr); + if (err < 0) { + fprintf(stderr, "failed to map history buffer: %s\n", strerror(-err)); + return err; + } + + memset(ptr, 0, 4096); + drm_tegra_bo_unmap(vic->hist.bo); + + err = drm_tegra_channel_map(channel, vic->hist.bo, DRM_TEGRA_CHANNEL_MAP_READ_WRITE, + &vic->hist.map); + if (err < 0) { + fprintf(stderr, "failed to map histogram buffer: %s\n", + strerror(-err)); + return err; + } + + if (vicp) + *vicp = &vic->base; + + return 0; +} diff -Nru libdrm-2.4.110/tests/tegra/vic30.h libdrm-2.4.113/tests/tegra/vic30.h --- libdrm-2.4.110/tests/tegra/vic30.h 1970-01-01 00:00:00.000000000 +0000 +++ libdrm-2.4.113/tests/tegra/vic30.h 2022-08-31 14:38:38.000000000 +0000 @@ -0,0 +1,439 @@ +/* + * 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 VIC30_H +#define VIC30_H + +#include + +#define NVA0B6_VIDEO_COMPOSITOR_SET_APPLICATION_ID 0x200 +#define NVA0B6_VIDEO_COMPOSITOR_EXECUTE 0x300 +#define NVA0B6_VIDEO_COMPOSITOR_EXECUTE_AWAKEN (1 << 8) +#define NVA0B6_VIDEO_COMPOSITOR_SET_SURFACE0_SLOT0_LUMA_OFFSET 0x400 +#define NVA0B6_VIDEO_COMPOSITOR_SET_SURFACE0_SLOT0_CHROMA_U_OFFSET 0x404 +#define NVA0B6_VIDEO_COMPOSITOR_SET_SURFACE0_SLOT0_CHROMA_V_OFFSET 0x408 +#define NVA0B6_VIDEO_COMPOSITOR_SET_CONTROL_PARAMS 0x700 +#define NVA0B6_VIDEO_COMPOSITOR_SET_CONFIG_STRUCT_OFFSET 0x720 +#define NVA0B6_VIDEO_COMPOSITOR_SET_PALETTE_OFFSET 0x724 +#define NVA0B6_VIDEO_COMPOSITOR_SET_HIST_OFFSET 0x728 +#define NVA0B6_VIDEO_COMPOSITOR_SET_OUTPUT_SURFACE_LUMA_OFFSET 0x730 +#define NVA0B6_VIDEO_COMPOSITOR_SET_OUTPUT_SURFACE_CHROMA_U_OFFSET 0x734 +#define NVA0B6_VIDEO_COMPOSITOR_SET_OUTPUT_SURFACE_CHROMA_V_OFFSET 0x738 + +#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_BLK_KIND_PITCH 0 +#define VIC_BLK_KIND_GENERIC_16Bx2 1 + +typedef struct { + uint64_t DeNoise0 : 1; /* 0 */ + uint64_t CadenceDetect0 : 1; /* 1 */ + uint64_t MotionMap0 : 1; /* 2 */ + uint64_t MedianFilter0 : 1; /* 3 */ + uint64_t DeNoise1 : 1; /* 4 */ + uint64_t CadenceDetect1 : 1; /* 5 */ + uint64_t MotionMap1 : 1; /* 6 */ + uint64_t MedianFilter1 : 1; /* 7 */ + uint64_t DeNoise2 : 1; /* 8 */ + uint64_t CadenceDetect2 : 1; /* 9 */ + uint64_t MotionMap2 : 1; /* 10 */ + uint64_t MedianFilter2 : 1; /* 11 */ + uint64_t DeNoise3 : 1; /* 12 */ + uint64_t CadenceDetect3 : 1; /* 13 */ + uint64_t MotionMap3 : 1; /* 14 */ + uint64_t MedianFilter3 : 1; /* 15 */ + uint64_t DeNoise4 : 1; /* 16 */ + uint64_t CadenceDetect4 : 1; /* 17 */ + uint64_t MotionMap4 : 1; /* 18 */ + uint64_t MedianFilter4 : 1; /* 19 */ + uint64_t IsEven0 : 1; /* 20 */ + uint64_t IsEven1 : 1; /* 21 */ + uint64_t IsEven2 : 1; /* 22 */ + uint64_t IsEven3 : 1; /* 23 */ + uint64_t IsEven4 : 1; /* 24 */ + uint64_t MMapCombine0 : 1; /* 25 */ + uint64_t MMapCombine1 : 1; /* 26 */ + uint64_t MMapCombine2 : 1; /* 27 */ + uint64_t MMapCombine3 : 1; /* 28 */ + uint64_t MMapCombine4 : 1; /* 29 */ + uint64_t reserved0 : 2; /* 31..30 */ + uint64_t PixelFormat0 : 7; /* 38..32 */ + uint64_t reserved1 : 1; /* 39 */ + uint64_t PixelFormat1 : 7; /* 46..40 */ + uint64_t reserved2 : 1; /* 47 */ + uint64_t PixelFormat2 : 7; /* 54..48 */ + uint64_t reserved3 : 1; /* 55 */ + uint64_t PixelFormat3 : 7; /* 62..56 */ + uint64_t reserved4 : 1; /* 63 */ + uint64_t PixelFormat4 : 7; /* 70..64 */ + uint64_t reserved5 : 1; /* 71 */ + uint64_t reserved6 : 24; /* 95..72 */ + uint64_t PPMotion0 : 1; /* 96 */ + uint64_t PPMotion1 : 1; /* 97 */ + uint64_t PPMotion2 : 1; /* 98 */ + uint64_t PPMotion3 : 1; /* 99 */ + uint64_t PPMotion4 : 1; /* 100 */ + uint64_t reserved7 : 3; /* 103..101 */ + uint64_t ChromaEven0 : 1; /* 104 */ + uint64_t ChromaEven1 : 1; /* 105 */ + uint64_t ChromaEven2 : 1; /* 106 */ + uint64_t ChromaEven3 : 1; /* 107 */ + uint64_t ChromaEven4 : 1; /* 108 */ + uint64_t reserved8 : 3; /* 111..109 */ + uint64_t AdvancedDenoise0 : 1; /* 112 */ + uint64_t AdvancedDenoise1 : 1; /* 113 */ + uint64_t AdvancedDenoise2 : 1; /* 114 */ + uint64_t AdvancedDenoise3 : 1; /* 115 */ + uint64_t AdvancedDenoise4 : 1; /* 116 */ + uint64_t reserved9 : 3; /* 119..117 */ + uint64_t reserved10 : 8; /* 127..120 */ +} SurfaceCache0Struct; + +typedef struct { + uint64_t ClearRectMask0 : 8; /* 7..0 */ + uint64_t ClearRectMask1 : 8; /* 15..8 */ + uint64_t ClearRectMask2 : 8; /* 23..16 */ + uint64_t ClearRectMask3 : 8; /* 31..24 */ + uint64_t ClearRectMask4 : 8; /* 39..32 */ + uint64_t reserved0 : 22; /* 61..40 */ + uint64_t OutputFlipX : 1; /* 62 */ + uint64_t OutputFlipY : 1; /* 63 */ + uint64_t TargetRectLeft : 14; /* 77..64 */ + uint64_t reserved1 : 2; /* 79..78 */ + uint64_t TargetRectRight : 14; /* 93..80 */ + uint64_t reserved2 : 2; /* 95..94 */ + uint64_t TargetRectTop : 14; /* 109..96 */ + uint64_t reserved3 : 2; /* 111..110 */ + uint64_t TargetRectBottom : 14; /* 125..112 */ + uint64_t reserved4 : 2; /* 127..126 */ +} SurfaceList0Struct; + +typedef struct { + uint64_t ClearRect0Left : 14; /* 13..0 */ + uint64_t reserved0 : 2; /* 15..14 */ + uint64_t ClearRect0Right : 14; /* 29..16 */ + uint64_t reserved1 : 2; /* 31..30 */ + uint64_t ClearRect0Top : 14; /* 45..32 */ + uint64_t reserved2 : 2; /* 47..46 */ + uint64_t ClearRect0Bottom : 14; /* 61..48 */ + uint64_t reserved3 : 2; /* 63..62 */ + uint64_t ClearRect1Left : 14; /* 77..64 */ + uint64_t reserved4 : 2; /* 79..78 */ + uint64_t ClearRect1Right : 14; /* 93..80 */ + uint64_t reserved5 : 2; /* 95..94 */ + uint64_t ClearRect1Top : 14; /* 109..96 */ + uint64_t reserved6 : 2; /* 111..110 */ + uint64_t ClearRect1Bottom : 14; /* 125..112 */ + uint64_t reserved7 : 2; /* 127..126 */ +} SurfaceListClearRectStruct; + +typedef struct { + uint64_t Enable : 1; /* 0 */ + uint64_t FrameFormat : 4; /* 4..1 */ + uint64_t PixelFormat : 7; /* 11..5 */ + uint64_t reserved0 : 2; /* 13..12 */ + uint64_t ChromaLocHoriz : 2; /* 15..14 */ + uint64_t ChromaLocVert : 2; /* 17..16 */ + uint64_t Panoramic : 12; /* 29..18 */ + uint64_t reserved1 : 4; /* 33..30 */ + uint64_t SurfaceWidth : 14; /* 47..34 */ + uint64_t reserved2 : 1; /* 48 */ + uint64_t SurfaceHeight : 14; /* 62..49 */ + uint64_t reserved3 : 1; /* 63 */ + uint64_t LumaWidth : 14; /* 77..64 */ + uint64_t reserved4 : 1; /* 78 */ + uint64_t LumaHeight : 14; /* 92..79 */ + uint64_t reserved5 : 1; /* 93 */ + uint64_t ChromaWidth : 14; /* 107..94 */ + uint64_t reserved6 : 1; /* 108 */ + uint64_t ChromaHeight : 14; /* 122..109 */ + uint64_t reserved7 : 1; /* 123 */ + uint64_t CacheWidth : 3; /* 126..124 */ + uint64_t reserved8 : 1; /* 127 */ + /* 128 */ + uint64_t FilterLengthY : 2; /* 1..0 */ + uint64_t FilterLengthX : 2; /* 3..2 */ + uint64_t DetailFltClamp : 6; /* 9..4 */ + uint64_t reserved9 : 2; /* 11..10 */ + uint64_t LightLevel : 4; /* 15..12 */ + uint64_t reserved10 : 4; /* 19..16 */ + uint64_t reserved11 : 8; /* 27..20 */ + uint64_t reserved12 : 32; /* 59..28 */ + uint64_t BlkKind : 4; /* 63..60 */ + uint64_t DestRectLeft : 14; /* 77..64 */ + uint64_t reserved13 : 1; /* 78 */ + uint64_t DestRectRight : 14; /* 92..79 */ + uint64_t reserved14 : 1; /* 93 */ + uint64_t DestRectTop : 14; /* 107..94 */ + uint64_t reserved15 : 1; /* 108 */ + uint64_t DestRectBottom : 14; /* 122..109 */ + uint64_t reserved16 : 1; /* 123 */ + uint64_t BlkHeight : 4; /* 127..124 */ + /* 256 */ + uint64_t SourceRectLeft : 30; /* 29..0 */ + uint64_t reserved17 : 2; /* 31..30 */ + uint64_t SourceRectRight : 30; /* 61..32 */ + uint64_t reserved18 : 2; /* 63..62 */ + uint64_t SourceRectTop : 30; /* 93..64 */ + uint64_t reserved19 : 2; /* 95..94 */ + uint64_t SourceRectBottom : 30; /* 125..96 */ + uint64_t reserved20 : 2; /* 127..126 */ +} SurfaceListSurfaceStruct; + +typedef struct { + uint64_t l0 : 20; /* 19..0 */ + uint64_t l1 : 20; /* 39..20 */ + uint64_t l2 : 20; /* 59..40 */ + uint64_t r_shift : 4; /* 63..60 */ + uint64_t l3 : 20; /* 83..64 */ + uint64_t PlanarAlpha : 10; /* 93..84 */ + uint64_t ConstantAlpha : 1; /* 94 */ + uint64_t ClipEnabled : 1; /* 95 */ + uint64_t LumaKeyLower : 10; /* 105..96 */ + uint64_t reserved6 : 3; /* 108..106 */ + uint64_t StereoInterleave : 3; /* 111..109 */ + uint64_t LumaKeyUpper : 10; /* 121..112 */ + uint64_t reserved7 : 2; /* 123..122 */ + uint64_t reserved8 : 1; /* 124 */ + uint64_t LumaKeyEnabled : 1; /* 125 */ + uint64_t reserved9 : 2; /* 127..126 */ +} ColorConversionLumaAlphaStruct; + +typedef struct { + uint64_t c00 : 20; /* 19..0 */ + uint64_t c10 : 20; /* 39..20 */ + uint64_t c20 : 20; /* 59..40 */ + uint64_t r_shift : 4; /* 63..60 */ + uint64_t c01 : 20; /* 83..64 */ + uint64_t c11 : 20; /* 103..84 */ + uint64_t c21 : 20; /* 123..104 */ + uint64_t reserved0 : 4; /* 127..124 */ + /* 128 */ + uint64_t c02 : 20; /* 19..0 */ + uint64_t c12 : 20; /* 39..20 */ + uint64_t c22 : 20; /* 59..40 */ + uint64_t reserved1 : 4; /* 63..60 */ + uint64_t c03 : 20; /* 83..64 */ + uint64_t c13 : 20; /* 103..84 */ + uint64_t c23 : 20; /* 123..104 */ + uint64_t reserved2 : 4; /* 127..124 */ +} ColorConversionMatrixStruct; + +typedef struct { + uint64_t low : 10; /* 9..0 */ + uint64_t reserved0 : 6; /* 15..10 */ + uint64_t high : 10; /* 25..16 */ + uint64_t reserved1 : 6; /* 31..26 */ + uint64_t reserved2 : 32; /* 63..32 */ + uint64_t reserved3 : 32; /* 95..64 */ + uint64_t reserved4 : 32; /* 127..96 */ +} ColorConversionClampStruct; + +typedef struct { + uint64_t PixelFormat : 7; /* 6..0 */ + uint64_t reserved0 : 1; /* 7 */ + uint64_t AlphaFillMode : 3; /* 10..8 */ + uint64_t AlphaFillSlot : 3; /* 13..11 */ + uint64_t BackgroundAlpha : 10; /* 23..14 */ + uint64_t BackgroundR : 10; /* 33..24 */ + uint64_t BackgroundG : 10; /* 43..34 */ + uint64_t BackgroundB : 10; /* 53..44 */ + uint64_t ChromaLocHoriz : 2; /* 55..54 */ + uint64_t ChromaLocVert : 2; /* 57..56 */ + uint64_t reserved1 : 6; /* 63..58 */ + uint64_t LumaWidth : 14; /* 77..64 */ + uint64_t reserved2 : 2; /* 79..78 */ + uint64_t LumaHeight : 14; /* 93..80 */ + uint64_t reserved3 : 2; /* 95..94 */ + uint64_t ChromaWidth : 14; /* 109..96 */ + uint64_t reserved4 : 2; /* 111..110 */ + uint64_t ChromaHeight : 14; /* 125..112 */ + uint64_t reserved5 : 2; /* 127..126 */ + /* 128 */ + uint64_t TargetRectLeft : 14; /* 13..0 */ + uint64_t reserved6 : 2; /* 15..14 */ + uint64_t TargetRectRight : 14; /* 29..16 */ + uint64_t reserved7 : 2; /* 31..30 */ + uint64_t TargetRectTop : 14; /* 45..32 */ + uint64_t reserved8 : 2; /* 47..46 */ + uint64_t TargetRectBottom : 14; /* 61..48 */ + uint64_t reserved9 : 2; /* 63..62 */ + uint64_t SurfaceWidth : 14; /* 77..64 */ + uint64_t reserved10 : 2; /* 79..78 */ + uint64_t SurfaceHeight : 14; /* 93..80 */ + uint64_t reserved11 : 2; /* 95..94 */ + uint64_t BlkKind : 4; /* 99..96 */ + uint64_t BlkHeight : 4; /* 103..100 */ + uint64_t OutputFlipX : 1; /* 104 */ + uint64_t OutputFlipY : 1; /* 105 */ + uint64_t OutputTranspose : 1; /* 106 */ + uint64_t reserved12 : 21; /* 127..107 */ +} Blending0Struct; + +typedef struct { + uint64_t AlphaK1 : 10; /* 9..0 */ + uint64_t reserved0 : 6; /* 15..10 */ + uint64_t AlphaK2 : 10; /* 25..16 */ + uint64_t reserved1 : 6; /* 31..26 */ + uint64_t SrcFactCMatchSelect : 3; /* 34..32 */ + uint64_t reserved2 : 1; /* 35 */ + uint64_t DstFactCMatchSelect : 3; /* 38..36 */ + uint64_t reserved3 : 1; /* 39 */ + uint64_t SrcFactAMatchSelect : 3; /* 42..40 */ + uint64_t reserved4 : 1; /* 43 */ + uint64_t DstFactAMatchSelect : 3; /* 46..44 */ + uint64_t reserved5 : 1; /* 47 */ + uint64_t reserved6 : 4; /* 51..48 */ + uint64_t reserved7 : 4; /* 55..52 */ + uint64_t reserved8 : 4; /* 59..56 */ + uint64_t reserved9 : 4; /* 63..60 */ + uint64_t reserved10 : 2; /* 65..64 */ + uint64_t OverrideR : 10; /* 75..66 */ + uint64_t OverrideG : 10; /* 85..76 */ + uint64_t OverrideB : 10; /* 95..86 */ + uint64_t OverrideA : 10; /* 105..96 */ + uint64_t reserved11 : 2; /* 107..106 */ + uint64_t UseOverrideR : 1; /* 108 */ + uint64_t UseOverrideG : 1; /* 109 */ + uint64_t UseOverrideB : 1; /* 110 */ + uint64_t UseOverrideA : 1; /* 111 */ + uint64_t MaskR : 1; /* 112 */ + uint64_t MaskG : 1; /* 113 */ + uint64_t MaskB : 1; /* 114 */ + uint64_t MaskA : 1; /* 115 */ + uint64_t reserved12 : 12; /* 127..116 */ +} BlendingSurfaceStruct; + +typedef struct { + uint64_t TargetRectLeft : 14; /* 13..0 */ + uint64_t reserved0 : 2; /* 15..14 */ + uint64_t TargetRectRight : 14; /* 29..16 */ + uint64_t reserved1 : 2; /* 31..30 */ + uint64_t TargetRectTop : 14; /* 45..32 */ + uint64_t reserved2 : 2; /* 47..46 */ + uint64_t TargetRectBottom : 14; /* 61..48 */ + uint64_t reserved3 : 2; /* 63..62 */ + uint64_t Enable0 : 8; /* 71..64 */ + uint64_t Enable1 : 8; /* 79..72 */ + uint64_t Enable2 : 8; /* 87..80 */ + uint64_t Enable3 : 8; /* 95..88 */ + uint64_t Enable4 : 8; /* 103..96 */ + uint64_t DownsampleHoriz : 11; /* 114..104 */ + uint64_t reserved4 : 1; /* 115 */ + uint64_t DownsampleVert : 11; /* 126..116 */ + uint64_t reserved5 : 1; /* 127 */ + /* 128 */ + uint64_t FilterNoise0 : 10; /* 9..0 */ + uint64_t FilterDetail0 : 10; /* 19..10 */ + uint64_t FilterNoise1 : 10; /* 29..20 */ + uint64_t reserved6 : 2; /* 31..30 */ + uint64_t FilterDetail1 : 10; /* 41..32 */ + uint64_t FilterNoise2 : 10; /* 51..42 */ + uint64_t FilterDetail2 : 10; /* 61..52 */ + uint64_t reserved7 : 2; /* 63..62 */ + uint64_t FilterNoise3 : 10; /* 73..64 */ + uint64_t FilterDetail3 : 10; /* 83..74 */ + uint64_t FilterNoise4 : 10; /* 93..84 */ + uint64_t reserved8 : 2; /* 95..94 */ + uint64_t FilterDetail4 : 10; /* 105..96 */ + uint64_t reserved9 : 22; /* 127..106 */ + /* 256 */ + uint64_t ChromaNoise0 : 10; /* 9..0 */ + uint64_t ChromaDetail0 : 10; /* 19..10 */ + uint64_t ChromaNoise1 : 10; /* 29..20 */ + uint64_t reserved10 : 2; /* 31..30 */ + uint64_t ChromaDetail1 : 10; /* 41..32 */ + uint64_t ChromaNoise2 : 10; /* 51..42 */ + uint64_t ChromaDetail2 : 10; /* 61..52 */ + uint64_t reserved11 : 2; /* 63..62 */ + uint64_t ChromaNoise3 : 10; /* 73..64 */ + uint64_t ChromaDetail3 : 10; /* 83..74 */ + uint64_t ChromaNoise4 : 10; /* 93..84 */ + uint64_t reserved12 : 2; /* 95..94 */ + uint64_t ChromaDetail4 : 10; /* 105..96 */ + uint64_t reserved13 : 22; /* 127..106 */ + /* 384 */ + uint64_t Mode0 : 4; /* 3..0 */ + uint64_t AccumWeight0 : 3; /* 6..4 */ + uint64_t Iir0 : 11; /* 17..7 */ + uint64_t reserved14 : 2; /* 19..18 */ + uint64_t Mode1 : 4; /* 23..20 */ + uint64_t AccumWeight1 : 3; /* 26..24 */ + uint64_t Iir1 : 11; /* 37..27 */ + uint64_t reserved15 : 2; /* 39..38 */ + uint64_t Mode2 : 4; /* 43..40 */ + uint64_t AccumWeight2 : 3; /* 46..44 */ + uint64_t Iir2 : 11; /* 57..47 */ + uint64_t reserved16 : 6; /* 63..58 */ + uint64_t Mode3 : 4; /* 67..64 */ + uint64_t AccumWeight3 : 3; /* 70..68 */ + uint64_t Iir3 : 11; /* 81..71 */ + uint64_t reserved17 : 2; /* 83..82 */ + uint64_t Mode4 : 4; /* 87..84 */ + uint64_t AccumWeight4 : 3; /* 90..88 */ + uint64_t Iir4 : 11; /* 101..91 */ + uint64_t reserved18 : 8; /* 109..102 */ + uint64_t OutputFlipX : 1; /* 110 */ + uint64_t OutputFlipY : 1; /* 111 */ + uint64_t reserved19 : 10; /* 121..112 */ + uint64_t reserved20 : 6; /* 127..122 */ +} FetchControl0Struct; + +typedef struct { + uint64_t f00 : 10; /* 9..0 */ + uint64_t f10 : 10; /* 19..10 */ + uint64_t f20 : 10; /* 29..20 */ + uint64_t reserved0 : 2; /* 31..30 */ + uint64_t f01 : 10; /* 41..32 */ + uint64_t f11 : 10; /* 51..42 */ + uint64_t f21 : 10; /* 61..52 */ + uint64_t reserved1 : 2; /* 63..62 */ + uint64_t f02 : 10; /* 73..64 */ + uint64_t f12 : 10; /* 83..74 */ + uint64_t f22 : 10; /* 93..84 */ + uint64_t reserved2 : 2; /* 95..94 */ + uint64_t f03 : 10; /* 105..96 */ + uint64_t f13 : 10; /* 115..106 */ + uint64_t f23 : 10; /* 125..116 */ + uint64_t reserved3 : 2; /* 127..126 */ +} FetchControlCoeffStruct; + +typedef struct { + SurfaceCache0Struct surfaceCache0Struct; + SurfaceList0Struct surfaceList0Struct; + SurfaceListClearRectStruct surfaceListClearRectStruct[4]; + SurfaceListSurfaceStruct surfaceListSurfaceStruct[5]; + ColorConversionLumaAlphaStruct colorConversionLumaAlphaStruct[5]; + ColorConversionMatrixStruct colorConversionMatrixStruct[5]; + ColorConversionClampStruct colorConversionClampStruct[5]; + Blending0Struct blending0Struct; + BlendingSurfaceStruct blendingSurfaceStruct[5]; + FetchControl0Struct fetchControl0Struct; + FetchControlCoeffStruct fetchControlCoeffStruct[520]; +} ConfigStruct; + +#endif diff -Nru libdrm-2.4.110/tests/tegra/vic40.c libdrm-2.4.113/tests/tegra/vic40.c --- libdrm-2.4.110/tests/tegra/vic40.c 1970-01-01 00:00:00.000000000 +0000 +++ libdrm-2.4.113/tests/tegra/vic40.c 2022-08-31 14:38:38.000000000 +0000 @@ -0,0 +1,338 @@ +/* + * 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 +#include + +#include "private.h" +#include "tegra.h" +#include "vic.h" +#include "vic40.h" + +struct vic40 { + struct vic base; + + struct { + struct drm_tegra_mapping *map; + struct drm_tegra_bo *bo; + } config; + + struct { + struct drm_tegra_mapping *map; + struct drm_tegra_bo *bo; + } filter; +}; + +static int vic40_fill(struct vic *v, struct vic_image *output, + unsigned int left, unsigned int top, + unsigned int right, unsigned int bottom, + unsigned int alpha, unsigned int red, + unsigned int green, unsigned int blue) +{ + struct vic40 *vic = container_of(v, struct vic40, base); + ConfigStruct *c; + int err; + + err = drm_tegra_bo_map(vic->config.bo, (void **)&c); + if (err < 0) { + fprintf(stderr, "failed to map configuration structure: %s\n", + strerror(-err)); + return err; + } + + memset(c, 0, sizeof(*c)); + + c->outputConfig.TargetRectTop = top; + c->outputConfig.TargetRectLeft = left; + c->outputConfig.TargetRectRight = right; + c->outputConfig.TargetRectBottom = bottom; + c->outputConfig.BackgroundAlpha = alpha; + c->outputConfig.BackgroundR = red; + c->outputConfig.BackgroundG = green; + c->outputConfig.BackgroundB = blue; + + c->outputSurfaceConfig.OutPixelFormat = output->format; + c->outputSurfaceConfig.OutBlkKind = output->kind; + c->outputSurfaceConfig.OutBlkHeight = 0; + c->outputSurfaceConfig.OutSurfaceWidth = output->width - 1; + c->outputSurfaceConfig.OutSurfaceHeight = output->height - 1; + c->outputSurfaceConfig.OutLumaWidth = output->stride - 1; + c->outputSurfaceConfig.OutLumaHeight = output->height - 1; + c->outputSurfaceConfig.OutChromaWidth = 16383; + c->outputSurfaceConfig.OutChromaHeight = 16383; + + drm_tegra_bo_unmap(vic->config.bo); + + return 0; +} + +static int vic40_blit(struct vic *v, struct vic_image *output, + struct vic_image *input) +{ + struct vic40 *vic = container_of(v, struct vic40, base); + SlotSurfaceConfig *surface; + SlotConfig *slot; + ConfigStruct *c; + int err; + + err = drm_tegra_bo_map(vic->config.bo, (void **)&c); + if (err < 0) { + fprintf(stderr, "failed to map configuration structure: %s\n", + strerror(-err)); + return err; + } + + memset(c, 0, sizeof(*c)); + + c->outputConfig.TargetRectTop = 0; + c->outputConfig.TargetRectLeft = 0; + c->outputConfig.TargetRectRight = output->width - 1; + c->outputConfig.TargetRectBottom = output->height - 1; + c->outputConfig.BackgroundAlpha = 1023; + c->outputConfig.BackgroundR = 1023; + c->outputConfig.BackgroundG = 1023; + c->outputConfig.BackgroundB = 1023; + + c->outputSurfaceConfig.OutPixelFormat = output->format; + c->outputSurfaceConfig.OutBlkKind = output->kind; + c->outputSurfaceConfig.OutBlkHeight = 0; + c->outputSurfaceConfig.OutSurfaceWidth = output->width - 1; + c->outputSurfaceConfig.OutSurfaceHeight = output->height - 1; + c->outputSurfaceConfig.OutLumaWidth = output->stride - 1; + c->outputSurfaceConfig.OutLumaHeight = output->height - 1; + c->outputSurfaceConfig.OutChromaWidth = 16383; + c->outputSurfaceConfig.OutChromaHeight = 16383; + + slot = &c->slotStruct[0].slotConfig; + slot->SlotEnable = 1; + slot->CurrentFieldEnable = 1; + slot->PlanarAlpha = 1023; + slot->ConstantAlpha = 1; + slot->SourceRectLeft = 0 << 16; + slot->SourceRectRight = (input->width - 1) << 16; + slot->SourceRectTop = 0 << 16; + slot->SourceRectBottom = (input->height - 1) << 16; + slot->DestRectLeft = 0; + slot->DestRectRight = output->width - 1; + slot->DestRectTop = 0; + slot->DestRectBottom = output->height - 1; + slot->SoftClampHigh = 1023; + + surface = &c->slotStruct[0].slotSurfaceConfig; + surface->SlotPixelFormat = input->format; + surface->SlotBlkKind = input->kind; + surface->SlotBlkHeight = 0; /* XXX */ + surface->SlotCacheWidth = VIC_CACHE_WIDTH_64Bx4; /* XXX */ + surface->SlotSurfaceWidth = input->width - 1; + surface->SlotSurfaceHeight = input->height - 1; + surface->SlotLumaWidth = input->stride - 1; + surface->SlotLumaHeight = input->height - 1; + surface->SlotChromaWidth = 16383; + surface->SlotChromaHeight = 16383; + + drm_tegra_bo_unmap(vic->config.bo); + + return 0; +} + +static int vic40_flip(struct vic *v, struct vic_image *output, + struct vic_image *input) +{ + struct vic40 *vic = container_of(v, struct vic40, base); + SlotSurfaceConfig *surface; + SlotConfig *slot; + ConfigStruct *c; + int err; + + err = drm_tegra_bo_map(vic->config.bo, (void **)&c); + if (err < 0) { + fprintf(stderr, "failed to map configuration structure: %s\n", + strerror(-err)); + return err; + } + + memset(c, 0, sizeof(*c)); + + c->outputConfig.TargetRectTop = 0; + c->outputConfig.TargetRectLeft = 0; + c->outputConfig.TargetRectRight = output->width - 1; + c->outputConfig.TargetRectBottom = output->height - 1; + c->outputConfig.BackgroundAlpha = 1023; + c->outputConfig.BackgroundR = 1023; + c->outputConfig.BackgroundG = 1023; + c->outputConfig.BackgroundB = 1023; + c->outputConfig.OutputFlipY = 1; + + c->outputSurfaceConfig.OutPixelFormat = output->format; + c->outputSurfaceConfig.OutBlkKind = output->kind; + c->outputSurfaceConfig.OutBlkHeight = 0; + c->outputSurfaceConfig.OutSurfaceWidth = output->width - 1; + c->outputSurfaceConfig.OutSurfaceHeight = output->height - 1; + c->outputSurfaceConfig.OutLumaWidth = output->stride - 1; + c->outputSurfaceConfig.OutLumaHeight = output->height - 1; + c->outputSurfaceConfig.OutChromaWidth = 16383; + c->outputSurfaceConfig.OutChromaHeight = 16383; + + slot = &c->slotStruct[0].slotConfig; + slot->SlotEnable = 1; + slot->CurrentFieldEnable = 1; + slot->PlanarAlpha = 1023; + slot->ConstantAlpha = 1; + slot->SourceRectLeft = 0 << 16; + slot->SourceRectRight = (input->width - 1) << 16; + slot->SourceRectTop = 0 << 16; + slot->SourceRectBottom = (input->height - 1) << 16; + slot->DestRectLeft = 0; + slot->DestRectRight = output->width - 1; + slot->DestRectTop = 0; + slot->DestRectBottom = output->height - 1; + slot->SoftClampHigh = 1023; + + surface = &c->slotStruct[0].slotSurfaceConfig; + surface->SlotPixelFormat = input->format; + surface->SlotBlkKind = input->kind; + surface->SlotBlkHeight = 0; /* XXX */ + surface->SlotCacheWidth = VIC_CACHE_WIDTH_64Bx4; /* XXX */ + surface->SlotSurfaceWidth = input->width - 1; + surface->SlotSurfaceHeight = input->height - 1; + surface->SlotLumaWidth = input->stride - 1; + surface->SlotLumaHeight = input->height - 1; + surface->SlotChromaWidth = 16383; + surface->SlotChromaHeight = 16383; + + drm_tegra_bo_unmap(vic->config.bo); + + return 0; +} + +static int vic40_execute(struct vic *v, struct drm_tegra_pushbuf *pushbuf, + uint32_t **ptrp, struct vic_image *output, + struct vic_image **inputs, unsigned int num_inputs) +{ + struct vic40 *vic = container_of(v, struct vic40, base); + unsigned int i; + + if (num_inputs > 1) + return -EINVAL; + + VIC_PUSH_METHOD(pushbuf, ptrp, NVB0B6_VIDEO_COMPOSITOR_SET_APPLICATION_ID, 1); + VIC_PUSH_METHOD(pushbuf, ptrp, NVB0B6_VIDEO_COMPOSITOR_SET_CONTROL_PARAMS, (sizeof(ConfigStruct) / 16) << 16); + VIC_PUSH_BUFFER(pushbuf, ptrp, NVB0B6_VIDEO_COMPOSITOR_SET_CONFIG_STRUCT_OFFSET, vic->config.map, 0, 0); + VIC_PUSH_BUFFER(pushbuf, ptrp, NVB0B6_VIDEO_COMPOSITOR_SET_OUTPUT_SURFACE_LUMA_OFFSET, output->map, 0, 0); + + for (i = 0; i < num_inputs; i++) + VIC_PUSH_BUFFER(pushbuf, ptrp, NVB0B6_VIDEO_COMPOSITOR_SET_SURFACE0_SLOT0_LUMA_OFFSET, inputs[i]->map, 0, 0); + + VIC_PUSH_METHOD(pushbuf, ptrp, NVB0B6_VIDEO_COMPOSITOR_EXECUTE, 1 << 8); + + return 0; +} + +static void vic40_free(struct vic *v) +{ + struct vic40 *vic = container_of(v, struct vic40, base); + + drm_tegra_channel_unmap(vic->filter.map); + drm_tegra_bo_unref(vic->filter.bo); + + drm_tegra_channel_unmap(vic->config.map); + drm_tegra_bo_unref(vic->config.bo); + + drm_tegra_syncpoint_free(v->syncpt); + + free(vic); +} + +static const struct vic_ops vic40_ops = { + .fill = vic40_fill, + .blit = vic40_blit, + .flip = vic40_flip, + .execute = vic40_execute, + .free = vic40_free, +}; + +int vic40_new(struct drm_tegra *drm, struct drm_tegra_channel *channel, + struct vic **vicp) +{ + struct vic40 *vic; + void *ptr; + int err; + + vic = calloc(1, sizeof(*vic)); + if (!vic) + return -ENOMEM; + + vic->base.drm = drm; + vic->base.channel = channel; + vic->base.ops = &vic40_ops; + vic->base.version = 0x21; + + err = drm_tegra_syncpoint_new(drm, &vic->base.syncpt); + if (err < 0) { + fprintf(stderr, "failed to allocate syncpoint: %s\n", strerror(-err)); + return err; + } + + err = drm_tegra_bo_new(drm, 0, 16384, &vic->config.bo); + if (err < 0) { + fprintf(stderr, "failed to allocate configuration structurer: %s\n", + strerror(-err)); + return err; + } + + err = drm_tegra_channel_map(channel, vic->config.bo, DRM_TEGRA_CHANNEL_MAP_READ, + &vic->config.map); + if (err < 0) { + fprintf(stderr, "failed to map configuration structure: %s\n", + strerror(-err)); + return err; + } + + err = drm_tegra_bo_new(drm, 0, 16384, &vic->filter.bo); + if (err < 0) { + fprintf(stderr, "failed to allocate filter buffer: %s\n", + strerror(-err)); + return err; + } + + err = drm_tegra_bo_map(vic->filter.bo, &ptr); + if (err < 0) { + fprintf(stderr, "failed to map filter buffer: %s\n", strerror(-err)); + return err; + } + + memset(ptr, 0, 16384); + drm_tegra_bo_unmap(vic->filter.bo); + + err = drm_tegra_channel_map(channel, vic->filter.bo, DRM_TEGRA_CHANNEL_MAP_READ, + &vic->filter.map); + if (err < 0) { + fprintf(stderr, "failed to map filter buffer: %s\n", + strerror(-err)); + return err; + } + + if (vicp) + *vicp = &vic->base; + + return 0; +} diff -Nru libdrm-2.4.110/tests/tegra/vic40.h libdrm-2.4.113/tests/tegra/vic40.h --- libdrm-2.4.110/tests/tegra/vic40.h 1970-01-01 00:00:00.000000000 +0000 +++ libdrm-2.4.113/tests/tegra/vic40.h 2022-08-31 14:38:38.000000000 +0000 @@ -0,0 +1,285 @@ +/* + * Copyright © 2016-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 VIC40_H +#define VIC40_H + +#include + +#define NVB0B6_VIDEO_COMPOSITOR_SET_APPLICATION_ID 0x00000200 +#define NVB0B6_VIDEO_COMPOSITOR_EXECUTE 0x00000300 +#define NVB0B6_VIDEO_COMPOSITOR_SET_SURFACE0_SLOT0_LUMA_OFFSET 0x00000400 +#define NVB0B6_VIDEO_COMPOSITOR_SET_SURFACE0_SLOT0_CHROMA_U_OFFSET 0x00000404 +#define NVB0B6_VIDEO_COMPOSITOR_SET_SURFACE0_SLOT0_CHROMA_V_OFFSET 0x00000408 +#define NVB0B6_VIDEO_COMPOSITOR_SET_CONTROL_PARAMS 0x00000704 +#define NVB0B6_VIDEO_COMPOSITOR_SET_CONFIG_STRUCT_OFFSET 0x00000708 +#define NVB0B6_VIDEO_COMPOSITOR_SET_HIST_OFFSET 0x00000714 +#define NVB0B6_VIDEO_COMPOSITOR_SET_OUTPUT_SURFACE_LUMA_OFFSET 0x00000720 + +typedef struct { + uint64_t SlotEnable : 1; /* 0 */ + uint64_t DeNoise : 1; /* 1 */ + uint64_t AdvancedDenoise : 1; /* 2 */ + uint64_t CadenceDetect : 1; /* 3 */ + uint64_t MotionMap : 1; /* 4 */ + uint64_t MMapCombine : 1; /* 5 */ + uint64_t IsEven : 1; /* 6 */ + uint64_t ChromaEven : 1; /* 7 */ + uint64_t CurrentFieldEnable : 1; /* 8 */ + uint64_t PrevFieldEnable : 1; /* 9 */ + uint64_t NextFieldEnable : 1; /* 10 */ + uint64_t NextNrFieldEnable : 1; /* 11 */ + uint64_t CurMotionFieldEnable : 1; /* 12 */ + uint64_t PrevMotionFieldEnable : 1; /* 13 */ + uint64_t PpMotionFieldEnable : 1; /* 14 */ + uint64_t CombMotionFieldEnable : 1; /* 15 */ + uint64_t FrameFormat : 4; /* 19..16 */ + uint64_t FilterLengthY : 2; /* 21..20 */ + uint64_t FilterLengthX : 2; /* 23..22 */ + uint64_t Panoramic : 12; /* 35..24 */ + uint64_t reserved1 : 22; /* 57..36 */ + uint64_t DetailFltClamp : 6; /* 63..58 */ + uint64_t FilterNoise : 10; /* 73..64 */ + uint64_t FilterDetail : 10; /* 83..74 */ + uint64_t ChromaNoise : 10; /* 93..84 */ + uint64_t ChromaDetail : 10; /* 103..94 */ + uint64_t DeinterlaceMode : 4; /* 107..104 */ + uint64_t MotionAccumWeight : 3; /* 110..108 */ + uint64_t NoiseIir : 11; /* 121..111 */ + uint64_t LightLevel : 4; /* 125..122 */ + uint64_t reserved4 : 2; /* 127..126 */ + /* 128 */ + uint64_t SoftClampLow : 10; /* 9..0 */ + uint64_t SoftClampHigh : 10; /* 19..10 */ + uint64_t reserved5 : 3; /* 22..20 */ + uint64_t reserved6 : 9; /* 31..23 */ + uint64_t PlanarAlpha : 10; /* 41..32 */ + uint64_t ConstantAlpha : 1; /* 42 */ + uint64_t StereoInterleave : 3; /* 45..43 */ + uint64_t ClipEnabled : 1; /* 46 */ + uint64_t ClearRectMask : 8; /* 54..47 */ + uint64_t DegammaMode : 2; /* 56..55 */ + uint64_t reserved7 : 1; /* 57 */ + uint64_t DecompressEnable : 1; /* 58 */ + uint64_t reserved9 : 5; /* 63..59 */ + uint64_t DecompressCtbCount : 8; /* 71..64 */ + uint64_t DecompressZbcColor : 32; /* 103..72 */ + uint64_t reserved12 : 24; /* 127..104 */ + /* 256 */ + uint64_t SourceRectLeft : 30; /* 29..0 */ + uint64_t reserved14 : 2; /* 31..30 */ + uint64_t SourceRectRight : 30; /* 61..32 */ + uint64_t reserved15 : 2; /* 63..62 */ + uint64_t SourceRectTop : 30; /* 93..64 */ + uint64_t reserved16 : 2; /* 95..94 */ + uint64_t SourceRectBottom : 30; /* 125..96 */ + uint64_t reserved17 : 2; /* 127..126 */ + /* 384 */ + uint64_t DestRectLeft : 14; /* 13..0 */ + uint64_t reserved18 : 2; /* 15..14 */ + uint64_t DestRectRight : 14; /* 29..16 */ + uint64_t reserved19 : 2; /* 31..30 */ + uint64_t DestRectTop : 14; /* 45..32 */ + uint64_t reserved20 : 2; /* 47..46 */ + uint64_t DestRectBottom : 14; /* 61..48 */ + uint64_t reserved21 : 2; /* 63..62 */ + uint64_t reserved22 : 32; /* 95..64 */ + uint64_t reserved23 : 32; /* 127..96 */ +} SlotConfig; + +typedef struct { + uint64_t SlotPixelFormat : 7; /* 6..0 */ + uint64_t SlotChromaLocHoriz : 2; /* 8..7 */ + uint64_t SlotChromaLocVert : 2; /* 10..9 */ + uint64_t SlotBlkKind : 4; /* 14..11 */ + uint64_t SlotBlkHeight : 4; /* 18..15 */ + uint64_t SlotCacheWidth : 3; /* 21..19 */ + uint64_t reserved0 : 10; /* 31..22 */ + uint64_t SlotSurfaceWidth : 14; /* 45..32 */ + uint64_t SlotSurfaceHeight : 14; /* 59..46 */ + uint64_t reserved1 : 4; /* 63..60 */ + uint64_t SlotLumaWidth : 14; /* 77..64 */ + uint64_t SlotLumaHeight : 14; /* 91..78 */ + uint64_t reserved2 : 4; /* 95..92 */ + uint64_t SlotChromaWidth : 14; /* 109..96 */ + uint64_t SlotChromaHeight : 14; /* 123..110 */ + uint64_t reserved3 : 4; /* 127..124 */ +} SlotSurfaceConfig; + +typedef struct { + uint64_t luma_coeff0 : 20; /* 19..0 */ + uint64_t luma_coeff1 : 20; /* 39..20 */ + uint64_t luma_coeff2 : 20; /* 59..40 */ + uint64_t luma_r_shift : 4; /* 63..60 */ + uint64_t luma_coeff3 : 20; /* 83..64 */ + uint64_t LumaKeyLower : 10; /* 93..84 */ + uint64_t LumaKeyUpper : 10; /* 103..94 */ + uint64_t LumaKeyEnabled : 1; /* 104 */ + uint64_t reserved0 : 2; /* 106..105 */ + uint64_t reserved1 : 21; /* 127..107 */ +} LumaKeyStruct; + +typedef struct { + uint64_t matrix_coeff00 : 20; /* 19..0 */ + uint64_t matrix_coeff10 : 20; /* 39..20 */ + uint64_t matrix_coeff20 : 20; /* 59..40 */ + uint64_t matrix_r_shift : 4; /* 63..60 */ + uint64_t matrix_coeff01 : 20; /* 83..64 */ + uint64_t matrix_coeff11 : 20; /* 103..84 */ + uint64_t matrix_coeff21 : 20; /* 123..104 */ + uint64_t reserved0 : 3; /* 126..124 */ + uint64_t matrix_enable : 1; /* 127 */ + /* 128 */ + uint64_t matrix_coeff02 : 20; /* 19..0 */ + uint64_t matrix_coeff12 : 20; /* 39..20 */ + uint64_t matrix_coeff22 : 20; /* 59..40 */ + uint64_t reserved1 : 4; /* 63..60 */ + uint64_t matrix_coeff03 : 20; /* 83..64 */ + uint64_t matrix_coeff13 : 20; /* 103..84 */ + uint64_t matrix_coeff23 : 20; /* 123..104 */ + uint64_t reserved2 : 4; /* 127..124 */ +} MatrixStruct; + +typedef struct { + uint64_t ClearRect0Left : 14; /* 13..0 */ + uint64_t reserved0 : 2; /* 15..14 */ + uint64_t ClearRect0Right : 14; /* 29..16 */ + uint64_t reserved1 : 2; /* 31..30 */ + uint64_t ClearRect0Top : 14; /* 45..32 */ + uint64_t reserved2 : 2; /* 47..46 */ + uint64_t ClearRect0Bottom : 14; /* 61..48 */ + uint64_t reserved3 : 2; /* 63..62 */ + uint64_t ClearRect1Left : 14; /* 77..64 */ + uint64_t reserved4 : 2; /* 79..78 */ + uint64_t ClearRect1Right : 14; /* 93..80 */ + uint64_t reserved5 : 2; /* 95..94 */ + uint64_t ClearRect1Top : 14; /* 109..96 */ + uint64_t reserved6 : 2; /* 111..110 */ + uint64_t ClearRect1Bottom : 14; /* 125..112 */ + uint64_t reserved7 : 2; /* 127..126 */ +} ClearRectStruct; + +typedef struct { + uint64_t AlphaK1 : 10; /* 9..0 */ + uint64_t reserved0 : 6; /* 15..10 */ + uint64_t AlphaK2 : 10; /* 25..16 */ + uint64_t reserved1 : 6; /* 31..26 */ + uint64_t SrcFactCMatchSelect : 3; /* 34..32 */ + uint64_t reserved2 : 1; /* 35 */ + uint64_t DstFactCMatchSelect : 3; /* 38..36 */ + uint64_t reserved3 : 1; /* 39 */ + uint64_t SrcFactAMatchSelect : 3; /* 42..40 */ + uint64_t reserved4 : 1; /* 43 */ + uint64_t DstFactAMatchSelect : 3; /* 46..44 */ + uint64_t reserved5 : 1; /* 47 */ + uint64_t reserved6 : 4; /* 51..48 */ + uint64_t reserved7 : 4; /* 55..52 */ + uint64_t reserved8 : 4; /* 59..56 */ + uint64_t reserved9 : 4; /* 63..60 */ + uint64_t reserved10 : 2; /* 65..64 */ + uint64_t OverrideR : 10; /* 75..66 */ + uint64_t OverrideG : 10; /* 85..76 */ + uint64_t OverrideB : 10; /* 95..86 */ + uint64_t OverrideA : 10; /* 105..96 */ + uint64_t reserved11 : 2; /* 107..106 */ + uint64_t UseOverrideR : 1; /* 108 */ + uint64_t UseOverrideG : 1; /* 109 */ + uint64_t UseOverrideB : 1; /* 110 */ + uint64_t UseOverrideA : 1; /* 111 */ + uint64_t MaskR : 1; /* 112 */ + uint64_t MaskG : 1; /* 113 */ + uint64_t MaskB : 1; /* 114 */ + uint64_t MaskA : 1; /* 115 */ + uint64_t reserved12 : 12; /* 127..116 */ +} BlendingSlotStruct; + +typedef struct { + uint64_t AlphaFillMode : 3; /* 2..0 */ + uint64_t AlphaFillSlot : 3; /* 5..3 */ + uint64_t BackgroundAlpha : 10; /* 15..6 */ + uint64_t BackgroundR : 10; /* 25..16 */ + uint64_t BackgroundG : 10; /* 35..26 */ + uint64_t BackgroundB : 10; /* 45..36 */ + uint64_t RegammaMode : 2; /* 47..46 */ + uint64_t OutputFlipX : 1; /* 48 */ + uint64_t OutputFlipY : 1; /* 49 */ + uint64_t OutputTranspose : 1; /* 50 */ + uint64_t reserved1 : 1; /* 51 */ + uint64_t reserved2 : 12; /* 63..52 */ + uint64_t TargetRectLeft : 14; /* 77..64 */ + uint64_t reserved3 : 2; /* 79..78 */ + uint64_t TargetRectRight : 14; /* 93..80 */ + uint64_t reserved4 : 2; /* 95..94 */ + uint64_t TargetRectTop : 14; /* 109..96 */ + uint64_t reserved5 : 2; /* 111..110 */ + uint64_t TargetRectBottom : 14; /* 125..112 */ + uint64_t reserved6 : 2; /* 127..126 */ +} OutputConfig; + +typedef struct { + uint64_t OutPixelFormat : 7; /* 6..0 */ + uint64_t OutChromaLocHoriz : 2; /* 8..7 */ + uint64_t OutChromaLocVert : 2; /* 10..9 */ + uint64_t OutBlkKind : 4; /* 14..11 */ + uint64_t OutBlkHeight : 4; /* 18..15 */ + uint64_t reserved0 : 3; /* 21..19 */ + uint64_t reserved1 : 10; /* 31..22 */ + uint64_t OutSurfaceWidth : 14; /* 45..32 */ + uint64_t OutSurfaceHeight : 14; /* 59..46 */ + uint64_t reserved2 : 4; /* 63..60 */ + uint64_t OutLumaWidth : 14; /* 77..64 */ + uint64_t OutLumaHeight : 14; /* 91..78 */ + uint64_t reserved3 : 4; /* 95..92 */ + uint64_t OutChromaWidth : 14; /* 109..96 */ + uint64_t OutChromaHeight : 14; /* 123..110 */ + uint64_t reserved4 : 4; /* 127..124 */ +} OutputSurfaceConfig; + +typedef struct { + uint64_t DownsampleHoriz : 11; /* 10..0 */ + uint64_t reserved0 : 5; /* 15..11 */ + uint64_t DownsampleVert : 11; /* 26..16 */ + uint64_t reserved1 : 5; /* 31..27 */ + uint64_t reserved2 : 32; /* 63..32 */ + uint64_t reserved3 : 32; /* 95..64 */ + uint64_t reserved4 : 32; /* 127..96 */ +} PipeConfig; + +typedef struct { + SlotConfig slotConfig; + SlotSurfaceConfig slotSurfaceConfig; + LumaKeyStruct lumaKeyStruct; + MatrixStruct colorMatrixStruct; + MatrixStruct gamutMatrixStruct; + BlendingSlotStruct blendingSlotStruct; +} SlotStruct; + +typedef struct { + PipeConfig pipeConfig; + OutputConfig outputConfig; + OutputSurfaceConfig outputSurfaceConfig; + MatrixStruct outColorMatrixStruct; + ClearRectStruct clearRectStruct[4]; + SlotStruct slotStruct[8]; +} ConfigStruct; + +#endif diff -Nru libdrm-2.4.110/tests/tegra/vic41.c libdrm-2.4.113/tests/tegra/vic41.c --- libdrm-2.4.110/tests/tegra/vic41.c 1970-01-01 00:00:00.000000000 +0000 +++ libdrm-2.4.113/tests/tegra/vic41.c 2022-08-31 14:38:38.000000000 +0000 @@ -0,0 +1,342 @@ +/* + * 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 +#include + +#include "private.h" +#include "tegra.h" +#include "vic.h" +#include "vic41.h" + +struct vic41 { + struct vic base; + + struct { + struct drm_tegra_mapping *map; + struct drm_tegra_bo *bo; + } config; + + struct { + struct drm_tegra_mapping *map; + struct drm_tegra_bo *bo; + } filter; +}; + +static int vic41_fill(struct vic *v, struct vic_image *output, + unsigned int left, unsigned int top, + unsigned int right, unsigned int bottom, + unsigned int alpha, unsigned int red, + unsigned int green, unsigned int blue) +{ + struct vic41 *vic = container_of(v, struct vic41, base); + ConfigStruct *c; + int err; + + err = drm_tegra_bo_map(vic->config.bo, (void **)&c); + if (err < 0) { + fprintf(stderr, "failed to map configuration structure: %s\n", + strerror(-err)); + return err; + } + + memset(c, 0, sizeof(*c)); + + c->outputConfig.TargetRectTop = top; + c->outputConfig.TargetRectLeft = left; + c->outputConfig.TargetRectRight = right; + c->outputConfig.TargetRectBottom = bottom; + c->outputConfig.BackgroundAlpha = alpha; + c->outputConfig.BackgroundR = red; + c->outputConfig.BackgroundG = green; + c->outputConfig.BackgroundB = blue; + + c->outputSurfaceConfig.OutPixelFormat = output->format; + c->outputSurfaceConfig.OutBlkKind = output->kind; + c->outputSurfaceConfig.OutBlkHeight = 0; + c->outputSurfaceConfig.OutSurfaceWidth = output->width - 1; + c->outputSurfaceConfig.OutSurfaceHeight = output->height - 1; + c->outputSurfaceConfig.OutLumaWidth = output->stride - 1; + c->outputSurfaceConfig.OutLumaHeight = output->height - 1; + c->outputSurfaceConfig.OutChromaWidth = 16383; + c->outputSurfaceConfig.OutChromaHeight = 16383; + + drm_tegra_bo_unmap(vic->config.bo); + + return 0; +} + +static int vic41_blit(struct vic *v, struct vic_image *output, + struct vic_image *input) +{ + struct vic41 *vic = container_of(v, struct vic41, base); + SlotSurfaceConfig *surface; + SlotConfig *slot; + ConfigStruct *c; + int err; + + err = drm_tegra_bo_map(vic->config.bo, (void **)&c); + if (err < 0) { + fprintf(stderr, "failed to map configuration structure: %s\n", + strerror(-err)); + return err; + } + + memset(c, 0, sizeof(*c)); + + c->outputConfig.TargetRectTop = 0; + c->outputConfig.TargetRectLeft = 0; + c->outputConfig.TargetRectRight = output->width - 1; + c->outputConfig.TargetRectBottom = output->height - 1; + c->outputConfig.BackgroundAlpha = 255; + c->outputConfig.BackgroundR = 1023; + c->outputConfig.BackgroundG = 1023; + c->outputConfig.BackgroundB = 1023; + + c->outputSurfaceConfig.OutPixelFormat = output->format; + c->outputSurfaceConfig.OutBlkKind = output->kind; + c->outputSurfaceConfig.OutBlkHeight = 0; + c->outputSurfaceConfig.OutSurfaceWidth = output->width - 1; + c->outputSurfaceConfig.OutSurfaceHeight = output->height - 1; + c->outputSurfaceConfig.OutLumaWidth = output->stride - 1; + c->outputSurfaceConfig.OutLumaHeight = output->height - 1; + c->outputSurfaceConfig.OutChromaWidth = 16383; + c->outputSurfaceConfig.OutChromaHeight = 16383; + + slot = &c->slotStruct[0].slotConfig; + slot->SlotEnable = 1; + slot->CurrentFieldEnable = 1; + slot->PlanarAlpha = 255; + slot->ConstantAlpha = 1; + slot->SourceRectLeft = 0 << 16; + slot->SourceRectRight = (input->width - 1) << 16; + slot->SourceRectTop = 0 << 16; + slot->SourceRectBottom = (input->height - 1) << 16; + slot->DestRectLeft = 0; + slot->DestRectRight = output->width - 1; + slot->DestRectTop = 0; + slot->DestRectBottom = output->height - 1; + slot->SoftClampHigh = 1023; + + surface = &c->slotStruct[0].slotSurfaceConfig; + surface->SlotPixelFormat = input->format; + surface->SlotBlkKind = input->kind; + surface->SlotBlkHeight = 0; /* XXX */ + surface->SlotCacheWidth = VIC_CACHE_WIDTH_64Bx4; /* XXX */ + surface->SlotSurfaceWidth = input->width - 1; + surface->SlotSurfaceHeight = input->height - 1; + surface->SlotLumaWidth = input->stride - 1; + surface->SlotLumaHeight = input->height - 1; + surface->SlotChromaWidth = 16383; + surface->SlotChromaHeight = 16383; + + drm_tegra_bo_unmap(vic->config.bo); + + return 0; +} + +static int vic41_flip(struct vic *v, struct vic_image *output, + struct vic_image *input) +{ + struct vic41 *vic = container_of(v, struct vic41, base); + SlotSurfaceConfig *surface; + SlotConfig *slot; + ConfigStruct *c; + int err; + + err = drm_tegra_bo_map(vic->config.bo, (void **)&c); + if (err < 0) { + fprintf(stderr, "failed to map configuration structure: %s\n", + strerror(-err)); + return err; + } + + memset(c, 0, sizeof(*c)); + + c->outputConfig.TargetRectTop = 0; + c->outputConfig.TargetRectLeft = 0; + c->outputConfig.TargetRectRight = output->width - 1; + c->outputConfig.TargetRectBottom = output->height - 1; + c->outputConfig.BackgroundAlpha = 255; + c->outputConfig.BackgroundR = 1023; + c->outputConfig.BackgroundG = 1023; + c->outputConfig.BackgroundB = 1023; + c->outputConfig.OutputFlipY = 1; + + c->outputSurfaceConfig.OutPixelFormat = output->format; + c->outputSurfaceConfig.OutBlkKind = output->kind; + c->outputSurfaceConfig.OutBlkHeight = 0; + c->outputSurfaceConfig.OutSurfaceWidth = output->width - 1; + c->outputSurfaceConfig.OutSurfaceHeight = output->height - 1; + c->outputSurfaceConfig.OutLumaWidth = output->stride - 1; + c->outputSurfaceConfig.OutLumaHeight = output->height - 1; + c->outputSurfaceConfig.OutChromaWidth = 16383; + c->outputSurfaceConfig.OutChromaHeight = 16383; + + slot = &c->slotStruct[0].slotConfig; + slot->SlotEnable = 1; + slot->CurrentFieldEnable = 1; + slot->PlanarAlpha = 255; + slot->ConstantAlpha = 1; + slot->SourceRectLeft = 0 << 16; + slot->SourceRectRight = (input->width - 1) << 16; + slot->SourceRectTop = 0 << 16; + slot->SourceRectBottom = (input->height - 1) << 16; + slot->DestRectLeft = 0; + slot->DestRectRight = output->width - 1; + slot->DestRectTop = 0; + slot->DestRectBottom = output->height - 1; + slot->SoftClampHigh = 1023; + + surface = &c->slotStruct[0].slotSurfaceConfig; + surface->SlotPixelFormat = input->format; + surface->SlotBlkKind = input->kind; + surface->SlotBlkHeight = 0; /* XXX */ + surface->SlotCacheWidth = VIC_CACHE_WIDTH_64Bx4; /* XXX */ + surface->SlotSurfaceWidth = input->width - 1; + surface->SlotSurfaceHeight = input->height - 1; + surface->SlotLumaWidth = input->stride - 1; + surface->SlotLumaHeight = input->height - 1; + surface->SlotChromaWidth = 16383; + surface->SlotChromaHeight = 16383; + + drm_tegra_bo_unmap(vic->config.bo); + + return 0; +} + +static int vic41_execute(struct vic *v, struct drm_tegra_pushbuf *pushbuf, + uint32_t **ptrp, struct vic_image *output, + struct vic_image **inputs, unsigned int num_inputs) +{ + struct vic41 *vic = container_of(v, struct vic41, base); + unsigned int i; + + if (num_inputs > 1) + return -EINVAL; + + VIC_PUSH_METHOD(pushbuf, ptrp, NVB1B6_VIDEO_COMPOSITOR_SET_APPLICATION_ID, 1); + VIC_PUSH_METHOD(pushbuf, ptrp, NVB1B6_VIDEO_COMPOSITOR_SET_CONTROL_PARAMS, (sizeof(ConfigStruct) / 16) << 16); + VIC_PUSH_BUFFER(pushbuf, ptrp, NVB1B6_VIDEO_COMPOSITOR_SET_CONFIG_STRUCT_OFFSET, vic->config.map, 0, 0); + VIC_PUSH_BUFFER(pushbuf, ptrp, NVB1B6_VIDEO_COMPOSITOR_SET_FILTER_STRUCT_OFFSET, vic->filter.map, 0, 0); + VIC_PUSH_BUFFER(pushbuf, ptrp, NVB1B6_VIDEO_COMPOSITOR_SET_OUTPUT_SURFACE_LUMA_OFFSET, output->map, 0, 0); + + for (i = 0; i < num_inputs; i++) { + uint32_t method = NVB1B6_VIDEO_COMPOSITOR_SET_SURFACE0_LUMA_OFFSET(0) + (i * 3) * 4; + + VIC_PUSH_BUFFER(pushbuf, ptrp, method, inputs[i]->map, 0, 0); + } + + VIC_PUSH_METHOD(pushbuf, ptrp, NVB1B6_VIDEO_COMPOSITOR_EXECUTE, 1 << 8); + + return 0; +} + +static void vic41_free(struct vic *v) +{ + struct vic41 *vic = container_of(v, struct vic41, base); + + drm_tegra_channel_unmap(vic->filter.map); + drm_tegra_bo_unref(vic->filter.bo); + + drm_tegra_channel_unmap(vic->config.map); + drm_tegra_bo_unref(vic->config.bo); + + drm_tegra_syncpoint_free(v->syncpt); + + free(vic); +} + +static const struct vic_ops vic41_ops = { + .fill = vic41_fill, + .blit = vic41_blit, + .flip = vic41_flip, + .execute = vic41_execute, + .free = vic41_free, +}; + +int vic41_new(struct drm_tegra *drm, struct drm_tegra_channel *channel, + struct vic **vicp) +{ + struct vic41 *vic; + void *ptr; + int err; + + vic = calloc(1, sizeof(*vic)); + if (!vic) + return -ENOMEM; + + vic->base.drm = drm; + vic->base.channel = channel; + vic->base.ops = &vic41_ops; + vic->base.version = 0x18; + + err = drm_tegra_syncpoint_new(drm, &vic->base.syncpt); + if (err < 0) { + fprintf(stderr, "failed to allocate syncpoint: %s\n", strerror(-err)); + return err; + } + + err = drm_tegra_bo_new(drm, 0, 16384, &vic->config.bo); + if (err < 0) { + fprintf(stderr, "failed to allocate configuration structurer: %s\n", + strerror(-err)); + return err; + } + + err = drm_tegra_channel_map(channel, vic->config.bo, DRM_TEGRA_CHANNEL_MAP_READ, + &vic->config.map); + if (err < 0) { + fprintf(stderr, "failed to map configuration structure: %s\n", + strerror(-err)); + return err; + } + + err = drm_tegra_bo_new(drm, 0, 16384, &vic->filter.bo); + if (err < 0) { + fprintf(stderr, "failed to allocate filter buffer: %s\n", + strerror(-err)); + return err; + } + + err = drm_tegra_bo_map(vic->filter.bo, &ptr); + if (err < 0) { + fprintf(stderr, "failed to map filter buffer: %s\n", strerror(-err)); + return err; + } + + memset(ptr, 0, 16384); + drm_tegra_bo_unmap(vic->filter.bo); + + err = drm_tegra_channel_map(channel, vic->filter.bo, DRM_TEGRA_CHANNEL_MAP_READ, + &vic->filter.map); + if (err < 0) { + fprintf(stderr, "failed to map filter buffer: %s\n", + strerror(-err)); + return err; + } + + if (vicp) + *vicp = &vic->base; + + return 0; +} diff -Nru libdrm-2.4.110/tests/tegra/vic41.h libdrm-2.4.113/tests/tegra/vic41.h --- libdrm-2.4.110/tests/tegra/vic41.h 1970-01-01 00:00:00.000000000 +0000 +++ libdrm-2.4.113/tests/tegra/vic41.h 2022-08-31 14:38:38.000000000 +0000 @@ -0,0 +1,372 @@ +/* + * 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 VIC41_H +#define VIC41_H + +#include + +#define NVB1B6_VIDEO_COMPOSITOR_SET_APPLICATION_ID 0x00000200 +#define NVB1B6_VIDEO_COMPOSITOR_EXECUTE 0x00000300 +#define NVB1B6_VIDEO_COMPOSITOR_SET_PICTURE_INDEX 0x00000700 +#define NVB1B6_VIDEO_COMPOSITOR_SET_CONTROL_PARAMS 0x00000704 +#define NVB1B6_VIDEO_COMPOSITOR_SET_CONFIG_STRUCT_OFFSET 0x00000708 +#define NVB1B6_VIDEO_COMPOSITOR_SET_FILTER_STRUCT_OFFSET 0x0000070c +#define NVB1B6_VIDEO_COMPOSITOR_SET_HIST_OFFSET 0x00000714 +#define NVB1B6_VIDEO_COMPOSITOR_SET_OUTPUT_SURFACE_LUMA_OFFSET 0x00000720 +#define NVB1B6_VIDEO_COMPOSITOR_SET_HISTORY_BUFFER_OFFSET(slot) (0x00000780 + (slot) * 4) +#define NVB1B6_VIDEO_COMPOSITOR_SET_SURFACE0_LUMA_OFFSET(slot) (0x00001200 + (slot) * 0x00000060) +#define NVB1B6_VIDEO_COMPOSITOR_SET_SURFACE0_CHROMA_U_OFFSET(slot) (0x00001204 + (slot) * 0x00000060) +#define NVB1B6_VIDEO_COMPOSITOR_SET_SURFACE0_CHROMA_V_OFFSET(slot) (0x00001208 + (slot) * 0x00000060) +#define NVB1B6_VIDEO_COMPOSITOR_SET_SURFACE1_LUMA_OFFSET(slot) (0x0000120c + (slot) * 0x00000060) +#define NVB1B6_VIDEO_COMPOSITOR_SET_SURFACE1_CHROMA_U_OFFSET(slot) (0x00001210 + (slot) * 0x00000060) +#define NVB1B6_VIDEO_COMPOSITOR_SET_SURFACE1_CHROMA_V_OFFSET(slot) (0x00001214 + (slot) * 0x00000060) +#define NVB1B6_VIDEO_COMPOSITOR_SET_SURFACE2_LUMA_OFFSET(slot) (0x00001218 + (slot) * 0x00000060) +#define NVB1B6_VIDEO_COMPOSITOR_SET_SURFACE2_CHROMA_U_OFFSET(slot) (0x0000121c + (slot) * 0x00000060) +#define NVB1B6_VIDEO_COMPOSITOR_SET_SURFACE2_CHROMA_V_OFFSET(slot) (0x00001220 + (slot) * 0x00000060) +#define NVB1B6_VIDEO_COMPOSITOR_SET_SURFACE3_LUMA_OFFSET(slot) (0x00001224 + (slot) * 0x00000060) +#define NVB1B6_VIDEO_COMPOSITOR_SET_SURFACE3_CHROMA_U_OFFSET(slot) (0x00001228 + (slot) * 0x00000060) +#define NVB1B6_VIDEO_COMPOSITOR_SET_SURFACE3_CHROMA_V_OFFSET(slot) (0x0000122c + (slot) * 0x00000060) +#define NVB1B6_VIDEO_COMPOSITOR_SET_SURFACE4_LUMA_OFFSET(slot) (0x00001230 + (slot) * 0x00000060) +#define NVB1B6_VIDEO_COMPOSITOR_SET_SURFACE4_CHROMA_U_OFFSET(slot) (0x00001234 + (slot) * 0x00000060) +#define NVB1B6_VIDEO_COMPOSITOR_SET_SURFACE4_CHROMA_V_OFFSET(slot) (0x00001238 + (slot) * 0x00000060) +#define NVB1B6_VIDEO_COMPOSITOR_SET_SURFACE5_LUMA_OFFSET(slot) (0x0000123c + (slot) * 0x00000060) +#define NVB1B6_VIDEO_COMPOSITOR_SET_SURFACE5_CHROMA_U_OFFSET(slot) (0x00001240 + (slot) * 0x00000060) +#define NVB1B6_VIDEO_COMPOSITOR_SET_SURFACE5_CHROMA_V_OFFSET(slot) (0x00001244 + (slot) * 0x00000060) +#define NVB1B6_VIDEO_COMPOSITOR_SET_SURFACE6_LUMA_OFFSET(slot) (0x00001248 + (slot) * 0x00000060) +#define NVB1B6_VIDEO_COMPOSITOR_SET_SURFACE6_CHROMA_U_OFFSET(slot) (0x0000124c + (slot) * 0x00000060) +#define NVB1B6_VIDEO_COMPOSITOR_SET_SURFACE6_CHROMA_V_OFFSET(slot) (0x00001250 + (slot) * 0x00000060) +#define NVB1B6_VIDEO_COMPOSITOR_SET_SURFACE7_LUMA_OFFSET(slot) (0x00001254 + (slot) * 0x00000060) +#define NVB1B6_VIDEO_COMPOSITOR_SET_SURFACE7_CHROMA_U_OFFSET(slot) (0x00001258 + (slot) * 0x00000060) +#define NVB1B6_VIDEO_COMPOSITOR_SET_SURFACE7_CHROMA_V_OFFSET(slot) (0x0000125c + (slot) * 0x00000060) + +typedef struct { + uint64_t SlotEnable : 1; /* 0 */ + uint64_t DeNoise : 1; /* 1 */ + uint64_t AdvancedDenoise : 1; /* 2 */ + uint64_t CadenceDetect : 1; /* 3 */ + uint64_t MotionMap : 1; /* 4 */ + uint64_t MMapCombine : 1; /* 5 */ + uint64_t IsEven : 1; /* 6 */ + uint64_t ChromaEven : 1; /* 7 */ + uint64_t CurrentFieldEnable : 1; /* 8 */ + uint64_t PrevFieldEnable : 1; /* 9 */ + uint64_t NextFieldEnable : 1; /* 10 */ + uint64_t NextNrFieldEnable : 1; /* 11 */ + uint64_t CurMotionFieldEnable : 1; /* 12 */ + uint64_t PrevMotionFieldEnable : 1; /* 13 */ + uint64_t PpMotionFieldEnable : 1; /* 14 */ + uint64_t CombMotionFieldEnable : 1; /* 15 */ + uint64_t FrameFormat : 4; /* 19..16 */ + uint64_t FilterLengthY : 2; /* 21..20 */ + uint64_t FilterLengthX : 2; /* 23..22 */ + uint64_t Panoramic : 12; /* 35..24 */ + uint64_t ChromaUpLengthY : 2; /* 37..36 */ + uint64_t ChromaUpLengthX : 2; /* 39..38 */ + uint64_t reserved1 : 18; /* 57..40 */ + uint64_t DetailFltClamp : 6; /* 63..58 */ + uint64_t FilterNoise : 10; /* 73..64 */ + uint64_t FilterDetail : 10; /* 83..74 */ + uint64_t ChromaNoise : 10; /* 93..84 */ + uint64_t ChromaDetail : 10; /* 103..94 */ + uint64_t DeinterlaceMode : 4; /* 107..104 */ + uint64_t MotionAccumWeight : 3; /* 110..108 */ + uint64_t NoiseIir : 11; /* 121..111 */ + uint64_t LightLevel : 4; /* 125..122 */ + uint64_t reserved4 : 2; /* 127..126 */ + /* 128 */ + uint64_t SoftClampLow : 10; /* 9..0 */ + uint64_t SoftClampHigh : 10; /* 19..10 */ + uint64_t reserved5 : 12; /* 31..20 */ + uint64_t reserved6 : 2; /* 33..32 */ + uint64_t PlanarAlpha : 8; /* 41..34 */ + uint64_t ConstantAlpha : 1; /* 42 */ + uint64_t StereoInterleave : 3; /* 45..43 */ + uint64_t ClipEnabled : 1; /* 46 */ + uint64_t ClearRectMask : 8; /* 54..47 */ + uint64_t DegammaMode : 2; /* 56..55 */ + uint64_t reserved7 : 1; /* 57 */ + uint64_t DecompressEnable : 1; /* 58 */ + uint64_t DecompressKind : 4; /* 62..59 */ + uint64_t reserved9 : 1; /* 63 */ + uint64_t DecompressCtbCount : 8; /* 71..64 */ + uint64_t DecompressZbcColor : 32; /* 103..72 */ + uint64_t reserved12 : 24; /* 127..104 */ + /* 256 */ + uint64_t SourceRectLeft : 30; /* 29..0 */ + uint64_t reserved14 : 2; /* 31..30 */ + uint64_t SourceRectRight : 30; /* 61..32 */ + uint64_t reserved15 : 2; /* 63..62 */ + uint64_t SourceRectTop : 30; /* 93..64 */ + uint64_t reserved16 : 2; /* 95..94 */ + uint64_t SourceRectBottom : 30; /* 125..96 */ + uint64_t reserved17 : 2; /* 127..126 */ + /* 384 */ + uint64_t DestRectLeft : 14; /* 13..0 */ + uint64_t reserved18 : 2; /* 15..14 */ + uint64_t DestRectRight : 14; /* 29..16 */ + uint64_t reserved19 : 2; /* 31..30 */ + uint64_t DestRectTop : 14; /* 45..32 */ + uint64_t reserved20 : 2; /* 47..46 */ + uint64_t DestRectBottom : 14; /* 61..48 */ + uint64_t reserved21 : 2; /* 63..62 */ + uint64_t reserved22 : 32; /* 95..64 */ + uint64_t reserved23 : 32; /* 127..96 */ +} SlotConfig; + +typedef struct { + uint64_t SlotPixelFormat : 7; /* 6..0 */ + uint64_t SlotChromaLocHoriz : 2; /* 8..7 */ + uint64_t SlotChromaLocVert : 2; /* 10..9 */ + uint64_t SlotBlkKind : 4; /* 14..11 */ + uint64_t SlotBlkHeight : 4; /* 18..15 */ + uint64_t SlotCacheWidth : 3; /* 21..19 */ + uint64_t reserved0 : 10; /* 31..22 */ + uint64_t SlotSurfaceWidth : 14; /* 45..32 */ + uint64_t SlotSurfaceHeight : 14; /* 59..46 */ + uint64_t reserved1 : 4; /* 63..60 */ + uint64_t SlotLumaWidth : 14; /* 77..64 */ + uint64_t SlotLumaHeight : 14; /* 91..78 */ + uint64_t reserved2 : 4; /* 95..92 */ + uint64_t SlotChromaWidth : 14; /* 109..96 */ + uint64_t SlotChromaHeight : 14; /* 123..110 */ + uint64_t reserved3 : 4; /* 127..124 */ +} SlotSurfaceConfig; + +typedef struct { + uint64_t luma_coeff0 : 20; /* 19..0 */ + uint64_t luma_coeff1 : 20; /* 39..20 */ + uint64_t luma_coeff2 : 20; /* 59..40 */ + uint64_t luma_r_shift : 4; /* 63..60 */ + uint64_t luma_coeff3 : 20; /* 83..64 */ + uint64_t LumaKeyLower : 10; /* 93..84 */ + uint64_t LumaKeyUpper : 10; /* 103..94 */ + uint64_t LumaKeyEnabled : 1; /* 104 */ + uint64_t reserved0 : 2; /* 106..105 */ + uint64_t reserved1 : 21; /* 127..107 */ +} LumaKeyStruct; + +typedef struct { + uint64_t matrix_coeff00 : 20; /* 19..0 */ + uint64_t matrix_coeff10 : 20; /* 39..20 */ + uint64_t matrix_coeff20 : 20; /* 59..40 */ + uint64_t matrix_r_shift : 4; /* 63..60 */ + uint64_t matrix_coeff01 : 20; /* 83..64 */ + uint64_t matrix_coeff11 : 20; /* 103..84 */ + uint64_t matrix_coeff21 : 20; /* 123..104 */ + uint64_t reserved0 : 3; /* 126..124 */ + uint64_t matrix_enable : 1; /* 127 */ + /* 128 */ + uint64_t matrix_coeff02 : 20; /* 19..0 */ + uint64_t matrix_coeff12 : 20; /* 39..20 */ + uint64_t matrix_coeff22 : 20; /* 59..40 */ + uint64_t reserved1 : 4; /* 63..60 */ + uint64_t matrix_coeff03 : 20; /* 83..64 */ + uint64_t matrix_coeff13 : 20; /* 103..84 */ + uint64_t matrix_coeff23 : 20; /* 123..104 */ + uint64_t reserved2 : 4; /* 127..124 */ +} MatrixStruct; + +typedef struct { + uint64_t ClearRect0Left : 14; /* 13..0 */ + uint64_t reserved0 : 2; /* 15..14 */ + uint64_t ClearRect0Right : 14; /* 29..16 */ + uint64_t reserved1 : 2; /* 31..30 */ + uint64_t ClearRect0Top : 14; /* 45..32 */ + uint64_t reserved2 : 2; /* 47..46 */ + uint64_t ClearRect0Bottom : 14; /* 61..48 */ + uint64_t reserved3 : 2; /* 63..62 */ + uint64_t ClearRect1Left : 14; /* 77..64 */ + uint64_t reserved4 : 2; /* 79..78 */ + uint64_t ClearRect1Right : 14; /* 93..80 */ + uint64_t reserved5 : 2; /* 95..94 */ + uint64_t ClearRect1Top : 14; /* 109..96 */ + uint64_t reserved6 : 2; /* 111..110 */ + uint64_t ClearRect1Bottom : 14; /* 125..112 */ + uint64_t reserved7 : 2; /* 127..126 */ +} ClearRectStruct; + +typedef struct { + uint64_t reserved0 : 2; /* 1..0 */ + uint64_t AlphaK1 : 8; /* 9..2 */ + uint64_t reserved1 : 6; /* 17..10 */ + uint64_t AlphaK2 : 8; /* 25..18 */ + uint64_t reserved2 : 6; /* 31..26 */ + uint64_t SrcFactCMatchSelect : 3; /* 34..32 */ + uint64_t reserved3 : 1; /* 35 */ + uint64_t DstFactCMatchSelect : 3; /* 38..36 */ + uint64_t reserved4 : 1; /* 39 */ + uint64_t SrcFactAMatchSelect : 3; /* 42..40 */ + uint64_t reserved5 : 1; /* 43 */ + uint64_t DstFactAMatchSelect : 3; /* 46..44 */ + uint64_t reserved6 : 1; /* 47 */ + uint64_t reserved7 : 4; /* 51..48 */ + uint64_t reserved8 : 4; /* 55..52 */ + uint64_t reserved9 : 4; /* 59..56 */ + uint64_t reserved10 : 4; /* 63..60 */ + uint64_t reserved11 : 2; /* 65..64 */ + uint64_t OverrideR : 10; /* 75..66 */ + uint64_t OverrideG : 10; /* 85..76 */ + uint64_t OverrideB : 10; /* 95..86 */ + uint64_t reserved12 : 2; /* 97..96 */ + uint64_t OverrideA : 8; /* 105..98 */ + uint64_t reserved13 : 2; /* 107..106 */ + uint64_t UseOverrideR : 1; /* 108 */ + uint64_t UseOverrideG : 1; /* 109 */ + uint64_t UseOverrideB : 1; /* 110 */ + uint64_t UseOverrideA : 1; /* 111 */ + uint64_t MaskR : 1; /* 112 */ + uint64_t MaskG : 1; /* 113 */ + uint64_t MaskB : 1; /* 114 */ + uint64_t MaskA : 1; /* 115 */ + uint64_t reserved14 : 12; /* 127..116 */ +} BlendingSlotStruct; + +typedef struct { + uint64_t AlphaFillMode : 3; /* 2..0 */ + uint64_t AlphaFillSlot : 3; /* 5..3 */ + uint64_t reserved0 : 2; /* 6..5 */ + uint64_t BackgroundAlpha : 8; /* 15..7 */ + uint64_t BackgroundR : 10; /* 25..16 */ + uint64_t BackgroundG : 10; /* 35..26 */ + uint64_t BackgroundB : 10; /* 45..36 */ + uint64_t RegammaMode : 2; /* 47..46 */ + uint64_t OutputFlipX : 1; /* 48 */ + uint64_t OutputFlipY : 1; /* 49 */ + uint64_t OutputTranspose : 1; /* 50 */ + uint64_t reserved1 : 1; /* 51 */ + uint64_t reserved2 : 12; /* 63..52 */ + uint64_t TargetRectLeft : 14; /* 77..64 */ + uint64_t reserved3 : 2; /* 79..78 */ + uint64_t TargetRectRight : 14; /* 93..80 */ + uint64_t reserved4 : 2; /* 95..94 */ + uint64_t TargetRectTop : 14; /* 109..96 */ + uint64_t reserved5 : 2; /* 111..110 */ + uint64_t TargetRectBottom : 14; /* 125..112 */ + uint64_t reserved6 : 2; /* 127..126 */ +} OutputConfig; + +typedef struct { + uint64_t OutPixelFormat : 7; /* 6..0 */ + uint64_t OutChromaLocHoriz : 2; /* 8..7 */ + uint64_t OutChromaLocVert : 2; /* 10..9 */ + uint64_t OutBlkKind : 4; /* 14..11 */ + uint64_t OutBlkHeight : 4; /* 18..15 */ + uint64_t reserved0 : 3; /* 21..19 */ + uint64_t reserved1 : 10; /* 31..22 */ + uint64_t OutSurfaceWidth : 14; /* 45..32 */ + uint64_t OutSurfaceHeight : 14; /* 59..46 */ + uint64_t reserved2 : 4; /* 63..60 */ + uint64_t OutLumaWidth : 14; /* 77..64 */ + uint64_t OutLumaHeight : 14; /* 91..78 */ + uint64_t reserved3 : 4; /* 95..92 */ + uint64_t OutChromaWidth : 14; /* 109..96 */ + uint64_t OutChromaHeight : 14; /* 123..110 */ + uint64_t reserved4 : 4; /* 127..124 */ +} OutputSurfaceConfig; + +typedef struct { + uint64_t f00 : 10; /* 9..0 */ + uint64_t f10 : 10; /* 19..10 */ + uint64_t f20 : 10; /* 29..20 */ + uint64_t reserved0 : 2; /* 31..30 */ + uint64_t f01 : 10; /* 41..32 */ + uint64_t f11 : 10; /* 51..42 */ + uint64_t f21 : 10; /* 61..52 */ + uint64_t reserved1 : 2; /* 63..62 */ + uint64_t f02 : 10; /* 73..64 */ + uint64_t f12 : 10; /* 83..74 */ + uint64_t f22 : 10; /* 93..84 */ + uint64_t reserved2 : 2; /* 95..94 */ + uint64_t f03 : 10; /* 105..96 */ + uint64_t f13 : 10; /* 115..106 */ + uint64_t f23 : 10; /* 125..116 */ + uint64_t reserved3 : 2; /* 127..126 */ +} FilterCoeffStruct; + +typedef struct { + uint64_t DownsampleHoriz : 11; /* 10..0 */ + uint64_t reserved0 : 5; /* 15..11 */ + uint64_t DownsampleVert : 11; /* 26..16 */ + uint64_t reserved1 : 5; /* 31..27 */ + uint64_t reserved2 : 32; /* 63..32 */ + uint64_t reserved3 : 32; /* 95..64 */ + uint64_t reserved4 : 32; /* 127..96 */ +} PipeConfig; + +typedef struct { + uint64_t OldCadence : 32; /* 31..0 */ + uint64_t OldDiff : 32; /* 63..32 */ + uint64_t OldWeave : 32; /* 95..64 */ + uint64_t OlderWeave : 32; /* 127..96 */ +} SlotHistoryBuffer; + +typedef struct { + uint64_t crc0 : 32; /* 31..0 */ + uint64_t crc1 : 32; /* 63..32 */ + uint64_t crc2 : 32; /* 95..64 */ + uint64_t crc3 : 32; /* 127..96 */ +} PartitionCrcStruct; + +typedef struct { + uint64_t crc0 : 32; /* 31..0 */ + uint64_t crc1 : 32; /* 63..32 */ +} SlotCrcStruct; + +typedef struct { + uint64_t ErrorStatus : 32; /* 31..0 */ + uint64_t CycleCount : 32; /* 63..32 */ + uint64_t reserved0 : 32; /* 95..64 */ + uint64_t reserved1 : 32; /* 127..96 */ +} StatusStruct; + +typedef struct { + SlotConfig slotConfig; + SlotSurfaceConfig slotSurfaceConfig; + LumaKeyStruct lumaKeyStruct; + MatrixStruct colorMatrixStruct; + MatrixStruct gamutMatrixStruct; + BlendingSlotStruct blendingSlotStruct; +} SlotStruct; + +typedef struct { + FilterCoeffStruct filterCoeffStruct[520]; +} FilterStruct; + +typedef struct { + PipeConfig pipeConfig; + OutputConfig outputConfig; + OutputSurfaceConfig outputSurfaceConfig; + MatrixStruct outColorMatrixStruct; + ClearRectStruct clearRectStruct[4]; + SlotStruct slotStruct[16]; +} ConfigStruct; + +typedef struct { + PartitionCrcStruct partitionCrcStruct[4]; +} InterfaceCrcStruct; + +typedef struct { + SlotCrcStruct slotCrcStruct[16]; +} InputCrcStruct; + +#endif diff -Nru libdrm-2.4.110/tests/tegra/vic42.c libdrm-2.4.113/tests/tegra/vic42.c --- libdrm-2.4.110/tests/tegra/vic42.c 1970-01-01 00:00:00.000000000 +0000 +++ libdrm-2.4.113/tests/tegra/vic42.c 2022-08-31 14:38:38.000000000 +0000 @@ -0,0 +1,342 @@ +/* + * 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 +#include + +#include "private.h" +#include "tegra.h" +#include "vic.h" +#include "vic42.h" + +struct vic42 { + struct vic base; + + struct { + struct drm_tegra_mapping *map; + struct drm_tegra_bo *bo; + } config; + + struct { + struct drm_tegra_mapping *map; + struct drm_tegra_bo *bo; + } filter; +}; + +static int vic42_fill(struct vic *v, struct vic_image *output, + unsigned int left, unsigned int top, + unsigned int right, unsigned int bottom, + unsigned int alpha, unsigned int red, + unsigned int green, unsigned int blue) +{ + struct vic42 *vic = container_of(v, struct vic42, base); + ConfigStruct *c; + int err; + + err = drm_tegra_bo_map(vic->config.bo, (void **)&c); + if (err < 0) { + fprintf(stderr, "failed to map configuration structure: %s\n", + strerror(-err)); + return err; + } + + memset(c, 0, sizeof(*c)); + + c->outputConfig.TargetRectTop = top; + c->outputConfig.TargetRectLeft = left; + c->outputConfig.TargetRectRight = right; + c->outputConfig.TargetRectBottom = bottom; + c->outputConfig.BackgroundAlpha = alpha; + c->outputConfig.BackgroundR = red; + c->outputConfig.BackgroundG = green; + c->outputConfig.BackgroundB = blue; + + c->outputSurfaceConfig.OutPixelFormat = output->format; + c->outputSurfaceConfig.OutBlkKind = output->kind; + c->outputSurfaceConfig.OutBlkHeight = 0; + c->outputSurfaceConfig.OutSurfaceWidth = output->width - 1; + c->outputSurfaceConfig.OutSurfaceHeight = output->height - 1; + c->outputSurfaceConfig.OutLumaWidth = output->stride - 1; + c->outputSurfaceConfig.OutLumaHeight = output->height - 1; + c->outputSurfaceConfig.OutChromaWidth = 16383; + c->outputSurfaceConfig.OutChromaHeight = 16383; + + drm_tegra_bo_unmap(vic->config.bo); + + return 0; +} + +static int vic42_blit(struct vic *v, struct vic_image *output, + struct vic_image *input) +{ + struct vic42 *vic = container_of(v, struct vic42, base); + SlotSurfaceConfig *surface; + SlotConfig *slot; + ConfigStruct *c; + int err; + + err = drm_tegra_bo_map(vic->config.bo, (void **)&c); + if (err < 0) { + fprintf(stderr, "failed to map configuration structure: %s\n", + strerror(-err)); + return err; + } + + memset(c, 0, sizeof(*c)); + + c->outputConfig.TargetRectTop = 0; + c->outputConfig.TargetRectLeft = 0; + c->outputConfig.TargetRectRight = output->width - 1; + c->outputConfig.TargetRectBottom = output->height - 1; + c->outputConfig.BackgroundAlpha = 255; + c->outputConfig.BackgroundR = 1023; + c->outputConfig.BackgroundG = 1023; + c->outputConfig.BackgroundB = 1023; + + c->outputSurfaceConfig.OutPixelFormat = output->format; + c->outputSurfaceConfig.OutBlkKind = output->kind; + c->outputSurfaceConfig.OutBlkHeight = 0; + c->outputSurfaceConfig.OutSurfaceWidth = output->width - 1; + c->outputSurfaceConfig.OutSurfaceHeight = output->height - 1; + c->outputSurfaceConfig.OutLumaWidth = output->stride - 1; + c->outputSurfaceConfig.OutLumaHeight = output->height - 1; + c->outputSurfaceConfig.OutChromaWidth = 16383; + c->outputSurfaceConfig.OutChromaHeight = 16383; + + slot = &c->slotStruct[0].slotConfig; + slot->SlotEnable = 1; + slot->CurrentFieldEnable = 1; + slot->PlanarAlpha = 255; + slot->ConstantAlpha = 1; + slot->SourceRectLeft = 0 << 16; + slot->SourceRectRight = (input->width - 1) << 16; + slot->SourceRectTop = 0 << 16; + slot->SourceRectBottom = (input->height - 1) << 16; + slot->DestRectLeft = 0; + slot->DestRectRight = output->width - 1; + slot->DestRectTop = 0; + slot->DestRectBottom = output->height - 1; + slot->SoftClampHigh = 1023; + + surface = &c->slotStruct[0].slotSurfaceConfig; + surface->SlotPixelFormat = input->format; + surface->SlotBlkKind = input->kind; + surface->SlotBlkHeight = 0; /* XXX */ + surface->SlotCacheWidth = VIC_CACHE_WIDTH_64Bx4; /* XXX */ + surface->SlotSurfaceWidth = input->width - 1; + surface->SlotSurfaceHeight = input->height - 1; + surface->SlotLumaWidth = input->stride - 1; + surface->SlotLumaHeight = input->height - 1; + surface->SlotChromaWidth = 16383; + surface->SlotChromaHeight = 16383; + + drm_tegra_bo_unmap(vic->config.bo); + + return 0; +} + +static int vic42_flip(struct vic *v, struct vic_image *output, + struct vic_image *input) +{ + struct vic42 *vic = container_of(v, struct vic42, base); + SlotSurfaceConfig *surface; + SlotConfig *slot; + ConfigStruct *c; + int err; + + err = drm_tegra_bo_map(vic->config.bo, (void **)&c); + if (err < 0) { + fprintf(stderr, "failed to map configuration structure: %s\n", + strerror(-err)); + return err; + } + + memset(c, 0, sizeof(*c)); + + c->outputConfig.TargetRectTop = 0; + c->outputConfig.TargetRectLeft = 0; + c->outputConfig.TargetRectRight = output->width - 1; + c->outputConfig.TargetRectBottom = output->height - 1; + c->outputConfig.BackgroundAlpha = 255; + c->outputConfig.BackgroundR = 1023; + c->outputConfig.BackgroundG = 1023; + c->outputConfig.BackgroundB = 1023; + c->outputConfig.OutputFlipY = 1; + + c->outputSurfaceConfig.OutPixelFormat = output->format; + c->outputSurfaceConfig.OutBlkKind = output->kind; + c->outputSurfaceConfig.OutBlkHeight = 0; + c->outputSurfaceConfig.OutSurfaceWidth = output->width - 1; + c->outputSurfaceConfig.OutSurfaceHeight = output->height - 1; + c->outputSurfaceConfig.OutLumaWidth = output->stride - 1; + c->outputSurfaceConfig.OutLumaHeight = output->height - 1; + c->outputSurfaceConfig.OutChromaWidth = 16383; + c->outputSurfaceConfig.OutChromaHeight = 16383; + + slot = &c->slotStruct[0].slotConfig; + slot->SlotEnable = 1; + slot->CurrentFieldEnable = 1; + slot->PlanarAlpha = 255; + slot->ConstantAlpha = 1; + slot->SourceRectLeft = 0 << 16; + slot->SourceRectRight = (input->width - 1) << 16; + slot->SourceRectTop = 0 << 16; + slot->SourceRectBottom = (input->height - 1) << 16; + slot->DestRectLeft = 0; + slot->DestRectRight = output->width - 1; + slot->DestRectTop = 0; + slot->DestRectBottom = output->height - 1; + slot->SoftClampHigh = 1023; + + surface = &c->slotStruct[0].slotSurfaceConfig; + surface->SlotPixelFormat = input->format; + surface->SlotBlkKind = input->kind; + surface->SlotBlkHeight = 0; /* XXX */ + surface->SlotCacheWidth = VIC_CACHE_WIDTH_64Bx4; /* XXX */ + surface->SlotSurfaceWidth = input->width - 1; + surface->SlotSurfaceHeight = input->height - 1; + surface->SlotLumaWidth = input->stride - 1; + surface->SlotLumaHeight = input->height - 1; + surface->SlotChromaWidth = 16383; + surface->SlotChromaHeight = 16383; + + drm_tegra_bo_unmap(vic->config.bo); + + return 0; +} + +static int vic42_execute(struct vic *v, struct drm_tegra_pushbuf *pushbuf, + uint32_t **ptrp, struct vic_image *output, + struct vic_image **inputs, unsigned int num_inputs) +{ + struct vic42 *vic = container_of(v, struct vic42, base); + unsigned int i; + + if (num_inputs > 1) + return -EINVAL; + + VIC_PUSH_METHOD(pushbuf, ptrp, NVC5B6_VIDEO_COMPOSITOR_SET_APPLICATION_ID, 1); + VIC_PUSH_METHOD(pushbuf, ptrp, NVC5B6_VIDEO_COMPOSITOR_SET_CONTROL_PARAMS, (sizeof(ConfigStruct) / 16) << 16); + VIC_PUSH_BUFFER(pushbuf, ptrp, NVC5B6_VIDEO_COMPOSITOR_SET_CONFIG_STRUCT_OFFSET, vic->config.map, 0, 0); + VIC_PUSH_BUFFER(pushbuf, ptrp, NVC5B6_VIDEO_COMPOSITOR_SET_FILTER_STRUCT_OFFSET, vic->filter.map, 0, 0); + VIC_PUSH_BUFFER(pushbuf, ptrp, NVC5B6_VIDEO_COMPOSITOR_SET_OUTPUT_SURFACE_LUMA_OFFSET, output->map, 0, 0); + + for (i = 0; i < num_inputs; i++) { + uint32_t method = NVC5B6_VIDEO_COMPOSITOR_SET_SURFACE0_LUMA_OFFSET(0) + (i * 3) * 4; + + VIC_PUSH_BUFFER(pushbuf, ptrp, method, inputs[i]->map, 0, 0); + } + + VIC_PUSH_METHOD(pushbuf, ptrp, NVC5B6_VIDEO_COMPOSITOR_EXECUTE, 1 << 8); + + return 0; +} + +static void vic42_free(struct vic *v) +{ + struct vic42 *vic = container_of(v, struct vic42, base); + + drm_tegra_channel_unmap(vic->filter.map); + drm_tegra_bo_unref(vic->filter.bo); + + drm_tegra_channel_unmap(vic->config.map); + drm_tegra_bo_unref(vic->config.bo); + + drm_tegra_syncpoint_free(v->syncpt); + + free(vic); +} + +static const struct vic_ops vic42_ops = { + .fill = vic42_fill, + .blit = vic42_blit, + .flip = vic42_flip, + .execute = vic42_execute, + .free = vic42_free, +}; + +int vic42_new(struct drm_tegra *drm, struct drm_tegra_channel *channel, + struct vic **vicp) +{ + struct vic42 *vic; + void *ptr; + int err; + + vic = calloc(1, sizeof(*vic)); + if (!vic) + return -ENOMEM; + + vic->base.drm = drm; + vic->base.channel = channel; + vic->base.ops = &vic42_ops; + vic->base.version = 0x19; + + err = drm_tegra_syncpoint_new(drm, &vic->base.syncpt); + if (err < 0) { + fprintf(stderr, "failed to allocate syncpoint: %s\n", strerror(-err)); + return err; + } + + err = drm_tegra_bo_new(drm, 0, 16384, &vic->config.bo); + if (err < 0) { + fprintf(stderr, "failed to allocate configuration structurer: %s\n", + strerror(-err)); + return err; + } + + err = drm_tegra_channel_map(channel, vic->config.bo, DRM_TEGRA_CHANNEL_MAP_READ, + &vic->config.map); + if (err < 0) { + fprintf(stderr, "failed to map configuration structure: %s\n", + strerror(-err)); + return err; + } + + err = drm_tegra_bo_new(drm, 0, 16384, &vic->filter.bo); + if (err < 0) { + fprintf(stderr, "failed to allocate filter buffer: %s\n", + strerror(-err)); + return err; + } + + err = drm_tegra_bo_map(vic->filter.bo, &ptr); + if (err < 0) { + fprintf(stderr, "failed to map filter buffer: %s\n", strerror(-err)); + return err; + } + + memset(ptr, 0, 16384); + drm_tegra_bo_unmap(vic->filter.bo); + + err = drm_tegra_channel_map(channel, vic->filter.bo, DRM_TEGRA_CHANNEL_MAP_READ, + &vic->filter.map); + if (err < 0) { + fprintf(stderr, "failed to map filter buffer: %s\n", + strerror(-err)); + return err; + } + + if (vicp) + *vicp = &vic->base; + + return 0; +} diff -Nru libdrm-2.4.110/tests/tegra/vic42.h libdrm-2.4.113/tests/tegra/vic42.h --- libdrm-2.4.110/tests/tegra/vic42.h 1970-01-01 00:00:00.000000000 +0000 +++ libdrm-2.4.113/tests/tegra/vic42.h 2022-08-31 14:38:38.000000000 +0000 @@ -0,0 +1,597 @@ +/* + * 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 VIC42_H +#define VIC42_H + +#include + +#define NVC5B6_VIDEO_COMPOSITOR_SET_APPLICATION_ID 0x00000200 +#define NVC5B6_VIDEO_COMPOSITOR_EXECUTE 0x00000300 +#define NVC5B6_VIDEO_COMPOSITOR_SET_CONTROL_PARAMS 0x00000704 +#define NVC5B6_VIDEO_COMPOSITOR_SET_CONFIG_STRUCT_OFFSET 0x00000708 +#define NVC5B6_VIDEO_COMPOSITOR_SET_FILTER_STRUCT_OFFSET 0x0000070c +#define NVC5B6_VIDEO_COMPOSITOR_SET_HIST_OFFSET 0x00000714 +#define NVC5B6_VIDEO_COMPOSITOR_SET_OUTPUT_SURFACE_LUMA_OFFSET 0x00000720 +#define NVC5B6_VIDEO_COMPOSITOR_SET_SURFACE0_LUMA_OFFSET(slot) (0x00001200 + (slot) * 0x00000060) +#define NVC5B6_VIDEO_COMPOSITOR_SET_SURFACE0_CHROMA_U_OFFSET(slot) (0x00001204 + (slot) * 0x00000060) +#define NVC5B6_VIDEO_COMPOSITOR_SET_SURFACE0_CHROMA_V_OFFSET(slot) (0x00001208 + (slot) * 0x00000060) +#define NVC5B6_VIDEO_COMPOSITOR_SET_SURFACE1_LUMA_OFFSET(slot) (0x0000120c + (slot) * 0x00000060) +#define NVC5B6_VIDEO_COMPOSITOR_SET_SURFACE1_CHROMA_U_OFFSET(slot) (0x00001210 + (slot) * 0x00000060) +#define NVC5B6_VIDEO_COMPOSITOR_SET_SURFACE1_CHROMA_V_OFFSET(slot) (0x00001214 + (slot) * 0x00000060) +#define NVC5B6_VIDEO_COMPOSITOR_SET_SURFACE2_LUMA_OFFSET(slot) (0x00001218 + (slot) * 0x00000060) +#define NVC5B6_VIDEO_COMPOSITOR_SET_SURFACE2_CHROMA_U_OFFSET(slot) (0x0000121c + (slot) * 0x00000060) +#define NVC5B6_VIDEO_COMPOSITOR_SET_SURFACE2_CHROMA_V_OFFSET(slot) (0x00001220 + (slot) * 0x00000060) +#define NVC5B6_VIDEO_COMPOSITOR_SET_SURFACE3_LUMA_OFFSET(slot) (0x00001224 + (slot) * 0x00000060) +#define NVC5B6_VIDEO_COMPOSITOR_SET_SURFACE3_CHROMA_U_OFFSET(slot) (0x00001228 + (slot) * 0x00000060) +#define NVC5B6_VIDEO_COMPOSITOR_SET_SURFACE3_CHROMA_V_OFFSET(slot) (0x0000122c + (slot) * 0x00000060) +#define NVC5B6_VIDEO_COMPOSITOR_SET_SURFACE4_LUMA_OFFSET(slot) (0x00001230 + (slot) * 0x00000060) +#define NVC5B6_VIDEO_COMPOSITOR_SET_SURFACE4_CHROMA_U_OFFSET(slot) (0x00001234 + (slot) * 0x00000060) +#define NVC5B6_VIDEO_COMPOSITOR_SET_SURFACE4_CHROMA_V_OFFSET(slot) (0x00001238 + (slot) * 0x00000060) +#define NVC5B6_VIDEO_COMPOSITOR_SET_SURFACE5_LUMA_OFFSET(slot) (0x0000123c + (slot) * 0x00000060) +#define NVC5B6_VIDEO_COMPOSITOR_SET_SURFACE5_CHROMA_U_OFFSET(slot) (0x00001240 + (slot) * 0x00000060) +#define NVC5B6_VIDEO_COMPOSITOR_SET_SURFACE5_CHROMA_V_OFFSET(slot) (0x00001244 + (slot) * 0x00000060) +#define NVC5B6_VIDEO_COMPOSITOR_SET_SURFACE6_LUMA_OFFSET(slot) (0x00001248 + (slot) * 0x00000060) +#define NVC5B6_VIDEO_COMPOSITOR_SET_SURFACE6_CHROMA_U_OFFSET(slot) (0x0000124c + (slot) * 0x00000060) +#define NVC5B6_VIDEO_COMPOSITOR_SET_SURFACE6_CHROMA_V_OFFSET(slot) (0x00001250 + (slot) * 0x00000060) +#define NVC5B6_VIDEO_COMPOSITOR_SET_SURFACE7_LUMA_OFFSET(slot) (0x00001254 + (slot) * 0x00000060) +#define NVC5B6_VIDEO_COMPOSITOR_SET_SURFACE7_CHROMA_U_OFFSET(slot) (0x00001258 + (slot) * 0x00000060) +#define NVC5B6_VIDEO_COMPOSITOR_SET_SURFACE7_CHROMA_V_OFFSET(slot) (0x0000125c + (slot) * 0x00000060) + +typedef struct { + uint64_t SlotEnable : 1; /* 0 */ + uint64_t DeNoise : 1; /* 1 */ + uint64_t AdvancedDenoise : 1; /* 2 */ + uint64_t CadenceDetect : 1; /* 3 */ + uint64_t MotionMap : 1; /* 4 */ + uint64_t MMapCombine : 1; /* 5 */ + uint64_t IsEven : 1; /* 6 */ + uint64_t ChromaEven : 1; /* 7 */ + uint64_t CurrentFieldEnable : 1; /* 8 */ + uint64_t PrevFieldEnable : 1; /* 9 */ + uint64_t NextFieldEnable : 1; /* 10 */ + uint64_t NextNrFieldEnable : 1; /* 11 */ + uint64_t CurMotionFieldEnable : 1; /* 12 */ + uint64_t PrevMotionFieldEnable : 1; /* 13 */ + uint64_t PpMotionFieldEnable : 1; /* 14 */ + uint64_t CombMotionFieldEnable : 1; /* 15 */ + uint64_t FrameFormat : 4; /* 19..16 */ + uint64_t FilterLengthY : 2; /* 21..20 */ + uint64_t FilterLengthX : 2; /* 23..22 */ + uint64_t Panoramic : 12; /* 35..24 */ + uint64_t ChromaUpLengthY : 2; /* 37..36 */ + uint64_t ChromaUpLengthX : 2; /* 39..38 */ + uint64_t reserved1 : 18; /* 57..40 */ + uint64_t DetailFltClamp : 6; /* 63..58 */ + uint64_t FilterNoise : 10; /* 73..64 */ + uint64_t FilterDetail : 10; /* 83..74 */ + uint64_t ChromaNoise : 10; /* 93..84 */ + uint64_t ChromaDetail : 10; /* 103..94 */ + uint64_t DeinterlaceMode : 4; /* 107..104 */ + uint64_t MotionAccumWeight : 3; /* 110..108 */ + uint64_t NoiseIir : 11; /* 121..111 */ + uint64_t LightLevel : 4; /* 125..122 */ + uint64_t reserved4 : 2; /* 127..126 */ + /* 128 */ + uint64_t SoftClampLow : 10; /* 9..0 */ + uint64_t SoftClampHigh : 10; /* 19..10 */ + uint64_t reserved5 : 12; /* 31..20 */ + uint64_t reserved6 : 2; /* 33..32 */ + uint64_t PlanarAlpha : 8; /* 41..34 */ + uint64_t ConstantAlpha : 1; /* 42 */ + uint64_t StereoInterleave : 3; /* 45..43 */ + uint64_t ClipEnabled : 1; /* 46 */ + uint64_t ClearRectMask : 8; /* 54..47 */ + uint64_t DegammaMode : 2; /* 56..55 */ + uint64_t reserved7 : 1; /* 57 */ + uint64_t DecompressEnable : 1; /* 58 */ + uint64_t DecompressKind : 4; /* 62..59 */ + uint64_t reserved9 : 1; /* 63 */ + uint64_t DecompressCtbCount : 8; /* 71..64 */ + uint64_t DecompressZbcColor : 32; /* 103..72 */ + uint64_t reserved12 : 24; /* 127..104 */ + /* 256 */ + uint64_t SourceRectLeft : 30; /* 29..0 */ + uint64_t reserved14 : 2; /* 31..30 */ + uint64_t SourceRectRight : 30; /* 61..32 */ + uint64_t reserved15 : 2; /* 63..62 */ + uint64_t SourceRectTop : 30; /* 93..64 */ + uint64_t reserved16 : 2; /* 95..94 */ + uint64_t SourceRectBottom : 30; /* 125..96 */ + uint64_t reserved17 : 2; /* 127..126 */ + /* 384 */ + uint64_t DestRectLeft : 14; /* 13..0 */ + uint64_t reserved18 : 2; /* 15..14 */ + uint64_t DestRectRight : 14; /* 29..16 */ + uint64_t reserved19 : 2; /* 31..30 */ + uint64_t DestRectTop : 14; /* 45..32 */ + uint64_t reserved20 : 2; /* 47..46 */ + uint64_t DestRectBottom : 14; /* 61..48 */ + uint64_t reserved21 : 2; /* 63..62 */ + uint64_t B16ScalerEnable : 1; /* 64 */ + uint64_t reserved22 : 31; /* 95..65 */ + uint64_t reserved23 : 32; /* 127..96 */ +} SlotConfig; + +typedef struct { + uint64_t SlotPixelFormat : 7; /* 6..0 */ + uint64_t SlotChromaLocHORIZ : 2; /* 8..7 */ + uint64_t SlotChromaLocVert : 2; /* 10..9 */ + uint64_t SlotBlkKind : 4; /* 14..11 */ + uint64_t SlotBlkHeight : 4; /* 18..15 */ + uint64_t SlotCacheWidth : 3; /* 21..19 */ + uint64_t reserved0 : 10; /* 31..22 */ + uint64_t SlotSurfaceWidth : 14; /* 45..32 */ + uint64_t SlotSurfaceHeight : 14; /* 59..46 */ + uint64_t reserved1 : 4; /* 63..60 */ + uint64_t SlotLumaWidth : 14; /* 77..64 */ + uint64_t SlotLumaHeight : 14; /* 91..78 */ + uint64_t reserved2 : 4; /* 95..92 */ + uint64_t SlotChromaWidth : 14; /* 109..96 */ + uint64_t SlotChromaHeight : 14; /* 123..110 */ + uint64_t reserved3 : 4; /* 127..124 */ +} SlotSurfaceConfig; + +typedef struct { + uint64_t luma_coeff0 : 20; /* 19..0 */ + uint64_t luma_coeff1 : 20; /* 39..20 */ + uint64_t luma_coeff2 : 20; /* 59..40 */ + uint64_t luma_r_shift : 4; /* 63..60 */ + uint64_t luma_coeff3 : 20; /* 83..64 */ + uint64_t LumaKeyLower : 10; /* 93..84 */ + uint64_t LumaKeyUpper : 10; /* 103..94 */ + uint64_t LumaKeyEnabled : 1; /* 104 */ + uint64_t reserved0 : 2; /* 106..105 */ + uint64_t reserved1 : 21; /* 127..107 */ +} LumaKeyStruct; + +typedef struct { + uint64_t matrix_coeff00 : 20; /* 19..0 */ + uint64_t matrix_coeff10 : 20; /* 39..20 */ + uint64_t matrix_coeff20 : 20; /* 59..40 */ + uint64_t matrix_r_shift : 4; /* 63..60 */ + uint64_t matrix_coeff01 : 20; /* 83..64 */ + uint64_t matrix_coeff11 : 20; /* 103..84 */ + uint64_t matrix_coeff21 : 20; /* 123..104 */ + uint64_t reserved0 : 3; /* 126..124 */ + uint64_t matrix_enable : 1; /* 127 */ + /* 128 */ + uint64_t matrix_coeff02 : 20; /* 19..0 */ + uint64_t matrix_coeff12 : 20; /* 39..20 */ + uint64_t matrix_coeff22 : 20; /* 59..40 */ + uint64_t reserved1 : 4; /* 63..60 */ + uint64_t matrix_coeff03 : 20; /* 83..64 */ + uint64_t matrix_coeff13 : 20; /* 103..84 */ + uint64_t matrix_coeff23 : 20; /* 123..104 */ + uint64_t reserved2 : 4; /* 127..124 */ +} MatrixStruct; + +typedef struct { + uint64_t ClearRect0Left : 14; /* 13..0 */ + uint64_t reserved0 : 2; /* 15..14 */ + uint64_t ClearRect0Right : 14; /* 29..16 */ + uint64_t reserved1 : 2; /* 31..30 */ + uint64_t ClearRect0Top : 14; /* 45..32 */ + uint64_t reserved2 : 2; /* 47..46 */ + uint64_t ClearRect0Bottom : 14; /* 61..48 */ + uint64_t reserved3 : 2; /* 63..62 */ + uint64_t ClearRect1Left : 14; /* 77..64 */ + uint64_t reserved4 : 2; /* 79..78 */ + uint64_t ClearRect1Right : 14; /* 93..80 */ + uint64_t reserved5 : 2; /* 95..94 */ + uint64_t ClearRect1Top : 14; /* 109..96 */ + uint64_t reserved6 : 2; /* 111..110 */ + uint64_t ClearRect1Bottom : 14; /* 125..112 */ + uint64_t reserved7 : 2; /* 127..126 */ +} ClearRectStruct; + +typedef struct { + uint64_t reserved0 : 2; /* 1..0 */ + uint64_t AlphaK1 : 8; /* 9..2 */ + uint64_t reserved1 : 6; /* 17..10 */ + uint64_t AlphaK2 : 8; /* 25..18 */ + uint64_t reserved2 : 6; /* 31..26 */ + uint64_t SrcFactCMatchSelect : 3; /* 34..32 */ + uint64_t reserved3 : 1; /* 35 */ + uint64_t DstFactCMatchSelect : 3; /* 38..36 */ + uint64_t reserved4 : 1; /* 39 */ + uint64_t SrcFactAMatchSelect : 3; /* 42..40 */ + uint64_t reserved5 : 1; /* 43 */ + uint64_t DstFactAMatchSelect : 3; /* 46..44 */ + uint64_t reserved6 : 1; /* 47 */ + uint64_t reserved7 : 4; /* 51..48 */ + uint64_t reserved8 : 4; /* 55..52 */ + uint64_t reserved9 : 4; /* 59..56 */ + uint64_t reserved10 : 4; /* 63..60 */ + uint64_t reserved11 : 2; /* 65..64 */ + uint64_t OverrideR : 10; /* 75..66 */ + uint64_t OverrideG : 10; /* 85..76 */ + uint64_t OverrideB : 10; /* 95..86 */ + uint64_t reserved12 : 2; /* 97..96 */ + uint64_t OverrideA : 8; /* 105..98 */ + uint64_t reserved13 : 2; /* 107..106 */ + uint64_t UseOverrideR : 1; /* 108 */ + uint64_t UseOverrideG : 1; /* 109 */ + uint64_t UseOverrideB : 1; /* 110 */ + uint64_t UseOverrideA : 1; /* 111 */ + uint64_t MaskR : 1; /* 112 */ + uint64_t MaskG : 1; /* 113 */ + uint64_t MaskB : 1; /* 114 */ + uint64_t MaskA : 1; /* 115 */ + uint64_t reserved14 : 12; /* 127..116 */ +} BlendingSlotStruct; + +typedef struct { + uint64_t AlphaFillMode : 3; /* 2..0 */ + uint64_t AlphaFillSlot : 3; /* 5..3 */ + uint64_t reserved0 : 2; /* 6..5 */ + uint64_t BackgroundAlpha : 8; /* 15..7 */ + uint64_t BackgroundR : 10; /* 25..16 */ + uint64_t BackgroundG : 10; /* 35..26 */ + uint64_t BackgroundB : 10; /* 45..36 */ + uint64_t RegammaMode : 2; /* 47..46 */ + uint64_t OutputFlipX : 1; /* 48 */ + uint64_t OutputFlipY : 1; /* 49 */ + uint64_t OutputTranspose : 1; /* 50 */ + uint64_t reserved1 : 1; /* 51 */ + uint64_t reserved2 : 12; /* 63..52 */ + uint64_t TargetRectLeft : 14; /* 77..64 */ + uint64_t reserved3 : 2; /* 79..78 */ + uint64_t TargetRectRight : 14; /* 93..80 */ + uint64_t reserved4 : 2; /* 95..94 */ + uint64_t TargetRectTop : 14; /* 109..96 */ + uint64_t reserved5 : 2; /* 111..110 */ + uint64_t TargetRectBottom : 14; /* 125..112 */ + uint64_t reserved6 : 2; /* 127..126 */ +} OutputConfig; + +typedef struct { + uint64_t OutPixelFormat : 7; /* 6..0 */ + uint64_t OutChromaLocHoriz : 2; /* 8..7 */ + uint64_t OutChromaLocVert : 2; /* 10..9 */ + uint64_t OutBlkKind : 4; /* 14..11 */ + uint64_t OutBlkHeight : 4; /* 18..15 */ + uint64_t reserved0 : 3; /* 21..19 */ + uint64_t reserved1 : 10; /* 31..22 */ + uint64_t OutSurfaceWidth : 14; /* 45..32 */ + uint64_t OutSurfaceHeight : 14; /* 59..46 */ + uint64_t reserved2 : 4; /* 63..60 */ + uint64_t OutLumaWidth : 14; /* 77..64 */ + uint64_t OutLumaHeight : 14; /* 91..78 */ + uint64_t reserved3 : 4; /* 95..92 */ + uint64_t OutChromaWidth : 14; /* 109..96 */ + uint64_t OutChromaHeight : 14; /* 123..110 */ + uint64_t reserved4 : 4; /* 127..124 */ +} OutputSurfaceConfig; + +typedef struct { + uint64_t f00 : 10; /* 9..0 */ + uint64_t f10 : 10; /* 19..10 */ + uint64_t f20 : 10; /* 29..20 */ + uint64_t reserved0 : 2; /* 31..30 */ + uint64_t f01 : 10; /* 41..32 */ + uint64_t f11 : 10; /* 51..42 */ + uint64_t f21 : 10; /* 61..52 */ + uint64_t reserved1 : 2; /* 63..62 */ + uint64_t f02 : 10; /* 73..64 */ + uint64_t f12 : 10; /* 83..74 */ + uint64_t f22 : 10; /* 93..84 */ + uint64_t reserved2 : 2; /* 95..94 */ + uint64_t f03 : 10; /* 105..96 */ + uint64_t f13 : 10; /* 115..106 */ + uint64_t f23 : 10; /* 125..116 */ + uint64_t reserved3 : 2; /* 127..126 */ +} FilterCoeffStruct; + +typedef struct { + uint64_t DownsampleHoriz : 11; /* 10..0 */ + uint64_t reserved0 : 5; /* 15..11 */ + uint64_t DownsampleVert : 11; /* 26..16 */ + uint64_t reserved1 : 5; /* 31..27 */ + uint64_t reserved2 : 32; /* 63..32 */ + uint64_t reserved3 : 32; /* 95..64 */ + uint64_t reserved4 : 32; /* 127..96 */ +} PipeConfig; + +typedef struct { + uint64_t OldCadence : 32; /* 31..0 */ + uint64_t OldDiff : 32; /* 63..32 */ + uint64_t OldWeave : 32; /* 95..64 */ + uint64_t OlderWeave : 32; /* 127..96 */ +} SlotHistoryBuffer; + +typedef struct { + uint64_t crc0 : 32; /* 31..0 */ + uint64_t crc1 : 32; /* 63..32 */ + uint64_t crc2 : 32; /* 95..64 */ + uint64_t crc3 : 32; /* 127..96 */ +} PartitionCrcStruct; + +typedef struct { + uint64_t crc0 : 32; /* 31..0 */ + uint64_t crc1 : 32; /* 63..32 */ +} SlotCrcStruct; + +typedef struct { + uint64_t ErrorStatus : 32; /* 31..0 */ + uint64_t CycleCount : 32; /* 63..32 */ + uint64_t reserved0 : 32; /* 95..64 */ + uint64_t reserved1 : 32; /* 127..96 */ +} StatusStruct; + +typedef struct { + uint64_t coeff_0 : 10; /* 9..0 */ + uint64_t reserved0 : 6; /* 15..10 */ + uint64_t coeff_1 : 10; /* 25..16 */ + uint64_t reserved1 : 6; /* 31..26 */ + uint64_t coeff_2 : 10; /* 41..32 */ + uint64_t reserved2 : 6; /* 47..42 */ + uint64_t coeff_3 : 10; /* 57..48 */ + uint64_t reserved3 : 6; /* 63..58 */ +} CoeffPhaseParamStruct; + +typedef struct { + uint64_t GeoTranEn : 1; /* 0 */ + uint64_t GeoTranMode : 2; /* 2..1 */ + uint64_t IPTMode : 1; /* 3 */ + uint64_t PixelFilterType : 2; /* 5..4 */ + uint64_t PixelFormat : 7; /* 12..6 */ + uint64_t CacheWidth : 3; /* 15..13 */ + uint64_t SrcBlkKind : 4; /* 19..16 */ + uint64_t SrcBlkHeight : 4; /* 23..20 */ + uint64_t DestBlkKind : 4; /* 27..24 */ + uint64_t DestBlkHeight : 4; /* 31..28 */ + uint64_t MskBitMapEn : 1; /* 32 */ + uint64_t MaskedPixelFillMode : 1; /* 33 */ + uint64_t XSobelMode : 2; /* 35..34 */ + uint64_t SubFrameEn : 1; /* 36 */ + uint64_t reserved0 : 3; /* 39..37 */ + uint64_t XSobelBlkKind : 4; /* 43..40 */ + uint64_t XSobelBlkHeight : 4; /* 47..44 */ + uint64_t XSobelDSBlkKind : 4; /* 51..48 */ + uint64_t XSobelDSBlkHeight : 4; /* 55..52 */ + uint64_t reserved1 : 8; /* 63..56 */ + uint64_t NonFixedPatchEn : 1; /* 64 */ + uint64_t HorRegionNum : 2; /* 66..65 */ + uint64_t VerRegionNum : 2; /* 68..67 */ + uint64_t reserved2 : 3; /* 71..69 */ + uint64_t log2HorSpace_0 : 3; /* 74..72 */ + uint64_t log2VerSpace_0 : 3; /* 77..75 */ + uint64_t log2HorSpace_1 : 3; /* 80..78 */ + uint64_t log2VerSpace_1 : 3; /* 83..81 */ + uint64_t log2HorSpace_2 : 3; /* 86..84 */ + uint64_t log2VerSpace_2 : 3; /* 89..87 */ + uint64_t log2HorSpace_3 : 3; /* 92..90 */ + uint64_t log2VerSpace_3 : 3; /* 95..93 */ + uint64_t horRegionWidth_0 : 14; /* 109..96 */ + uint64_t reserved3 : 2; /* 111..110 */ + uint64_t horRegionWidth_1 : 14; /* 125..112 */ + uint64_t reserved4 : 2; /* 127..126 */ + uint64_t horRegionWidth_2 : 14; /* 141..128 */ + uint64_t reserved5 : 2; /* 143..142 */ + uint64_t horRegionWidth_3 : 14; /* 157..144 */ + uint64_t reserved6 : 2; /* 159..158 */ + uint64_t verRegionHeight_0 : 14; /* 173..160 */ + uint64_t reserved7 : 2; /* 175..174 */ + uint64_t verRegionHeight_1 : 14; /* 189..176 */ + uint64_t reserved8 : 2; /* 191..190 */ + uint64_t verRegionHeight_2 : 14; /* 205..192 */ + uint64_t reserved9 : 2; /* 207..206 */ + uint64_t verRegionHeight_3 : 14; /* 221..208 */ + uint64_t reserved10 : 2; /* 223..222 */ + uint64_t IPT_M11 : 32; /* 255..224 */ + uint64_t IPT_M12 : 32; /* 287..256 */ + uint64_t IPT_M13 : 32; /* 319..288 */ + uint64_t IPT_M21 : 32; /* 351..320 */ + uint64_t IPT_M22 : 32; /* 383..352 */ + uint64_t IPT_M23 : 32; /* 415..384 */ + uint64_t IPT_M31 : 32; /* 447..416 */ + uint64_t IPT_M32 : 32; /* 479..448 */ + uint64_t IPT_M33 : 32; /* 511..480 */ + uint64_t SourceRectLeft : 14; /* 525..512 */ + uint64_t reserved11 : 2; /* 527..526 */ + uint64_t SourceRectRight : 14; /* 541..528 */ + uint64_t reserved12 : 2; /* 543..542 */ + uint64_t SourceRectTop : 14; /* 557..544 */ + uint64_t reserved13 : 2; /* 559..558 */ + uint64_t SourceRectBottom : 14; /* 573..560 */ + uint64_t reserved14; /* 575..574 */ + uint64_t SrcImgWidth : 14; /* 589..576 */ + uint64_t reserved15 : 2; /* 591..590 */ + uint64_t SrcImgHeight : 14; /* 605..592 */ + uint64_t reserved16 : 2; /* 607..606 */ + uint64_t SrcSfcLumaWidth : 14; /* 621..608 */ + uint64_t reserved17 : 2; /* 623..622 */ + uint64_t SrcSfcLumaHeight : 14; /* 637..624 */ + uint64_t reserved18 : 2; /* 639..638 */ + uint64_t SrcSfcChromaWidth : 14; /* 653..640 */ + uint64_t reserved19 : 2; /* 655..654 */ + uint64_t SrcSfcChromaHeight : 14; /* 669..656 */ + uint64_t reserved20 : 2; /* 671..670 */ + uint64_t DestRectLeft : 14; /* 685..672 */ + uint64_t reserved21 : 2; /* 687..686 */ + uint64_t DestRectRight : 14; /* 701..688 */ + uint64_t reserved22 : 2; /* 703..702 */ + uint64_t DestRectTop : 14; /* 717..704 */ + uint64_t reserved23 : 2; /* 719..718 */ + uint64_t DestRectBottom : 14; /* 733..720 */ + uint64_t reserved24 : 2; /* 735..734 */ + uint64_t SubFrameRectTop : 14; /* 749..736 */ + uint64_t reserved25 : 2; /* 751..750 */ + uint64_t SubFrameRectBottom : 14; /* 765..752 */ + uint64_t reserved26 : 2; /* 767..766 */ + uint64_t DestSfcLumaWidth : 14; /* 781..768 */ + uint64_t reserved27 : 2; /* 783..782 */ + uint64_t DestSfcLumaHeight : 14; /* 797..784 */ + uint64_t reserved28 : 2; /* 799..798 */ + uint64_t DestSfcChromaWidth : 14; /* 813..800 */ + uint64_t reserved29 : 2; /* 815..814 */ + uint64_t DestSfcChromaHeight : 14; /* 829..816 */ + uint64_t reserved30 : 2; /* 831..830 */ + uint64_t SparseWarpMapWidth : 14; /* 845..832 */ + uint64_t reserved31 : 2; /* 847..846 */ + uint64_t SparseWarpMapHeight : 14; /* 861..848 */ + uint64_t reserved32 : 2; /* 863..862 */ + uint64_t SparseWarpMapStride : 14; /* 877..864 */ + uint64_t reserved33 : 2; /* 879..878 */ + uint64_t MaskBitMapWidth : 14; /* 893..880 */ + uint64_t reserved34 : 2; /* 895..894 */ + uint64_t MaskBitMapHeight : 14; /* 909..896 */ + uint64_t reserved35 : 2; /* 911..910 */ + uint64_t MaskBitMapStride : 14; /* 925..912 */ + uint64_t reserved36 : 2; /* 927..926 */ + uint64_t XSobelWidth : 14; /* 941..928 */ + uint64_t reserved37 : 2; /* 943..942 */ + uint64_t XSobelHeight : 14; /* 957..944 */ + uint64_t reserved38 : 2; /* 959..958 */ + uint64_t XSobelStride : 14; /* 973..960 */ + uint64_t reserved39 : 2; /* 975..974 */ + uint64_t DSStride : 14; /* 989..976 */ + uint64_t reserved40 : 2; /* 991..990 */ + uint64_t XSobelTopOffset : 32; /* 1023..992 */ + uint64_t reserved41 : 32; /* 1055..1024 */ + uint64_t maskY : 16; /* 1071..1056 */ + uint64_t maskU : 16; /* 1087..1072 */ + uint64_t maskV : 16; /* 1103..1088 */ + uint64_t reserved42 : 16; /* 1119..1104 */ +} GeoTranConfigParamStruct; + +typedef struct { + uint64_t TNR3En : 1; /* 0 */ + uint64_t BetaBlendingEn : 1; /* 1 */ + uint64_t AlphaBlendingEn : 1; /* 2 */ + uint64_t AlphaSmoothEn : 1; /* 3 */ + uint64_t TempAlphaRestrictEn : 1; /* 4 */ + uint64_t AlphaClipEn : 1; /* 5 */ + uint64_t BFRangeEn : 1; /* 6 */ + uint64_t BFDomainEn : 1; /* 7 */ + uint64_t BFRangeLumaShift : 4; /* 11..8 */ + uint64_t BFRangeChromaShift : 4; /* 15..12 */ + uint64_t SADMultiplier : 6; /* 21..16 */ + uint64_t reserved1 : 2; /* 23..22 */ + uint64_t SADWeightLuma : 6; /* 29..24 */ + uint64_t reserved2 : 2; /* 31..30 */ + uint64_t TempAlphaRestrictIncCap : 11; /* 42..32 */ + uint64_t reserved3 : 5; /* 47..43 */ + uint64_t AlphaScaleIIR : 11; /* 58..48 */ + uint64_t reserved4 : 5; /* 63..59 */ + uint64_t AlphaClipMaxLuma : 11; /* 74..64 */ + uint64_t reserved5 : 5; /* 79..75 */ + uint64_t AlphaClipMinLuma : 11; /* 90..80 */ + uint64_t reserved6 : 5; /* 95..91 */ + uint64_t AlphaClipMaxChroma : 11; /* 106..96 */ + uint64_t reserved7 : 5; /* 111..107 */ + uint64_t AlphaClipMinChroma : 11; /* 122..112 */ + uint64_t reserved8 : 5; /* 127..123 */ + uint64_t BetaCalcMaxBeta : 11; /* 138..128 */ + uint64_t reserved9 : 5; /* 143..139 */ + uint64_t BetaCalcMinBeta : 11; /* 154..144 */ + uint64_t reserved10 : 5; /* 159..155 */ + uint64_t BetaCalcBetaX1 : 11; /* 170..160 */ + uint64_t reserved11 : 5; /* 175..171 */ + uint64_t BetaCalcBetaX2 : 11; /* 186..176 */ + uint64_t reserved12 : 5; /* 191..187 */ + uint64_t BetaCalcStepBeta : 11; /* 202..192 */ + uint64_t reserved13 : 5; /* 207..203 */ + uint64_t reserved14 : 16; /* 223..208 */ + uint64_t BFDomainLumaCoeffC00 : 7; /* 230..224 */ + uint64_t reserved15 : 1; /* 231 */ + uint64_t BFDomainLumaCoeffC01 : 7; /* 238..232 */ + uint64_t reserved16 : 1; /* 239 */ + uint64_t BFDomainLumaCoeffC02 : 7; /* 246..240 */ + uint64_t reserved17 : 1; /* 247 */ + uint64_t BFDomainLumaCoeffC11 : 7; /* 254..248 */ + uint64_t reserved18 : 1; /* 255 */ + uint64_t BFDomainLumaCoeffC12 : 7; /* 262..256 */ + uint64_t reserved19 : 1; /* 263 */ + uint64_t BFDomainLumaCoeffC22 : 7; /* 270..264 */ + uint64_t reserved20 : 1; /* 271 */ + uint64_t reserved21 : 16; /* 287..272 */ + uint64_t BFDomainChromaCoeffC00 : 7; /* 294..288 */ + uint64_t reserved22 : 1; /* 295 */ + uint64_t BFDomainChromaCoeffC01 : 7; /* 302..296 */ + uint64_t reserved23 : 1; /* 303 */ + uint64_t BFDomainChromaCoeffC02 : 7; /* 310..304 */ + uint64_t reserved24 : 1; /* 311 */ + uint64_t BFDomainChromaCoeffC11 : 7; /* 318..312 */ + uint64_t reserved25 : 1; /* 319 */ + uint64_t BFDomainChromaCoeffC12 : 7; /* 326..320 */ + uint64_t reserved26 : 1; /* 327 */ + uint64_t BFDomainChromaCoeffC22 : 7; /* 334..328 */ + uint64_t reserved27 : 1; /* 335 */ + uint64_t reserved28 : 16; /* 351..336 */ + uint64_t LeftBufSize : 32; /* 383..352 */ + uint64_t TopBufSize : 32; /* 415..384 */ + uint64_t AlphaSufStride : 14; /* 429..416 */ + uint64_t reserved29 : 18; /* 447..430 */ +} TNR3ConfigParamStruct; + +typedef struct { + uint64_t item0 : 7; /* 6..0 */ + uint64_t reserved0 : 9; /* 15..7 */ + uint64_t item1 : 7; /* 22..16 */ + uint64_t reserved1 : 9; /* 31..23 */ + uint64_t item2 : 7; /* 38..32 */ + uint64_t reserved2 : 9; /* 47..39 */ + uint64_t item3 : 7; /* 54..48 */ + uint64_t reserved3 : 9; /* 63..55 */ +} BFRangeTableItems; + +typedef struct { + SlotConfig slotConfig; + SlotSurfaceConfig slotSurfaceConfig; + LumaKeyStruct lumaKeyStruct; + MatrixStruct colorMatrixStruct; + MatrixStruct gamutMatrixStruct; + BlendingSlotStruct blendingSlotStruct; +} SlotStruct; + +typedef struct { + FilterCoeffStruct filterCoeffStruct[520]; +} FilterStruct; + +typedef struct { + PipeConfig pipeConfig; + OutputConfig outputConfig; + OutputSurfaceConfig outputSurfaceConfig; + MatrixStruct outColorMatrixStruct; + ClearRectStruct clearRectStruct[4]; + SlotStruct slotStruct[16]; +} ConfigStruct; + +typedef struct { + PartitionCrcStruct partitionCrcStruct[2]; +} InterfaceCrcStruct; + +typedef struct { + SlotCrcStruct slotCrcStruct[16]; +} InputCrcStruct; + +typedef struct { + GeoTranConfigParamStruct paramConfig; + CoeffPhaseParamStruct FilterCoeff[17]; + TNR3ConfigParamStruct tnr3Config; + BFRangeTableItems BFRangeTableLuma[16]; + BFRangeTableItems BFRangeTableChroma[16]; +} GeoTranConfigStruct; + +#endif diff -Nru libdrm-2.4.110/tests/tegra/vic-blit.c libdrm-2.4.113/tests/tegra/vic-blit.c --- libdrm-2.4.110/tests/tegra/vic-blit.c 1970-01-01 00:00:00.000000000 +0000 +++ libdrm-2.4.113/tests/tegra/vic-blit.c 2022-08-31 14:38:38.000000000 +0000 @@ -0,0 +1,333 @@ +/* + * 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 +#include +#include +#include +#include + +#include "tegra.h" + +#include "host1x.h" +#include "vic.h" + +/* clear output image to red */ +static int clear(struct vic *vic, struct drm_tegra_channel *channel, + struct vic_image *output) +{ + struct drm_tegra_pushbuf *pushbuf; + struct drm_tegra_job *job; + uint32_t *ptr; + int err; + + err = drm_tegra_job_new(channel, &job); + if (err < 0) { + fprintf(stderr, "failed to create job: %s\n", strerror(-err)); + return 1; + } + + err = drm_tegra_job_get_pushbuf(job, &pushbuf); + if (err < 0) { + fprintf(stderr, "failed to create push buffer: %s\n", strerror(-err)); + return 1; + } + + err = vic_clear(vic, output, 1023, 1023, 0, 0); + if (err < 0) { + fprintf(stderr, "failed to clear surface: %s\n", strerror(-err)); + return err; + } + + err = drm_tegra_pushbuf_begin(pushbuf, 32, &ptr); + if (err < 0) { + fprintf(stderr, "failed to prepare push buffer: %s\n", strerror(-err)); + return err; + } + + err = vic->ops->execute(vic, pushbuf, &ptr, output, NULL, 0); + if (err < 0) { + fprintf(stderr, "failed to execute operation: %s\n", strerror(-err)); + return err; + } + + err = drm_tegra_pushbuf_sync_cond(pushbuf, &ptr, vic->syncpt, + DRM_TEGRA_SYNC_COND_OP_DONE); + if (err < 0) { + fprintf(stderr, "failed to push syncpoint: %s\n", strerror(-err)); + return err; + } + + err = drm_tegra_pushbuf_end(pushbuf, ptr); + if (err < 0) { + fprintf(stderr, "failed to update push buffer: %s\n", strerror(-err)); + return err; + } + + err = drm_tegra_job_submit(job, NULL); + if (err < 0) { + fprintf(stderr, "failed to submit job: %s\n", strerror(-err)); + return err; + } + + err = drm_tegra_job_wait(job, 1000000000); + if (err < 0) { + fprintf(stderr, "failed to wait for job: %s\n", strerror(-err)); + return err; + } + + drm_tegra_job_free(job); + + return 0; +} + +/* fill bottom half of image to blue */ +static int fill(struct vic *vic, struct drm_tegra_channel *channel, + struct vic_image *output) +{ + struct drm_tegra_pushbuf *pushbuf; + struct drm_tegra_job *job; + uint32_t *ptr; + int err; + + err = drm_tegra_job_new(channel, &job); + if (err < 0) { + fprintf(stderr, "failed to create job: %s\n", strerror(-err)); + return 1; + } + + err = drm_tegra_job_get_pushbuf(job, &pushbuf); + if (err < 0) { + fprintf(stderr, "failed to create push buffer: %s\n", strerror(-err)); + return 1; + } + + err = drm_tegra_pushbuf_begin(pushbuf, 32, &ptr); + if (err < 0) { + fprintf(stderr, "failed to prepare push buffer: %s\n", strerror(-err)); + return err; + } + + err = vic->ops->fill(vic, output, 0, output->height / 2, output->width - 1, + output->height -1, 1023, 0, 0, 1023); + if (err < 0) { + fprintf(stderr, "failed to fill surface: %s\n", strerror(-err)); + return err; + } + + err = vic->ops->execute(vic, pushbuf, &ptr, output, NULL, 0); + if (err < 0) { + fprintf(stderr, "failed to execute operation: %s\n", strerror(-err)); + return err; + } + + err = drm_tegra_pushbuf_sync_cond(pushbuf, &ptr, vic->syncpt, + DRM_TEGRA_SYNC_COND_OP_DONE); + if (err < 0) { + fprintf(stderr, "failed to push syncpoint: %s\n", strerror(-err)); + return err; + } + + err = drm_tegra_pushbuf_end(pushbuf, ptr); + if (err < 0) { + fprintf(stderr, "failed to update push buffer: %s\n", strerror(-err)); + return err; + } + + err = drm_tegra_job_submit(job, NULL); + if (err < 0) { + fprintf(stderr, "failed to submit job: %s\n", strerror(-err)); + return err; + } + + err = drm_tegra_job_wait(job, 1000000000); + if (err < 0) { + fprintf(stderr, "failed to wait for job: %s\n", strerror(-err)); + return err; + } + + drm_tegra_job_free(job); + + return 0; +} + +/* blit image */ +static int blit(struct vic *vic, struct drm_tegra_channel *channel, + struct vic_image *output, struct vic_image *input) +{ + struct drm_tegra_pushbuf *pushbuf; + struct drm_tegra_job *job; + uint32_t *ptr; + int err; + + err = drm_tegra_job_new(channel, &job); + if (err < 0) { + fprintf(stderr, "failed to create job: %s\n", strerror(-err)); + return 1; + } + + err = drm_tegra_job_get_pushbuf(job, &pushbuf); + if (err < 0) { + fprintf(stderr, "failed to create push buffer: %s\n", strerror(-err)); + return 1; + } + + err = drm_tegra_pushbuf_begin(pushbuf, 32, &ptr); + if (err < 0) { + fprintf(stderr, "failed to prepare push buffer: %s\n", strerror(-err)); + return err; + } + + err = vic->ops->blit(vic, output, input); + if (err < 0) { + fprintf(stderr, "failed to blit surface: %s\n", strerror(-err)); + return err; + } + + err = vic->ops->execute(vic, pushbuf, &ptr, output, &input, 1); + if (err < 0) { + fprintf(stderr, "failed to execute operation: %s\n", strerror(-err)); + return err; + } + + err = drm_tegra_pushbuf_sync_cond(pushbuf, &ptr, vic->syncpt, + DRM_TEGRA_SYNC_COND_OP_DONE); + if (err < 0) { + fprintf(stderr, "failed to push syncpoint: %s\n", strerror(-err)); + return err; + } + + err = drm_tegra_pushbuf_end(pushbuf, ptr); + if (err < 0) { + fprintf(stderr, "failed to update push buffer: %s\n", strerror(-err)); + return err; + } + + err = drm_tegra_job_submit(job, NULL); + if (err < 0) { + fprintf(stderr, "failed to submit job: %s\n", strerror(-err)); + return err; + } + + err = drm_tegra_job_wait(job, 1000000000); + if (err < 0) { + fprintf(stderr, "failed to wait for job: %s\n", strerror(-err)); + return err; + } + + drm_tegra_job_free(job); + + return 0; +} + +int main(int argc, char *argv[]) +{ + const unsigned int format = VIC_PIXEL_FORMAT_A8R8G8B8; + const unsigned int kind = VIC_BLK_KIND_PITCH; + const unsigned int width = 16, height = 16; + const char *device = "/dev/dri/renderD128"; + struct drm_tegra_channel *channel; + struct vic_image *input, *output; + struct drm_tegra *drm; + unsigned int version; + struct vic *vic; + int fd, err; + + if (argc > 1) + device = argv[1]; + + fd = open(device, O_RDWR); + if (fd < 0) { + fprintf(stderr, "open() failed: %s\n", strerror(errno)); + return 1; + } + + err = drm_tegra_new(fd, &drm); + if (err < 0) { + fprintf(stderr, "failed to open Tegra device: %s\n", strerror(-err)); + close(fd); + return 1; + } + + err = drm_tegra_channel_open(drm, DRM_TEGRA_VIC, &channel); + if (err < 0) { + fprintf(stderr, "failed to open channel to VIC: %s\n", strerror(-err)); + return 1; + } + + version = drm_tegra_channel_get_version(channel); + printf("version: %08x\n", version); + + err = vic_new(drm, channel, &vic); + if (err < 0) { + fprintf(stderr, "failed to create VIC: %s\n", strerror(-err)); + return 1; + } + + err = vic_image_new(vic, width, height, format, kind, DRM_TEGRA_CHANNEL_MAP_READ_WRITE, + &input); + if (err < 0) { + fprintf(stderr, "failed to create input image: %d\n", err); + return 1; + } + + err = vic_image_new(vic, width, height, format, kind, DRM_TEGRA_CHANNEL_MAP_READ_WRITE, + &output); + if (err < 0) { + fprintf(stderr, "failed to create output image: %d\n", err); + return 1; + } + + err = clear(vic, channel, input); + if (err < 0) { + fprintf(stderr, "failed to clear image: %s\n", strerror(-err)); + return 1; + } + + err = fill(vic, channel, input); + if (err < 0) { + fprintf(stderr, "failed to fill rectangle: %s\n", strerror(-err)); + return 1; + } + + err = blit(vic, channel, output, input); + if (err < 0) { + fprintf(stderr, "failed to blit image: %s\n", strerror(-err)); + return 1; + } + + printf("input: %ux%u\n", input->width, input->height); + vic_image_dump(input, stdout); + + printf("output: %ux%u\n", output->width, output->height); + vic_image_dump(output, stdout); + + vic_image_free(output); + vic_image_free(input); + + vic_free(vic); + drm_tegra_channel_close(channel); + drm_tegra_close(drm); + close(fd); + + return 0; +} diff -Nru libdrm-2.4.110/tests/tegra/vic.c libdrm-2.4.113/tests/tegra/vic.c --- libdrm-2.4.110/tests/tegra/vic.c 1970-01-01 00:00:00.000000000 +0000 +++ libdrm-2.4.113/tests/tegra/vic.c 2022-08-31 14:38:38.000000000 +0000 @@ -0,0 +1,184 @@ +/* + * 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 +#include /* XXX remove */ +#include + +#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 *vic, unsigned int width, unsigned int height, + unsigned int format, unsigned int kind, uint32_t flags, + struct vic_image **imagep) +{ + 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(vic->drm, 0, image->size, &image->bo); + if (err < 0) { + free(image); + return err; + } + + err = drm_tegra_channel_map(vic->channel, image->bo, flags, &image->map); + if (err < 0) { + drm_tegra_bo_unref(image->bo); + free(image); + return err; + } + + *imagep = image; + return 0; +} + +void vic_image_free(struct vic_image *image) +{ + if (image) { + drm_tegra_channel_unmap(image->map); + 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); +} + +/* from vic30.c */ +int vic30_new(struct drm_tegra *drm, struct drm_tegra_channel *channel, + struct vic **vicp); + +/* from vic40.c */ +int vic40_new(struct drm_tegra *drm, struct drm_tegra_channel *channel, + struct vic **vicp); + +/* from vic41.c */ +int vic41_new(struct drm_tegra *drm, struct drm_tegra_channel *channel, + struct vic **vicp); + +/* from vic42.c */ +int vic42_new(struct drm_tegra *drm, struct drm_tegra_channel *channel, + struct vic **vicp); + +int vic_new(struct drm_tegra *drm, struct drm_tegra_channel *channel, + struct vic **vicp) +{ + unsigned int version; + + version = drm_tegra_channel_get_version(channel); + + switch (version) { + case 0x40: + return vic30_new(drm, channel, vicp); + + case 0x21: + return vic40_new(drm, channel, vicp); + + case 0x18: + return vic41_new(drm, channel, vicp); + + case 0x19: + return vic42_new(drm, channel, vicp); + } + + return -ENOTSUP; +} + +void vic_free(struct vic *vic) +{ + if (vic) + vic->ops->free(vic); +} + +int vic_clear(struct vic *vic, struct vic_image *output, unsigned int alpha, + unsigned int red, unsigned int green, unsigned int blue) +{ + return vic->ops->fill(vic, output, 0, 0, output->width - 1, + output->height - 1, alpha, red, green, blue); +} diff -Nru libdrm-2.4.110/tests/tegra/vic-clear.c libdrm-2.4.113/tests/tegra/vic-clear.c --- libdrm-2.4.110/tests/tegra/vic-clear.c 1970-01-01 00:00:00.000000000 +0000 +++ libdrm-2.4.113/tests/tegra/vic-clear.c 2022-08-31 14:38:38.000000000 +0000 @@ -0,0 +1,173 @@ +/* + * 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 +#include +#include +#include +#include + +#include "util_math.h" + +#include "tegra.h" + +#include "host1x.h" +#include "vic.h" + +#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) + +int main(int argc, char *argv[]) +{ + const unsigned int format = VIC_PIXEL_FORMAT_A8R8G8B8; + const unsigned int kind = VIC_BLK_KIND_PITCH; + const unsigned int width = 16, height = 16; + const char *device = "/dev/dri/renderD128"; + struct drm_tegra_channel *channel; + struct drm_tegra_pushbuf *pushbuf; + struct drm_tegra_job *job; + struct vic_image *output; + struct drm_tegra *drm; + unsigned int version; + struct vic *vic; + uint32_t *pb; + int fd, err; + void *ptr; + + if (argc > 1) + device = argv[1]; + + fd = open(device, O_RDWR); + if (fd < 0) { + fprintf(stderr, "open() failed: %s\n", strerror(errno)); + return 1; + } + + err = drm_tegra_new(fd, &drm); + if (err < 0) { + fprintf(stderr, "failed to open Tegra device: %s\n", strerror(-err)); + close(fd); + return 1; + } + + err = drm_tegra_channel_open(drm, DRM_TEGRA_VIC, &channel); + if (err < 0) { + fprintf(stderr, "failed to open channel to VIC: %s\n", strerror(-err)); + return 1; + } + + version = drm_tegra_channel_get_version(channel); + printf("version: %08x\n", version); + + err = vic_new(drm, channel, &vic); + if (err < 0) { + fprintf(stderr, "failed to create VIC: %s\n", strerror(-err)); + return 1; + } + + err = vic_image_new(vic, width, height, format, kind, DRM_TEGRA_CHANNEL_MAP_READ_WRITE, + &output); + if (err < 0) { + fprintf(stderr, "failed to create output image: %d\n", err); + return 1; + } + + printf("image: %zu bytes\n", output->size); + + err = drm_tegra_bo_map(output->bo, &ptr); + if (err < 0) { + fprintf(stderr, "failed to map output image: %d\n", err); + return 1; + } + + memset(ptr, 0xff, output->size); + drm_tegra_bo_unmap(output->bo); + + printf("output: %ux%u\n", output->width, output->height); + vic_image_dump(output, stdout); + + err = drm_tegra_job_new(channel, &job); + if (err < 0) { + fprintf(stderr, "failed to create job: %s\n", strerror(-err)); + return 1; + } + + err = drm_tegra_job_get_pushbuf(job, &pushbuf); + if (err < 0) { + fprintf(stderr, "failed to create push buffer: %s\n", strerror(-err)); + return 1; + } + + err = drm_tegra_pushbuf_begin(pushbuf, 32, &pb); + if (err < 0) { + fprintf(stderr, "failed to prepare push buffer: %s\n", strerror(-err)); + return 1; + } + + err = vic_clear(vic, output, 1023, 0, 0, 1023); + if (err < 0) { + fprintf(stderr, "failed to clear surface: %s\n", strerror(-err)); + return err; + } + + err = vic->ops->execute(vic, pushbuf, &pb, output, NULL, 0); + if (err < 0) { + fprintf(stderr, "failed to execute operation: %s\n", strerror(-err)); + return 1; + } + + err = drm_tegra_pushbuf_sync_cond(pushbuf, &pb, vic->syncpt, + DRM_TEGRA_SYNC_COND_OP_DONE); + if (err < 0) { + fprintf(stderr, "failed to push syncpoint: %s\n", strerror(-err)); + return 1; + } + + err = drm_tegra_pushbuf_end(pushbuf, pb); + if (err < 0) { + fprintf(stderr, "failed to update push buffer: %s\n", strerror(-err)); + return 1; + } + + err = drm_tegra_job_submit(job, NULL); + if (err < 0) { + fprintf(stderr, "failed to submit job: %s\n", strerror(-err)); + return 1; + } + + err = drm_tegra_job_wait(job, 1000000000); + if (err < 0) { + fprintf(stderr, "failed to wait for job: %s\n", strerror(-err)); + return 1; + } + + printf("output: %ux%u\n", output->width, output->height); + vic_image_dump(output, stdout); + + drm_tegra_job_free(job); + vic_image_free(output); + vic_free(vic); + drm_tegra_channel_close(channel); + drm_tegra_close(drm); + close(fd); + + return 0; +} diff -Nru libdrm-2.4.110/tests/tegra/vic-flip.c libdrm-2.4.113/tests/tegra/vic-flip.c --- libdrm-2.4.110/tests/tegra/vic-flip.c 1970-01-01 00:00:00.000000000 +0000 +++ libdrm-2.4.113/tests/tegra/vic-flip.c 2022-08-31 14:38:38.000000000 +0000 @@ -0,0 +1,333 @@ +/* + * 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 +#include +#include +#include +#include + +#include "tegra.h" + +#include "host1x.h" +#include "vic.h" + +/* clear output image to red */ +static int clear(struct vic *vic, struct drm_tegra_channel *channel, + struct vic_image *output) +{ + struct drm_tegra_pushbuf *pushbuf; + struct drm_tegra_job *job; + uint32_t *ptr; + int err; + + err = drm_tegra_job_new(channel, &job); + if (err < 0) { + fprintf(stderr, "failed to create job: %s\n", strerror(-err)); + return 1; + } + + err = drm_tegra_job_get_pushbuf(job, &pushbuf); + if (err < 0) { + fprintf(stderr, "failed to create push buffer: %s\n", strerror(-err)); + return 1; + } + + err = drm_tegra_pushbuf_begin(pushbuf, 32, &ptr); + if (err < 0) { + fprintf(stderr, "failed to prepare push buffer: %s\n", strerror(-err)); + return err; + } + + err = vic_clear(vic, output, 1023, 0, 0, 1023); + if (err < 0) { + fprintf(stderr, "failed to clear surface: %s\n", strerror(-err)); + return err; + } + + err = vic->ops->execute(vic, pushbuf, &ptr, output, NULL, 0); + if (err < 0) { + fprintf(stderr, "failed to execute operation: %s\n", strerror(-err)); + return err; + } + + err = drm_tegra_pushbuf_sync_cond(pushbuf, &ptr, vic->syncpt, + DRM_TEGRA_SYNC_COND_OP_DONE); + if (err < 0) { + fprintf(stderr, "failed to push syncpoint: %s\n", strerror(-err)); + return err; + } + + err = drm_tegra_pushbuf_end(pushbuf, ptr); + if (err < 0) { + fprintf(stderr, "failed to update push buffer: %s\n", strerror(-err)); + return err; + } + + err = drm_tegra_job_submit(job, NULL); + if (err < 0) { + fprintf(stderr, "failed to submit job: %s\n", strerror(-err)); + return err; + } + + err = drm_tegra_job_wait(job, 1000000000); + if (err < 0) { + fprintf(stderr, "failed to wait for job: %s\n", strerror(-err)); + return err; + } + + drm_tegra_job_free(job); + + return 0; +} + +/* fill bottom half of image to blue */ +static int fill(struct vic *vic, struct drm_tegra_channel *channel, + struct vic_image *output) +{ + struct drm_tegra_pushbuf *pushbuf; + struct drm_tegra_job *job; + uint32_t *ptr; + int err; + + err = drm_tegra_job_new(channel, &job); + if (err < 0) { + fprintf(stderr, "failed to create job: %s\n", strerror(-err)); + return 1; + } + + err = drm_tegra_job_get_pushbuf(job, &pushbuf); + if (err < 0) { + fprintf(stderr, "failed to create push buffer: %s\n", strerror(-err)); + return 1; + } + + err = drm_tegra_pushbuf_begin(pushbuf, 32, &ptr); + if (err < 0) { + fprintf(stderr, "failed to prepare push buffer: %s\n", strerror(-err)); + return err; + } + + err = vic->ops->fill(vic, output, 0, output->height / 2, output->width - 1, + output->height - 1, 0, 0, 1023, 1023); + if (err < 0) { + fprintf(stderr, "failed ot fill surface: %s\n", strerror(-err)); + return err; + } + + err = vic->ops->execute(vic, pushbuf, &ptr, output, NULL, 0); + if (err < 0) { + fprintf(stderr, "failed to execute operation: %s\n", strerror(-err)); + return err; + } + + err = drm_tegra_pushbuf_sync_cond(pushbuf, &ptr, vic->syncpt, + DRM_TEGRA_SYNC_COND_OP_DONE); + if (err < 0) { + fprintf(stderr, "failed to push syncpoint: %s\n", strerror(-err)); + return err; + } + + err = drm_tegra_pushbuf_end(pushbuf, ptr); + if (err < 0) { + fprintf(stderr, "failed to update push buffer: %s\n", strerror(-err)); + return err; + } + + err = drm_tegra_job_submit(job, NULL); + if (err < 0) { + fprintf(stderr, "failed to submit job: %s\n", strerror(-err)); + return err; + } + + err = drm_tegra_job_wait(job, 1000000000); + if (err < 0) { + fprintf(stderr, "failed to wait for job: %s\n", strerror(-err)); + return err; + } + + drm_tegra_job_free(job); + + return 0; +} + +/* flip image vertically */ +static int flip(struct vic *vic, struct drm_tegra_channel *channel, + struct vic_image *output, struct vic_image *input) +{ + struct drm_tegra_pushbuf *pushbuf; + struct drm_tegra_job *job; + uint32_t *ptr; + int err; + + err = drm_tegra_job_new(channel, &job); + if (err < 0) { + fprintf(stderr, "failed to create job: %s\n", strerror(-err)); + return 1; + } + + err = drm_tegra_job_get_pushbuf(job, &pushbuf); + if (err < 0) { + fprintf(stderr, "failed to create push buffer: %s\n", strerror(-err)); + return 1; + } + + err = drm_tegra_pushbuf_begin(pushbuf, 32, &ptr); + if (err < 0) { + fprintf(stderr, "failed to prepare push buffer: %s\n", strerror(-err)); + return err; + } + + err = vic->ops->flip(vic, output, input); + if (err < 0) { + fprintf(stderr, "failed to flip: %s\n", strerror(-err)); + return err; + } + + err = vic->ops->execute(vic, pushbuf, &ptr, output, &input, 1); + if (err < 0) { + fprintf(stderr, "failed to execute operation: %s\n", strerror(-err)); + return err; + } + + err = drm_tegra_pushbuf_sync_cond(pushbuf, &ptr, vic->syncpt, + DRM_TEGRA_SYNC_COND_OP_DONE); + if (err < 0) { + fprintf(stderr, "failed to push syncpoint: %s\n", strerror(-err)); + return err; + } + + err = drm_tegra_pushbuf_end(pushbuf, ptr); + if (err < 0) { + fprintf(stderr, "failed to update push buffer: %s\n", strerror(-err)); + return err; + } + + err = drm_tegra_job_submit(job, NULL); + if (err < 0) { + fprintf(stderr, "failed to submit job: %s\n", strerror(-err)); + return err; + } + + err = drm_tegra_job_wait(job, 1000000000); + if (err < 0) { + fprintf(stderr, "failed to wait for job: %s\n", strerror(-err)); + return err; + } + + drm_tegra_job_free(job); + + return 0; +} + +int main(int argc, char *argv[]) +{ + const unsigned int format = VIC_PIXEL_FORMAT_A8R8G8B8; + const unsigned int kind = VIC_BLK_KIND_PITCH; + const unsigned int width = 16, height = 16; + const char *device = "/dev/dri/renderD128"; + struct drm_tegra_channel *channel; + struct vic_image *input, *output; + struct drm_tegra *drm; + unsigned int version; + struct vic *vic; + int fd, err; + + if (argc > 1) + device = argv[1]; + + fd = open(device, O_RDWR); + if (fd < 0) { + fprintf(stderr, "open() failed: %s\n", strerror(errno)); + return 1; + } + + err = drm_tegra_new(fd, &drm); + if (err < 0) { + fprintf(stderr, "failed to open Tegra device: %s\n", strerror(-err)); + close(fd); + return 1; + } + + err = drm_tegra_channel_open(drm, DRM_TEGRA_VIC, &channel); + if (err < 0) { + fprintf(stderr, "failed to open channel to VIC: %s\n", strerror(-err)); + return 1; + } + + version = drm_tegra_channel_get_version(channel); + printf("version: %08x\n", version); + + err = vic_new(drm, channel, &vic); + if (err < 0) { + fprintf(stderr, "failed to create VIC: %s\n", strerror(-err)); + return 1; + } + + err = vic_image_new(vic, width, height, format, kind, DRM_TEGRA_CHANNEL_MAP_READ_WRITE, + &input); + if (err < 0) { + fprintf(stderr, "failed to create input image: %d\n", err); + return 1; + } + + err = vic_image_new(vic, width, height, format, kind, DRM_TEGRA_CHANNEL_MAP_READ_WRITE, + &output); + if (err < 0) { + fprintf(stderr, "failed to create output image: %d\n", err); + return 1; + } + + err = clear(vic, channel, input); + if (err < 0) { + fprintf(stderr, "failed to clear image: %s\n", strerror(-err)); + return 1; + } + + err = fill(vic, channel, input); + if (err < 0) { + fprintf(stderr, "failed to fill rectangle: %s\n", strerror(-err)); + return 1; + } + + err = flip(vic, channel, output, input); + if (err < 0) { + fprintf(stderr, "failed to flip image: %s\n", strerror(-err)); + return 1; + } + + printf("input: %ux%u\n", input->width, input->height); + vic_image_dump(input, stdout); + + printf("output: %ux%u\n", output->width, output->height); + vic_image_dump(output, stdout); + + vic_image_free(output); + vic_image_free(input); + + vic_free(vic); + drm_tegra_channel_close(channel); + drm_tegra_close(drm); + close(fd); + + return 0; +} diff -Nru libdrm-2.4.110/tests/tegra/vic.h libdrm-2.4.113/tests/tegra/vic.h --- libdrm-2.4.110/tests/tegra/vic.h 1970-01-01 00:00:00.000000000 +0000 +++ libdrm-2.4.113/tests/tegra/vic.h 2022-08-31 14:38:38.000000000 +0000 @@ -0,0 +1,181 @@ +/* + * 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 + +#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; +}; + + +#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 **ptrp, uint32_t method, + uint32_t value) +{ + *(*ptrp)++ = HOST1X_OPCODE_INCR(VIC_UCLASS_METHOD_OFFSET, 2); + *(*ptrp)++ = method >> 2; + *(*ptrp)++ = value; +} + +static inline void VIC_PUSH_BUFFER(struct drm_tegra_pushbuf *pushbuf, + uint32_t **ptrp, uint32_t method, + struct drm_tegra_mapping *map, + unsigned long offset, unsigned long flags) +{ + *(*ptrp)++ = HOST1X_OPCODE_INCR(VIC_UCLASS_METHOD_OFFSET, 2); + *(*ptrp)++ = method >> 2; + + drm_tegra_pushbuf_relocate(pushbuf, ptrp, map, offset, 8, flags); +} + +struct vic_image; +struct vic; + +struct vic_ops { + int (*fill)(struct vic *vic, 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); + int (*blit)(struct vic *vic, struct vic_image *output, + struct vic_image *input); + int (*flip)(struct vic *vic, struct vic_image *output, + struct vic_image *input); + int (*execute)(struct vic *vic, + struct drm_tegra_pushbuf *pushbuf, + uint32_t **ptrp, + struct vic_image *output, + struct vic_image **inputs, + unsigned int num_inputs); + void (*free)(struct vic *vic); +}; + +struct vic { + struct drm_tegra *drm; + struct drm_tegra_channel *channel; + struct drm_tegra_syncpoint *syncpt; + const struct vic_ops *ops; + unsigned int version; +}; + +int vic_new(struct drm_tegra *drm, struct drm_tegra_channel *channel, + struct vic **vicp); +void vic_free(struct vic *vic); + +int vic_clear(struct vic *vic, struct vic_image *output, unsigned int alpha, + unsigned int red, unsigned int green, unsigned int blue); + +struct vic_image { + struct drm_tegra_bo *bo; + struct drm_tegra_mapping *map; + 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 *vic, unsigned int width, unsigned int height, + unsigned int format, unsigned int kind, uint32_t flags, + struct vic_image **imagep); +void vic_image_free(struct vic_image *image); +void vic_image_dump(struct vic_image *image, FILE *fp); + +#endif diff -Nru libdrm-2.4.110/tests/util/kms.c libdrm-2.4.113/tests/util/kms.c --- libdrm-2.4.110/tests/util/kms.c 2022-02-16 10:00:13.000000000 +0000 +++ libdrm-2.4.113/tests/util/kms.c 2022-08-31 14:38:38.000000000 +0000 @@ -96,33 +96,6 @@ ARRAY_SIZE(connector_status_names)); } -static const struct type_name connector_type_names[] = { - { DRM_MODE_CONNECTOR_Unknown, "unknown" }, - { DRM_MODE_CONNECTOR_VGA, "VGA" }, - { DRM_MODE_CONNECTOR_DVII, "DVI-I" }, - { DRM_MODE_CONNECTOR_DVID, "DVI-D" }, - { DRM_MODE_CONNECTOR_DVIA, "DVI-A" }, - { DRM_MODE_CONNECTOR_Composite, "composite" }, - { DRM_MODE_CONNECTOR_SVIDEO, "s-video" }, - { DRM_MODE_CONNECTOR_LVDS, "LVDS" }, - { DRM_MODE_CONNECTOR_Component, "component" }, - { DRM_MODE_CONNECTOR_9PinDIN, "9-pin DIN" }, - { DRM_MODE_CONNECTOR_DisplayPort, "DP" }, - { DRM_MODE_CONNECTOR_HDMIA, "HDMI-A" }, - { DRM_MODE_CONNECTOR_HDMIB, "HDMI-B" }, - { DRM_MODE_CONNECTOR_TV, "TV" }, - { DRM_MODE_CONNECTOR_eDP, "eDP" }, - { DRM_MODE_CONNECTOR_VIRTUAL, "Virtual" }, - { DRM_MODE_CONNECTOR_DSI, "DSI" }, - { DRM_MODE_CONNECTOR_DPI, "DPI" }, -}; - -const char *util_lookup_connector_type_name(unsigned int type) -{ - return util_lookup_type_name(type, connector_type_names, - ARRAY_SIZE(connector_type_names)); -} - static const char * const modules[] = { "i915", "amdgpu", @@ -150,6 +123,7 @@ "komeda", "imx-dcss", "mxsfb-drm", + "simpledrm", }; int util_open(const char *device, const char *module) diff -Nru libdrm-2.4.110/tests/util/kms.h libdrm-2.4.113/tests/util/kms.h --- libdrm-2.4.110/tests/util/kms.h 2022-02-16 10:00:13.000000000 +0000 +++ libdrm-2.4.113/tests/util/kms.h 2022-08-31 14:38:38.000000000 +0000 @@ -28,7 +28,6 @@ const char *util_lookup_encoder_type_name(unsigned int type); const char *util_lookup_connector_status_name(unsigned int type); -const char *util_lookup_connector_type_name(unsigned int type); int util_open(const char *device, const char *module); diff -Nru libdrm-2.4.110/xf86atomic.h libdrm-2.4.113/xf86atomic.h --- libdrm-2.4.110/xf86atomic.h 2022-02-16 10:00:13.000000000 +0000 +++ libdrm-2.4.113/xf86atomic.h 2022-08-31 14:38:38.000000000 +0000 @@ -108,7 +108,7 @@ c = atomic_read(v); while (c != unless && (old = atomic_cmpxchg(v, c, c + add)) != c) c = old; - return c == unless; + return c != unless; } #endif diff -Nru libdrm-2.4.110/xf86drm.c libdrm-2.4.113/xf86drm.c --- libdrm-2.4.110/xf86drm.c 2022-02-16 10:00:13.000000000 +0000 +++ libdrm-2.4.113/xf86drm.c 2022-08-31 14:38:38.000000000 +0000 @@ -261,6 +261,7 @@ static bool drmGetAfrcFormatModifierNameFromArm(uint64_t modifier, FILE *fp) { + bool scan_layout; for (unsigned int i = 0; i < 2; ++i) { uint64_t coding_unit_block = (modifier >> (i * 4)) & AFRC_FORMAT_MOD_CU_SIZE_MASK; @@ -292,7 +293,7 @@ } } - bool scan_layout = + scan_layout = (modifier & AFRC_FORMAT_MOD_LAYOUT_SCAN) == AFRC_FORMAT_MOD_LAYOUT_SCAN; if (scan_layout) { fprintf(fp, "SCAN"); @@ -848,7 +849,7 @@ } #endif - fd = open(buf, O_RDWR | O_CLOEXEC, 0); + fd = open(buf, O_RDWR | O_CLOEXEC); drmMsg("drmOpenDevice: open result is %d, (%s)\n", fd, fd < 0 ? strerror(errno) : "OK"); if (fd >= 0) @@ -868,7 +869,7 @@ chmod(buf, devmode); } } - fd = open(buf, O_RDWR | O_CLOEXEC, 0); + fd = open(buf, O_RDWR | O_CLOEXEC); drmMsg("drmOpenDevice: open result is %d, (%s)\n", fd, fd < 0 ? strerror(errno) : "OK"); if (fd >= 0) @@ -906,7 +907,7 @@ return -EINVAL; sprintf(buf, dev_name, DRM_DIR_NAME, minor); - if ((fd = open(buf, O_RDWR | O_CLOEXEC, 0)) >= 0) + if ((fd = open(buf, O_RDWR | O_CLOEXEC)) >= 0) return fd; return -errno; } @@ -1134,7 +1135,7 @@ int retcode; sprintf(proc_name, "/proc/dri/%d/name", i); - if ((fd = open(proc_name, O_RDONLY, 0)) >= 0) { + if ((fd = open(proc_name, O_RDONLY)) >= 0) { retcode = read(fd, buf, sizeof(buf)-1); close(fd); if (retcode) { @@ -3891,7 +3892,7 @@ if (get_sysctl_pci_bus_info(maj, min, &info) != 0) return -EINVAL; - fd = open("/dev/pci", O_RDONLY, 0); + fd = open("/dev/pci", O_RDONLY); if (fd < 0) return -errno; @@ -5105,3 +5106,38 @@ return modifier_found; } + +/** + * Get a human-readable name for a DRM FourCC format. + * + * \param format The format. + * \return A malloc'ed string containing the format name. Caller is responsible + * for freeing it. + */ +drm_public char * +drmGetFormatName(uint32_t format) +{ + char *str; + size_t str_size, i; + char a, b, c, d; + + if (format == DRM_FORMAT_INVALID) + return strdup("INVALID"); + + str_size = 5; + str = malloc(str_size); + if (!str) + return NULL; + + a = (char) ((format >> 0) & 0xFF); + b = (char) ((format >> 8) & 0xFF); + c = (char) ((format >> 16) & 0xFF); + d = (char) ((format >> 24) & 0xFF); + snprintf(str, str_size, "%c%c%c%c", a, b, c, d); + + /* Trim spaces at the end */ + for (i = 3; i > 0 && str[i] == ' '; i--) + str[i] = '\0'; + + return str; +} diff -Nru libdrm-2.4.110/xf86drm.h libdrm-2.4.113/xf86drm.h --- libdrm-2.4.110/xf86drm.h 2022-02-16 10:00:13.000000000 +0000 +++ libdrm-2.4.113/xf86drm.h 2022-08-31 14:38:38.000000000 +0000 @@ -954,6 +954,9 @@ extern char * drmGetFormatModifierName(uint64_t modifier); +extern char * +drmGetFormatName(uint32_t format); + #ifndef fourcc_mod_get_vendor #define fourcc_mod_get_vendor(modifier) \ (((modifier) >> 56) & 0xff) diff -Nru libdrm-2.4.110/xf86drmMode.c libdrm-2.4.113/xf86drmMode.c --- libdrm-2.4.110/xf86drmMode.c 2022-02-16 10:00:13.000000000 +0000 +++ libdrm-2.4.113/xf86drmMode.c 2022-08-31 14:38:38.000000000 +0000 @@ -610,6 +610,29 @@ return _drmModeGetConnector(fd, connector_id, 0); } +drm_public uint32_t drmModeConnectorGetPossibleCrtcs(int fd, + const drmModeConnector *connector) +{ + drmModeEncoder *encoder; + int i; + uint32_t possible_crtcs; + + possible_crtcs = 0; + for (i = 0; i < connector->count_encoders; i++) { + encoder = drmModeGetEncoder(fd, connector->encoders[i]); + if (!encoder) { + return 0; + } + + possible_crtcs |= encoder->possible_crtcs; + drmModeFreeEncoder(encoder); + } + + if (possible_crtcs == 0) + errno = ENOENT; + return possible_crtcs; +} + drm_public int drmModeAttachMode(int fd, uint32_t connector_id, drmModeModeInfoPtr mode_info) { struct drm_mode_mode_cmd res; @@ -1348,7 +1371,7 @@ return req; } -drm_public drmModeAtomicReqPtr drmModeAtomicDuplicate(drmModeAtomicReqPtr old) +drm_public drmModeAtomicReqPtr drmModeAtomicDuplicate(const drmModeAtomicReqPtr old) { drmModeAtomicReqPtr new; @@ -1378,7 +1401,7 @@ } drm_public int drmModeAtomicMerge(drmModeAtomicReqPtr base, - drmModeAtomicReqPtr augment) + const drmModeAtomicReqPtr augment) { uint32_t i; @@ -1411,7 +1434,7 @@ return 0; } -drm_public int drmModeAtomicGetCursor(drmModeAtomicReqPtr req) +drm_public int drmModeAtomicGetCursor(const drmModeAtomicReqPtr req) { if (!req) return -EINVAL; @@ -1480,7 +1503,7 @@ return first->cursor - second->cursor; } -drm_public int drmModeAtomicCommit(int fd, drmModeAtomicReqPtr req, +drm_public int drmModeAtomicCommit(int fd, const drmModeAtomicReqPtr req, uint32_t flags, void *user_data) { drmModeAtomicReqPtr sorted; @@ -1747,3 +1770,56 @@ { drmFree(ptr); } + +drm_public const char * +drmModeGetConnectorTypeName(uint32_t connector_type) +{ + /* Keep the strings in sync with the kernel's drm_connector_enum_list in + * drm_connector.c. */ + switch (connector_type) { + case DRM_MODE_CONNECTOR_Unknown: + return "Unknown"; + case DRM_MODE_CONNECTOR_VGA: + return "VGA"; + case DRM_MODE_CONNECTOR_DVII: + return "DVI-I"; + case DRM_MODE_CONNECTOR_DVID: + return "DVI-D"; + case DRM_MODE_CONNECTOR_DVIA: + return "DVI-A"; + case DRM_MODE_CONNECTOR_Composite: + return "Composite"; + case DRM_MODE_CONNECTOR_SVIDEO: + return "SVIDEO"; + case DRM_MODE_CONNECTOR_LVDS: + return "LVDS"; + case DRM_MODE_CONNECTOR_Component: + return "Component"; + case DRM_MODE_CONNECTOR_9PinDIN: + return "DIN"; + case DRM_MODE_CONNECTOR_DisplayPort: + return "DP"; + case DRM_MODE_CONNECTOR_HDMIA: + return "HDMI-A"; + case DRM_MODE_CONNECTOR_HDMIB: + return "HDMI-B"; + case DRM_MODE_CONNECTOR_TV: + return "TV"; + case DRM_MODE_CONNECTOR_eDP: + return "eDP"; + case DRM_MODE_CONNECTOR_VIRTUAL: + return "Virtual"; + case DRM_MODE_CONNECTOR_DSI: + return "DSI"; + case DRM_MODE_CONNECTOR_DPI: + return "DPI"; + case DRM_MODE_CONNECTOR_WRITEBACK: + return "Writeback"; + case DRM_MODE_CONNECTOR_SPI: + return "SPI"; + case DRM_MODE_CONNECTOR_USB: + return "USB"; + default: + return NULL; + } +} diff -Nru libdrm-2.4.110/xf86drmMode.h libdrm-2.4.113/xf86drmMode.h --- libdrm-2.4.110/xf86drmMode.h 2022-02-16 10:00:13.000000000 +0000 +++ libdrm-2.4.113/xf86drmMode.h 2022-08-31 14:38:38.000000000 +0000 @@ -381,6 +381,19 @@ uint32_t connector_id); /** + * Get a bitmask of CRTCs a connector is compatible with. + * + * The bits reference CRTC indices. If the n-th CRTC is compatible with the + * connector, the n-th bit will be set. The indices are taken from the array + * returned by drmModeGetResources(). The indices are different from the object + * IDs. + * + * Zero is returned on error. + */ +extern uint32_t drmModeConnectorGetPossibleCrtcs(int fd, + const drmModeConnector *connector); + +/** * Attaches the given mode to an connector. */ extern int drmModeAttachMode(int fd, uint32_t connectorId, drmModeModeInfoPtr mode_info); @@ -433,18 +446,18 @@ typedef struct _drmModeAtomicReq drmModeAtomicReq, *drmModeAtomicReqPtr; extern drmModeAtomicReqPtr drmModeAtomicAlloc(void); -extern drmModeAtomicReqPtr drmModeAtomicDuplicate(drmModeAtomicReqPtr req); +extern drmModeAtomicReqPtr drmModeAtomicDuplicate(const drmModeAtomicReqPtr req); extern int drmModeAtomicMerge(drmModeAtomicReqPtr base, - drmModeAtomicReqPtr augment); + const drmModeAtomicReqPtr augment); extern void drmModeAtomicFree(drmModeAtomicReqPtr req); -extern int drmModeAtomicGetCursor(drmModeAtomicReqPtr req); +extern int drmModeAtomicGetCursor(const drmModeAtomicReqPtr req); extern void drmModeAtomicSetCursor(drmModeAtomicReqPtr req, int cursor); extern int drmModeAtomicAddProperty(drmModeAtomicReqPtr req, uint32_t object_id, uint32_t property_id, uint64_t value); extern int drmModeAtomicCommit(int fd, - drmModeAtomicReqPtr req, + const drmModeAtomicReqPtr req, uint32_t flags, void *user_data); @@ -475,6 +488,15 @@ extern int drmModeRevokeLease(int fd, uint32_t lessee_id); +/** + * Get a string describing a connector type. + * + * NULL is returned if the connector type is unsupported. Callers should handle + * this gracefully, e.g. by falling back to "Unknown" or printing the raw value. + */ +extern const char * +drmModeGetConnectorTypeName(uint32_t connector_type); + #if defined(__cplusplus) } #endif